Provide more advanced way of adding internal signals or ports

Now, every snippet of RTL in the YAML file can also hold internal
variables (i.e., signals), input or output ports. Furthermore, the
input/output port lists are replaced by a dictionary to prevent
duplicate entries.
This commit is contained in:
Dennis Potter 2021-05-23 17:46:48 +02:00
parent c5755bf104
commit 085e2ea2dc
Signed by: Dennis
GPG Key ID: 186A8AD440942BAF
7 changed files with 392 additions and 207 deletions

View File

@ -33,6 +33,7 @@ class AddrMap(Component):
# We need a dictionary since it might be required to access the objects later
# by name (for example, in case of aliases)
self.registers = dict()
self.rdl_nodes = dict()
# Traverse through children
for child in obj.children():
@ -61,24 +62,26 @@ class AddrMap(Component):
# Input ports
input_ports_rtl = [
AddrMap.templ_dict['input_port'].format(
name = x.name,
packed_dim = x.packed_dim,
name = key,
signal_type = value[0],
unpacked_dim = '[{}]'.format(
']['.join(
[str(y) for y in x.unpacked_dim]))
if x.unpacked_dim else '')
for x in self.get_ports('input')]
[str(y) for y in value[1]]))
if value[1] else '')
for (key, value) in self.get_ports('input').items()
]
# Output ports
output_ports_rtl = [
AddrMap.templ_dict['output_port'].format(
name = x.name,
packed_dim = x.packed_dim,
name = key,
signal_type = value[0],
unpacked_dim = '[{}]'.format(
']['.join(
[str(y) for y in x.unpacked_dim]))
if x.unpacked_dim else '')
for x in self.get_ports('output')]
[str(y) for y in value[1]]))
if value[1] else '')
for (key, value) in self.get_ports('output').items()
]
# Remove comma from last port entry
output_ports_rtl[-1] = output_ports_rtl[-1].rstrip(',')

View File

@ -7,10 +7,13 @@ from systemrdl import node
from log.log import create_logger
# Define NamedTuple
class Port(NamedTuple):
class TypeDefMembers(NamedTuple):
name: str
packed_dim: str
unpacked_dim: list
member_type: str
class TypeDef(NamedTuple):
name: str
members: list[TypeDefMembers]
class Component():
def __init__(self):
@ -18,9 +21,10 @@ class Component():
self.rtl_footer = []
self.children = []
self.ports = dict()
self.ports['input'] = []
self.ports['output'] = []
self.ports['inout'] = []
self.signals = dict()
self.ports['input'] = dict()
self.ports['output'] = dict()
self.field_type = ''
def create_logger(self, name: str, config: dict):
self.logger = create_logger(
@ -32,10 +36,19 @@ class Component():
def get_ports(self, port_type: str):
self.logger.debug("Return port list")
return [
*self.ports[port_type],
*list(chain(*[x.get_ports(port_type) for x in self.children]))
]
for x in self.children:
self.ports[port_type] |= x.get_ports(port_type)
return self.ports[port_type]
def get_signals(self):
self.logger.debug("Return signal list")
for x in self.children:
self.signals |= x.get_signals()
return self.signals
def get_rtl(self, tab_width: int = 0, real_tabs: bool = False) -> str:
self.logger.debug("Return RTL")
@ -102,25 +115,60 @@ class Component():
@staticmethod
def split_dimensions(path: str):
new_path = re.match(r'(.*?)(\[.*\])?(.*)', path)
return (''.join([new_path.group(1), new_path.group(3)]),
new_path.group(2) if new_path.group(2) else '[0]')
re_dimensions = re.compile('(\[[^]]\])')
new_path = re_dimensions.sub('', path)
return (new_path, ''.join(re_dimensions.findall(path)))
@staticmethod
def get_ref_name(obj):
def get_signal_name(obj):
name = []
try:
child_obj = obj.node
except AttributeError:
child_obj = obj
split_name = Component.split_dimensions(
Component.get_underscored_path(
obj.get_path(),
obj.owning_addrmap.inst_name)
child_obj.get_path(),
child_obj.owning_addrmap.inst_name)
)
name.append(split_name[0])
if isinstance(obj, (node.FieldNode)):
if isinstance(obj, node.FieldNode):
name.append('_q')
elif isinstance(obj, node.SignalNode):
pass
else:
name.append('_')
name.append(obj.name)
name.append(split_name[1])
return ''.join(name)
def yaml_signals_to_list(self, yaml_obj):
try:
for x in yaml_obj['signals']:
self.signals[x['name'].format(path = self.path_underscored)] =\
(x['signal_type'].format(field_type = self.field_type),
self.array_dimensions)
except (TypeError, KeyError):
pass
try:
for x in yaml_obj['input_ports']:
self.ports['input'][x['name'].format(path = self.path_underscored)] =\
(x['signal_type'].format(field_type = self.field_type),
self.array_dimensions)
except (TypeError, KeyError):
pass
try:
for x in yaml_obj['output_ports']:
self.ports['output'][x['name'].format(path = self.path_underscored)] =\
(x['signal_type'].format(field_type = self.field_type),
self.array_dimensions)
except (TypeError, KeyError):
pass

