aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xhost/lib/ic_reg_maps/common.py50
-rwxr-xr-xhost/lib/ic_reg_maps/gen_zbx_cpld_regs.py63
-rw-r--r--host/lib/usrp/dboard/zbx/zbx_cpld_ctrl.cpp2
3 files changed, 80 insertions, 35 deletions
diff --git a/host/lib/ic_reg_maps/common.py b/host/lib/ic_reg_maps/common.py
index a689872ff..2275c68e2 100755
--- a/host/lib/ic_reg_maps/common.py
+++ b/host/lib/ic_reg_maps/common.py
@@ -235,6 +235,18 @@ def to_num(arg):
"""
return int(eval(arg))
+def is_int(arg):
+ """
+ check whether arg is convertable to an integer
+ (including non-decimal representation)
+ """
+ try:
+ to_num(arg)
+ return True
+ except:
+ return False
+
+
class reg:
def __init__(self, reg_des):
self.is_array = False
@@ -247,6 +259,22 @@ class reg:
'Error parsing register description: "{}"\nWhat: {}'
.format(reg_des, e))
+ def _parse_options(self, optionstr):
+ """
+ `optionstr` contains additional register information in a
+ comma-separated list as key=value pairs.
+
+ For backward compability a number <x> is converted to
+ `default=<x>,rw`
+ which retains the previous behaviour.
+ """
+ if is_int(optionstr):
+ # convert number into option list for backward compability
+ optionstr = f"default={optionstr},rw"
+ options = [option.partition("=") for option in optionstr.split(",")]
+ result = { item[0] : item[2] or None for item in options }
+ return result
+
def parse(self, reg_des):
"""
Parse a regmap line.
@@ -268,15 +296,15 @@ class reg:
initialized to 0. duper_reg is an array of length 128, of 32-bit registers.
"""
x = re.match(
- r'^(\w*)(\[([0-9:]*)\])?\s*(\w*)\[(.*)\]\s*(\w*)\s*(.*)$',
+ r'^(\w*)(\[([0-9:]*)\])?\s*(\w*)\[(.*)\]\s*([=,\w]*)\s*(.*)$',
reg_des)
- name, _, addr_range, addr, bit_range, default, enums = x.groups()
+ name, _, addr_range, addr, bit_range, options, enums = x.groups()
#store variables
self._name = name
self._addr = to_num(addr)
if ':' in bit_range: self._addr_spec = sorted(map(int, bit_range.split(':')))
else: self._addr_spec = int(bit_range), int(bit_range)
- self._default = to_num(default)
+ self.options = self._parse_options(options)
#extract enum
self._enums = list()
if enums:
@@ -313,9 +341,10 @@ class reg:
def get_enums(self): return self._enums
def get_name(self): return self._name
def get_default(self):
+ default_val = to_num(self.options.get("default", "0"))
for key, val in self.get_enums():
- if val == self._default: return ('%s_%s'%(self.get_name(), key)).upper()
- return self._default
+ if val == default_val: return ('%s_%s'%(self.get_name(), key)).upper()
+ return default_val
def get_type(self):
if self.get_enums(): return '%s_t'%self.get_name()
return 'uint%d_t'%max(2**math.ceil(math.log(self.get_bit_width(), 2)), 8)
@@ -334,6 +363,11 @@ class reg:
Return the step size for register arrays
"""
return self._addr_step
+ def is_readonly(self):
+ """
+ Check whether register is marked as readonly via option string
+ """
+ return "ro" in self.options
class mreg:
def __init__(self, mreg_des, regs):
@@ -353,7 +387,7 @@ class mreg:
def get_type(self):
return 'uint%d_t'%max(2**math.ceil(math.log(self.get_bit_width(), 2)), 8)
-def generate(name, regs_tmpl, body_tmpl='', py_body_tmpl='', file=__file__, append=False):
+def generate(name, regs_tmpl, body_tmpl='', py_body_tmpl='', file=__file__, append=False, **kwargs):
# determine if the destination file is a Python or C++ header file
out_file = sys.argv[1]
if out_file.endswith('.py'): # Write a Python file
@@ -373,15 +407,17 @@ def generate(name, regs_tmpl, body_tmpl='', py_body_tmpl='', file=__file__, appe
regs.append(reg(entry))
#evaluate the body template with the list of registers
- body = '\n '.join(parse_tmpl(body_template, regs=regs).splitlines())
+ body = '\n '.join(parse_tmpl(body_template, **dict(kwargs, regs=regs)).splitlines())
#evaluate the code template with the parsed registers and arguments
code = parse_tmpl(template,
+ **dict(kwargs,
name=name,
regs=regs,
mregs=mregs,
body=body,
file=file,
+ )
)
#write the generated code to file specified by argv1
diff --git a/host/lib/ic_reg_maps/gen_zbx_cpld_regs.py b/host/lib/ic_reg_maps/gen_zbx_cpld_regs.py
index 0efc8a4d7..fce051d53 100755
--- a/host/lib/ic_reg_maps/gen_zbx_cpld_regs.py
+++ b/host/lib/ic_reg_maps/gen_zbx_cpld_regs.py
@@ -18,24 +18,24 @@ REGS_TMPL = """\
########################################################################
## SLAVE SETUP
########################################################################
-BOARD_ID 0x0000[0:15] 0
-REVISION 0x0004[0:31] 0
-OLDEST_COMPAT_REVISION 0x0008[0:31] 0
+BOARD_ID 0x0000[0:15] ro
+REVISION 0x0004[0:31] ro
+OLDEST_COMPAT_REVISION 0x0008[0:31] ro
SCRATCH 0x000C[0:31] 0
-GIT_HASH 0x0010[0:31] 0
-ENABLE_TX_POS_7V0 0x0040[0] 0 disable, enable
-ENABLE_RX_POS_7V0 0x0040[1] 0 disable, enable
-ENABLE_POS_3V3 0x0040[2] 0 disable, enable
-P7V_B_STATUS 0x0044[0] 0
-P7V_A_STATUS 0x0044[1] 0
-PLL_REF_CLOCK_ENABLE 0x0048[0] 0 disable, enable
+GIT_HASH 0x0010[0:31] ro
+ENABLE_TX_POS_7V0 0x0040[0] scope=mpm disable, enable
+ENABLE_RX_POS_7V0 0x0040[1] scope=mpm disable, enable
+ENABLE_POS_3V3 0x0040[2] scope=mpm disable, enable
+P7V_B_STATUS 0x0044[0] scope=mpm,ro
+P7V_A_STATUS 0x0044[1] scope=mpm,ro
+PLL_REF_CLOCK_ENABLE 0x0048[0] scope=mpm disable, enable
########################################################################
## ATR
########################################################################
-CURRENT_RF0_CONFIG 0x1000[0:7] 1
-CURRENT_RF1_CONFIG 0x1000[8:15] 1
-CURRENT_RF0_DSA_CONFIG 0x1000[23:16] 1
-CURRENT_RF1_DSA_CONFIG 0x1000[31:24] 1
+CURRENT_RF0_CONFIG 0x1000[0:7] ro
+CURRENT_RF1_CONFIG 0x1000[8:15] ro
+CURRENT_RF0_DSA_CONFIG 0x1000[23:16] ro
+CURRENT_RF1_DSA_CONFIG 0x1000[31:24] ro
RF0_OPTION 0x1004[0:1] 0 sw_defined, classic_atr, fpga_state
RF1_OPTION 0x1004[8:9] 0 sw_defined, classic_atr, fpga_state
RF0_DSA_OPTION 0x1004[17:16] 0 sw_defined, classic_atr, fpga_state
@@ -52,8 +52,8 @@ ADDRESS 0x1020[16:22] 0
READ_FLAG 0x1020[23] 1 write, read
LO_SELECT 0x1020[24:26] 0 TX0_LO1, TX0_LO2, TX1_LO1, TX1_LO2, RX0_LO1, RX0_LO2, RX1_LO1, RX1_LO2
START_TRANSACTION 0x1020[28] 0 disable, enable
-SPI_READY 0x1020[30] 0
-DATA_VALID 0x1020[31] 0
+SPI_READY 0x1020[30] ro
+DATA_VALID 0x1020[31] ro
########################################################################
## LO SYNC
########################################################################
@@ -301,7 +301,7 @@ uint32_t get_field(zbx_cpld_field_t field, const size_t idx) {
void set_field(zbx_cpld_field_t field, uint32_t value) {
switch(field) {
% for addr in sorted(set([r.get_addr() for r in regs if not r.is_array])):
- % for reg in filter(lambda r: r.get_addr() == addr, regs):
+ % for reg in filter(lambda r: r.get_addr() == addr and not r.is_readonly(), regs):
case zbx_cpld_field_t::${reg.get_name()}:
${reg.get_name()} = static_cast<${reg.get_type()}>(value);
break;
@@ -399,17 +399,19 @@ void set_reg(uint16_t addr, uint32_t val)
}
}
-<%
- all_addrs = set()
- for reg in regs:
- for index in range(reg.get_array_len() if reg.is_array else 1):
- all_addrs.add(reg.get_addr() + index * reg.get_addr_step_size())
-%>
-std::set<size_t> get_all_addrs()
+template<typename T> std::set<T> get_all_addrs(bool include_ro = false)
{
- std::set<size_t> addrs;
- % for addr in sorted(all_addrs):
- addrs.insert(${addr});
+ std::set<T> addrs;
+ % for reg in filter(all_addr_filter, regs):
+ % if reg.is_readonly():
+ if (include_ro) {
+ % else:
+ {
+ % endif
+ % for index in range(reg.get_array_len() if reg.is_array else 1):
+ addrs.insert(${reg.get_addr() + index * reg.get_addr_step_size()});
+ % endfor
+ }
% endfor
return addrs;
}
@@ -440,11 +442,18 @@ uint16_t get_addr(const std::string& reg_name)
"""
if __name__ == '__main__':
+ import sys
import common
+ outfile=sys.argv[1]
+ if outfile.endswith(".hpp"):
+ all_addr_filter = lambda reg: "mpm" not in reg.options.get("scope", "")
+ else:
+ all_addr_filter = lambda reg: True
common.generate(
name='zbx_cpld_regs',
regs_tmpl=REGS_TMPL,
body_tmpl=BODY_TMPL,
py_body_tmpl=PY_BODY_TMPL,
file=__file__,
+ all_addr_filter=all_addr_filter
)
diff --git a/host/lib/usrp/dboard/zbx/zbx_cpld_ctrl.cpp b/host/lib/usrp/dboard/zbx/zbx_cpld_ctrl.cpp
index 352a7def9..28a7c6347 100644
--- a/host/lib/usrp/dboard/zbx/zbx_cpld_ctrl.cpp
+++ b/host/lib/usrp/dboard/zbx/zbx_cpld_ctrl.cpp
@@ -900,7 +900,7 @@ void zbx_cpld_ctrl::commit(const chan_t chan, const bool save_all)
UHD_LOG_TRACE(_log_id,
"Storing register cache " << (save_all ? "completely" : "selectively")
<< " to CPLD...");
- const auto changed_addrs = save_all ? _regs.get_all_addrs()
+ const auto changed_addrs = save_all ? _regs.get_all_addrs<size_t>()
: _regs.get_changed_addrs<size_t>();
for (const auto addr : changed_addrs) {
_poke32(addr, _regs.get_reg(addr), save_all ? NO_CHAN : chan);