aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToni Jones <toni.jones@ni.com>2019-02-21 14:57:05 -0600
committerAaron Rossetto <aaron.rossetto@ni.com>2020-10-06 15:20:37 -0500
commitf8674adcd3eb50ba9629726627305235aaa74006 (patch)
treea545e71f63cd07697886dc8e0df4bfc0220fb1f6
parentd0892d5738b254d312fe7f9ee42a6b0263b6a16e (diff)
downloaduhd-f8674adcd3eb50ba9629726627305235aaa74006.tar.gz
uhd-f8674adcd3eb50ba9629726627305235aaa74006.tar.bz2
uhd-f8674adcd3eb50ba9629726627305235aaa74006.zip
ic_reg_maps: Add common regmap template for Python
Add COMMON_PY_TMPL which is identical to COMMON_TMPL in functionality but generates Python syntax rather than C++ header syntax. Modify the generate function which will now determine if the destination regmap file is a Python file or not and will use the appropriate template.
-rwxr-xr-xhost/lib/ic_reg_maps/common.py92
1 files changed, 88 insertions, 4 deletions
diff --git a/host/lib/ic_reg_maps/common.py b/host/lib/ic_reg_maps/common.py
index 7e1eac086..46e02094a 100755
--- a/host/lib/ic_reg_maps/common.py
+++ b/host/lib/ic_reg_maps/common.py
@@ -91,6 +91,81 @@ private:
#endif /* INCLUDED_${name.upper()}_HPP */
"""
+# This template matches the functionality of COMMON_TMPL in Python syntax
+COMMON_PY_TMPL = """<% import time %>\
+##########################################################################
+# This file was generated by ${file} on ${time.strftime("%c")}
+<%text>##########################################################################</%text>
+
+from enum import Enum
+
+## Create a class for the register map
+class ${name}_t:
+ ## Create an enum for each register which has defined values
+ % for reg in regs:
+ % if reg.get_enums():
+ class ${reg.get_type()} (Enum):
+ % for i,enum in enumerate(reg.get_enums()):
+ ${reg.get_name().upper()}_${enum[0].upper()} = ${enum[1]}
+ % endfor
+ % endif
+ %endfor
+
+ def __init__(self):
+ ## Assign each register to its default value
+ self._state = None
+ % for reg in regs:
+ % if reg.get_enums():
+ self.${reg.get_name()} = self.${reg.get_name()}_t.${reg.get_default()}
+ % else:
+ self.${reg.get_name()} = ${reg.get_default()}
+ % endif
+ self.${reg.get_name()}_addr = ${reg.get_addr()}
+ self.${reg.get_name()}_mask = ${reg.get_mask()}
+ self.${reg.get_name()}_shift = ${reg.get_shift()}
+ % endfor
+
+ ${body}
+
+ def save_state(self):
+ if self._state is None:
+ self._state = ${name}_t()
+ % for reg in regs:
+ self._state.${reg.get_name()} = self.${reg.get_name()}
+ % endfor
+
+ def get_changed_addrs(self):
+ if self._state is None:
+ raise RuntimeError("No saved state")
+ #check each register for changes
+ addrs = set()
+ % for reg in regs:
+ if self._state.${reg.get_name()} != self.${reg.get_name()}:
+ addrs.add(${reg.get_addr()})
+ % endfor
+ return addrs
+
+ % for mreg in mregs:
+ def get_${mreg.get_name()}(self):
+ return ( <% shift = 0 %>
+ % for reg in mreg.get_regs():
+ % if reg.get_enums():
+ (self.${reg.get_name()}.value & ${reg.get_mask()} << ${shift}) |<% shift = shift + reg.get_bit_width() %>
+ % else:
+ (self.${reg.get_name()} & ${reg.get_mask()} << ${shift}) |<% shift = shift + reg.get_bit_width() %>
+ % endif
+ % endfor
+ 0
+ )
+
+ def set_${mreg.get_name()}(self, reg): <% shift = 0 %>
+ % for reg in mreg.get_regs():
+ self.${reg.get_name()} = (reg >> ${shift}) & ${reg.get_mask()}<% shift = shift + reg.get_bit_width() %>
+ % endfor
+
+ %endfor
+"""
+
def parse_tmpl(_tmpl_text, **kwargs):
return Template(_tmpl_text).render(**kwargs)
@@ -158,7 +233,16 @@ 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='', file=__file__, append=False):
+def generate(name, regs_tmpl, body_tmpl='', py_body_tmpl='', file=__file__, append=False):
+ # 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
+ template = COMMON_PY_TMPL
+ body_template = py_body_tmpl
+ else: # default to C++ Header
+ template = COMMON_TMPL
+ body_template = body_tmpl
+
#evaluate the regs template and parse each line into a register
regs = list(); mregs = list()
for entry in parse_tmpl(regs_tmpl).splitlines():
@@ -166,10 +250,10 @@ def generate(name, regs_tmpl, body_tmpl='', file=__file__, append=False):
else: regs.append(reg(entry))
#evaluate the body template with the list of registers
- body = '\n '.join(parse_tmpl(body_tmpl, regs=regs).splitlines())
+ body = '\n '.join(parse_tmpl(body_template, regs=regs).splitlines())
#evaluate the code template with the parsed registers and arguments
- code = parse_tmpl(COMMON_TMPL,
+ code = parse_tmpl(template,
name=name,
regs=regs,
mregs=mregs,
@@ -178,5 +262,5 @@ def generate(name, regs_tmpl, body_tmpl='', file=__file__, append=False):
)
#write the generated code to file specified by argv1
- with open(sys.argv[1], 'a' if append else 'w') as f:
+ with open(out_file, 'a' if append else 'w') as f:
f.write(code)