From 59b91536ed941227e3a8d3d7a07253a02571ac08 Mon Sep 17 00:00:00 2001 From: Dennis Date: Tue, 11 May 2021 00:28:52 +0200 Subject: [PATCH] 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. --- srdl2sv/components/addrmap.py | 22 ++++++++++------ srdl2sv/components/field.py | 14 ++++++++++- srdl2sv/components/register.py | 16 ++++++++++-- srdl2sv/components/templates/fields.yaml | 2 ++ srdl2sv/log/log.py | 12 ++++++++- srdl2sv/main.py | 32 +++++++++++++++++++----- 6 files changed, 81 insertions(+), 17 deletions(-) diff --git a/srdl2sv/components/addrmap.py b/srdl2sv/components/addrmap.py index 651d5c2..84fd5e7 100644 --- a/srdl2sv/components/addrmap.py +++ b/srdl2sv/components/addrmap.py @@ -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) diff --git a/srdl2sv/components/field.py b/srdl2sv/components/field.py index 3e6e256..d861458 100644 --- a/srdl2sv/components/field.py +++ b/srdl2sv/components/field.py @@ -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 = [] diff --git a/srdl2sv/components/register.py b/srdl2sv/components/register.py index c6e2a9e..e7d6578 100644 --- a/srdl2sv/components/register.py +++ b/srdl2sv/components/register.py @@ -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 diff --git a/srdl2sv/components/templates/fields.yaml b/srdl2sv/components/templates/fields.yaml index 2fc3912..82e1eb5 100644 --- a/srdl2sv/components/templates/fields.yaml +++ b/srdl2sv/components/templates/fields.yaml @@ -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}; diff --git a/srdl2sv/log/log.py b/srdl2sv/log/log.py index 13d730c..081497a 100644 --- a/srdl2sv/log/log.py +++ b/srdl2sv/log/log.py @@ -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) diff --git a/srdl2sv/main.py b/srdl2sv/main.py index d6376f6..58e6f76 100755 --- a/srdl2sv/main.py +++ b/srdl2sv/main.py @@ -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)