diff options
author | Toni Jones <toni.jones@ni.com> | 2019-02-21 14:57:05 -0600 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2020-10-06 15:20:37 -0500 |
commit | f8674adcd3eb50ba9629726627305235aaa74006 (patch) | |
tree | a545e71f63cd07697886dc8e0df4bfc0220fb1f6 /host/lib/ic_reg_maps | |
parent | d0892d5738b254d312fe7f9ee42a6b0263b6a16e (diff) | |
download | uhd-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.
Diffstat (limited to 'host/lib/ic_reg_maps')
-rwxr-xr-x | host/lib/ic_reg_maps/common.py | 92 |
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) |