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 # We need a dictionary since it might be required to access the objects later
# by name (for example, in case of aliases) # by name (for example, in case of aliases)
self.registers = dict() self.registers = dict()
self.rdl_nodes = dict()
# Traverse through children # Traverse through children
for child in obj.children(): for child in obj.children():
@ -61,24 +62,26 @@ class AddrMap(Component):
# Input ports # Input ports
input_ports_rtl = [ input_ports_rtl = [
AddrMap.templ_dict['input_port'].format( AddrMap.templ_dict['input_port'].format(
name = x.name, name = key,
packed_dim = x.packed_dim, signal_type = value[0],
unpacked_dim = '[{}]'.format( unpacked_dim = '[{}]'.format(
']['.join( ']['.join(
[str(y) for y in x.unpacked_dim])) [str(y) for y in value[1]]))
if x.unpacked_dim else '') if value[1] else '')
for x in self.get_ports('input')] for (key, value) in self.get_ports('input').items()
]
# Output ports # Output ports
output_ports_rtl = [ output_ports_rtl = [
AddrMap.templ_dict['output_port'].format( AddrMap.templ_dict['output_port'].format(
name = x.name, name = key,
packed_dim = x.packed_dim, signal_type = value[0],
unpacked_dim = '[{}]'.format( unpacked_dim = '[{}]'.format(
']['.join( ']['.join(
[str(y) for y in x.unpacked_dim])) [str(y) for y in value[1]]))
if x.unpacked_dim else '') if value[1] else '')
for x in self.get_ports('output')] for (key, value) in self.get_ports('output').items()
]
# Remove comma from last port entry # Remove comma from last port entry
output_ports_rtl[-1] = output_ports_rtl[-1].rstrip(',') 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 from log.log import create_logger
# Define NamedTuple # Define NamedTuple
class Port(NamedTuple): class TypeDefMembers(NamedTuple):
name: str name: str
packed_dim: str member_type: str
unpacked_dim: list
class TypeDef(NamedTuple):
name: str
members: list[TypeDefMembers]
class Component(): class Component():
def __init__(self): def __init__(self):
@ -18,9 +21,10 @@ class Component():
self.rtl_footer = [] self.rtl_footer = []
self.children = [] self.children = []
self.ports = dict() self.ports = dict()
self.ports['input'] = [] self.signals = dict()
self.ports['output'] = [] self.ports['input'] = dict()
self.ports['inout'] = [] self.ports['output'] = dict()
self.field_type = ''
def create_logger(self, name: str, config: dict): def create_logger(self, name: str, config: dict):
self.logger = create_logger( self.logger = create_logger(
@ -32,10 +36,19 @@ class Component():
def get_ports(self, port_type: str): def get_ports(self, port_type: str):
self.logger.debug("Return port list") self.logger.debug("Return port list")
return [
*self.ports[port_type], for x in self.children:
*list(chain(*[x.get_ports(port_type) 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: def get_rtl(self, tab_width: int = 0, real_tabs: bool = False) -> str:
self.logger.debug("Return RTL") self.logger.debug("Return RTL")
@ -102,25 +115,60 @@ class Component():
@staticmethod @staticmethod
def split_dimensions(path: str): def split_dimensions(path: str):
new_path = re.match(r'(.*?)(\[.*\])?(.*)', path) re_dimensions = re.compile('(\[[^]]\])')
return (''.join([new_path.group(1), new_path.group(3)]), new_path = re_dimensions.sub('', path)
new_path.group(2) if new_path.group(2) else '[0]') return (new_path, ''.join(re_dimensions.findall(path)))
@staticmethod @staticmethod
def get_ref_name(obj): def get_signal_name(obj):
name = [] name = []
try:
child_obj = obj.node
except AttributeError:
child_obj = obj
split_name = Component.split_dimensions( split_name = Component.split_dimensions(
Component.get_underscored_path( Component.get_underscored_path(
obj.get_path(), child_obj.get_path(),
obj.owning_addrmap.inst_name) child_obj.owning_addrmap.inst_name)
) )
name.append(split_name[0]) name.append(split_name[0])
if isinstance(obj, (node.FieldNode)): if isinstance(obj, node.FieldNode):
name.append('_q') name.append('_q')
elif isinstance(obj, node.SignalNode):
pass
else:
name.append('_')
name.append(obj.name)
name.append(split_name[1]) name.append(split_name[1])
return ''.join(name) 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 from systemrdl.rdltypes import PrecedenceType, AccessType, OnReadType, OnWriteType
# Local modules # Local modules
from components.component import Component, Port from components.component import Component
from . import templates from . import templates
class Field(Component): class Field(Component):
@ -16,11 +16,11 @@ class Field(Component):
pkg_resources.read_text(templates, 'fields.yaml'), pkg_resources.read_text(templates, 'fields.yaml'),
Loader=yaml.FullLoader) 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__() super().__init__()
# Save and/or process important variables # Save and/or process important variables
self.__process_variables(obj, dimensions) self.__process_variables(obj, array_dimensions)
# Create logger object # Create logger object
self.create_logger("{}.{}".format(self.owning_addrmap, self.path), config) self.create_logger("{}.{}".format(self.owning_addrmap, self.path), config)
@ -40,49 +40,55 @@ class Field(Component):
self.__add_access_rtl() self.__add_access_rtl()
self.__add_combo() self.__add_combo()
self.__add_ports() self.__add_ports()
self.__prepend_signal_declarations()
def __add_combo(self): def __add_combo(self):
operations = [] operations = []
if self.obj.get_property('anded'): if self.obj.get_property('anded'):
operations.append(['anded', '&']) operations.append(['&', 'assign_anded_operation'])
if self.obj.get_property('ored'): if self.obj.get_property('ored'):
operations.append(['ored', '|']) operations.append(['|', 'assign_ored_operation'])
if self.obj.get_property('xored'): if self.obj.get_property('xored'):
operations.append(['xored', '^']) operations.append(['^', 'assign_xored_operation'])
if len(operations) > 0: if len(operations) > 0:
self.rtl_header.append( self.rtl_header.append(
Field.templ_dict['combo_operation_comment'].format( Field.templ_dict['combo_operation_comment']['rtl'].format(
path = self.path_underscored)) path = self.path_underscored))
self.rtl_header = [ self.rtl_header = [
*self.rtl_header, *self.rtl_header,
*[Field.templ_dict['assign_combo_operation'].format( *[Field.templ_dict[i[1]]['rtl'].format(
path = self.path_underscored, path = self.path_underscored,
genvars = self.genvars_str, genvars = self.genvars_str,
op_name = i[0], op_verilog = i[0]) for i in operations]
op_verilog = i[1]) 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 # Save object
self.obj = obj self.obj = obj
# Create full name # Create full name
self.owning_addrmap = obj.owning_addrmap.inst_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('[]', '')\
.replace('{}.'.format(self.owning_addrmap), '') .replace('{}.'.format(self.owning_addrmap), '')
self.path_underscored = self.path.replace('.', '_') self.path_underscored = self.path.replace('.', '_')
self.path_wo_field = '.'.join(self.path.split('.', -1)[0:-1]) self.path_wo_field = '.'.join(self.path.split('.', -1)[0:-1])
# Field type
self.field_type = 'logic'
# Save dimensions of unpacked dimension # Save dimensions of unpacked dimension
self.dimensions = dimensions self.array_dimensions = array_dimensions
# Calculate how many genvars shall be added # 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) self.genvars_str = ''.join(genvars)
# Write enable # Write enable
@ -138,7 +144,7 @@ class Field(Component):
# Add comment with summary on field's properties # Add comment with summary on field's properties
return \ return \
Field.templ_dict['field_comment'].format( Field.templ_dict['field_comment']['rtl'].format(
name = self.obj.inst_name, name = self.obj.inst_name,
hw_access = str(self.hw_access)[11:], hw_access = str(self.hw_access)[11:],
sw_access = str(self.sw_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' sense_list = 'sense_list_rst' if self.rst['async'] else 'sense_list_no_rst'
self.rtl_header.append( self.rtl_header.append(
Field.templ_dict[sense_list].format( Field.templ_dict[sense_list]['rtl'].format(
clk_name = "clk", clk_name = "clk",
rst_edge = self.rst['edge'], rst_edge = self.rst['edge'],
rst_name = self.rst['name'])) rst_name = self.rst['name']))
@ -164,15 +170,24 @@ class Field(Component):
# Add actual reset line # Add actual reset line
if self.rst['name']: if self.rst['name']:
self.rtl_header.append( self.rtl_header.append(
Field.templ_dict['rst_field_assign'].format( Field.templ_dict['rst_field_assign']['rtl'].format(
path = self.path_underscored, path = self.path_underscored,
rst_name = self.rst['name'], rst_name = self.rst['name'],
rst_negl = "!" if self.rst['active'] == "active_high" else "", rst_negl = "!" if self.rst['active'] == "active_high" else "",
rst_value = self.rst['value'], rst_value = self.rst['value'],
genvars = self.genvars_str)) genvars = self.genvars_str))
self.yaml_signals_to_list(Field.templ_dict['rst_field_assign'])
self.rtl_header.append("begin") 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): def __add_access_rtl(self):
# Not all access types are required and the order might differ # Not all access types are required and the order might differ
# depending on what types are defined and what precedence is # 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.hw_access in (AccessType.rw, AccessType.w):
if self.we_or_wel: if self.we_or_wel:
access_rtl['hw_write'].append( 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 '', negl = '!' if self.obj.get_property('wel') else '',
path = self.path_underscored, path = self.path_underscored,
genvars = self.genvars_str)) genvars = self.genvars_str))
else: else:
access_rtl['hw_write'].append( 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( access_rtl['hw_write'].append(
Field.templ_dict['hw_access_field'].format( Field.templ_dict['hw_access_field']['rtl'].format(
path = self.path_underscored, path = self.path_underscored,
genvars = self.genvars_str)) genvars = self.genvars_str))
self.yaml_signals_to_list(Field.templ_dict['hw_access_field'])
# Define software access (if applicable) # Define software access (if applicable)
access_rtl['sw_write'] = [] access_rtl['sw_write'] = []
@ -213,19 +230,19 @@ class Field(Component):
if isinstance(swwe, (node.FieldNode, node.SignalNode)): if isinstance(swwe, (node.FieldNode, node.SignalNode)):
access_rtl['sw_write'].append( 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, path_wo_field = self.path_wo_field,
genvars = self.genvars_str, genvars = self.genvars_str,
swwe = Component.get_ref_name(swwe))) swwe = Component.get_signal_name(swwe)))
elif isinstance(swwel, (node.FieldNode, node.SignalNode)): elif isinstance(swwel, (node.FieldNode, node.SignalNode)):
access_rtl['sw_write'].append( 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, path_wo_field = self.path_wo_field,
genvars = self.genvars_str, genvars = self.genvars_str,
swwel = Component.get_ref_name(swwel))) swwel = Component.get_signal_name(swwel)))
else: else:
access_rtl['sw_write'].append( 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, path_wo_field = self.path_wo_field,
genvars = self.genvars_str)) genvars = self.genvars_str))
@ -237,7 +254,7 @@ class Field(Component):
self.logger.warning("The OnReadType.wuser is not yet supported!") self.logger.warning("The OnReadType.wuser is not yet supported!")
elif onwrite in (OnWriteType.wclr, OnWriteType.wset): elif onwrite in (OnWriteType.wclr, OnWriteType.wset):
access_rtl['sw_write'].append( access_rtl['sw_write'].append(
Field.templ_dict[str(onwrite)].format( Field.templ_dict[str(onwrite)]['rtl'].format(
path = self.path_underscored, path = self.path_underscored,
genvars = self.genvars_str, genvars = self.genvars_str,
path_wo_field = self.path_wo_field 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! # 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)):
access_rtl['sw_write'].append( access_rtl['sw_write'].append(
Field.templ_dict[str(onwrite)].format( Field.templ_dict[str(onwrite)]['rtl'].format(
path = self.path_underscored, path = self.path_underscored,
genvars = self.genvars_str, genvars = self.genvars_str,
i = i, i = i,
@ -260,7 +277,7 @@ class Field(Component):
# 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)):
access_rtl['sw_write'].append( access_rtl['sw_write'].append(
Field.templ_dict['sw_access_byte'].format( Field.templ_dict['sw_access_byte']['rtl'].format(
path = self.path_underscored, path = self.path_underscored,
genvars = self.genvars_str, genvars = self.genvars_str,
i = i, i = i,
@ -279,7 +296,7 @@ class Field(Component):
self.logger.warning("The OnReadType.ruser is not yet supported!") self.logger.warning("The OnReadType.ruser is not yet supported!")
else: else:
access_rtl['sw_read'].append( access_rtl['sw_read'].append(
Field.templ_dict[str(onread)].format( Field.templ_dict[str(onread)]['rtl'].format(
path = self.path_underscored, path = self.path_underscored,
genvars = self.genvars_str, genvars = self.genvars_str,
path_wo_field = self.path_wo_field path_wo_field = self.path_wo_field
@ -289,7 +306,7 @@ class Field(Component):
# Add singlepulse property # Add singlepulse property
if self.obj.get_property('singlepulse'): if self.obj.get_property('singlepulse'):
access_rtl['singlepulse'] = [ access_rtl['singlepulse'] = [
Field.templ_dict['singlepulse'].format( Field.templ_dict['singlepulse']['rtl'].format(
path = self.path_underscored, path = self.path_underscored,
genvars = self.genvars_str) genvars = self.genvars_str)
] ]
@ -335,40 +352,19 @@ class Field(Component):
self.rtl_header = [*self.rtl_header, *order_list_rtl] self.rtl_header = [*self.rtl_header, *order_list_rtl]
self.rtl_header.append( self.rtl_header.append(
Field.templ_dict['end_field_ff'].format( Field.templ_dict['end_field_ff']['rtl'].format(
path = self.path_underscored)) path = self.path_underscored))
def __add_ports(self): 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): 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 # Connect flops to output port
self.rtl_header.append( self.rtl_header.append(
Field.templ_dict['out_port_assign'].format( Field.templ_dict['out_port_assign']['rtl'].format(
genvars = self.genvars_str, genvars = self.genvars_str,
path = self.path_underscored)) path = self.path_underscored))
self.yaml_signals_to_list(Field.templ_dict['out_port_assign'])
def sanity_checks(self): def sanity_checks(self):
# If hw=rw/sw=[r]w and hw has no we/wel, sw will never be able to write # 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 "\ "precedence for hardware will render software's "\
"write property useless since hardware will "\ "write property useless since hardware will "\
"write every cycle.") "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.create_logger("{}.{}".format(self.owning_addrmap, self.path), config)
self.logger.debug('Starting to process register "{}"'.format(obj.inst_name)) 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 # Create RTL for fields
# Fields should be in order in RTL,therefore, use list # Fields should be in order in RTL,therefore, use list
for field in obj.fields(): for field in obj.fields():
@ -57,6 +35,15 @@ class Register(Component):
self.children.append(field_obj) 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 # End loops
for i in range(self.dimensions-1, -1, -1): for i in range(self.dimensions-1, -1, -1):
self.rtl_footer.append( self.rtl_footer.append(
@ -72,7 +59,7 @@ class Register(Component):
rw_wire_assign_field = 'rw_wire_assign_1_dim' rw_wire_assign_field = 'rw_wire_assign_1_dim'
self.rtl_header.append( self.rtl_header.append(
Register.templ_dict[rw_wire_assign_field].format( Register.templ_dict[rw_wire_assign_field]['rtl'].format(
path = self.path, path = self.path,
addr = self.obj.absolute_address, addr = self.obj.absolute_address,
genvars = self.genvars_str, genvars = self.genvars_str,
@ -80,6 +67,34 @@ class Register(Component):
stride = self.obj.array_stride, stride = self.obj.array_stride,
depth = self.depth)) 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): def __process_variables(self, obj: node.RootNode):
# Save object # Save object
self.obj = obj self.obj = obj

View File

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

View File

@ -1,80 +1,110 @@
--- ---
sense_list_rst: |- sense_list_rst:
rtl: |-
always_ff @(posedge {clk_name} or {rst_edge} {rst_name}) always_ff @(posedge {clk_name} or {rst_edge} {rst_name})
sense_list_no_rst: |- sense_list_no_rst:
rtl: |-
always_ff @(posedge {clk_name}) always_ff @(posedge {clk_name})
rst_field_assign: |- rst_field_assign:
rtl: |-
if ({rst_negl}{rst_name}) if ({rst_negl}{rst_name})
begin begin
{path}_q{genvars} <= {rst_value}; {path}_q{genvars} <= {rst_value};
end end
else else
sw_access_field: |- signals:
- name: '{path}_q'
signal_type: '{field_type}'
sw_access_field:
rtl: |-
if ({path_wo_field}_sw_wr{genvars}) if ({path_wo_field}_sw_wr{genvars})
begin begin
sw_access_field_swwe: |- sw_access_field_swwe:
rtl: |-
if ({path_wo_field}_sw_wr{genvars} && {swwe}) // swwe property if ({path_wo_field}_sw_wr{genvars} && {swwe}) // swwe property
begin begin
sw_access_field_swwel: |- sw_access_field_swwel:
rtl: |-
if ({path_wo_field}_sw_wr{genvars} && !{swwel}) // swwel property if ({path_wo_field}_sw_wr{genvars} && !{swwel}) // swwel property
begin begin
sw_access_byte: |- sw_access_byte:
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}-:{field_w}] <= sw_wr_bus[{msb_bus}-:{bus_w}];
end end
hw_access_we_wel: |- hw_access_we_wel:
rtl: |-
if ({negl}{path}_hw_wr{genvars}) if ({negl}{path}_hw_wr{genvars})
hw_access_no_we_wel: |- hw_access_no_we_wel:
rtl: |-
// we or wel property not set // we or wel property not set
hw_access_field: |- hw_access_field:
rtl: |-
begin begin
{path}_q{genvars} <= {path}_in{genvars}; {path}_q{genvars} <= {path}_in{genvars};
end end
end_field_ff: |- 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 end // of {path}'s always_ff
OnWriteType.woset: |- OnWriteType.woset:
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}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] | sw_wr_bus[{msb_bus}-:{bus_w}];
end end
OnWriteType.woclr: |- OnWriteType.woclr:
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}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] & ~sw_wr_bus[{msb_bus}-:{bus_w}];
end end
OnWriteType.wot: |- OnWriteType.wot:
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}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] ^ sw_wr_bus[{msb_bus}-:{bus_w}];
end end
OnWriteType.wzs: |- OnWriteType.wzs:
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}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] & sw_wr_bus[{msb_bus}-:{bus_w}];
end end
OnWriteType.wzt: |- OnWriteType.wzt:
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}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] ~^ sw_wr_bus[{msb_bus}-:{bus_w}];
end end
OnWriteType.wclr: |- OnWriteType.wclr:
rtl: |-
{path}_q{genvars} <= {{width{{1'b0}}}}; {path}_q{genvars} <= {{width{{1'b0}}}};
OnWriteType.wset: |- OnWriteType.wset:
rtl: |-
{path}_q{genvars} <= {{width{{1'b1}}}}; {path}_q{genvars} <= {{width{{1'b1}}}};
OnReadType.rclr: |- OnReadType.rclr:
rtl: |-
if ({path_wo_field}_sw_rd{genvars}) // rclr property if ({path_wo_field}_sw_rd{genvars}) // rclr property
begin begin
{path}_q{genvars} <= {{width{{1'b0}}}}; {path}_q{genvars} <= {{width{{1'b0}}}};
end end
OnReadType.rset: |- OnReadType.rset:
rtl: |-
if ({path_wo_field}_sw_rd{genvars}) // rset property if ({path_wo_field}_sw_rd{genvars}) // rset property
begin begin
{path}_q{genvars} <= {{width{{1'b1}}}}; {path}_q{genvars} <= {{width{{1'b1}}}};
end end
field_comment: |- field_comment:
rtl: |-
//-----------------FIELD SUMMARY----------------- //-----------------FIELD SUMMARY-----------------
// name : {name} ({path_wo_field}[{msb}:{lsb}]) // name : {name} ({path_wo_field}[{msb}:{lsb}])
@ -83,17 +113,80 @@ field_comment: |-
// reset : {rst_active} / {rst_type} // reset : {rst_active} / {rst_type}
// flags : {misc_flags} // flags : {misc_flags}
//----------------------------------------------- //-----------------------------------------------
combo_operation_comment: |- combo_operation_comment:
rtl: |-
// Combinational logic for {path} // Combinational logic for {path}
assign_combo_operation: |- assign_anded_operation:
assign {path}_{op_name}{genvars} = {op_verilog}{path}_q{genvars} rtl: |-
singlepulse: |- 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 begin
{path}{genvars} <= 0; {path}{genvars}_q <= 0;
end end
out_port_assign: |- out_port_assign:
rtl: |-
// Connect register to hardware output port // Connect register to hardware output port
assign {path}_r{genvars} = {path}_q{genvars}; 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})

View File

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