mirror of
https://github.com/Silicon1602/srdl2sv.git
synced 2024-12-22 06:58:41 +00:00
Fix alias bugs introduced when adding external registers
Furthermore, some compilation bugs were added when optimizing away swacc and swmod wires when not required.
This commit is contained in:
parent
c589a17ea5
commit
0887372dbd
@ -68,6 +68,7 @@ class Field(Component):
|
|||||||
elif self.storage_type is not StorageType.FLOPS:
|
elif self.storage_type is not StorageType.FLOPS:
|
||||||
self.__add_wire_const()
|
self.__add_wire_const()
|
||||||
self.__add_hw_rd_access()
|
self.__add_hw_rd_access()
|
||||||
|
self.__add_swmod_swacc()
|
||||||
self.add_sw_access(obj)
|
self.add_sw_access(obj)
|
||||||
else:
|
else:
|
||||||
self.__add_always_ff()
|
self.__add_always_ff()
|
||||||
@ -84,17 +85,37 @@ class Field(Component):
|
|||||||
self.add_sw_access(obj)
|
self.add_sw_access(obj)
|
||||||
|
|
||||||
def add_sw_access(self, obj, alias = False):
|
def add_sw_access(self, obj, alias = False):
|
||||||
|
|
||||||
|
# Perform some basic checks
|
||||||
|
if onwrite := obj.get_property('onwrite') \
|
||||||
|
and not self.properties['sw_wr']:
|
||||||
|
self.logger.fatal("An onwrite property '%s' is defined but "\
|
||||||
|
"software does not have write-access. This is not "\
|
||||||
|
"legal.", onwrite)
|
||||||
|
|
||||||
|
sys.exit(1)
|
||||||
|
elif onread := obj.get_property('onread') \
|
||||||
|
and self.storage_type is not StorageType.FLOPS:
|
||||||
|
self.logger.warning("Field has an onread property but does not "
|
||||||
|
"implement a flop. Since the flop itself is "
|
||||||
|
"implemented outside of the register block it is "
|
||||||
|
"advised to remove the property and notify the external "
|
||||||
|
"hardware by using the 'swacc' property.")
|
||||||
|
|
||||||
access_rtl = {}
|
access_rtl = {}
|
||||||
|
|
||||||
if alias:
|
if alias:
|
||||||
_, _, path, path_underscored =\
|
_, _, path, alias_path_underscored = \
|
||||||
Field.create_underscored_path_static(obj)
|
Field.create_underscored_path_static(obj)
|
||||||
else:
|
else:
|
||||||
owning_addrmap, full_path, path, path_underscored =\
|
path = self.path
|
||||||
self.owning_addrmap, self.full_path, self.path, self.path_underscored
|
|
||||||
|
|
||||||
path_wo_field = '__'.join(path.split('.', -1)[0:-1])
|
path_wo_field = '__'.join(path.split('.', -1)[0:-1])
|
||||||
|
|
||||||
|
# path_wo_field_vec & path_undrescored_vec only used for external registers
|
||||||
|
self.path_wo_field_vec.append(path_wo_field)
|
||||||
|
self.path_underscored_vec.append(alias_path_underscored if alias else self.path_underscored)
|
||||||
|
|
||||||
# Define software access (if applicable)
|
# Define software access (if applicable)
|
||||||
access_rtl['sw_write'] = ([], False)
|
access_rtl['sw_write'] = ([], False)
|
||||||
|
|
||||||
@ -151,7 +172,7 @@ class Field(Component):
|
|||||||
access_rtl['sw_write'][0].append(
|
access_rtl['sw_write'][0].append(
|
||||||
self._process_yaml(
|
self._process_yaml(
|
||||||
Field.templ_dict[str(onwrite)],
|
Field.templ_dict[str(onwrite)],
|
||||||
{'path': path_underscored,
|
{'path': self.path_underscored,
|
||||||
'genvars': self.genvars_str,
|
'genvars': self.genvars_str,
|
||||||
'i': i,
|
'i': i,
|
||||||
'width': msb_bus - lsb_bus + 1,
|
'width': msb_bus - lsb_bus + 1,
|
||||||
@ -186,19 +207,18 @@ class Field(Component):
|
|||||||
|
|
||||||
access_rtl['sw_write'][0].append("end")
|
access_rtl['sw_write'][0].append("end")
|
||||||
|
|
||||||
onread = obj.get_property('onread')
|
|
||||||
|
|
||||||
access_rtl['sw_read'] = ([], False)
|
access_rtl['sw_read'] = ([], False)
|
||||||
|
|
||||||
if obj.get_property('sw') in (AccessType.rw, AccessType.r):
|
if obj.get_property('sw') in (AccessType.rw, AccessType.r):
|
||||||
# Append to list of registers that can read
|
# Append to list of registers that can read
|
||||||
self.readable_by.add(path_wo_field)
|
self.readable_by.add(path_wo_field)
|
||||||
|
|
||||||
self.properties['sw_wr'] = True
|
self.properties['sw_rd'] = True
|
||||||
|
|
||||||
# Set onread properties
|
# Set onread properties
|
||||||
if onread == OnReadType.ruser:
|
if onread is OnReadType.ruser:
|
||||||
self.logger.error("The OnReadType.ruser is not yet supported!")
|
self.logger.error("The OnReadType.ruser is not yet supported!")
|
||||||
elif onread:
|
elif onread and self.storage_type is StorageType.FLOPS:
|
||||||
self.properties['sw_rd_wire'] = True
|
self.properties['sw_rd_wire'] = True
|
||||||
|
|
||||||
access_rtl['sw_read'][0].append(
|
access_rtl['sw_read'][0].append(
|
||||||
@ -215,7 +235,7 @@ class Field(Component):
|
|||||||
access_rtl['sw_read'][0].append(
|
access_rtl['sw_read'][0].append(
|
||||||
self._process_yaml(
|
self._process_yaml(
|
||||||
Field.templ_dict[str(onread)],
|
Field.templ_dict[str(onread)],
|
||||||
{'path': path_underscored,
|
{'path': self.path_underscored,
|
||||||
'genvars': self.genvars_str,
|
'genvars': self.genvars_str,
|
||||||
'i': i,
|
'i': i,
|
||||||
'width': msb_bus - lsb_bus + 1,
|
'width': msb_bus - lsb_bus + 1,
|
||||||
@ -252,9 +272,6 @@ class Field(Component):
|
|||||||
self.access_rtl['sw_read'] = [access_rtl['sw_read']]
|
self.access_rtl['sw_read'] = [access_rtl['sw_read']]
|
||||||
self.access_rtl['sw_write'] = [access_rtl['sw_write']]
|
self.access_rtl['sw_write'] = [access_rtl['sw_write']]
|
||||||
|
|
||||||
self.path_underscored_vec.append(path_underscored)
|
|
||||||
self.path_wo_field_vec.append(path_wo_field)
|
|
||||||
|
|
||||||
def __add_counter(self):
|
def __add_counter(self):
|
||||||
if self.obj.get_property('counter'):
|
if self.obj.get_property('counter'):
|
||||||
self.logger.debug("Detected counter property")
|
self.logger.debug("Detected counter property")
|
||||||
@ -683,6 +700,9 @@ class Field(Component):
|
|||||||
if self.obj.get_property('swmod'):
|
if self.obj.get_property('swmod'):
|
||||||
self.logger.debug("Field has swmod property")
|
self.logger.debug("Field has swmod property")
|
||||||
|
|
||||||
|
self.properties['swmod'] = True
|
||||||
|
self.properties['sw_wr_wire'] = True
|
||||||
|
|
||||||
swmod_assigns = []
|
swmod_assigns = []
|
||||||
|
|
||||||
# Check if read side-effects are defined.
|
# Check if read side-effects are defined.
|
||||||
@ -1379,7 +1399,9 @@ class Field(Component):
|
|||||||
sw_prop = self.obj.get_property('sw')
|
sw_prop = self.obj.get_property('sw')
|
||||||
|
|
||||||
# Check the storage type, according to Table 12 of the SystemRDL 2.0 LRM
|
# Check the storage type, according to Table 12 of the SystemRDL 2.0 LRM
|
||||||
if hw_prop is AccessType.r and sw_prop is AccessType.r:
|
if self.obj.get_property('intr'):
|
||||||
|
self.storage_type = StorageType.FLOPS
|
||||||
|
elif hw_prop is AccessType.r and sw_prop is AccessType.r:
|
||||||
# hw=r/sw=r --> Constant
|
# hw=r/sw=r --> Constant
|
||||||
self.storage_type = StorageType.CONST
|
self.storage_type = StorageType.CONST
|
||||||
elif hw_prop is AccessType.na and sw_prop is AccessType.r:
|
elif hw_prop is AccessType.na and sw_prop is AccessType.r:
|
||||||
|
@ -152,7 +152,7 @@ class Register(Component):
|
|||||||
accesswidth = self.obj.get_property('accesswidth') - 1
|
accesswidth = self.obj.get_property('accesswidth') - 1
|
||||||
self.rtl_footer.append("")
|
self.rtl_footer.append("")
|
||||||
|
|
||||||
for na_map in self.name_addr_mappings:
|
for alias_idx, na_map in enumerate(self.name_addr_mappings):
|
||||||
current_bit = 0
|
current_bit = 0
|
||||||
|
|
||||||
# Start tracking errors
|
# Start tracking errors
|
||||||
@ -352,6 +352,7 @@ class Register(Component):
|
|||||||
'genvars': self.genvars_str if not no_reads else '',
|
'genvars': self.genvars_str if not no_reads else '',
|
||||||
'rdy_condition': sw_rdy_condition,
|
'rdy_condition': sw_rdy_condition,
|
||||||
'err_condition': sw_err_condition,
|
'err_condition': sw_err_condition,
|
||||||
|
'alias_indicator': '(alias)' if alias_idx > 0 else '',
|
||||||
'list_of_fields': ', '.join(reversed(list_of_fields))}
|
'list_of_fields': ', '.join(reversed(list_of_fields))}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -471,18 +472,28 @@ class Register(Component):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Add combined signal to be used for general access of the register
|
# Add combined signal to be used for general access of the register
|
||||||
|
if self.properties['swacc'] or self.properties['swmod']:
|
||||||
|
self.rtl_header.append(
|
||||||
|
self._process_yaml(
|
||||||
|
Register.templ_dict['w_wire_assign_any_alias'],
|
||||||
|
{'path': self.name_addr_mappings[0][0],
|
||||||
|
'genvars': self.genvars_str,
|
||||||
|
'sw_wrs_w_genvars': ' || '.join(
|
||||||
|
[''.join([x[0], '_sw_wr', self.genvars_str])
|
||||||
|
for x in self.name_addr_mappings])
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if self.properties['swacc']:
|
if self.properties['swacc']:
|
||||||
self.rtl_header.append(
|
self.rtl_header.append(
|
||||||
self._process_yaml(
|
self._process_yaml(
|
||||||
Register.templ_dict['rw_wire_assign_any_alias'],
|
Register.templ_dict['r_wire_assign_any_alias'],
|
||||||
{'path': self.name_addr_mappings[0][0],
|
{'path': self.name_addr_mappings[0][0],
|
||||||
'genvars': self.genvars_str,
|
'genvars': self.genvars_str,
|
||||||
'sw_rds_w_genvars': ' || '.join(
|
'sw_rds_w_genvars': ' || '.join(
|
||||||
[''.join([x[0], '_sw_rd', self.genvars_str])
|
[''.join([x[0], '_sw_rd', self.genvars_str])
|
||||||
for x in self.name_addr_mappings]),
|
for x in self.name_addr_mappings]),
|
||||||
'sw_wrs_w_genvars': ' || '.join(
|
|
||||||
[''.join([x[0], '_sw_wr', self.genvars_str])
|
|
||||||
for x in self.name_addr_mappings])
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -136,42 +136,63 @@ OnWriteType.woset:
|
|||||||
<<INDENT>>
|
<<INDENT>>
|
||||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] | widget_if.w_data[{msb_bus}:{lsb_bus}];
|
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] | widget_if.w_data[{msb_bus}:{lsb_bus}];
|
||||||
<<UNINDENT>>
|
<<UNINDENT>>
|
||||||
|
signals:
|
||||||
|
- name: '{path}_q'
|
||||||
|
signal_type: '{field_type}'
|
||||||
OnWriteType.woclr:
|
OnWriteType.woclr:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if (widget_if.byte_en[{i}]) // woclr property
|
if (widget_if.byte_en[{i}]) // woclr property
|
||||||
<<INDENT>>
|
<<INDENT>>
|
||||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] & ~widget_if.w_data[{msb_bus}:{lsb_bus}];
|
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] & ~widget_if.w_data[{msb_bus}:{lsb_bus}];
|
||||||
<<UNINDENT>>
|
<<UNINDENT>>
|
||||||
|
signals:
|
||||||
|
- name: '{path}_q'
|
||||||
|
signal_type: '{field_type}'
|
||||||
OnWriteType.wot:
|
OnWriteType.wot:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if (widget_if.byte_en[{i}]) // wot property
|
if (widget_if.byte_en[{i}]) // wot property
|
||||||
<<INDENT>>
|
<<INDENT>>
|
||||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] ^ widget_if.w_data[{msb_bus}:{lsb_bus}];
|
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] ^ widget_if.w_data[{msb_bus}:{lsb_bus}];
|
||||||
<<UNINDENT>>
|
<<UNINDENT>>
|
||||||
|
signals:
|
||||||
|
- name: '{path}_q'
|
||||||
|
signal_type: '{field_type}'
|
||||||
OnWriteType.wzs:
|
OnWriteType.wzs:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if (widget_if.byte_en[{i}]) // wzs property
|
if (widget_if.byte_en[{i}]) // wzs property
|
||||||
<<INDENT>>
|
<<INDENT>>
|
||||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] & widget_if.w_data[{msb_bus}:{lsb_bus}];
|
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] & widget_if.w_data[{msb_bus}:{lsb_bus}];
|
||||||
<<UNINDENT>>
|
<<UNINDENT>>
|
||||||
|
signals:
|
||||||
|
- name: '{path}_q'
|
||||||
|
signal_type: '{field_type}'
|
||||||
OnWriteType.wzt:
|
OnWriteType.wzt:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if (widget_if.byte_en[{i}]) // wzt property
|
if (widget_if.byte_en[{i}]) // wzt property
|
||||||
<<INDENT>>
|
<<INDENT>>
|
||||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] ~^ widget_if.w_data[{msb_bus}:{lsb_bus}];
|
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] ~^ widget_if.w_data[{msb_bus}:{lsb_bus}];
|
||||||
<<UNINDENT>>
|
<<UNINDENT>>
|
||||||
|
signals:
|
||||||
|
- name: '{path}_q'
|
||||||
|
signal_type: '{field_type}'
|
||||||
OnWriteType.wclr:
|
OnWriteType.wclr:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if (widget_if.byte_en[{i}]) // wclr property
|
if (widget_if.byte_en[{i}]) // wclr property
|
||||||
<<INDENT>>
|
<<INDENT>>
|
||||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {width}'b0;
|
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {width}'b0;
|
||||||
<<UNINDENT>>
|
<<UNINDENT>>
|
||||||
|
signals:
|
||||||
|
- name: '{path}_q'
|
||||||
|
signal_type: '{field_type}'
|
||||||
OnWriteType.wset:
|
OnWriteType.wset:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if (widget_if.byte_en[{i}]) // wclr property
|
if (widget_if.byte_en[{i}]) // wclr property
|
||||||
<<INDENT>>
|
<<INDENT>>
|
||||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {{{width}{{1'b1}}}};
|
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {{{width}{{1'b1}}}};
|
||||||
<<UNINDENT>>
|
<<UNINDENT>>
|
||||||
|
signals:
|
||||||
|
- name: '{path}_q'
|
||||||
|
signal_type: '{field_type}'
|
||||||
sw_read_access_field:
|
sw_read_access_field:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if ({path_wo_field}_sw_rd{genvars})
|
if ({path_wo_field}_sw_rd{genvars})
|
||||||
@ -260,13 +281,13 @@ swmod_always_comb:
|
|||||||
end
|
end
|
||||||
output_ports:
|
output_ports:
|
||||||
- name: '{path}_swmod'
|
- name: '{path}_swmod'
|
||||||
signal_type: 'logic'
|
signal_type: 'reg'
|
||||||
swmod_assign:
|
swmod_assign:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
{path}_swmod{genvars} |= {path_wo_field}__any_alias_sw_{rd_wr}{genvars} && |widget_if.byte_en[{msbyte}:{lsbyte}];
|
{path}_swmod{genvars} |= {path_wo_field}__any_alias_sw_{rd_wr}{genvars} && |widget_if.byte_en[{msbyte}:{lsbyte}];
|
||||||
output_ports:
|
output_ports:
|
||||||
- name: '{path}_swmod'
|
- name: '{path}_swmod'
|
||||||
signal_type: 'logic'
|
signal_type: 'reg'
|
||||||
counter_comment:
|
counter_comment:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
/***********************
|
/***********************
|
||||||
|
@ -39,17 +39,22 @@ write_wire_assign_0:
|
|||||||
signals:
|
signals:
|
||||||
- name: '{path}_sw_wr'
|
- name: '{path}_sw_wr'
|
||||||
signal_type: 'logic'
|
signal_type: 'logic'
|
||||||
rw_wire_assign_any_alias:
|
w_wire_assign_any_alias:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
|
|
||||||
// Combined register activation. These will become active
|
// Combined register activation. These will become active on
|
||||||
assign {path}__any_alias_sw_rd{genvars} = {sw_rds_w_genvars};
|
// access via any of the alias registers.
|
||||||
assign {path}__any_alias_sw_wr{genvars} = {sw_wrs_w_genvars};
|
assign {path}__any_alias_sw_wr{genvars} = {sw_wrs_w_genvars};
|
||||||
signals:
|
signals:
|
||||||
- name: '{path}__any_alias_sw_rd'
|
|
||||||
signal_type: 'logic'
|
|
||||||
- name: '{path}__any_alias_sw_wr'
|
- name: '{path}__any_alias_sw_wr'
|
||||||
signal_type: 'logic'
|
signal_type: 'logic'
|
||||||
|
r_wire_assign_any_alias:
|
||||||
|
rtl: |-
|
||||||
|
|
||||||
|
assign {path}__any_alias_sw_rd{genvars} = {sw_rds_w_genvars};
|
||||||
|
signals:
|
||||||
|
- name: '{path}__any_alias_sw_rd'
|
||||||
|
signal_type: 'logic'
|
||||||
reg_comment: |-
|
reg_comment: |-
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
@ -96,9 +101,9 @@ sw_err_condition:
|
|||||||
sw_data_assignment:
|
sw_data_assignment:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
|
|
||||||
/**************************************
|
/**********************************************
|
||||||
* Assign all fields to signal to Mux *
|
* Assign all fields to signal to Mux {alias_indicator:7} *
|
||||||
**************************************/
|
**********************************************/
|
||||||
// Assign all fields. Fields that are not readable are tied to 0.
|
// Assign all fields. Fields that are not readable are tied to 0.
|
||||||
assign {sw_data_assignment_var_name}{genvars} = {{{list_of_fields}}};
|
assign {sw_data_assignment_var_name}{genvars} = {{{list_of_fields}}};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user