Minor clean up, mostly Python Lint warnings

This commit is contained in:
Dennis Potter 2021-10-20 23:51:07 -07:00
parent 1ed801a565
commit abf3fac24f
Signed by: Dennis
GPG Key ID: 186A8AD440942BAF
9 changed files with 189 additions and 197 deletions

View File

@ -20,7 +20,7 @@
* *
* Generation information: * Generation information:
* - User: : dpotter * - User: : dpotter
* - Time : October 20 2021 22:32:15 * - Time : October 20 2021 23:49:07
* - Path : /home/dpotter/srdl2sv_second_repo/examples/simple_rw_reg * - Path : /home/dpotter/srdl2sv_second_repo/examples/simple_rw_reg
* - RDL file : ['simple_rw_reg.rdl'] * - RDL file : ['simple_rw_reg.rdl']
* - Hostname : ArchXPS * - Hostname : ArchXPS
@ -30,7 +30,7 @@
* *
* Commandline arguments to srdl2sv: * Commandline arguments to srdl2sv:
* - Ouput Directory : ./srdl2sv_out * - Ouput Directory : ./srdl2sv_out
* - Stream Log Level : WARNING * - Stream Log Level : INFO
* - File Log Level : INFO * - File Log Level : INFO
* - Use Real Tabs : False * - Use Real Tabs : False
* - Tab Width : 4 * - Tab Width : 4
@ -175,7 +175,7 @@ assign register_1d_sw_wr = register_1d_active && b2r.w_vld;
// access : hw = rw // access : hw = rw
// sw = rw (precedence) // sw = rw (precedence)
// reset : - / - // reset : - / -
// flags : {'we', 'sw'} // flags : ['sw', 'we']
// external : False // external : False
//----------------------------------------------- //-----------------------------------------------
@ -203,7 +203,7 @@ assign register_1d__f1_r = register_1d__f1_q;
// access : hw = rw // access : hw = rw
// sw = rw (precedence) // sw = rw (precedence)
// reset : - / - // reset : - / -
// flags : {'we', 'sw'} // flags : ['sw', 'we']
// external : False // external : False
//----------------------------------------------- //-----------------------------------------------
@ -270,7 +270,7 @@ begin
// access : hw = rw // access : hw = rw
// sw = rw (precedence) // sw = rw (precedence)
// reset : - / - // reset : - / -
// flags : {'we', 'sw'} // flags : ['sw', 'we']
// external : False // external : False
//----------------------------------------------- //-----------------------------------------------
@ -298,7 +298,7 @@ begin
// access : hw = rw // access : hw = rw
// sw = rw (precedence) // sw = rw (precedence)
// reset : - / - // reset : - / -
// flags : {'we', 'sw'} // flags : ['sw', 'we']
// external : False // external : False
//----------------------------------------------- //-----------------------------------------------
@ -371,7 +371,7 @@ begin
// access : hw = rw // access : hw = rw
// sw = rw (precedence) // sw = rw (precedence)
// reset : - / - // reset : - / -
// flags : {'we', 'sw'} // flags : ['sw', 'we']
// external : False // external : False
//----------------------------------------------- //-----------------------------------------------
@ -399,7 +399,7 @@ begin
// access : hw = rw // access : hw = rw
// sw = rw (precedence) // sw = rw (precedence)
// reset : - / - // reset : - / -
// flags : {'we', 'sw'} // flags : ['sw', 'we']
// external : False // external : False
//----------------------------------------------- //-----------------------------------------------

View File

