Add get_package_rtl()-method to regfiles

This commit is contained in:
Dennis Potter 2021-06-24 01:00:36 +02:00
parent 0db14e8815
commit 31179eeecc
Signed by: Dennis
GPG Key ID: 186A8AD440942BAF
5 changed files with 116 additions and 12 deletions

View File

@ -135,13 +135,14 @@ class AddrMap(Component):
import_package_list = [] import_package_list = []
try: try:
import_package_list = [[ for x in self.get_package_names():
AddrMap.templ_dict['import_package']['rtl'].format( import_package_list.append(
name = self.name), AddrMap.templ_dict['import_package']['rtl'].format(name = x)
',\n' )
] for x in self.get_package_names()][0][:-1]
import_package_list.append(';') import_package_list.append('\n')
import_package_list.pop()
except IndexError: except IndexError:
pass pass
@ -272,8 +273,10 @@ class AddrMap(Component):
names = set() names = set()
for i in self.registers.values(): for i in self.registers.values():
for key, value in i.get_typedefs().items(): for x in i.get_typedefs().values():
names.add(value.scope) names.add(x.scope)
[names.update(x.get_package_names()) for x in self.regfiles.values()]
return names return names
@ -341,7 +344,9 @@ class AddrMap(Component):
tab_width, tab_width,
real_tabs) 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 return rtl_return

View File

@ -167,3 +167,86 @@ class RegFile(Component):
for i in self.children.values(): for i in self.children.values():
yield from i.create_mux_string() 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}

View File

@ -21,7 +21,7 @@ module_declaration:
); );
import_package: import_package:
rtl: |- rtl: |-
import {name}_pkg::* import {name}_pkg::*;
reset_port: reset_port:
rtl: rtl:
input {name}, input {name},

View File

@ -15,3 +15,18 @@ generate_for_start:
generate_for_end: generate_for_end:
rtl: |- rtl: |-
end // of for loop with iterator {dimension} 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}

View File

@ -73,8 +73,9 @@ if __name__ == "__main__":
tab_width=config['tab_width'], tab_width=config['tab_width'],
real_tabs=config['real_tabs'] real_tabs=config['real_tabs']
).items(): ).items():
with open('{}/{}_pkg.sv'.format(config['output_dir'], key), 'w') as file: if value:
file.write(value) with open('{}/{}_pkg.sv'.format(config['output_dir'], key), 'w') as file:
file.write(value)
# Copy over widget RTL from widget directory # Copy over widget RTL from widget directory
widget_rtl = pkg_resources.read_text(widgets, '{}.sv'.format(config['bus'])) widget_rtl = pkg_resources.read_text(widgets, '{}.sv'.format(config['bus']))