Propgate logger through components and let top-level write SV

Previously, the SystemVerilog was simply written to the shell. This
started to become too long to be readable. Now, the application dumps
everything to the output directory that is defined on the command line
(or the default).

Temporary workaround: the AddrMap component's RTL is completely
overwritten by the Register's RTL. This is temporary until the AddrMap
also uses a YAML file.
This commit is contained in:
Dennis Potter 2021-05-11 00:28:52 +02:00
parent 27c4e9de3c
commit 59b91536ed
6 changed files with 81 additions and 17 deletions

View File

@ -4,9 +4,9 @@ import re
from systemrdl import RDLCompiler, RDLCompileError, RDLWalker, RDLListener, node
from systemrdl.node import FieldNode
# Local packages
from components.register import Register
from log.log import create_logger
from . import templates
# Import templates
@ -17,9 +17,19 @@ except ImportError:
import importlib_resources as pkg_resources
class AddrMap:
def __init__(self, rdlc: RDLCompiler, obj: node.RootNode):
def __init__(self, rdlc: RDLCompiler, obj: node.RootNode, config: dict):
self.rdlc = rdlc
self.name = obj.inst_name
# Create logger object
self.logger = create_logger(
"{}.{}".format(__name__, obj.inst_name),
stream_log_level=config['stream_log_level'],
file_log_level=config['file_log_level'],
file_name=config['file_log_location'])
self.logger.debug('Starting to process addrmap "{}"'.format(obj.inst_name))
template = pkg_resources.read_text(templates, 'addrmap.sv')
@ -37,12 +47,10 @@ class AddrMap:
elif isinstance(child, node.RegfileNode):
pass
elif isinstance(child, node.RegNode):
self.registers.add(Register(child))
self.registers.add(Register(child, config))
for i in self.registers:
print("\n\n")
for j in i.rtl:
print(j)
# TODO: Temporarily override RTL
self.rtl = [x.get_rtl() for x in self.registers]
def get_rtl(self) -> str:
return '\n'.join(self.rtl)

View File

@ -6,6 +6,9 @@ from systemrdl.node import FieldNode
from systemrdl.rdltypes import PrecedenceType, AccessType
from itertools import chain
# Local modules
from log.log import create_logger
TAB = " "
class Field:
@ -13,11 +16,20 @@ class Field:
with open('srdl2sv/components/templates/fields.yaml', 'r') as file:
templ_dict = yaml.load(file, Loader=yaml.FullLoader)
def __init__(self, obj: node.RootNode, indent_lvl: int, dimensions: int):
def __init__(self, obj: node.RootNode, indent_lvl: int, dimensions: int, config:dict):
self.obj = obj
self.rtl = []
self.bytes = math.ceil(obj.width / 8)
# Create logger object
self.logger = create_logger(
"{}.{}".format(__name__, obj.inst_name),
stream_log_level=config['stream_log_level'],
file_log_level=config['file_log_level'],
file_name=config['file_log_location'])
self.logger.debug('Starting to process field "{}"'.format(obj.inst_name))
# Make a list of I/O that shall be added to the addrmap
self.input_ports = []
self.output_ports = []

View File

@ -5,6 +5,9 @@ from systemrdl.node import FieldNode
from components.field import Field
# Local modules
from log.log import create_logger
TAB = " "
class Register:
@ -12,11 +15,20 @@ class Register:
with open('srdl2sv/components/templates/regs.yaml', 'r') as file:
templ_dict = yaml.load(file, Loader=yaml.FullLoader)
def __init__(self, obj: node.RootNode):
def __init__(self, obj: node.RootNode, config: dict):
self.obj = obj
self.name = obj.inst_name
self.rtl = []
# Create logger object
self.logger = create_logger(
"{}.{}".format(__name__, obj.inst_name),
stream_log_level=config['stream_log_level'],
file_log_level=config['file_log_level'],
file_name=config['file_log_location'])
self.logger.debug('Starting to process register "{}"'.format(obj.inst_name))
if obj.is_array:
sel_arr = 'array'
array_dimensions = obj.array_dimensions
@ -60,7 +72,7 @@ class Register:
self.fields = []
for field in obj.fields():
field_obj = Field(field, indent_lvl, dimensions)
field_obj = Field(field, indent_lvl, dimensions, config)
self.fields.append(field_obj)
self.rtl += field_obj.rtl

View File

@ -16,6 +16,8 @@ sw_access_byte: |-
hw_access_we_wel: |-
{indent}if ({negl}{reg_name}_{field_name}_hw_wr{genvars})
hw_access_no_we_wel: |-
{indent}if (1) // we or wel property not set
hw_access_field: |-
{indent}begin
{indent} {reg_name}_{field_name}_q{genvars} <= {reg_name}_{field_name}_in{genvars};

View File

@ -36,8 +36,18 @@ def create_logger (
file_name: Optional[str] = None):
log = logging.getLogger(mod_name)
log.setLevel(min(stream_log_level, file_log_level))
# Set log level. If the minimum log level of one of the
# two loggers is 0, the maximum of both values must be taken.
# Otherwise, the complete logger gets deactivated.
min_log_level = min(stream_log_level, file_log_level)
if min_log_level == 0:
log.setLevel(max(stream_log_level, file_log_level))
else:
log.setLevel(min_log_level)
# Create log handlers
if file_log_level > 0 and file_name:
file_handler = logging.FileHandler(file_name)
file_handler.setLevel(file_log_level)

View File

@ -3,6 +3,7 @@
# Standard modules
import sys
import time
import os
# Imported modules
from systemrdl import RDLCompiler, RDLCompileError
@ -20,6 +21,13 @@ if __name__ == "__main__":
cli_arguments = CliArguments()
config = cli_arguments.get_config()
# Create logger
logger = create_logger(
__name__,
stream_log_level=config['stream_log_level'],
file_log_level=config['file_log_level'],
file_name=config['file_log_location'])
# Compile and elaborate files provided from the command line
rdlc = RDLCompiler()
@ -32,11 +40,23 @@ if __name__ == "__main__":
except RDLCompileError:
sys.exit(1)
addrmap = AddrMap(rdlc, root.top)
addrmap = AddrMap(rdlc, root.top, config)
# Create output directory
try:
os.makedirs(config['output_dir'])
logger.info('Succesfully created directory "{}"'.format(
config['output_dir']))
except FileExistsError:
logger.info('Directory "{}" does already exist'.format(
config['output_dir']))
# Save RTL to file
out_file_name = "{}/{}.sv".format(config['output_dir'], addrmap.name)
with open(out_file_name, 'w') as file:
file.write(addrmap.get_rtl())
logger.info('Succesfully created "{}"'.format(out_file_name))
logger = create_logger(
__name__,
stream_log_level=config['stream_log_level'],
file_log_level=config['file_log_level'],
file_name=config['file_log_location'])
logger.info("Elapsed time: %f seconds", time.time() - start)