@ -14,6 +14,7 @@ logging_map = {
} }
class CliArguments(): class CliArguments():
# TODO: Add option to remove timestamp (for SCM)
def __init__(self): def __init__(self):
self.parser = argparse.ArgumentParser( self.parser = argparse.ArgumentParser(

View File

@ -1,6 +1,9 @@
import re
import importlib.resources as pkg_resources import importlib.resources as pkg_resources
import sys import sys
import getpass
import socket
import time
import os
import yaml import yaml
from systemrdl import node from systemrdl import node
@ -24,7 +27,7 @@ class AddrMap(Component):
super().__init__(obj, config) super().__init__(obj, config)
# Check if global resets are defined # Check if global resets are defined
glbl_settings = dict() glbl_settings = {}
# Set defaults so that some of the common component methods work # Set defaults so that some of the common component methods work
self.total_dimensions = 0 self.total_dimensions = 0
@ -44,9 +47,9 @@ class AddrMap(Component):
# Empty dictionary of register objects # Empty dictionary of register objects
# 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 = {}
self.regfiles = dict() self.regfiles = {}
self.mems = dict() self.mems = {}
self.regwidth = 0 self.regwidth = 0
# Traverse through children # Traverse through children
@ -80,8 +83,8 @@ class AddrMap(Component):
# Simply ignore nodes like SignalNodes # Simply ignore nodes like SignalNodes
pass pass
self.logger.info("Detected maximum register width of whole addrmap to be '{}'".format( self.logger.info(
self.regwidth)) f"Detected maximum register width of whole addrmap to be '{self.regwidth}'")
# Add registers to children. This must be done in a last step # Add registers to children. This must be done in a last step
# to account for all possible alias combinations # to account for all possible alias combinations
@ -91,7 +94,8 @@ class AddrMap(Component):
# Create RTL of all registers. Registers in regfiles are # Create RTL of all registers. Registers in regfiles are
# already built and so are memories. # already built and so are memories.
[x.create_rtl() for x in self.registers.values()] for register in self.registers.values():
register.create_rtl()
# Add bus widget ports # Add bus widget ports
widget_rtl = self.__get_widget_ports_rtl() widget_rtl = self.__get_widget_ports_rtl()
@ -176,11 +180,6 @@ class AddrMap(Component):
import_package_list.pop() import_package_list.pop()
import getpass
import socket
import time
import os
self.rtl_header.append( self.rtl_header.append(
AddrMap.templ_dict['header'].format( AddrMap.templ_dict['header'].format(
user = getpass.getuser(), user = getpass.getuser(),
@ -251,7 +250,7 @@ class AddrMap(Component):
) )
def __add_signal_instantiation(self): def __add_signal_instantiation(self):
dict_list = [(key, value) for (key, value) in self.get_signals(True).items()] dict_list = list(self.get_signals(True).items())
signal_width = min(max([len(value[0]) for (_, value) in dict_list]), 40) signal_width = min(max([len(value[0]) for (_, value) in dict_list]), 40)
name_width = min(max([len(key) for (key, _) in dict_list]), 40) name_width = min(max([len(key) for (key, _) in dict_list]), 40)
@ -274,7 +273,7 @@ class AddrMap(Component):
def __get_widget_ports_rtl(self): def __get_widget_ports_rtl(self):
self.widget_templ_dict = yaml.load( self.widget_templ_dict = yaml.load(
pkg_resources.read_text(widgets, 'srdl2sv_{}.yaml'.format(self.config['bus'])), pkg_resources.read_text(widgets, f"srdl2sv_{self.config['bus']}.yaml"),
Loader=yaml.FullLoader) Loader=yaml.FullLoader)
return self.process_yaml( return self.process_yaml(
@ -301,27 +300,28 @@ class AddrMap(Component):
def get_package_names(self) -> set(): def get_package_names(self) -> set():
names = set() names = set()
for i in self.registers.values(): for register in self.registers.values():
for x in i.get_typedefs().values(): for typedef in register.get_typedefs().values():
names.add(x.scope) names.add(typedef.scope)
[names.update(x.get_package_names()) for x in self.regfiles.values()] for regfile in self.regfiles.values():
names.update(regfile.get_package_names())
return names return names
def get_package_rtl(self, tab_width: int = 4, real_tabs = False) -> dict(): def get_package_rtl(self, tab_width: int = 4, real_tabs = False) -> dict():
if not self.config['enums']: if not self.config['enums']:
return dict() return {}
# First go through all registers in this scope to generate a package # First go through all registers in this scope to generate a package
package_rtl = [] package_rtl = []
rtl_return = dict() rtl_return = {}
# Need to keep track of enum names since they shall be unique # Need to keep track of enum names since they shall be unique
# per scope # per scope
enum_rtl = dict() enum_rtl = {}
enum_rtl[self.name] = [] enum_rtl[self.name] = []
enum_members = dict() enum_members = {}
for i in self.registers.values(): for i in self.registers.values():
for key, value in i.get_typedefs().items(): for key, value in i.get_typedefs().items():
@ -335,18 +335,15 @@ class AddrMap(Component):
enum_members[var[0]] = "::".join([self.name, key]) enum_members[var[0]] = "::".join([self.name, key])
else: else:
self.logger.fatal( self.logger.fatal(
"Enum member '{}' was found at multiple locations in the same "\ f"Enum member '{var[0]}' was found at multiple locations in the same "\
"main scope: \n"\ "main scope: \n"\
" -- 1st occurance: '{}'\n"\ f" -- 1st occurance: '{enum_members[var[0]]}'\n"\
" -- 2nd occurance: '{}'\n\n"\ f" -- 2nd occurance: '{'::'.join([self.name, key])}'\n\n"\
"This is not legal because all these enums will be defined "\ "This is not legal because all these enums will be defined "\
"in the same SystemVerilog scope. To share the same enum among "\ "in the same SystemVerilog scope. To share the same enum among "\
"different registers, define them on a higher level in the "\ "different registers, define them on a higher level in the "\
"hierarchy.\n\n"\ "hierarchy.\n\n"\
"Exiting...".format( "Exiting...")
var[0],
enum_members[var[0]],
"::".join([self.name, key])))
sys.exit(1) sys.exit(1)

View File

@ -1,10 +1,10 @@
import re import re
import sys import sys
from itertools import chain
from typing import NamedTuple from typing import NamedTuple
from systemrdl import node
from dataclasses import dataclass from dataclasses import dataclass
from systemrdl import node
# Local modules # Local modules
from log.log import create_logger from log.log import create_logger
@ -30,13 +30,13 @@ class Component():
def __init__(self, obj, config): def __init__(self, obj, config):
self.rtl_header = [] self.rtl_header = []
self.rtl_footer = [] self.rtl_footer = []
self.children = dict() self.children = {}
self.typedefs = dict() self.typedefs = {}
self.ports = dict() self.ports = {}
self.resets = set() self.resets = set()
self.signals = dict() self.signals = {}
self.ports['input'] = dict() self.ports['input'] = {}
self.ports['output'] = dict() self.ports['output'] = {}
self.field_type = '' self.field_type = ''
# Save object # Save object
@ -65,14 +65,12 @@ class Component():
} }
# Create logger object # Create logger object
self.create_logger("{}".format(self.full_path), config) self.create_logger(self.full_path, config)
self.logger.debug('Starting to process {} "{}"'.format( self.logger.debug(f"Starting to process {self.__class__.__name__} '{obj.inst_name}'")
self.__class__.__name__,
obj.inst_name))
def create_logger(self, name: str, config: dict): def create_logger(self, name: str, config: dict):
self.logger = create_logger( self.logger = create_logger(
"{}".format(name), name,
stream_log_level=config['stream_log_level'], stream_log_level=config['stream_log_level'],
file_log_level=config['file_log_level'], file_log_level=config['file_log_level'],
file_name=config['file_log_location']) file_name=config['file_log_location'])
@ -81,23 +79,23 @@ class Component():
def get_resets(self): def get_resets(self):
self.logger.debug("Return reset list") self.logger.debug("Return reset list")
for x in self.children.values(): for child in self.children.values():
self.resets |= x.get_resets() self.resets |= child.get_resets()
return self.resets return self.resets
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")
for x in self.children.values(): for child in self.children.values():
self.ports[port_type] |= x.get_ports(port_type) self.ports[port_type] |= child.get_ports(port_type)
return self.ports[port_type] return self.ports[port_type]
def get_max_dim_depth(self) -> int: def get_max_dim_depth(self) -> int:
self.logger.debug("Return depth '{}' for dimensions (including "\ self.logger.debug(f"Return depth '{self.total_dimensions}' for dimensions (including "\
"parents) '{}'".format(self.total_dimensions, f"parents) '{self.total_array_dimensions}'")
self.total_array_dimensions))
return max([ return max([
self.total_dimensions, self.total_dimensions,
*[x.get_max_dim_depth() for x in self.children.values()] *[x.get_max_dim_depth() for x in self.children.values()]
@ -107,16 +105,16 @@ class Component():
self.logger.debug("Return signal list") self.logger.debug("Return signal list")
if not no_children: if not no_children:
for x in self.children.values(): for child in self.children.values():
self.signals |= x.get_signals() self.signals |= child.get_signals()
return self.signals return self.signals
def get_typedefs(self): def get_typedefs(self):
self.logger.debug("Return typedef list") self.logger.debug("Return typedef list")
for x in self.children.values(): for child in self.children.values():
self.typedefs |= x.get_typedefs() self.typedefs |= child.get_typedefs()
return self.typedefs return self.typedefs
@ -126,8 +124,8 @@ class Component():
# Loop through children and append RTL # Loop through children and append RTL
rtl_children = [] rtl_children = []
for x in self.children.values(): for child in self.children.values():
rtl_children.append(x.get_rtl()) rtl_children.append(child.get_rtl())
# Concatenate header, main, and footer # Concatenate header, main, and footer
rtl = [*self.rtl_header, *rtl_children, *self.rtl_footer] rtl = [*self.rtl_header, *rtl_children, *self.rtl_footer]
@ -153,10 +151,10 @@ class Component():
# Define triggers for which the indentation level will increment or # Define triggers for which the indentation level will increment or
# decrement on the next line # decrement on the next line
trigger_re = re.compile(r""" trigger_re = re.compile(r"""
.*?( .*?(?P<keyword>
(?:\bbegin\b|\{|\bcase\b|<<INDENT>>)| (?:\bbegin\b|\{|\bcase\b|<<INDENT>>)|
(?:\bend\b|}|\bendcase\b|<<UNINDENT>>) (?:\bend\b|}|\bendcase\b|<<UNINDENT>>)
)([^$]*) )(?P<remainder>[^$]*)
""", flags=re.VERBOSE) """, flags=re.VERBOSE)
rtl_indented = [] rtl_indented = []
@ -171,16 +169,14 @@ class Component():
while 1: while 1:
# Check if indentation must be decremented # Check if indentation must be decremented
matchObj = trigger_re.match(line_split) if match_obj := trigger_re.match(line_split):
if match_obj.group('keyword') in ('begin', '{', 'case', '<<INDENT>>'):
if matchObj:
if matchObj.group(1) in ('begin', '{', 'case', '<<INDENT>>'):
indent_lvl_next += 1 indent_lvl_next += 1
else: else:
indent_lvl = indent_lvl_next - 1 indent_lvl = indent_lvl_next - 1
indent_lvl_next -= 1 indent_lvl_next -= 1
line_split = matchObj.group(2) line_split = match_obj.group('remainder')
if not line_split: if not line_split:
break break
@ -189,9 +185,7 @@ class Component():
# Add tabs # Add tabs
if line.strip() not in ("<<INDENT>>", "<<UNINDENT>>", "<<SQUASH_NEWLINE>>"): if line.strip() not in ("<<INDENT>>", "<<UNINDENT>>", "<<SQUASH_NEWLINE>>"):
rtl_indented.append("{}{}".format(tab*indent_lvl, line)) rtl_indented.append(f"{tab*indent_lvl}{line}")
return '\n'.join(rtl_indented) return '\n'.join(rtl_indented)
@ -199,12 +193,12 @@ class Component():
def get_underscored_path(path: str, owning_addrmap: str): def get_underscored_path(path: str, owning_addrmap: str):
return path\ return path\
.replace('[]', '')\ .replace('[]', '')\
.replace('{}.'.format(owning_addrmap), '')\ .replace(f"{owning_addrmap}.", '')\
.replace('.', '__') .replace('.', '__')
@staticmethod @staticmethod
def split_dimensions(path: str): def split_dimensions(path: str):
re_dimensions = re.compile('(\[[^]]*\])') re_dimensions = re.compile(r'(\[[^]]*\])')
new_path = re_dimensions.sub('', path) new_path = re_dimensions.sub('', path)
return (new_path, ''.join(re_dimensions.findall(path))) return (new_path, ''.join(re_dimensions.findall(path)))
@ -229,19 +223,19 @@ class Component():
elif isinstance(obj, node.SignalNode): elif isinstance(obj, node.SignalNode):
# Must add it to signal list # Must add it to signal list
self.ports['input'][obj.inst_name] =\ self.ports['input'][obj.inst_name] =\
("logic" if obj.width == 1 else 'logic [{}:0]'.format(obj.width), []) ("logic" if obj.width == 1 else f"logic [{obj.width}:0]", [])
else: else:
name.append('_') name.append('_')
name.append(obj.name) name.append(obj.name)
# This is a property. Check if the original field actually has this property # This is a property. Check if the original field actually has this property
if obj.name == "intr" or obj.name == "halt": if obj.name in ("intr", "halt"):
pass pass
elif not obj.node.get_property(obj.name): elif not obj.node.get_property(obj.name):
self.logger.fatal("Reference to the property '{}' of instance '{}' found. " self.logger.fatal(f"Reference to the property '{obj.name}' of instance "
"This instance does hold the reference property! Please " f"'{obj.node.get_path()}' found. This instance does "
"fix this if you want me to do my job properly." "hold the reference property! Please fix this if you "
.format(obj.name, obj.node.get_path())) "want me to do my job properly.")
sys.exit(1) sys.exit(1)
@ -259,14 +253,14 @@ class Component():
if skip_signals: if skip_signals:
raise KeyError raise KeyError
for x in yaml_obj['signals']: for signal in yaml_obj['signals']:
try: try:
array_dimensions = [] if x['no_unpacked'] else self.total_array_dimensions array_dimensions = [] if signal['no_unpacked'] else self.total_array_dimensions
except KeyError: except KeyError:
array_dimensions = self.total_array_dimensions array_dimensions = self.total_array_dimensions
self.signals[x['name'].format(**values)] =\ self.signals[signal['name'].format(**values)] =\
(x['signal_type'].format(**values), (signal['signal_type'].format(**values),
array_dimensions) array_dimensions)
except (TypeError, KeyError): except (TypeError, KeyError):
pass pass
@ -275,14 +269,14 @@ class Component():
if skip_inputs: if skip_inputs:
raise KeyError raise KeyError
for x in yaml_obj['input_ports']: for input in yaml_obj['input_ports']:
try: try:
array_dimensions = [] if x['no_unpacked'] else self.total_array_dimensions array_dimensions = [] if input['no_unpacked'] else self.total_array_dimensions
except KeyError: except KeyError:
array_dimensions = self.total_array_dimensions array_dimensions = self.total_array_dimensions
self.ports['input'][x['name'].format(**values)] =\ self.ports['input'][input['name'].format(**values)] =\
(x['signal_type'].format(**values), (input['signal_type'].format(**values),
array_dimensions) array_dimensions)
except (TypeError, KeyError): except (TypeError, KeyError):
pass pass
@ -291,14 +285,14 @@ class Component():
if skip_outputs: if skip_outputs:
raise KeyError raise KeyError
for x in yaml_obj['output_ports']: for output in yaml_obj['output_ports']:
try: try:
array_dimensions = [] if x['no_unpacked'] else self.total_array_dimensions array_dimensions = [] if output['no_unpacked'] else self.total_array_dimensions
except KeyError: except KeyError:
array_dimensions = self.total_array_dimensions array_dimensions = self.total_array_dimensions
self.ports['output'][x['name'].format(**values)] =\ self.ports['output'][output['name'].format(**values)] =\
(x['signal_type'].format(**values), (output['signal_type'].format(**values),
array_dimensions) array_dimensions)
except (TypeError, KeyError): except (TypeError, KeyError):
pass pass
@ -308,9 +302,9 @@ class Component():
@staticmethod @staticmethod
def process_reset_signal(reset_signal): def process_reset_signal(reset_signal):
rst = dict() rst = {}
try: try:
rst['name'] = reset_signal.inst_name rst['name'] = reset_signal.inst_name
rst['async'] = reset_signal.get_property("async") rst['async'] = reset_signal.get_property("async")
rst['type'] = "asynchronous" if rst['async'] else "synchronous" rst['type'] = "asynchronous" if rst['async'] else "synchronous"
@ -340,8 +334,7 @@ class Component():
def create_underscored_path_static(obj): def create_underscored_path_static(obj):
owning_addrmap = obj.owning_addrmap.inst_name owning_addrmap = obj.owning_addrmap.inst_name
full_path = Component.split_dimensions(obj.get_path())[0] full_path = Component.split_dimensions(obj.get_path())[0]
path = full_path\ path = full_path.replace(f"{owning_addrmap}.", '')
.replace('{}.'.format(owning_addrmap), '')
path_underscored = path.replace('.', '__') path_underscored = path.replace('.', '__')

View File

@ -5,7 +5,7 @@ import sys
import yaml import yaml
from systemrdl.node import FieldNode, SignalNode from systemrdl.node import FieldNode, SignalNode
from systemrdl.component import Reg, Regfile, Addrmap, Root from systemrdl.component import Reg, Regfile
from systemrdl.rdltypes import PrecedenceType, AccessType, OnReadType, OnWriteType, InterruptType from systemrdl.rdltypes import PrecedenceType, AccessType, OnReadType, OnWriteType, InterruptType
# Local modules # Local modules
@ -61,7 +61,7 @@ class Field(Component):
self.add_sw_access(obj) self.add_sw_access(obj)
def add_sw_access(self, obj, alias = False): def add_sw_access(self, obj, alias = False):
access_rtl = dict() access_rtl = {}
if alias: if alias:
owning_addrmap, full_path, path, path_underscored =\ owning_addrmap, full_path, path, path_underscored =\
@ -156,7 +156,7 @@ class Field(Component):
else: else:
# 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 i in range(self.lsbyte, self.msbyte+1):
msb_bus = 8*(i+1)-1 if i != self.msbyte else obj.msb 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 lsb_bus = 8*i if i != self.lsbyte else obj.inst.lsb
@ -315,8 +315,8 @@ class Field(Component):
if obj_incr_width: if obj_incr_width:
self.logger.error( self.logger.error(
"The 'incrwidth' and 'incrvalue' properties are both "\ "The 'incrwidth' and 'incrvalue' properties are both "
"defined. This is not legal and the incrwidth property "\ "defined. This is not legal and the incrwidth property "
"will be ignored!") "will be ignored!")
else: else:
incr_value = self.get_signal_name(obj_incr_value) incr_value = self.get_signal_name(obj_incr_value)
@ -324,14 +324,14 @@ class Field(Component):
if obj_incr_value.width > self.obj.width: if obj_incr_value.width > self.obj.width:
self.logger.error( self.logger.error(
"Width of 'incr_value' signal '{}' is wider than current "\ f"Width of 'incr_value' signal '{obj_incr_value.get_path()}' is "
"counter field. This could potentially cause ugly errors.".format( "wider than current counter field. This could potentiall cause "
obj_incr_value.get_path())) "ugly errors.")
if obj_incr_width: if obj_incr_width:
self.logger.error( self.logger.error(
"The 'incrwidth' and 'incrvalue' properties are both "\ "The 'incrwidth' and 'incrvalue' properties are both "
"defined. This is not legal and the incrwidth property "\ "defined. This is not legal and the incrwidth property "
"will be ignored!") "will be ignored!")
@ -383,8 +383,8 @@ class Field(Component):
if obj_decr_width: if obj_decr_width:
self.logger.error( self.logger.error(
"The 'decrwidth' and 'decrvalue' properties are both "\ "The 'decrwidth' and 'decrvalue' properties are both "
"defined. This is not legal and the decrwidth property "\ "defined. This is not legal and the decrwidth property "
"will be ignored!") "will be ignored!")
else: else:
decr_value = self.get_signal_name(obj_decr_value) decr_value = self.get_signal_name(obj_decr_value)
@ -392,14 +392,14 @@ class Field(Component):
if obj_decr_value.width > self.obj.width: if obj_decr_value.width > self.obj.width:
self.logger.error( self.logger.error(
"Width of 'decr_value' signal '{}' is wider than current "\ f"Width of 'decr_value' signal '{obj_decr_value.get_path()}' is "
"counter field. This could potentially cause ugly errors.".format( "wider than current counter field. This could potentiall cause "
obj_decr_value.get_path())) "ugly errors.")
if obj_decr_width: if obj_decr_width:
self.logger.error( self.logger.error(
"The 'decrwidth' and 'decrvalue' properties are both "\ "The 'decrwidth' and 'decrvalue' properties are both "
"defined. This is not legal and the decrwidth property "\ "defined. This is not legal and the decrwidth property "
"will be ignored!") "will be ignored!")
@ -449,10 +449,10 @@ class Field(Component):
try: try:
if incr.width > 0: if incr.width > 0:
self.logger.error("Increment signal '{}' is wider than 1-bit. "\ self.logger.error(
"This might result in unwanted behavior and "\ f"Increment signal '{incr.inst_name}' is wider than "
"will also cause Lint-errors.".format( "1 bit. This might result in unwanted behavior and "
incr.inst_name)) "will also cause Lint-errors.")
except AttributeError: except AttributeError:
# 'PropRef_overflow' object has no attribute 'width' # 'PropRef_overflow' object has no attribute 'width'
pass pass
@ -490,10 +490,10 @@ class Field(Component):
try: try:
if decr.width > 0: if decr.width > 0:
self.logger.error("Decrement signal '{}' is wider than 1-bit. "\ self.logger.error(
"This might result in unwanted behavior and "\ f"Decrement signal '{decr.inst_name}' is wider than "
"will also cause Lint-errors.".format( "1 bit. This might result in unwanted behavior and "
decr.inst_name)) "will also cause Lint-errors.")
except AttributeError: except AttributeError:
# 'PropRef_underflow' object has no attribute 'width' # 'PropRef_underflow' object has no attribute 'width'
pass pass
@ -627,9 +627,9 @@ class Field(Component):
if self.obj.get_property('swmod'): if self.obj.get_property('swmod'):
self.logger.debug("Field has swmod property") self.logger.debug("Field has swmod property")
swmod_assigns = list() swmod_assigns = []
# Check if read side-effects are defined. # Check if read side-effects are defined.
if self.obj.get_property('onread'): if self.obj.get_property('onread'):
swmod_assigns.append( swmod_assigns.append(
self.process_yaml( self.process_yaml(
@ -982,7 +982,7 @@ class Field(Component):
'enable_mask_start': enable_mask_start_rtl, 'enable_mask_start': enable_mask_start_rtl,
'enable_mask_end': enable_mask_end_rtl, 'enable_mask_end': enable_mask_end_rtl,
'idx': enable_mask_idx, 'idx': enable_mask_idx,
'constant': "{{{}{{1'b1}}}}".format(self.obj.width) 'constant': f"{{{self.obj.width}{{1'b1}}}}"
if not enable_mask else "1'b1" if not enable_mask else "1'b1"
} }
) )
@ -997,7 +997,7 @@ class Field(Component):
'enable_mask_start': enable_mask_start_rtl, 'enable_mask_start': enable_mask_start_rtl,
'enable_mask_end': enable_mask_end_rtl, 'enable_mask_end': enable_mask_end_rtl,
'idx': enable_mask_idx, 'idx': enable_mask_idx,
'constant': "{{{}{{1'b0}}}}".format(self.obj.width) 'constant': f"{{{self.obj.width}{{1'b0}}}}"
if not enable_mask else "1'b0" if not enable_mask else "1'b0"
} }
) )
@ -1024,7 +1024,7 @@ class Field(Component):
# Create bit-wise mask so that outside logic knows what # Create bit-wise mask so that outside logic knows what
# bits it may change # bits it may change
mask = [] mask = []
for j, byte_idx in enumerate(range(self.msbyte, self.lsbyte-1, -1)): for byte_idx in range(self.msbyte, self.lsbyte-1, -1):
if byte_idx == self.lsbyte: if byte_idx == self.lsbyte:
width = (self.lsbyte+1)*8 - self.lsb width = (self.lsbyte+1)*8 - self.lsb
elif byte_idx == self.msbyte: elif byte_idx == self.msbyte:
@ -1183,7 +1183,7 @@ class Field(Component):
# kill the try block in most cases # kill the try block in most cases
parent_scope = enum.get_parent_scope() parent_scope = enum.get_parent_scope()
self.logger.debug("Starting to parse '{}'".format(enum)) self.logger.debug(f"Starting to parse '{enum}'")
if isinstance(parent_scope, Reg): if isinstance(parent_scope, Reg):
enum_name = '__'.join([enum.get_scope_path().split('::')[-1], enum.__name__]) enum_name = '__'.join([enum.get_scope_path().split('::')[-1], enum.__name__])
@ -1219,12 +1219,12 @@ class Field(Component):
self.field_type =\ self.field_type =\
'::'.join(['_'.join([scope, 'pkg']), enum_name]) '::'.join(['_'.join([scope, 'pkg']), enum_name])
self.logger.info("Parsed enum '{}'".format(enum_name)) self.logger.info(f"Parsed enum '{enum_name}'")
except AttributeError: except AttributeError:
# In case of an AttributeError, the encode property is None. Hence, # In case of an AttributeError, the encode property is None. Hence,
# the field has a simple width # the field has a simple width
self.field_type = 'logic [{}:0]'.format(self.obj.width-1) self.field_type = f"logic [{self.obj.width-1}:0]"
def __process_variables(self, obj: FieldNode, array_dimensions: list, glbl_settings: dict): def __process_variables(self, obj: FieldNode, array_dimensions: list, glbl_settings: dict):
# Create full name # Create full name
@ -1248,7 +1248,7 @@ class Field(Component):
self.total_dimensions = len(self.total_array_dimensions) self.total_dimensions = len(self.total_array_dimensions)
# Calculate how many genvars shall be added # Calculate how many genvars shall be added
genvars = ['[gv_{}]'.format(chr(97+i)) for i in range(len(array_dimensions))] genvars = [f"[gv_{chr(97+i)}]" for i in range(len(array_dimensions))]
self.genvars_str = ''.join(genvars) self.genvars_str = ''.join(genvars)
# Write enable # Write enable
@ -1285,18 +1285,23 @@ class Field(Component):
obj.get_property('reset') obj.get_property('reset')
# Define dict that holds all RTL # Define dict that holds all RTL
self.access_rtl = dict() self.access_rtl = {}
self.access_rtl['else'] = (["else"], False) self.access_rtl['else'] = (["else"], False)
self.access_rtl[''] = ([''], False) self.access_rtl[''] = ([''], False)
def summary(self): def summary(self):
# Additional flags that are set # Additional flags that are set
misc_flags = set(self.obj.list_properties()) # Use list, rather than set, to ensure the order stays the same
# when compiled multiple times
misc_flags = list(self.obj.list_properties())
# Remove some flags that are not interesting # Remove some flags that are not interesting
# or that are listed elsewhere # or that are listed elsewhere
misc_flags.discard('hw') for rdl_property in ('hw', 'reset'):
misc_flags.discard('reset') try:
misc_flags.remove(rdl_property)
except ValueError:
pass
precedence = self.obj.get_property('precedence') precedence = self.obj.get_property('precedence')

View File

@ -1,11 +1,9 @@
import re
import importlib.resources as pkg_resources import importlib.resources as pkg_resources
import sys import sys
import math import math
import yaml import yaml
from systemrdl import node from systemrdl import node
from systemrdl.node import FieldNode
from systemrdl.rdltypes import AccessType from systemrdl.rdltypes import AccessType
# Local packages # Local packages
@ -24,7 +22,7 @@ class Memory(Component):
obj: node.RegfileNode, obj: node.RegfileNode,
parents_dimensions: list, parents_dimensions: list,
parents_stride: list, parents_stride: list,
config: dict, config: dict,
glbl_settings: dict): glbl_settings: dict):
super().__init__(obj, config) super().__init__(obj, config)
@ -70,10 +68,10 @@ class Memory(Component):
) )
) )
# Assign variables that go to register bus multiplexer # Assign variables that go to register bus multiplexer
self.__add_sw_mux_assignments() self.__add_sw_mux_assignments()
# We can/should only do this if there is no encapsulating # We can/should only do this if there is no encapsulating
# regfile which create a generate # regfile which create a generate
self.__add_signal_instantiations() self.__add_signal_instantiations()
@ -192,10 +190,8 @@ class Memory(Component):
] ]
def get_signal_instantiations_list(self): def get_signal_instantiations_list(self):
dict_list = [(key, value) for (key, value) in self.get_signals().items()] dict_list = list(self.get_signals().items())
signal_width = min(max([len(value[0]) for (_, value) in dict_list]), 40) signal_width = min(max([len(value[0]) for (_, value) in dict_list]), 40)
name_width = min(max([len(key) for (key, _) in dict_list]), 40) name_width = min(max([len(key) for (key, _) in dict_list]), 40)
return [Memory.templ_dict['signal_declaration'].format( return [Memory.templ_dict['signal_declaration'].format(

View File

@ -1,4 +1,3 @@
import re
import importlib.resources as pkg_resources import importlib.resources as pkg_resources
import sys import sys
import math import math
@ -35,8 +34,8 @@ class RegFile(Component):
# Empty dictionary of register objects # Empty dictionary of register objects
# 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 = {}
self.regfiles = dict() self.regfiles = {}
# Set object to 0 for easy addressing # Set object to 0 for easy addressing
self.obj.current_idx = [0] self.obj.current_idx = [0]
@ -216,12 +215,12 @@ class RegFile(Component):
# First go through all registers in this scope to generate a package # First go through all registers in this scope to generate a package
package_rtl = [] package_rtl = []
enum_rtl = dict() enum_rtl = {}
rtl_return = list() rtl_return = []
# Need to keep track of enum names since they shall be unique # Need to keep track of enum names since they shall be unique
# per scope # per scope
enum_members = dict() enum_members = {}
for i in self.registers.values(): for i in self.registers.values():
for key, value in i.get_typedefs().items(): for key, value in i.get_typedefs().items():

View File

@ -2,7 +2,6 @@ import importlib.resources as pkg_resources
import math import math
import sys import sys
import yaml import yaml
import itertools
from systemrdl import node from systemrdl import node
@ -52,9 +51,11 @@ class Register(Component):
def create_rtl(self): def create_rtl(self):
# Create RTL of children # Create RTL of children
if self.config['external']: if self.config['external']:
[x.create_external_rtl() for x in self.children.values()] for child in self.children.values():
child.create_external_rtl()
else: else:
[x.create_internal_rtl() for x in self.children.values()] for child in self.children.values():
child.create_internal_rtl()
# Create generate block for register and add comment # Create generate block for register and add comment
if self.dimensions and not self.generate_active: if self.dimensions and not self.generate_active:
@ -89,7 +90,7 @@ class Register(Component):
# Add wire instantiation # Add wire instantiation
if not self.generate_active: if not self.generate_active:
# We can/should only do this if there is no encapsulating # We can/should only do this if there is no encapsulating
# regfile which create a generate # regfile which create a generate
self.__add_signal_instantiations() self.__add_signal_instantiations()
@ -110,11 +111,11 @@ class Register(Component):
def __add_interrupts(self): def __add_interrupts(self):
# Semantics on the intr and halt property: # Semantics on the intr and halt property:
# a) The intr and halt register properties are outputs; they should only # a) The intr and halt register properties are outputs; they should only
# occur on the right-hand side of an assignment in SystemRDL. # occur on the right-hand side of an assignment in SystemRDL.
# b) The intr property shall always be present on a intr register even if # b) The intr property shall always be present on a intr register even if
# no mask or enables are specified. # no mask or enables are specified.
# c) The halt property shall only be present if haltmask or haltenable is # c) The halt property shall only be present if haltmask or haltenable is
# specified on at least one field in the register. # specified on at least one field in the register.
if self.properties['intr']: if self.properties['intr']:
self.rtl_footer.append(Register.templ_dict['interrupt_comment']['rtl']) self.rtl_footer.append(Register.templ_dict['interrupt_comment']['rtl'])
@ -166,14 +167,16 @@ class Register(Component):
list_of_fields.append( list_of_fields.append(
f"{{{empty_bits}{{1'b{self.glbl_settings['rsvd_val']}}}}}") f"{{{empty_bits}{{1'b{self.glbl_settings['rsvd_val']}}}}}")
list_of_fields.append("{}_q{}".format(field.path_underscored, self.genvars_str)) list_of_fields.append(f"{field.path_underscored}_q{self.genvars_str}")
# Add to appropriate bytes # Add to appropriate bytes
[bytes_read.add(x) for x in range(field.lsbyte, field.msbyte+1)] for byte in range(field.lsbyte, field.msbyte+1):
bytes_read.add(byte)
if na_map[0] in field.writable_by: if na_map[0] in field.writable_by:
# Add to appropriate bytes # Add to appropriate bytes
[bytes_written.add(x) for x in range(field.lsbyte, field.msbyte+1)] for byte in range(field.lsbyte, field.msbyte+1):
bytes_written.add(byte)
empty_bits = accesswidth - current_bit + 1 empty_bits = accesswidth - current_bit + 1
@ -208,8 +211,8 @@ class Register(Component):
# an error. # an error.
# #
# Furthermore, consider an error indication that is set for external registers # Furthermore, consider an error indication that is set for external registers
bytes_read_format = ["b2r.byte_en[{}]".format(x) for x in list(map(str, bytes_read))] bytes_read_format = [f"b2r.byte_en[{x}]" for x in list(map(str, bytes_read))]
bytes_written_format = ["b2r.byte_en[{}]".format(x) for x in list(map(str, bytes_written))] bytes_written_format = [f"b2r.byte_en[{x}]" for x in list(map(str, bytes_written))]
sw_err_condition_vec = [] sw_err_condition_vec = []
@ -331,7 +334,7 @@ class Register(Component):
vec[depth] = i vec[depth] = i
if depth == len(dimensions) - 1: if depth == len(dimensions) - 1:
yield '[{}]'.format(']['.join(map(str, vec))) yield f"[{']['.join(map(str, vec))}]"
else: else:
yield from Register.eval_genvars(vec, depth+1, dimensions) yield from Register.eval_genvars(vec, depth+1, dimensions)
@ -346,11 +349,11 @@ class Register(Component):
else: else:
access_wire_assign_field = 'access_wire_assign_1_dim' access_wire_assign_field = 'access_wire_assign_1_dim'
for i, x in enumerate(self.name_addr_mappings): for i, name_addr_map in enumerate(self.name_addr_mappings):
self.rtl_header.append( self.rtl_header.append(
self.process_yaml( self.process_yaml(
Register.templ_dict['access_wire_comment'], Register.templ_dict['access_wire_comment'],
{'path': x[0], {'path': name_addr_map[0],
'alias': '(alias)' if i > 0 else '', 'alias': '(alias)' if i > 0 else '',
} }
) )
@ -359,8 +362,8 @@ class Register(Component):
self.rtl_header.append( self.rtl_header.append(
self.process_yaml( self.process_yaml(
Register.templ_dict[access_wire_assign_field], Register.templ_dict[access_wire_assign_field],
{'path': x[0], {'path': name_addr_map[0],
'addr': x[1], 'addr': name_addr_map[1],
'genvars': self.genvars_str, 'genvars': self.genvars_str,
'genvars_sum': self.genvars_sum_str, 'genvars_sum': self.genvars_sum_str,
'depth': self.depth, 'depth': self.depth,
@ -376,8 +379,8 @@ class Register(Component):
self.rtl_header.append( self.rtl_header.append(
self.process_yaml( self.process_yaml(
Register.templ_dict['read_wire_assign'], Register.templ_dict['read_wire_assign'],
{'path': x[0], {'path': name_addr_map[0],
'addr': x[1], 'addr': name_addr_map[1],
'genvars': self.genvars_str, 'genvars': self.genvars_str,
'genvars_sum': self.genvars_sum_str, 'genvars_sum': self.genvars_sum_str,
'depth': self.depth, 'depth': self.depth,
@ -388,7 +391,7 @@ class Register(Component):
self.rtl_header.append( self.rtl_header.append(
self.process_yaml( self.process_yaml(
Register.templ_dict['read_wire_assign_0'], Register.templ_dict['read_wire_assign_0'],
{'path': x[0], {'path': name_addr_map[0],
'genvars': self.genvars_str, 'genvars': self.genvars_str,
} }
) )
@ -402,8 +405,8 @@ class Register(Component):
self.rtl_header.append( self.rtl_header.append(
self.process_yaml( self.process_yaml(
Register.templ_dict['write_wire_assign'], Register.templ_dict['write_wire_assign'],
{'path': x[0], {'path': name_addr_map[0],
'addr': x[1], 'addr': name_addr_map[1],
'genvars': self.genvars_str, 'genvars': self.genvars_str,
'genvars_sum': self.genvars_sum_str, 'genvars_sum': self.genvars_sum_str,
'depth': self.depth, 'depth': self.depth,
@ -414,7 +417,7 @@ class Register(Component):
self.rtl_header.append( self.rtl_header.append(
self.process_yaml( self.process_yaml(
Register.templ_dict['write_wire_assign_0'], Register.templ_dict['write_wire_assign_0'],
{'path': x[0], {'path': name_addr_map[0],
'genvars': self.genvars_str, 'genvars': self.genvars_str,
} }
) )
@ -446,7 +449,7 @@ class Register(Component):
] ]
def get_signal_instantiations_list(self): def get_signal_instantiations_list(self):
dict_list = [(key, value) for (key, value) in self.get_signals().items()] dict_list = list(self.get_signals().items())
signal_width = min(max([len(value[0]) for (_, value) in dict_list]), 40) signal_width = min(max([len(value[0]) for (_, value) in dict_list]), 40)
@ -472,13 +475,12 @@ class Register(Component):
try: try:
self.children[field_range].add_sw_access(field, alias=True) self.children[field_range].add_sw_access(field, alias=True)
except KeyError: except KeyError:
self.logger.fatal("Range of field '{}' in alias register '{}' does " self.logger.fatal(
"not correspond to range of field in original " f"Range of field '{field.inst_name}' in alias register "
"register '{}'. This is illegal according to 10.5.1 b)" f"'{obj.inst_name}' does not correspond to range of field "
"of the SystemRDL 2.0 LRM.". format( f"in original register '{self.name}'. This is illegal "
field.inst_name, "according to 10.5.1 b) of the SystemRDL 2.0 LRM.")
obj.inst_name,
self.name))
sys.exit(1) sys.exit(1)
# Add name to list # Add name to list
@ -520,7 +522,7 @@ class Register(Component):
# Merge parent's stride with stride of this regfile. Before doing so, the # Merge parent's stride with stride of this regfile. Before doing so, the
# respective stride of the different dimensions shall be calculated # respective stride of the different dimensions shall be calculated
self.total_stride = [ self.total_stride = [
*parents_stride, *parents_stride,
*[math.prod(self.array_dimensions[i+1:]) *[math.prod(self.array_dimensions[i+1:])
*self.obj.array_stride *self.obj.array_stride
for i, _ in enumerate(self.array_dimensions)] for i, _ in enumerate(self.array_dimensions)]
@ -541,7 +543,7 @@ class Register(Component):
self.dimensions = len(self.array_dimensions) self.dimensions = len(self.array_dimensions)
# Calculate how many genvars shall be added # Calculate how many genvars shall be added
genvars = ['[gv_{}]'.format(chr(97+i)) for i in range(self.total_dimensions)] genvars = [f"[gv_{chr(97+i)}]" for i in range(self.total_dimensions)]
self.genvars_str = ''.join(genvars) self.genvars_str = ''.join(genvars)
# Determine value to compare address with # Determine value to compare address with
@ -564,9 +566,9 @@ class Register(Component):
genvars_sum_vectorized.pop() genvars_sum_vectorized.pop()
self.logger.debug( self.logger.debug(
"Multidimensional with dimensions '{}' and stride '{}'".format( f"Multidimensional with dimensions '{self.total_array_dimensions}' "
self.total_array_dimensions, f"and stride '{self.total_stride}'")
self.total_stride))
except TypeError: except TypeError:
self.logger.debug( self.logger.debug(
"Caught expected TypeError because self.total_stride is empty") "Caught expected TypeError because self.total_stride is empty")

View File

@ -3,7 +3,6 @@
# Standard modules # Standard modules
import sys import sys
import time import time
import os
import importlib.resources as pkg_resources import importlib.resources as pkg_resources
# Imported modules # Imported modules
@ -42,16 +41,16 @@ if __name__ == "__main__":
except RDLCompileError: except RDLCompileError:
sys.exit(1) sys.exit(1)
except FileNotFoundError: except FileNotFoundError:
logger.fatal("Could not find '{}'".format(input_file)) logger.fatal(f"Could not find '{input_file}'")
sys.exit(1) sys.exit(1)
addrmap = AddrMap(root.top, config) addrmap = AddrMap(root.top, config)
# Save RTL to file # Save RTL to file
# Start out with addrmap # Start out with addrmap
out_addrmap_file = "{}/{}.sv".format(config['output_dir'], addrmap.name) out_addrmap_file = f"{config['output_dir']}/{addrmap.name}.sv"
with open(out_addrmap_file, 'w') as file: with open(out_addrmap_file, 'w', encoding='UTF-8') as file:
print( print(
addrmap.get_rtl( addrmap.get_rtl(
tab_width=config['tab_width'], tab_width=config['tab_width'],
@ -60,7 +59,7 @@ if __name__ == "__main__":
file=file file=file
) )
logger.info('Succesfully created "{}"'.format(out_addrmap_file)) logger.info("Succesfully created '{out_addrmap_file}'")
# Start grabbing packages. This returns a dictionary for the main addrmap # Start grabbing packages. This returns a dictionary for the main addrmap
# and all it's child regfiles/addrmaps # and all it's child regfiles/addrmaps
@ -69,25 +68,25 @@ if __name__ == "__main__":
real_tabs=config['real_tabs'] real_tabs=config['real_tabs']
).items(): ).items():
if value: if value:
with open('{}/{}_pkg.sv'.format(config['output_dir'], key), 'w') as file: with open(f"{config['output_dir']}/{key}_pkg.sv", 'w', encoding="UTF-8") as file:
print(value, file=file) print(value, file=file)
# Copy over widget RTL from widget directory # Copy over widget RTL from widget directory
widget_rtl = pkg_resources.read_text(widgets, 'srdl2sv_{}.sv'.format(config['bus'])) widget_rtl = pkg_resources.read_text(widgets, f"srdl2sv_{config['bus']}.sv")
out_widget_file = "{}/srdl2sv_{}.sv".format(config['output_dir'], config['bus']) out_widget_file = f"{config['output_dir']}/srdl2sv_{config['bus']}.sv"
with open(out_widget_file, 'w') as file: with open(out_widget_file, 'w', encoding="UTF-8") as file:
print(widget_rtl, file=file) print(widget_rtl, file=file)
logger.info("Selected, implemented, and copied '{}' widget".format(config['bus'])) logger.info(f"Selected, implemented, and copied '{config['bus']}' widget")
# Copy over generic srdl2sv_interface_pkg # Copy over generic srdl2sv_interface_pkg
widget_if_rtl = pkg_resources.read_text(widgets, 'srdl2sv_if_pkg.sv') widget_if_rtl = pkg_resources.read_text(widgets, 'srdl2sv_if_pkg.sv')
out_if_file = "{}/srdl2sv_if_pkg.sv".format(config['output_dir']) out_if_file = f"{config['output_dir']}/srdl2sv_if_pkg.sv"
with open(out_if_file, 'w') as file: with open(out_if_file, 'w', encoding="UTF-8") as file:
widget_if_rtl_parsed = widget_if_rtl.format( widget_if_rtl_parsed = widget_if_rtl.format(
regwidth_bit = addrmap.get_regwidth() - 1, regwidth_bit = addrmap.get_regwidth() - 1,
regwidth_byte = int(addrmap.get_regwidth() / 8) - 1, regwidth_byte = int(addrmap.get_regwidth() / 8) - 1,