View File

@ -7,7 +7,7 @@ from systemrdl.node import FieldNode
from systemrdl.rdltypes import PrecedenceType, AccessType, OnReadType, OnWriteType
# Local modules
from components.component import Component, Port
from components.component import Component
from . import templates
class Field(Component):
@ -16,11 +16,11 @@ class Field(Component):
pkg_resources.read_text(templates, 'fields.yaml'),
Loader=yaml.FullLoader)
def __init__(self, obj: node.FieldNode, dimensions: list, config:dict):
def __init__(self, obj: node.FieldNode, array_dimensions: list, config:dict):
super().__init__()
# Save and/or process important variables
self.__process_variables(obj, dimensions)
self.__process_variables(obj, array_dimensions)
# Create logger object
self.create_logger("{}.{}".format(self.owning_addrmap, self.path), config)
@ -40,49 +40,55 @@ class Field(Component):
self.__add_access_rtl()
self.__add_combo()
self.__add_ports()
self.__prepend_signal_declarations()
def __add_combo(self):
operations = []
if self.obj.get_property('anded'):
operations.append(['anded', '&'])
operations.append(['&', 'assign_anded_operation'])
if self.obj.get_property('ored'):
operations.append(['ored', '|'])
operations.append(['|', 'assign_ored_operation'])
if self.obj.get_property('xored'):
operations.append(['xored', '^'])
operations.append(['^', 'assign_xored_operation'])
if len(operations) > 0:
self.rtl_header.append(
Field.templ_dict['combo_operation_comment'].format(
Field.templ_dict['combo_operation_comment']['rtl'].format(
path = self.path_underscored))
self.rtl_header = [
*self.rtl_header,
*[Field.templ_dict['assign_combo_operation'].format(
*[Field.templ_dict[i[1]]['rtl'].format(
path = self.path_underscored,
genvars = self.genvars_str,
op_name = i[0],
op_verilog = i[1]) for i in operations]
op_verilog = i[0]) for i in operations]
]
[self.yaml_signals_to_list(Field.templ_dict[i[1]]) for i in operations]
def __process_variables(self, obj: node.RootNode, dimensions: list):
def __process_variables(self, obj: node.RootNode, array_dimensions: list):
# Save object
self.obj = obj
# Create full name
self.owning_addrmap = obj.owning_addrmap.inst_name
self.path = obj.get_path()\
self.full_path = obj.get_path().replace('[]', '')
self.path = self.full_path\
.replace('[]', '')\
.replace('{}.'.format(self.owning_addrmap), '')
self.path_underscored = self.path.replace('.', '_')
self.path_wo_field = '.'.join(self.path.split('.', -1)[0:-1])
# Field type
self.field_type = 'logic'
# Save dimensions of unpacked dimension
self.dimensions = dimensions
self.array_dimensions = array_dimensions
# Calculate how many genvars shall be added
genvars = ['[{}]'.format(chr(97+i)) for i in range(len(dimensions))]
genvars = ['[{}]'.format(chr(97+i)) for i in range(len(array_dimensions))]
self.genvars_str = ''.join(genvars)
# Write enable
@ -138,7 +144,7 @@ class Field(Component):
# Add comment with summary on field's properties
return \
Field.templ_dict['field_comment'].format(
Field.templ_dict['field_comment']['rtl'].format(
name = self.obj.inst_name,
hw_access = str(self.hw_access)[11:],
sw_access = str(self.sw_access)[11:],
@ -156,7 +162,7 @@ class Field(Component):
sense_list = 'sense_list_rst' if self.rst['async'] else 'sense_list_no_rst'
self.rtl_header.append(
Field.templ_dict[sense_list].format(
Field.templ_dict[sense_list]['rtl'].format(
clk_name = "clk",
rst_edge = self.rst['edge'],
rst_name = self.rst['name']))
@ -164,15 +170,24 @@ class Field(Component):
# Add actual reset line
if self.rst['name']:
self.rtl_header.append(
Field.templ_dict['rst_field_assign'].format(
Field.templ_dict['rst_field_assign']['rtl'].format(
path = self.path_underscored,
rst_name = self.rst['name'],
rst_negl = "!" if self.rst['active'] == "active_high" else "",
rst_value = self.rst['value'],
genvars = self.genvars_str))
self.yaml_signals_to_list(Field.templ_dict['rst_field_assign'])
self.rtl_header.append("begin")
# Add name of actual field to Signal field
# TODO
def __prepend_signal_declarations(self):
pass
def __add_access_rtl(self):
# Not all access types are required and the order might differ
# depending on what types are defined and what precedence is
@ -191,19 +206,21 @@ class Field(Component):
if self.hw_access in (AccessType.rw, AccessType.w):
if self.we_or_wel:
access_rtl['hw_write'].append(
Field.templ_dict['hw_access_we_wel'].format(
Field.templ_dict['hw_access_we_wel']['rtl'].format(
negl = '!' if self.obj.get_property('wel') else '',
path = self.path_underscored,
genvars = self.genvars_str))
else:
access_rtl['hw_write'].append(
Field.templ_dict['hw_access_no_we_wel'])
Field.templ_dict['hw_access_no_we_wel']['rtl'])
access_rtl['hw_write'].append(
Field.templ_dict['hw_access_field'].format(
Field.templ_dict['hw_access_field']['rtl'].format(
path = self.path_underscored,
genvars = self.genvars_str))
self.yaml_signals_to_list(Field.templ_dict['hw_access_field'])
# Define software access (if applicable)
access_rtl['sw_write'] = []
@ -213,19 +230,19 @@ class Field(Component):
if isinstance(swwe, (node.FieldNode, node.SignalNode)):
access_rtl['sw_write'].append(
Field.templ_dict['sw_access_field_swwe'].format(
Field.templ_dict['sw_access_field_swwe']['rtl'].format(
path_wo_field = self.path_wo_field,
genvars = self.genvars_str,
swwe = Component.get_ref_name(swwe)))
swwe = Component.get_signal_name(swwe)))
elif isinstance(swwel, (node.FieldNode, node.SignalNode)):
access_rtl['sw_write'].append(
Field.templ_dict['sw_access_field_swwel'].format(
Field.templ_dict['sw_access_field_swwel']['rtl'].format(
path_wo_field = self.path_wo_field,
genvars = self.genvars_str,
swwel = Component.get_ref_name(swwel)))
swwel = Component.get_signal_name(swwel)))
else:
access_rtl['sw_write'].append(
Field.templ_dict['sw_access_field'].format(
Field.templ_dict['sw_access_field']['rtl'].format(
path_wo_field = self.path_wo_field,
genvars = self.genvars_str))
@ -237,7 +254,7 @@ class Field(Component):
self.logger.warning("The OnReadType.wuser is not yet supported!")
elif onwrite in (OnWriteType.wclr, OnWriteType.wset):
access_rtl['sw_write'].append(
Field.templ_dict[str(onwrite)].format(
Field.templ_dict[str(onwrite)]['rtl'].format(
path = self.path_underscored,
genvars = self.genvars_str,
path_wo_field = self.path_wo_field
@ -247,7 +264,7 @@ class Field(Component):
# If field spans multiple bytes, every byte shall have a seperate enable!
for j, i in enumerate(range(self.lsbyte, self.msbyte+1)):
access_rtl['sw_write'].append(
Field.templ_dict[str(onwrite)].format(
Field.templ_dict[str(onwrite)]['rtl'].format(
path = self.path_underscored,
genvars = self.genvars_str,
i = i,
@ -260,7 +277,7 @@ class Field(Component):
# If field spans multiple bytes, every byte shall have a seperate enable!
for j, i in enumerate(range(self.lsbyte, self.msbyte+1)):
access_rtl['sw_write'].append(
Field.templ_dict['sw_access_byte'].format(
Field.templ_dict['sw_access_byte']['rtl'].format(
path = self.path_underscored,
genvars = self.genvars_str,
i = i,
@ -279,7 +296,7 @@ class Field(Component):
self.logger.warning("The OnReadType.ruser is not yet supported!")
else:
access_rtl['sw_read'].append(
Field.templ_dict[str(onread)].format(
Field.templ_dict[str(onread)]['rtl'].format(
path = self.path_underscored,
genvars = self.genvars_str,
path_wo_field = self.path_wo_field
@ -289,7 +306,7 @@ class Field(Component):
# Add singlepulse property
if self.obj.get_property('singlepulse'):
access_rtl['singlepulse'] = [
Field.templ_dict['singlepulse'].format(
Field.templ_dict['singlepulse']['rtl'].format(
path = self.path_underscored,
genvars = self.genvars_str)
]
@ -335,40 +352,19 @@ class Field(Component):
self.rtl_header = [*self.rtl_header, *order_list_rtl]
self.rtl_header.append(
Field.templ_dict['end_field_ff'].format(
Field.templ_dict['end_field_ff']['rtl'].format(
path = self.path_underscored))
def __add_ports(self):
# Port is writable by hardware --> Input port from hardware
if self.hw_access in (AccessType.rw, AccessType.w):
self.ports['input'].append(
Port("{}_in".format(self.path_underscored),
"",
self.dimensions
))
# Port has enable signal --> create such an enable
if self.we_or_wel:
self.ports['input'].append(
Port("{}_hw_wr".format(self.path_underscored),
"",
self.dimensions
))
if self.hw_access in (AccessType.rw, AccessType.r):
self.ports['output'].append(
Port("{}_r".format(self.path_underscored),
"[{}:0]".format(self.obj.width-1) if self.obj.width > 1 else "",
self.dimensions
))
# Connect flops to output port
self.rtl_header.append(
Field.templ_dict['out_port_assign'].format(
Field.templ_dict['out_port_assign']['rtl'].format(
genvars = self.genvars_str,
path = self.path_underscored))
self.yaml_signals_to_list(Field.templ_dict['out_port_assign'])
def sanity_checks(self):
# If hw=rw/sw=[r]w and hw has no we/wel, sw will never be able to write
@ -381,3 +377,6 @@ class Field(Component):
"precedence for hardware will render software's "\
"write property useless since hardware will "\
"write every cycle.")
# TODO: Counter & hw=r shouldn't work

View File

@ -25,28 +25,6 @@ class Register(Component):
self.create_logger("{}.{}".format(self.owning_addrmap, self.path), config)
self.logger.debug('Starting to process register "{}"'.format(obj.inst_name))
# Create comment and provide user information about register he/she
# is looking at.
self.rtl_header.append(
Register.templ_dict['reg_comment'].format(
name = obj.inst_name,
dimensions = self.dimensions,
depth = self.depth))
# Create wires every register
self.rtl_header.append(
Register.templ_dict['rw_wire_declare'].format(
path = self.path,
depth = self.depth))
# Create generate block for register and add comment
self.rtl_header.append("generate")
for i in range(self.dimensions):
self.rtl_header.append(
Register.templ_dict['generate_for_start'].format(
iterator = chr(97+i),
limit = self.array_dimensions[i]))
# Create RTL for fields
# Fields should be in order in RTL,therefore, use list
for field in obj.fields():
@ -57,6 +35,15 @@ class Register(Component):
self.children.append(field_obj)
# Create generate block for register and add comment
self.rtl_header.append("generate")
for i in range(self.dimensions):
self.rtl_header.append(
Register.templ_dict['generate_for_start'].format(
iterator = chr(97+i),
limit = self.array_dimensions[i]))
# End loops
for i in range(self.dimensions-1, -1, -1):
self.rtl_footer.append(
@ -72,7 +59,7 @@ class Register(Component):
rw_wire_assign_field = 'rw_wire_assign_1_dim'
self.rtl_header.append(
Register.templ_dict[rw_wire_assign_field].format(
Register.templ_dict[rw_wire_assign_field]['rtl'].format(
path = self.path,
addr = self.obj.absolute_address,
genvars = self.genvars_str,
@ -80,6 +67,34 @@ class Register(Component):
stride = self.obj.array_stride,
depth = self.depth))
self.yaml_signals_to_list(Register.templ_dict[rw_wire_assign_field])
# Add wire/register instantiations
self.rtl_header = [
*[
Register.templ_dict['signal_declaration'].format(
name = key,
type = value[0],
unpacked_dim = '[{}]'.format(
']['.join(
[str(y) for y in value[1]]))
if value[1] else '')
for (key, value) in self.get_signals().items()],
'',
*self.rtl_header,
]
# Create comment and provide user information about register he/she
# is looking at.
self.rtl_header = [
Register.templ_dict['reg_comment'].format(
name = obj.inst_name,
dimensions = self.dimensions,
depth = self.depth),
*self.rtl_header
]
def __process_variables(self, obj: node.RootNode):
# Save object
self.obj = obj

View File

@ -11,6 +11,6 @@ module_declaration: |-
{outputs}
);
input_port: |-
input {packed_dim:15s}{name:25s} {unpacked_dim},
input {signal_type:15s}{name:25s} {unpacked_dim},
output_port: |-
output {packed_dim:15s}{name:25s} {unpacked_dim},
output {signal_type:15s}{name:25s} {unpacked_dim},

View File

@ -1,99 +1,192 @@
---
sense_list_rst: |-
always_ff @(posedge {clk_name} or {rst_edge} {rst_name})
sense_list_no_rst: |-
always_ff @(posedge {clk_name})
rst_field_assign: |-
if ({rst_negl}{rst_name})
begin
{path}_q{genvars} <= {rst_value};
end
else
sw_access_field: |-
if ({path_wo_field}_sw_wr{genvars})
begin
sw_access_field_swwe: |-
if ({path_wo_field}_sw_wr{genvars} && {swwe}) // swwe property
begin
sw_access_field_swwel: |-
if ({path_wo_field}_sw_wr{genvars} && !{swwel}) // swwel property
begin
sw_access_byte: |-
if (byte_enable[{i}])
begin
{path}_q{genvars}[{msb_field}-:{field_w}] <= sw_wr_bus[{msb_bus}-:{bus_w}];
end
sense_list_rst:
rtl: |-
always_ff @(posedge {clk_name} or {rst_edge} {rst_name})
sense_list_no_rst:
rtl: |-
always_ff @(posedge {clk_name})
rst_field_assign:
rtl: |-
if ({rst_negl}{rst_name})
begin
{path}_q{genvars} <= {rst_value};
end
else
signals:
- name: '{path}_q'
signal_type: '{field_type}'
sw_access_field:
rtl: |-
if ({path_wo_field}_sw_wr{genvars})
begin
sw_access_field_swwe:
rtl: |-
if ({path_wo_field}_sw_wr{genvars} && {swwe}) // swwe property
begin
sw_access_field_swwel:
rtl: |-
if ({path_wo_field}_sw_wr{genvars} && !{swwel}) // swwel property
begin
sw_access_byte:
rtl: |-
if (byte_enable[{i}])
begin
{path}_q{genvars}[{msb_field}-:{field_w}] <= sw_wr_bus[{msb_bus}-:{bus_w}];
end
hw_access_we_wel: |-
if ({negl}{path}_hw_wr{genvars})
hw_access_no_we_wel: |-
// we or wel property not set
hw_access_field: |-
begin
{path}_q{genvars} <= {path}_in{genvars};
end
end_field_ff: |-
end // of {path}'s always_ff
OnWriteType.woset: |-
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}];
end
OnWriteType.woclr: |-
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}];
end
OnWriteType.wot: |-
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}];
end
OnWriteType.wzs: |-
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}];
end
OnWriteType.wzt: |-
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}];
end
OnWriteType.wclr: |-
{path}_q{genvars} <= {{width{{1'b0}}}};
OnWriteType.wset: |-
{path}_q{genvars} <= {{width{{1'b1}}}};
OnReadType.rclr: |-
if ({path_wo_field}_sw_rd{genvars}) // rclr property
begin
{path}_q{genvars} <= {{width{{1'b0}}}};
end
OnReadType.rset: |-
if ({path_wo_field}_sw_rd{genvars}) // rset property
begin
{path}_q{genvars} <= {{width{{1'b1}}}};
end
hw_access_we_wel:
rtl: |-
if ({negl}{path}_hw_wr{genvars})
hw_access_no_we_wel:
rtl: |-
// we or wel property not set
hw_access_field:
rtl: |-
begin
{path}_q{genvars} <= {path}_in{genvars};
end
signals:
- name: '{path}_q'
signal_type: '{field_type}'
input_ports:
- name: '{path}_in'
signal_type: '{field_type}'
end_field_ff:
rtl: |-
end // of {path}'s always_ff
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}];
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}];
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}];
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}];
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}];
end
OnWriteType.wclr:
rtl: |-
{path}_q{genvars} <= {{width{{1'b0}}}};
OnWriteType.wset:
rtl: |-
{path}_q{genvars} <= {{width{{1'b1}}}};
OnReadType.rclr:
rtl: |-
if ({path_wo_field}_sw_rd{genvars}) // rclr property
begin
{path}_q{genvars} <= {{width{{1'b0}}}};
end
OnReadType.rset:
rtl: |-
if ({path_wo_field}_sw_rd{genvars}) // rset property
begin
{path}_q{genvars} <= {{width{{1'b1}}}};
end
field_comment:
rtl: |-
//-----------------FIELD SUMMARY-----------------
// name : {name} ({path_wo_field}[{msb}:{lsb}])
// access : hw = {hw_access} {hw_precedence}
// sw = {sw_access} {sw_precedence}
// reset : {rst_active} / {rst_type}
// flags : {misc_flags}
//-----------------------------------------------
combo_operation_comment:
rtl: |-
// Combinational logic for {path}
assign_anded_operation:
rtl: |-
assign {path}_anded{genvars} = {op_verilog}{path}_q{genvars};
output_ports:
- name: '{path}_anded'
signal_type: 'logic'
assign_ored_operation:
rtl: |-
assign {path}_ored{genvars} = {op_verilog}{path}_q{genvars};
output_ports:
- name: '{path}_ored'
signal_type: 'logic'
assign_xored_operation:
rtl: |-
assign {path}_xored{genvars} = {op_verilog}{path}_q{genvars};
output_ports:
- name: '{path}_xored'
signal_type: 'logic'
singlepulse:
rtl: |-
begin
{path}{genvars}_q <= 0;
end
out_port_assign:
rtl: |-
// Connect register to hardware output port
assign {path}_r{genvars} = {path}_q{genvars};
output_ports:
- name: '{path}_r'
signal_type: '{field_type}'
counter:
rtl: |-
always_comb
begin
{path}_next{genvars} = {path}_q{genvars};
{path}_update_cnt{genvars} = 0;
{incr_counter}
{decr_counter}
end
incr_counter:
rtl: |-
{incr_counter_condition}
begin
{path}_next{genvars} += {path}_{operation_str}_val{genvars};
{path}_update_cnt{genvars} = 1;
end
decr_counter:
rtl: |-
{incr_counter_condition}
begin
{path}_next{genvars} += {path}_{operation_str}_val{genvars};
{path}_update_cnt{genvars} = 1;
end
incr_counter_condition:
rtl: |-
if ({path}_incr{genvars})
incr_sat_counter_condition:
rtl: |-
if ({path}_incr{genvars} && {path}_next{genvars} + {path}_incr_val{genvars} <= {sat_value})
decr_counter_condition:
rtl: |-
if ({path}_decr{genvars})
decr_sat_counter_condition:
rtl: |-
if ({path}_decr{genvars} && {path}_next{genvars} - {path}_decr_val{genvars} >= {sat_value})
field_comment: |-
//-----------------FIELD SUMMARY-----------------
// name : {name} ({path_wo_field}[{msb}:{lsb}])
// access : hw = {hw_access} {hw_precedence}
// sw = {sw_access} {sw_precedence}
// reset : {rst_active} / {rst_type}
// flags : {misc_flags}
//-----------------------------------------------
combo_operation_comment: |-
// Combinational logic for {path}
assign_combo_operation: |-
assign {path}_{op_name}{genvars} = {op_verilog}{path}_q{genvars}
singlepulse: |-
begin
{path}{genvars} <= 0;
end
out_port_assign: |-
// Connect register to hardware output port
assign {path}_r{genvars} = {path}_q{genvars};

View File

@ -1,14 +1,39 @@
---
rw_wire_declare: |
logic {path}_sw_wr {depth};
logic {path}_sw_rd {depth};
rw_wire_assign_1_dim: |
assign {path}_sw_wr{genvars} = addr == {addr} && r_vld;
assign {path}_sw_rd{genvars} = addr == {addr} && w_vld;
rw_wire_assign_multi_dim: |
assign {path}_sw_wr{genvars} = addr == ({addr}+({genvars_sum})*{stride}) && r_vld;
assign {path}_sw_rd{genvars} = addr == ({addr}+({genvars_sum})*{stride}) && w_vld;
rw_wire_assign_1_dim:
rtl: |
// Assign register-activation signals
assign {path}_reg_active{genvars} = addr == {addr};
assign {path}_sw_wr = {path}_reg_active && r_vld;
assign {path}_sw_rd = {path}_reg_active && w_vld;
signals:
- name: '{path}_sw_wr'
signal_type: 'logic'
- name: '{path}_sw_rd'
signal_type: 'logic'
- name: '{path}_reg_active'
signal_type: 'logic'
input_ports:
output_ports:
rw_wire_assign_multi_dim:
rtl: |
// Assign register-activation signals
assign {path}_reg_active{genvars} = addr == ({addr}+({genvars_sum})*{stride});
assign {path}_sw_wr{genvars} = {path}_reg_active{genvars} && r_vld;
assign {path}_sw_rd{genvars} = {path}_reg_active{genvars} && w_vld;
signals:
- name: '{path}_sw_wr'
signal_type: 'logic'
- name: '{path}_sw_rd'
signal_type: 'logic'
- name: '{path}_reg_active'
signal_type: 'logic'
input_ports:
output_ports:
reg_comment: |-
/*******************************************************************
*******************************************************************
* REGISTER : {name}
@ -21,3 +46,5 @@ generate_for_start: |-
begin
generate_for_end: |-
end // of for loop with iterator {dimension}
signal_declaration: |-
{type:10s}{name:20s} {unpacked_dim};