mirror of
https://github.com/Silicon1602/srdl2sv.git
synced 2024-12-22 06:58:41 +00:00
Minor clean up, mostly Python Lint warnings
This commit is contained in:
parent
1ed801a565
commit
abf3fac24f
@ -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
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
|
|
||||||
|
@ -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(
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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('.', '__')
|
||||||
|
|
||||||
|
@ -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')
|
||||||
|
|
||||||
|
@ -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(
|
||||||
|
@ -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():
|
||||||
|
@ -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")
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user