diff --git a/srdl2sv/components/field.py b/srdl2sv/components/field.py index 310041e..943a156 100644 --- a/srdl2sv/components/field.py +++ b/srdl2sv/components/field.py @@ -1,4 +1,5 @@ import math + import importlib.resources as pkg_resources import yaml @@ -47,6 +48,7 @@ class Field(Component): self.__add_combo() self.add_sw_access(obj) + self.add_swmod_swacc(obj) def add_sw_access(self, obj, alias = False): access_rtl = dict() @@ -117,6 +119,9 @@ class Field(Component): else: # If field spans multiple bytes, every byte shall have a seperate enable! for j, i in enumerate(range(self.lsbyte, self.msbyte+1)): + msb_bus = 8*(i+1)-1 if i != self.msbyte else obj.msb + lsb_bus = 8*i if i != self.lsbyte else obj.inst.lsb + access_rtl['sw_write'][0].append( self.process_yaml( Field.templ_dict[str(onwrite)], @@ -124,10 +129,10 @@ class Field(Component): 'genvars': self.genvars_str, 'i': i, 'width': obj.width, - 'msb_bus': str(8*(i+1)-1 if i != self.msbyte else obj.msb), - 'bus_w': str(8 if i != self.msbyte else obj.width-(8*j)), - 'msb_field': str(8*(j+1)-1 if i != self.msbyte else obj.width-1), - 'field_w': str(8 if i != self.msbyte else obj.width-(8*j)), + 'msb_bus': str(msb_bus), + 'lsb_bus': str(lsb_bus), + 'msb_field': str(msb_bus-obj.inst.lsb), + 'lsb_field': str(lsb_bus-obj.inst.lsb), 'field_type': self.field_type} ) ) @@ -136,16 +141,19 @@ class Field(Component): # Normal write # If field spans multiple bytes, every byte shall have a seperate enable! for j, i in enumerate(range(self.lsbyte, self.msbyte+1)): + msb_bus = 8*(i+1)-1 if i != self.msbyte else obj.msb + lsb_bus = 8*i if i != self.lsbyte else obj.inst.lsb + access_rtl['sw_write'][0].append( self.process_yaml( Field.templ_dict['sw_access_byte'], {'path': self.path_underscored, 'genvars': self.genvars_str, 'i': i, - 'msb_bus': str(8*(i+1)-1 if i != self.msbyte else obj.msb), - 'bus_w': str(8 if i != self.msbyte else obj.width-(8*j)), - 'msb_field': str(8*(j+1)-1 if i != self.msbyte else obj.width-1), - 'field_w': str(8 if i != self.msbyte else obj.width-(8*j)), + 'msb_bus': str(msb_bus), + 'lsb_bus': str(lsb_bus), + 'msb_field': str(msb_bus-obj.inst.lsb), + 'lsb_field': str(lsb_bus-obj.inst.lsb), 'field_type': self.field_type} ) ) @@ -198,6 +206,68 @@ class Field(Component): self.access_rtl['sw_read'] = [access_rtl['sw_read']] self.access_rtl['sw_write'] = [access_rtl['sw_write']] + def add_swmod_swacc(self, obj): + if obj.get_property('swmod'): + swmod_assigns = list() + swacc_assigns = list() + + # Check if read side-effects are defined. + if obj.get_property('onread'): + swmod_assigns.append( + self.process_yaml( + Field.templ_dict['swmod_assign'], + {'path': self.path_underscored, + 'path_wo_field': self.path_wo_field, + 'genvars': self.genvars_str, + 'rd_wr': 'rd', + 'msbyte': self.msbyte, + 'lsbyte': self.lsbyte, + 'swmod_assigns': '\n'.join(swmod_assigns) + } + ) + ) + + # Check if SW has write access to the field + if obj.get_property('sw') in (AccessType.rw, AccessType.w): + swmod_assigns.append( + self.process_yaml( + Field.templ_dict['swmod_assign'], + {'path': self.path_underscored, + 'path_wo_field': self.path_wo_field, + 'genvars': self.genvars_str, + 'rd_wr': 'wr', + 'msbyte': self.msbyte, + 'lsbyte': self.lsbyte, + 'swmod_assigns': '\n'.join(swmod_assigns) + } + ) + ) + + swmod_props = self.process_yaml( + Field.templ_dict['swmod_always_comb'], + {'path': self.path_underscored, + 'genvars': self.genvars_str, + 'swmod_assigns': '\n'.join(swmod_assigns) + } + ) + else: + swmod_props = '' + + if obj.get_property('swacc') and obj.get_property('sw') in (AccessType.rw, AccessType.r): + swacc_props = self.process_yaml( + Field.templ_dict['swacc_assign'], + {'path': self.path_underscored, + 'path_wo_field': self.path_wo_field, + 'genvars': self.genvars_str, + 'msbyte': self.msbyte, + 'lsbyte': self.lsbyte, + } + ) + else: + swacc_props = '' + + self.rtl_footer = [*self.rtl_footer, swmod_props, swacc_props] + def __add_hw_access(self): # Define hardware access (if applicable) if self.obj.get_property('hw') in (AccessType.rw, AccessType.w): diff --git a/srdl2sv/components/register.py b/srdl2sv/components/register.py index f146614..7cc3026 100644 --- a/srdl2sv/components/register.py +++ b/srdl2sv/components/register.py @@ -182,6 +182,22 @@ class Register(Component): ) ) for i, x in enumerate(self.name_addr_mappings)] + # Add combined signal to be used for general access of the register + self.rtl_header.append( + self.process_yaml( + Register.templ_dict['rw_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]) + } + ) + ) + def __add_signal_instantiations(self): # Add wire/register instantiations self.rtl_header = [ diff --git a/srdl2sv/components/templates/addrmap.yaml b/srdl2sv/components/templates/addrmap.yaml index a6a4b2a..9f8d2ea 100644 --- a/srdl2sv/components/templates/addrmap.yaml +++ b/srdl2sv/components/templates/addrmap.yaml @@ -73,9 +73,6 @@ module_declaration: input bus_rst_n, {resets} - // Bus I/O - // TODO - // Inputs {inputs} diff --git a/srdl2sv/components/templates/fields.yaml b/srdl2sv/components/templates/fields.yaml index 2edf465..8b20ee7 100644 --- a/srdl2sv/components/templates/fields.yaml +++ b/srdl2sv/components/templates/fields.yaml @@ -31,7 +31,7 @@ sw_access_byte: rtl: |- if (byte_enable[{i}]) begin - {path}_q{genvars}[{msb_field}-:{field_w}] <= sw_wr_bus[{msb_bus}-:{bus_w}]; + {path}_q{genvars}[{msb_field}:{lsb_field}] <= sw_wr_bus[{msb_bus}:{lsb_bus}]; end signals: - name: '{path}_q' @@ -63,31 +63,31 @@ OnWriteType.woset: rtl: |- if (byte_enable[{i}]) // woset property begin - {path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] | sw_wr_bus[{msb_bus}-:{bus_w}]; + {path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] | sw_wr_bus[{msb_bus}:{lsb_bus}]; end OnWriteType.woclr: rtl: |- if (byte_enable[{i}]) // woclr property begin - {path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] & ~sw_wr_bus[{msb_bus}-:{bus_w}]; + {path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] & ~sw_wr_bus[{msb_bus}:{lsb_bus}]; end OnWriteType.wot: rtl: |- if (byte_enable[{i}]) // wot property begin - {path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] ^ sw_wr_bus[{msb_bus}-:{bus_w}]; + {path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] ^ sw_wr_bus[{msb_bus}:{lsb_bus}]; end OnWriteType.wzs: rtl: |- if (byte_enable[{i}]) // wzs property begin - {path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] & sw_wr_bus[{msb_bus}-:{bus_w}]; + {path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] & sw_wr_bus[{msb_bus}:{lsb_bus}]; end OnWriteType.wzt: rtl: |- if (byte_enable[{i}]) // wzt property begin - {path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] ~^ sw_wr_bus[{msb_bus}-:{bus_w}]; + {path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] ~^ sw_wr_bus[{msb_bus}:{lsb_bus}]; end OnWriteType.wclr: rtl: |- @@ -153,6 +153,32 @@ out_port_assign: output_ports: - name: '{path}_r' signal_type: '{field_type}' +swacc_assign: + rtl: |- + + // Combinational block to generate swacc-output signals + assign {path}_swacc{genvars} = ({path_wo_field}__any_alias_sw_wr{genvars} || {path_wo_field}__any_alias_sw_rd{genvars}) && |byte_enable[{msbyte}:{lsbyte}]; + output_ports: + - name: '{path}_swacc' + signal_type: 'logic' +swmod_always_comb: + rtl: |- + + // Combinational block to generate swmod-output signals + always_comb + begin + {path}_swmod{genvars} = 0; + {swmod_assigns} + end + output_ports: + - name: '{path}_swmod' + signal_type: 'logic' +swmod_assign: + rtl: |- + {path}_swmod{genvars} |= {path_wo_field}__any_alias_sw_{rd_wr}{genvars} && |byte_enable[{msbyte}:{lsbyte}]; + output_ports: + - name: '{path}_swmod' + signal_type: 'logic' counter: rtl: |- always_comb @@ -190,9 +216,3 @@ decr_counter_condition: decr_sat_counter_condition: rtl: |- if ({path}_decr{genvars} && {path}_next{genvars} - {path}_decr_val{genvars} >= {sat_value}) - - - - - - diff --git a/srdl2sv/components/templates/regs.yaml b/srdl2sv/components/templates/regs.yaml index e85eedd..26c6983 100644 --- a/srdl2sv/components/templates/regs.yaml +++ b/srdl2sv/components/templates/regs.yaml @@ -1,6 +1,7 @@ --- rw_wire_assign_1_dim: rtl: | + // Register-activation for '{path}' {alias} assign {path}_accss = addr == {addr}; assign {path}_sw_wr = {path}_accss && r_vld; @@ -12,10 +13,9 @@ rw_wire_assign_1_dim: signal_type: 'logic' - name: '{path}_accss' signal_type: 'logic' - input_ports: - output_ports: rw_wire_assign_multi_dim: rtl: |- + // Register-activation for '{path}' {alias} assign {path}_accss{genvars} = addr == {addr}+({genvars_sum}); assign {path}_sw_wr{genvars} = {path}_accss{genvars} && r_vld; @@ -27,8 +27,18 @@ rw_wire_assign_multi_dim: signal_type: 'logic' - name: '{path}_accss' signal_type: 'logic' - input_ports: - output_ports: +rw_wire_assign_any_alias: + rtl: |- + + // Combined register activation. These will become active + // _any_ alias accesses a certain register. + assign {path}__any_alias_sw_wr{genvars} = {sw_wrs_w_genvars}; + assign {path}__any_alias_sw_rd{genvars} = {sw_rds_w_genvars}; + signals: + - name: '{path}__any_alias_sw_wr' + signal_type: 'logic' + - name: '{path}__any_alias_sw_rd' + signal_type: 'logic' reg_comment: |- /*******************************************************************