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,99 +1,192 @@
--- ---
sense_list_rst: |- sense_list_rst:
always_ff @(posedge {clk_name} or {rst_edge} {rst_name}) rtl: |-
sense_list_no_rst: |- always_ff @(posedge {clk_name} or {rst_edge} {rst_name})
always_ff @(posedge {clk_name}) sense_list_no_rst:
rst_field_assign: |- rtl: |-
if ({rst_negl}{rst_name}) always_ff @(posedge {clk_name})
begin rst_field_assign:
{path}_q{genvars} <= {rst_value}; rtl: |-
end if ({rst_negl}{rst_name})
else begin
sw_access_field: |- {path}_q{genvars} <= {rst_value};
if ({path_wo_field}_sw_wr{genvars}) end
begin else
sw_access_field_swwe: |- signals:
if ({path_wo_field}_sw_wr{genvars} && {swwe}) // swwe property - name: '{path}_q'
begin signal_type: '{field_type}'
sw_access_field_swwel: |- sw_access_field:
if ({path_wo_field}_sw_wr{genvars} && !{swwel}) // swwel property rtl: |-
begin if ({path_wo_field}_sw_wr{genvars})
sw_access_byte: |- begin
if (byte_enable[{i}]) sw_access_field_swwe:
begin rtl: |-
{path}_q{genvars}[{msb_field}-:{field_w}] <= sw_wr_bus[{msb_bus}-:{bus_w}]; if ({path_wo_field}_sw_wr{genvars} && {swwe}) // swwe property
end 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: |- hw_access_we_wel:
if ({negl}{path}_hw_wr{genvars}) rtl: |-
hw_access_no_we_wel: |- if ({negl}{path}_hw_wr{genvars})
// we or wel property not set hw_access_no_we_wel:
hw_access_field: |- rtl: |-
begin // we or wel property not set
{path}_q{genvars} <= {path}_in{genvars}; hw_access_field:
end rtl: |-
end_field_ff: |- begin
end // of {path}'s always_ff {path}_q{genvars} <= {path}_in{genvars};
OnWriteType.woset: |- end
if (byte_enable[{i}]) // woset property signals:
begin - name: '{path}_q'
{path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] | sw_wr_bus[{msb_bus}-:{bus_w}]; signal_type: '{field_type}'
end input_ports:
OnWriteType.woclr: |- - name: '{path}_in'
if (byte_enable[{i}]) // woclr property signal_type: '{field_type}'
begin end_field_ff:
{path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] & ~sw_wr_bus[{msb_bus}-:{bus_w}]; rtl: |-
end end // of {path}'s always_ff
OnWriteType.wot: |- OnWriteType.woset:
if (byte_enable[{i}]) // wot property rtl: |-
begin if (byte_enable[{i}]) // woset property
{path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] ^ sw_wr_bus[{msb_bus}-:{bus_w}]; begin
end {path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] | sw_wr_bus[{msb_bus}-:{bus_w}];
OnWriteType.wzs: |- end
if (byte_enable[{i}]) // wzs property OnWriteType.woclr:
begin rtl: |-
{path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] & sw_wr_bus[{msb_bus}-:{bus_w}]; if (byte_enable[{i}]) // woclr property
end begin
OnWriteType.wzt: |- {path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] & ~sw_wr_bus[{msb_bus}-:{bus_w}];
if (byte_enable[{i}]) // wzt property end
begin OnWriteType.wot:
{path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] ~^ sw_wr_bus[{msb_bus}-:{bus_w}]; rtl: |-
end if (byte_enable[{i}]) // wot property
OnWriteType.wclr: |- begin
{path}_q{genvars} <= {{width{{1'b0}}}}; {path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] ^ sw_wr_bus[{msb_bus}-:{bus_w}];
OnWriteType.wset: |- end
{path}_q{genvars} <= {{width{{1'b1}}}}; OnWriteType.wzs:
OnReadType.rclr: |- rtl: |-
if ({path_wo_field}_sw_rd{genvars}) // rclr property if (byte_enable[{i}]) // wzs property
begin begin
{path}_q{genvars} <= {{width{{1'b0}}}}; {path}_q{genvars}[{msb_field}-:{field_w}] <= {path}_q{genvars}[{msb_field}-:{field_w}] & sw_wr_bus[{msb_bus}-:{bus_w}];
end end
OnReadType.rset: |- OnWriteType.wzt:
if ({path_wo_field}_sw_rd{genvars}) // rset property rtl: |-
begin if (byte_enable[{i}]) // wzt property
{path}_q{genvars} <= {{width{{1'b1}}}}; begin
end {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: | 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};