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 import RDLCompiler, RDLCompileError, RDLWalker, RDLListener, node
from systemrdl.node import FieldNode from systemrdl.node import FieldNode
# Local packages # Local packages
from components.register import Register from components.register import Register
from log.log import create_logger
from . import templates from . import templates
# Import templates # Import templates
@ -17,9 +17,19 @@ except ImportError:
import importlib_resources as pkg_resources import importlib_resources as pkg_resources
class AddrMap: class AddrMap:
def __init__(self, rdlc: RDLCompiler, obj: node.RootNode): def __init__(self, rdlc: RDLCompiler, obj: node.RootNode, config: dict):
self.rdlc = rdlc 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') template = pkg_resources.read_text(templates, 'addrmap.sv')
@ -37,12 +47,10 @@ class AddrMap:
elif isinstance(child, node.RegfileNode): elif isinstance(child, node.RegfileNode):
pass pass
elif isinstance(child, node.RegNode): elif isinstance(child, node.RegNode):
self.registers.add(Register(child)) self.registers.add(Register(child, config))
for i in self.registers: # TODO: Temporarily override RTL
print("\n\n") self.rtl = [x.get_rtl() for x in self.registers]
for j in i.rtl:
print(j)
def get_rtl(self) -> str: def get_rtl(self) -> str:
return '\n'.join(self.rtl) return '\n'.join(self.rtl)

View File

@ -6,6 +6,9 @@ from systemrdl.node import FieldNode
from systemrdl.rdltypes import PrecedenceType, AccessType from systemrdl.rdltypes import PrecedenceType, AccessType
from itertools import chain from itertools import chain
# Local modules
from log.log import create_logger
TAB = " " TAB = " "
class Field: class Field:
@ -13,11 +16,20 @@ class Field:
with open('srdl2sv/components/templates/fields.yaml', 'r') as file: with open('srdl2sv/components/templates/fields.yaml', 'r') as file:
templ_dict = yaml.load(file, Loader=yaml.FullLoader) 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.obj = obj
self.rtl = [] self.rtl = []
self.bytes = math.ceil(obj.width / 8) 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 # Make a list of I/O that shall be added to the addrmap
self.input_ports = [] self.input_ports = []
self.output_ports = [] self.output_ports = []

View File

@ -5,6 +5,9 @@ from systemrdl.node import FieldNode
from components.field import Field from components.field import Field
# Local modules
from log.log import create_logger
TAB = " " TAB = " "
class Register: class Register:
@ -12,11 +15,20 @@ class Register:
with open('srdl2sv/components/templates/regs.yaml', 'r') as file: with open('srdl2sv/components/templates/regs.yaml', 'r') as file:
templ_dict = yaml.load(file, Loader=yaml.FullLoader) 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.obj = obj
self.name = obj.inst_name self.name = obj.inst_name
self.rtl = [] 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: if obj.is_array:
sel_arr = 'array' sel_arr = 'array'
array_dimensions = obj.array_dimensions array_dimensions = obj.array_dimensions
@ -60,7 +72,7 @@ class Register:
self.fields = [] self.fields = []
for field in obj.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.fields.append(field_obj)
self.rtl += field_obj.rtl self.rtl += field_obj.rtl

View File

@ -16,6 +16,8 @@ sw_access_byte: |-
hw_access_we_wel: |- hw_access_we_wel: |-
{indent}if ({negl}{reg_name}_{field_name}_hw_wr{genvars}) {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: |- hw_access_field: |-
{indent}begin {indent}begin
{indent} {reg_name}_{field_name}_q{genvars} <= {reg_name}_{field_name}_in{genvars}; {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): file_name: Optional[str] = None):
log = logging.getLogger(mod_name) 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: if file_log_level > 0 and file_name:
file_handler = logging.FileHandler(file_name) file_handler = logging.FileHandler(file_name)
file_handler.setLevel(file_log_level) file_handler.setLevel(file_log_level)

View File

@ -3,6 +3,7 @@
# Standard modules # Standard modules
import sys import sys
import time import time
import os
# Imported modules # Imported modules
from systemrdl import RDLCompiler, RDLCompileError from systemrdl import RDLCompiler, RDLCompileError
@ -20,6 +21,13 @@ if __name__ == "__main__":
cli_arguments = CliArguments() cli_arguments = CliArguments()
config = cli_arguments.get_config() 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 # Compile and elaborate files provided from the command line
rdlc = RDLCompiler() rdlc = RDLCompiler()
@ -32,11 +40,23 @@ if __name__ == "__main__":
except RDLCompileError: except RDLCompileError:
sys.exit(1) 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) logger.info("Elapsed time: %f seconds", time.time() - start)