def add_registerData(self, parent: minidom.Element, node: RegNode) -> None: if self.standard == Standard.IEEE_1685_2014: # registers and registerFiles can be interleaved for child in node.children(skip_not_present=False): if isinstance(child, RegNode): self.add_register(parent, child) elif isinstance(child, (AddrmapNode, RegfileNode)): self.add_registerFile(parent, child) elif isinstance(child, MemNode): self.msg.warning( "IP-XACT does not support 'mem' nodes that are nested in hierarchy. Discarding '%s'" % child.get_path(), child.inst.inst_src_ref) elif self.standard == Standard.IEEE_1685_2009: # registers must all be listed before register files for child in node.children(skip_not_present=False): if isinstance(child, RegNode): self.add_register(parent, child) for child in node.children(skip_not_present=False): if isinstance(child, (AddrmapNode, RegfileNode)): self.add_registerFile(parent, child) elif isinstance(child, MemNode): self.msg.warning( "IP-XACT does not support 'mem' nodes that are nested in hierarchy. Discarding '%s'" % child.get_path(), child.inst.inst_src_ref) else: raise RuntimeError
def get_reg_reset(self, node: RegNode) -> str: """ Concatenate the value of the individual fields to form the register value """ reg_reset = 0 # Deduce the reset value for field in node.fields(): if isinstance(field, FieldNode): field_reset = field.get_property('reset', default=0) field_lsb_pos = field.lsb reg_reset |= field_reset << field_lsb_pos # Format the value register_width = node.get_property('regwidth') no_of_nib = register_width / 4 # 64bit data if no_of_nib == 16: format_number = no_of_nib + 3 # 32bit data elif no_of_nib == 8: format_number = no_of_nib + 1 # 16bit or 8bit data else: format_number = no_of_nib # format the string to have underscore in hex value format_str = '{:0' + str(int(format_number)) + '_x}' final_value = (format_str.format(reg_reset)) return (str(register_width) + "'h" + final_value.upper())
def has_intr(self, node: RegNode) -> bool: """ Register has interrupt fields """ for f in node.fields(): if f.get_property('intr'): return True return False
def enter_Reg(self, node: RegNode) -> None: if self.unroll: addr = node.absolute_address size = node.size else: addr = node.raw_absolute_address size = node.total_size print( f"0x{addr:0{self.hex_digits}x}-0x{addr+size-1:0{self.hex_digits}x}:", node.get_path(empty_array_suffix="[{dim:d}]"))
def get_reg_access(self, node: RegNode) -> str: """ Get register's access for the map """ # Default value regaccess = "RW" # Check if the udp is defined is_defined = self.check_udp("regaccess_p", node) if not is_defined: return regaccess # Get the upd value regaccess = node.get_property("regaccess_p", default=regaccess) return regaccess
def convert_reg(rdlc: RDLCompiler, obj: node.RegNode) -> dict: if obj.is_array: # Use the RDL Compiler message system to print an error # fatal() raises RDLCompileError rdlc.msg.fatal("JSON export does not support arrays", obj.inst.inst_src_ref) # Convert information about the register json_obj = dict() json_obj['type'] = 'reg' json_obj['inst_name'] = obj.inst_name json_obj['addr_offset'] = obj.address_offset # Iterate over all the fields in this reg and convert them json_obj['children'] = [] for field in obj.fields(): json_field = convert_field(rdlc, field) json_obj['children'].append(json_field) return json_obj
def reg_fields_are_low_to_high(node: RegNode) -> bool: for field in node.fields(): if field.msb < field.lsb: return True return False
def add_register(self, parent: minidom.Element, node: RegNode) -> None: register = self.doc.createElement(self.ns + "register") parent.appendChild(register) self.add_nameGroup(register, self.get_name(node), node.get_property("name", default=None), node.get_property("desc")) if (self.standard >= Standard.IEEE_1685_2014 ) and not node.get_property("ispresent"): self.add_value(register, self.ns + "isPresent", "0") if node.is_array: if node.array_stride != (node.get_property("regwidth") / 8): self.msg.fatal( "IP-XACT does not support register arrays whose stride is larger then the register's size", node.inst.inst_src_ref) for dim in node.array_dimensions: self.add_value(register, self.ns + "dim", "%d" % dim) self.add_value(register, self.ns + "addressOffset", self.hex_str(self.get_reg_addr_offset(node))) # DNE: <spirit/ipxact:typeIdentifier> self.add_value(register, self.ns + "size", "%d" % node.get_property("regwidth")) if self._max_width is None: self._max_width = node.get_property("regwidth") else: self._max_width = max(node.get_property("regwidth"), self._max_width) # DNE: <spirit/ipxact:volatile> # DNE: <spirit/ipxact:access> if self.standard <= Standard.IEEE_1685_2009: reset = 0 mask = 0 for field in node.fields(skip_not_present=False): field_reset = field.get_property("reset") if field_reset is not None: field_mask = ((1 << field.width) - 1) << field.lsb field_reset = (field_reset << field.lsb) & field_mask reset |= field_reset mask |= field_mask if mask != 0: reset_el = self.doc.createElement(self.ns + "reset") register.appendChild(reset_el) self.add_value(reset_el, self.ns + "value", self.hex_str(reset)) self.add_value(reset_el, self.ns + "mask", self.hex_str(mask)) for field in node.fields(skip_not_present=False): self.add_field(register, field) # DNE: <spirit/ipxact:alternateRegisters> [...] # DNE: <spirit/ipxact:parameters> vendorExtensions = self.doc.createElement(self.ns + "vendorExtensions") self.register_vendorExtensions(vendorExtensions, node) if vendorExtensions.hasChildNodes(): register.appendChild(vendorExtensions)
def __init__(self, **kwargs): """ Constructor for the Verilog Exporter class Parameters ---------- user_template_dir: str Path to a directory where user-defined template overrides are stored. user_template_context: dict Additional context variables to load into the template namespace. """ user_template_dir = kwargs.pop("user_template_dir", None) self.user_template_context = kwargs.pop("user_template_context", dict()) # Check for stray kwargs if kwargs: raise TypeError("got an unexpected keyword argument '%s'" % list(kwargs.keys())[0]) if user_template_dir: loader = jj.ChoiceLoader([ jj.FileSystemLoader(user_template_dir), jj.FileSystemLoader( os.path.join(os.path.dirname(__file__), "templates")), jj.PrefixLoader( { 'user': jj.FileSystemLoader(user_template_dir), 'base': jj.FileSystemLoader( os.path.join(os.path.dirname(__file__), "templates")) }, delimiter=":") ]) else: loader = jj.ChoiceLoader([ jj.FileSystemLoader( os.path.join(os.path.dirname(__file__), "templates")), jj.PrefixLoader( { 'base': jj.FileSystemLoader( os.path.join(os.path.dirname(__file__), "templates")) }, delimiter=":") ]) self.jj_env = jj.Environment(loader=loader, undefined=jj.StrictUndefined) # Define variables used during export RegNode.add_derived_property(self.bit_range) RegNode.add_derived_property(self.signal_prefix) FieldNode.add_derived_property(self.is_hw_writable) FieldNode.add_derived_property(self.is_hw_readable) FieldNode.add_derived_property(self.bit_range) FieldNode.add_derived_property(self.signal_prefix) # Top-level node self.top = None # Dictionary of group-like nodes (addrmap, regfile) and their bus # widths. # key = node path # value = max accesswidth/memwidth used in node's descendants self.bus_width_db = {} # Dictionary of root-level type definitions # key = definition type name # value = representative object # components, this is the original_def (which can be None in some cases) self.namespace_db = {}