mirror of
https://github.com/Silicon1602/srdl2sv.git
synced 2024-12-22 15:08:39 +00:00
Add swmod and swacc properties and fix field-range bug
This commit is contained in:
parent
95fef548cf
commit
2e22d82146
@ -1,4 +1,5 @@
|
|||||||
import math
|
import math
|
||||||
|
|
||||||
import importlib.resources as pkg_resources
|
import importlib.resources as pkg_resources
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
@ -47,6 +48,7 @@ class Field(Component):
|
|||||||
self.__add_combo()
|
self.__add_combo()
|
||||||
|
|
||||||
self.add_sw_access(obj)
|
self.add_sw_access(obj)
|
||||||
|
self.add_swmod_swacc(obj)
|
||||||
|
|
||||||
def add_sw_access(self, obj, alias = False):
|
def add_sw_access(self, obj, alias = False):
|
||||||
access_rtl = dict()
|
access_rtl = dict()
|
||||||
@ -117,6 +119,9 @@ class Field(Component):
|
|||||||
else:
|
else:
|
||||||
# If field spans multiple bytes, every byte shall have a seperate enable!
|
# If field spans multiple bytes, every byte shall have a seperate enable!
|
||||||
for j, i in enumerate(range(self.lsbyte, self.msbyte+1)):
|
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(
|
access_rtl['sw_write'][0].append(
|
||||||
self.process_yaml(
|
self.process_yaml(
|
||||||
Field.templ_dict[str(onwrite)],
|
Field.templ_dict[str(onwrite)],
|
||||||
@ -124,10 +129,10 @@ class Field(Component):
|
|||||||
'genvars': self.genvars_str,
|
'genvars': self.genvars_str,
|
||||||
'i': i,
|
'i': i,
|
||||||
'width': obj.width,
|
'width': obj.width,
|
||||||
'msb_bus': str(8*(i+1)-1 if i != self.msbyte else obj.msb),
|
'msb_bus': str(msb_bus),
|
||||||
'bus_w': str(8 if i != self.msbyte else obj.width-(8*j)),
|
'lsb_bus': str(lsb_bus),
|
||||||
'msb_field': str(8*(j+1)-1 if i != self.msbyte else obj.width-1),
|
'msb_field': str(msb_bus-obj.inst.lsb),
|
||||||
'field_w': str(8 if i != self.msbyte else obj.width-(8*j)),
|
'lsb_field': str(lsb_bus-obj.inst.lsb),
|
||||||
'field_type': self.field_type}
|
'field_type': self.field_type}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -136,16 +141,19 @@ class Field(Component):
|
|||||||
# Normal write
|
# Normal write
|
||||||
# If field spans multiple bytes, every byte shall have a seperate enable!
|
# If field spans multiple bytes, every byte shall have a seperate enable!
|
||||||
for j, i in enumerate(range(self.lsbyte, self.msbyte+1)):
|
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(
|
access_rtl['sw_write'][0].append(
|
||||||
self.process_yaml(
|
self.process_yaml(
|
||||||
Field.templ_dict['sw_access_byte'],
|
Field.templ_dict['sw_access_byte'],
|
||||||
{'path': self.path_underscored,
|
{'path': self.path_underscored,
|
||||||
'genvars': self.genvars_str,
|
'genvars': self.genvars_str,
|
||||||
'i': i,
|
'i': i,
|
||||||
'msb_bus': str(8*(i+1)-1 if i != self.msbyte else obj.msb),
|
'msb_bus': str(msb_bus),
|
||||||
'bus_w': str(8 if i != self.msbyte else obj.width-(8*j)),
|
'lsb_bus': str(lsb_bus),
|
||||||
'msb_field': str(8*(j+1)-1 if i != self.msbyte else obj.width-1),
|
'msb_field': str(msb_bus-obj.inst.lsb),
|
||||||
'field_w': str(8 if i != self.msbyte else obj.width-(8*j)),
|
'lsb_field': str(lsb_bus-obj.inst.lsb),
|
||||||
'field_type': self.field_type}
|
'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_read'] = [access_rtl['sw_read']]
|
||||||
self.access_rtl['sw_write'] = [access_rtl['sw_write']]
|
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):
|
def __add_hw_access(self):
|
||||||
# Define hardware access (if applicable)
|
# Define hardware access (if applicable)
|
||||||
if self.obj.get_property('hw') in (AccessType.rw, AccessType.w):
|
if self.obj.get_property('hw') in (AccessType.rw, AccessType.w):
|
||||||
|
@ -182,6 +182,22 @@ class Register(Component):
|
|||||||
)
|
)
|
||||||
) for i, x in enumerate(self.name_addr_mappings)]
|
) 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):
|
def __add_signal_instantiations(self):
|
||||||
# Add wire/register instantiations
|
# Add wire/register instantiations
|
||||||
self.rtl_header = [
|
self.rtl_header = [
|
||||||
|
@ -73,9 +73,6 @@ module_declaration:
|
|||||||
input bus_rst_n,
|
input bus_rst_n,
|
||||||
{resets}
|
{resets}
|
||||||
|
|
||||||
// Bus I/O
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
// Inputs
|
// Inputs
|
||||||
{inputs}
|
{inputs}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ sw_access_byte:
|
|||||||
rtl: |-
|
rtl: |-
|
||||||
if (byte_enable[{i}])
|
if (byte_enable[{i}])
|
||||||
begin
|
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
|
end
|
||||||
signals:
|
signals:
|
||||||
- name: '{path}_q'
|
- name: '{path}_q'
|
||||||
@ -63,31 +63,31 @@ OnWriteType.woset:
|
|||||||
rtl: |-
|
rtl: |-
|
||||||
if (byte_enable[{i}]) // woset property
|
if (byte_enable[{i}]) // woset property
|
||||||
begin
|
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
|
end
|
||||||
OnWriteType.woclr:
|
OnWriteType.woclr:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if (byte_enable[{i}]) // woclr property
|
if (byte_enable[{i}]) // woclr property
|
||||||
begin
|
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
|
end
|
||||||
OnWriteType.wot:
|
OnWriteType.wot:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if (byte_enable[{i}]) // wot property
|
if (byte_enable[{i}]) // wot property
|
||||||
begin
|
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
|
end
|
||||||
OnWriteType.wzs:
|
OnWriteType.wzs:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if (byte_enable[{i}]) // wzs property
|
if (byte_enable[{i}]) // wzs property
|
||||||
begin
|
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
|
end
|
||||||
OnWriteType.wzt:
|
OnWriteType.wzt:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if (byte_enable[{i}]) // wzt property
|
if (byte_enable[{i}]) // wzt property
|
||||||
begin
|
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
|
end
|
||||||
OnWriteType.wclr:
|
OnWriteType.wclr:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
@ -153,6 +153,32 @@ out_port_assign:
|
|||||||
output_ports:
|
output_ports:
|
||||||
- name: '{path}_r'
|
- name: '{path}_r'
|
||||||
signal_type: '{field_type}'
|
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:
|
counter:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
always_comb
|
always_comb
|
||||||
@ -190,9 +216,3 @@ decr_counter_condition:
|
|||||||
decr_sat_counter_condition:
|
decr_sat_counter_condition:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
if ({path}_decr{genvars} && {path}_next{genvars} - {path}_decr_val{genvars} >= {sat_value})
|
if ({path}_decr{genvars} && {path}_next{genvars} - {path}_decr_val{genvars} >= {sat_value})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
rw_wire_assign_1_dim:
|
rw_wire_assign_1_dim:
|
||||||
rtl: |
|
rtl: |
|
||||||
|
|
||||||
// Register-activation for '{path}' {alias}
|
// Register-activation for '{path}' {alias}
|
||||||
assign {path}_accss = addr == {addr};
|
assign {path}_accss = addr == {addr};
|
||||||
assign {path}_sw_wr = {path}_accss && r_vld;
|
assign {path}_sw_wr = {path}_accss && r_vld;
|
||||||
@ -12,10 +13,9 @@ rw_wire_assign_1_dim:
|
|||||||
signal_type: 'logic'
|
signal_type: 'logic'
|
||||||
- name: '{path}_accss'
|
- name: '{path}_accss'
|
||||||
signal_type: 'logic'
|
signal_type: 'logic'
|
||||||
input_ports:
|
|
||||||
output_ports:
|
|
||||||
rw_wire_assign_multi_dim:
|
rw_wire_assign_multi_dim:
|
||||||
rtl: |-
|
rtl: |-
|
||||||
|
|
||||||
// Register-activation for '{path}' {alias}
|
// Register-activation for '{path}' {alias}
|
||||||
assign {path}_accss{genvars} = addr == {addr}+({genvars_sum});
|
assign {path}_accss{genvars} = addr == {addr}+({genvars_sum});
|
||||||
assign {path}_sw_wr{genvars} = {path}_accss{genvars} && r_vld;
|
assign {path}_sw_wr{genvars} = {path}_accss{genvars} && r_vld;
|
||||||
@ -27,8 +27,18 @@ rw_wire_assign_multi_dim:
|
|||||||
signal_type: 'logic'
|
signal_type: 'logic'
|
||||||
- name: '{path}_accss'
|
- name: '{path}_accss'
|
||||||
signal_type: 'logic'
|
signal_type: 'logic'
|
||||||
input_ports:
|
rw_wire_assign_any_alias:
|
||||||
output_ports:
|
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: |-
|
reg_comment: |-
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
|
Loading…
Reference in New Issue
Block a user