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:
|
||||
self.__add_wire_const()
|
||||
self.__add_hw_rd_access()
|
||||
self.__add_swmod_swacc()
|
||||
self.add_sw_access(obj)
|
||||
else:
|
||||
self.__add_always_ff()
|
||||
@ -84,17 +85,37 @@ class Field(Component):
|
||||
self.add_sw_access(obj)
|
||||
|
||||
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 = {}
|
||||
|
||||
if alias:
|
||||
_, _, path, path_underscored =\
|
||||
_, _, path, alias_path_underscored = \
|
||||
Field.create_underscored_path_static(obj)
|
||||
else:
|
||||
owning_addrmap, full_path, path, path_underscored =\
|
||||
self.owning_addrmap, self.full_path, self.path, self.path_underscored
|
||||
path = self.path
|
||||
|
||||
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)
|
||||
access_rtl['sw_write'] = ([], False)
|
||||
|
||||
@ -151,7 +172,7 @@ class Field(Component):
|
||||
access_rtl['sw_write'][0].append(
|
||||
self._process_yaml(
|
||||
Field.templ_dict[str(onwrite)],
|
||||
{'path': path_underscored,
|
||||
{'path': self.path_underscored,
|
||||
'genvars': self.genvars_str,
|
||||
'i': i,
|
||||
'width': msb_bus - lsb_bus + 1,
|
||||
@ -186,19 +207,18 @@ class Field(Component):
|
||||
|
||||
access_rtl['sw_write'][0].append("end")
|
||||
|
||||
onread = obj.get_property('onread')
|
||||
|
||||
access_rtl['sw_read'] = ([], False)
|
||||
|
||||
if obj.get_property('sw') in (AccessType.rw, AccessType.r):
|
||||
# Append to list of registers that can read
|
||||
self.readable_by.add(path_wo_field)
|
||||
|
||||
self.properties['sw_wr'] = True
|
||||
self.properties['sw_rd'] = True
|
||||
|
||||
# Set onread properties
|
||||
if onread == OnReadType.ruser:
|
||||
if onread is OnReadType.ruser:
|
||||
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
|
||||
|
||||
access_rtl['sw_read'][0].append(
|
||||
@ -215,7 +235,7 @@ class Field(Component):
|
||||
access_rtl['sw_read'][0].append(
|
||||
self._process_yaml(
|
||||
Field.templ_dict[str(onread)],
|
||||
{'path': path_underscored,
|
||||
{'path': self.path_underscored,
|
||||
'genvars': self.genvars_str,
|
||||
'i': i,
|
||||
'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_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):
|
||||
if self.obj.get_property('counter'):
|
||||
self.logger.debug("Detected counter property")
|
||||
@ -683,6 +700,9 @@ class Field(Component):
|
||||
if self.obj.get_property('swmod'):
|
||||
self.logger.debug("Field has swmod property")
|
||||
|
||||
self.properties['swmod'] = True
|
||||
self.properties['sw_wr_wire'] = True
|
||||
|
||||
swmod_assigns = []
|
||||
|
||||
# Check if read side-effects are defined.
|
||||
@ -1379,7 +1399,9 @@ class Field(Component):
|
||||
sw_prop = self.obj.get_property('sw')
|
||||
|
||||
# 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
|
||||
self.storage_type = StorageType.CONST
|
||||
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
|
||||
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
|
||||
|
||||
# Start tracking errors
|
||||
@ -352,6 +352,7 @@ class Register(Component):
|
||||
'genvars': self.genvars_str if not no_reads else '',
|
||||
'rdy_condition': sw_rdy_condition,
|
||||
'err_condition': sw_err_condition,
|
||||
'alias_indicator': '(alias)' if alias_idx > 0 else '',
|
||||
'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
|
||||
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']:
|
||||
self.rtl_header.append(
|
||||
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],
|
||||
'genvars': self.genvars_str,
|
||||
'sw_rds_w_genvars': ' || '.join(
|
||||
[''.join([x[0], '_sw_rd', self.genvars_str])
|
||||
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>>
|
||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] | widget_if.w_data[{msb_bus}:{lsb_bus}];
|
||||
<<UNINDENT>>
|
||||
signals:
|
||||
- name: '{path}_q'
|
||||
signal_type: '{field_type}'
|
||||
OnWriteType.woclr:
|
||||
rtl: |-
|
||||
if (widget_if.byte_en[{i}]) // woclr property
|
||||
<<INDENT>>
|
||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] & ~widget_if.w_data[{msb_bus}:{lsb_bus}];
|
||||
<<UNINDENT>>
|
||||
signals:
|
||||
- name: '{path}_q'
|
||||
signal_type: '{field_type}'
|
||||
OnWriteType.wot:
|
||||
rtl: |-
|
||||
if (widget_if.byte_en[{i}]) // wot property
|
||||
<<INDENT>>
|
||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] ^ widget_if.w_data[{msb_bus}:{lsb_bus}];
|
||||
<<UNINDENT>>
|
||||
signals:
|
||||
- name: '{path}_q'
|
||||
signal_type: '{field_type}'
|
||||
OnWriteType.wzs:
|
||||
rtl: |-
|
||||
if (widget_if.byte_en[{i}]) // wzs property
|
||||
<<INDENT>>
|
||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] & widget_if.w_data[{msb_bus}:{lsb_bus}];
|
||||
<<UNINDENT>>
|
||||
signals:
|
||||
- name: '{path}_q'
|
||||
signal_type: '{field_type}'
|
||||
OnWriteType.wzt:
|
||||
rtl: |-
|
||||
if (widget_if.byte_en[{i}]) // wzt property
|
||||
<<INDENT>>
|
||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] ~^ widget_if.w_data[{msb_bus}:{lsb_bus}];
|
||||
<<UNINDENT>>
|
||||
signals:
|
||||
- name: '{path}_q'
|
||||
signal_type: '{field_type}'
|
||||
OnWriteType.wclr:
|
||||
rtl: |-
|
||||
if (widget_if.byte_en[{i}]) // wclr property
|
||||
<<INDENT>>
|
||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {width}'b0;
|
||||
<<UNINDENT>>
|
||||
signals:
|
||||
- name: '{path}_q'
|
||||
signal_type: '{field_type}'
|
||||
OnWriteType.wset:
|
||||
rtl: |-
|
||||
if (widget_if.byte_en[{i}]) // wclr property
|
||||
<<INDENT>>
|
||||
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {{{width}{{1'b1}}}};
|
||||
<<UNINDENT>>
|
||||
signals:
|
||||
- name: '{path}_q'
|
||||
signal_type: '{field_type}'
|
||||
sw_read_access_field:
|
||||
rtl: |-
|
||||
if ({path_wo_field}_sw_rd{genvars})
|
||||
@ -260,13 +281,13 @@ swmod_always_comb:
|
||||
end
|
||||
output_ports:
|
||||
- name: '{path}_swmod'
|
||||
signal_type: 'logic'
|
||||
signal_type: 'reg'
|
||||
swmod_assign:
|
||||
rtl: |-
|
||||
{path}_swmod{genvars} |= {path_wo_field}__any_alias_sw_{rd_wr}{genvars} && |widget_if.byte_en[{msbyte}:{lsbyte}];
|
||||
output_ports:
|
||||
- name: '{path}_swmod'
|
||||
signal_type: 'logic'
|
||||
signal_type: 'reg'
|
||||
counter_comment:
|
||||
rtl: |-
|
||||
/***********************
|
||||
|
@ -39,17 +39,22 @@ write_wire_assign_0:
|
||||
signals:
|
||||
- name: '{path}_sw_wr'
|
||||
signal_type: 'logic'
|
||||
rw_wire_assign_any_alias:
|
||||
w_wire_assign_any_alias:
|
||||
rtl: |-
|
||||
|
||||
// Combined register activation. These will become active
|
||||
assign {path}__any_alias_sw_rd{genvars} = {sw_rds_w_genvars};
|
||||
// Combined register activation. These will become active on
|
||||
// access via any of the alias registers.
|
||||
assign {path}__any_alias_sw_wr{genvars} = {sw_wrs_w_genvars};
|
||||
signals:
|
||||
- name: '{path}__any_alias_sw_rd'
|
||||
signal_type: 'logic'
|
||||
- name: '{path}__any_alias_sw_wr'
|
||||
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: |-
|
||||
|
||||
/*******************************************************************
|
||||
@ -96,9 +101,9 @@ sw_err_condition:
|
||||
sw_data_assignment:
|
||||
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 {sw_data_assignment_var_name}{genvars} = {{{list_of_fields}}};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user