diff --git a/srdl2sv/components/addrmap.py b/srdl2sv/components/addrmap.py index d8275d9..77f2448 100644 --- a/srdl2sv/components/addrmap.py +++ b/srdl2sv/components/addrmap.py @@ -135,13 +135,14 @@ class AddrMap(Component): import_package_list = [] try: - import_package_list = [[ - AddrMap.templ_dict['import_package']['rtl'].format( - name = self.name), - ',\n' - ] for x in self.get_package_names()][0][:-1] + for x in self.get_package_names(): + import_package_list.append( + AddrMap.templ_dict['import_package']['rtl'].format(name = x) + ) - import_package_list.append(';') + import_package_list.append('\n') + + import_package_list.pop() except IndexError: pass @@ -272,8 +273,10 @@ class AddrMap(Component): names = set() for i in self.registers.values(): - for key, value in i.get_typedefs().items(): - names.add(value.scope) + for x in i.get_typedefs().values(): + names.add(x.scope) + + [names.update(x.get_package_names()) for x in self.regfiles.values()] return names @@ -341,7 +344,9 @@ class AddrMap(Component): tab_width, real_tabs) - # TODO Later, request get_package_rtl()-method of all child regfiles + # Invoke get_package_rtl method from regfiles + [rtl_return.update(x.get_package_rtl(tab_width, real_tabs)) + for x in self.regfiles.values()] return rtl_return diff --git a/srdl2sv/components/regfile.py b/srdl2sv/components/regfile.py index 23abc7f..b031507 100644 --- a/srdl2sv/components/regfile.py +++ b/srdl2sv/components/regfile.py @@ -167,3 +167,86 @@ class RegFile(Component): for i in self.children.values(): yield from i.create_mux_string() + def get_package_names(self) -> set(): + names = set() + + for i in self.registers.values(): + for key, value in i.get_typedefs().items(): + names.add(value.scope) + + return names + + def get_package_rtl(self, tab_width: int = 4, real_tabs = False) -> dict(): + if not self.config['enums']: + return None + + # First go through all registers in this scope to generate a package + package_rtl = [] + enum_rtl = [] + rtl_return = list() + + # Need to keep track of enum names since they shall be unique + # per scope + enum_members = dict() + enum_found = False + + for i in self.registers.values(): + for key, value in i.get_typedefs().items(): + if not enum_found: + enum_found = True + scope = value.scope + + variable_list = [] + + max_name_width = min( + max([len(x[0]) for x in value.members]), 40) + + for var in value.members: + if var[0] not in enum_members: + enum_members[var[0]] = "::".join([self.name, key]) + else: + self.logger.fatal( + "Enum member '{}' was found at multiple locations in the same "\ + "main scope: \n"\ + " -- 1st occurance: '{}'\n"\ + " -- 2nd occurance: '{}'\n\n"\ + "This is not legal because all these enums will be defined "\ + "in the same SystemVerilog scope. To share the same enum among "\ + "different registers, define them on a higher level in the "\ + "hierarchy.\n\n"\ + "Exiting...".format( + var[0], + enum_members[var[0]], + "::".join([self.name, key]))) + + sys.exit(1) + + variable_list.append( + RegFile.templ_dict['enum_var_list_item']['rtl'].format( + value = var[1], + width = value.width, + max_name_width = max_name_width, + name = var[0])) + + enum_rtl.append( + RegFile.templ_dict['enum_declaration']['rtl'].format( + width=value.width-1, + name = key, + enum_var_list = ',\n'.join(variable_list))) + + if enum_found: + package_rtl =\ + RegFile.templ_dict['package_declaration']['rtl'].format( + name = scope, + pkg_content = '\n\n'.join(enum_rtl)) + + + return {scope: + RegFile.add_tabs( + package_rtl, + tab_width, + real_tabs) + } + else: + return {None: None} + diff --git a/srdl2sv/components/templates/addrmap.yaml b/srdl2sv/components/templates/addrmap.yaml index 95f578c..7375a0b 100644 --- a/srdl2sv/components/templates/addrmap.yaml +++ b/srdl2sv/components/templates/addrmap.yaml @@ -21,7 +21,7 @@ module_declaration: ); import_package: rtl: |- - import {name}_pkg::* + import {name}_pkg::*; reset_port: rtl: input {name}, diff --git a/srdl2sv/components/templates/regfile.yaml b/srdl2sv/components/templates/regfile.yaml index 2f89736..1c28bbc 100644 --- a/srdl2sv/components/templates/regfile.yaml +++ b/srdl2sv/components/templates/regfile.yaml @@ -15,3 +15,18 @@ generate_for_start: generate_for_end: rtl: |- end // of for loop with iterator {dimension} +package_declaration: + rtl: |- + package {name}_pkg; + + {pkg_content} + + endpackage +enum_declaration: + rtl: |- + typedef enum logic [{width}:0] {{ + {enum_var_list} + }} {name}; +enum_var_list_item: + rtl: |- + {name:{max_name_width}} = {width}'d{value} diff --git a/srdl2sv/main.py b/srdl2sv/main.py index 29f74d0..66f47d7 100755 --- a/srdl2sv/main.py +++ b/srdl2sv/main.py @@ -73,8 +73,9 @@ if __name__ == "__main__": tab_width=config['tab_width'], real_tabs=config['real_tabs'] ).items(): - with open('{}/{}_pkg.sv'.format(config['output_dir'], key), 'w') as file: - file.write(value) + if value: + with open('{}/{}_pkg.sv'.format(config['output_dir'], key), 'w') as file: + file.write(value) # Copy over widget RTL from widget directory widget_rtl = pkg_resources.read_text(widgets, '{}.sv'.format(config['bus']))