mirror of
https://github.com/Silicon1602/srdl2sv.git
synced 2024-11-13 02:53:37 +00:00
Pull declaration of variables outside of generate scope
This ensures that code is compilation clean again. Prior to this change, the multiplexer was reading from variables that were declared inside of generate-scopes. Furthermore, a small bug regarding the dimension detection of registers was fixed. If a register wasn't multidimensional itself, but its parent is, the multidimensionalness wasn't detected.
This commit is contained in:
parent
3089edc20d
commit
ce4782c11d
@ -31,42 +31,6 @@ class RegFile(Component):
|
||||
# Save and/or process important variables
|
||||
self.__process_variables(obj, parents_dimensions, parents_stride)
|
||||
|
||||
# Create comment and provide user information about register he/she
|
||||
# is looking at.
|
||||
self.rtl_header = [
|
||||
self.process_yaml(
|
||||
RegFile.templ_dict['regfile_comment'],
|
||||
{'name': obj.inst_name,
|
||||
'dimensions': self.dimensions,
|
||||
'depth': self.depth}
|
||||
),
|
||||
*self.rtl_header
|
||||
]
|
||||
|
||||
# Create generate block for register and add comment
|
||||
for i in range(self.dimensions-1, -1, -1):
|
||||
self.rtl_footer.append(
|
||||
self.process_yaml(
|
||||
RegFile.templ_dict['generate_for_end'],
|
||||
{'dimension': chr(97+i)}
|
||||
)
|
||||
)
|
||||
|
||||
if self.dimensions and not glbl_settings['generate_active']:
|
||||
self.rtl_header.append("generate")
|
||||
self.generate_initiated = True
|
||||
glbl_settings['generate_active'] = True
|
||||
else:
|
||||
self.generate_initiated = False
|
||||
|
||||
for i in range(self.dimensions):
|
||||
self.rtl_header.append(
|
||||
self.process_yaml(
|
||||
RegFile.templ_dict['generate_for_start'],
|
||||
{'iterator': chr(97+i+self.parents_depths),
|
||||
'limit': self.array_dimensions[i]}
|
||||
)
|
||||
)
|
||||
|
||||
# Empty dictionary of register objects
|
||||
# We need a dictionary since it might be required to access the objects later
|
||||
@ -77,6 +41,14 @@ class RegFile(Component):
|
||||
# Set object to 0 for easy addressing
|
||||
self.obj.current_idx = [0]
|
||||
|
||||
# Determine whether this regfile must add a generate block and for-loop
|
||||
if self.dimensions and not glbl_settings['generate_active']:
|
||||
self.generate_initiated = True
|
||||
glbl_settings['generate_active'] = True
|
||||
else:
|
||||
self.generate_initiated = False
|
||||
|
||||
|
||||
# Traverse through children
|
||||
for child in obj.children():
|
||||
if isinstance(child, node.AddrmapNode):
|
||||
@ -115,15 +87,53 @@ class RegFile(Component):
|
||||
# to account for all possible alias combinations
|
||||
self.children = {**self.regfiles, **self.registers}
|
||||
|
||||
# Create RTL of all registers
|
||||
[x.create_rtl() for x in self.registers.values()]
|
||||
|
||||
self.logger.info("Done generating all child-regfiles/registers")
|
||||
|
||||
# If this regfile create a generate-block, all the register's wires must
|
||||
# be declared outside of that block
|
||||
if self.generate_initiated:
|
||||
self.rtl_header = [*self.rtl_header, *self.get_signal_instantiations_list()]
|
||||
self.rtl_header.append("")
|
||||
self.rtl_header.append("generate")
|
||||
|
||||
# Create comment and provide user information about register he/she
|
||||
# is looking at.
|
||||
self.rtl_header = [
|
||||
self.process_yaml(
|
||||
RegFile.templ_dict['regfile_comment'],
|
||||
{'name': obj.inst_name,
|
||||
'dimensions': self.dimensions,
|
||||
'depth': self.depth}
|
||||
),
|
||||
*self.rtl_header
|
||||
]
|
||||
|
||||
# Create generate block for register and add comment
|
||||
for i in range(self.dimensions-1, -1, -1):
|
||||
self.rtl_footer.append(
|
||||
self.process_yaml(
|
||||
RegFile.templ_dict['generate_for_end'],
|
||||
{'dimension': chr(97+i)}
|
||||
)
|
||||
)
|
||||
|
||||
for i in range(self.dimensions):
|
||||
self.rtl_header.append(
|
||||
self.process_yaml(
|
||||
RegFile.templ_dict['generate_for_start'],
|
||||
{'iterator': chr(97+i+self.parents_depths),
|
||||
'limit': self.array_dimensions[i]}
|
||||
)
|
||||
)
|
||||
|
||||
# End generate loop
|
||||
if self.generate_initiated:
|
||||
glbl_settings['generate_active'] = False
|
||||
self.rtl_footer.append("endgenerate")
|
||||
|
||||
# Create RTL of all registers
|
||||
[x.create_rtl() for x in self.registers.values()]
|
||||
self.rtl_footer.append("")
|
||||
|
||||
def __process_variables(self,
|
||||
obj: node.RegfileNode,
|
||||
@ -167,6 +177,16 @@ class RegFile(Component):
|
||||
for i in self.children.values():
|
||||
yield from i.create_mux_string()
|
||||
|
||||
def get_signal_instantiations_list(self) -> set():
|
||||
instantiations = list()
|
||||
|
||||
for i in self.children.values():
|
||||
if isinstance(i, Register):
|
||||
instantiations.append("\n// Variables of register '{}'".format(i.name))
|
||||
instantiations = [*instantiations, *i.get_signal_instantiations_list()]
|
||||
|
||||
return instantiations
|
||||
|
||||
def get_package_names(self) -> set():
|
||||
names = set()
|
||||
|
||||
|
@ -76,7 +76,10 @@ class Register(Component):
|
||||
self.__add_sw_read_assignments()
|
||||
|
||||
# Add wire instantiation
|
||||
self.__add_signal_instantiations()
|
||||
if not self.generate_active:
|
||||
# We can/should only do this if there is no encapsulating
|
||||
# regfile which create a generate
|
||||
self.__add_signal_instantiations()
|
||||
|
||||
# Create comment and provide user information about register he/she is looking at
|
||||
self.rtl_header = [
|
||||
@ -159,7 +162,7 @@ class Register(Component):
|
||||
# Assign variables from bus
|
||||
self.obj.current_idx = [0]
|
||||
|
||||
if self.dimensions:
|
||||
if self.total_dimensions:
|
||||
rw_wire_assign_field = 'rw_wire_assign_multi_dim'
|
||||
else:
|
||||
rw_wire_assign_field = 'rw_wire_assign_1_dim'
|
||||
@ -179,27 +182,29 @@ class Register(Component):
|
||||
|
||||
def __add_signal_instantiations(self):
|
||||
# Add wire/register instantiations
|
||||
self.rtl_header = [
|
||||
*self.get_signal_instantiations_list(),
|
||||
'',
|
||||
*self.rtl_header
|
||||
]
|
||||
|
||||
def get_signal_instantiations_list(self):
|
||||
dict_list = [(key, value) for (key, value) in self.get_signals().items()]
|
||||
|
||||
signal_width = min(max([len(value[0]) for (_, value) in dict_list]), 40)
|
||||
|
||||
name_width = min(max([len(key) for (key, _) in dict_list]), 40)
|
||||
|
||||
self.rtl_header = [
|
||||
*[
|
||||
Register.templ_dict['signal_declaration'].format(
|
||||
name = key,
|
||||
type = value[0],
|
||||
signal_width = signal_width,
|
||||
name_width = name_width,
|
||||
unpacked_dim = '[{}]'.format(
|
||||
']['.join(
|
||||
[str(y) for y in value[1]]))
|
||||
if value[1] else '')
|
||||
for (key, value) in dict_list],
|
||||
'',
|
||||
*self.rtl_header,
|
||||
]
|
||||
return [Register.templ_dict['signal_declaration'].format(
|
||||
name = key,
|
||||
type = value[0],
|
||||
signal_width = signal_width,
|
||||
name_width = name_width,
|
||||
unpacked_dim = '[{}]'.format(
|
||||
']['.join(
|
||||
[str(y) for y in value[1]]))
|
||||
if value[1] else '')
|
||||
for (key, value) in dict_list]
|
||||
|
||||
def add_alias(self, obj: node.RegNode):
|
||||
for field in obj.fields():
|
||||
|
Loading…
Reference in New Issue
Block a user