Skip to content

created rdl2verilog based on readme #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.5, 3.6, 3.7, 3.8]
python-version: [3.7, 3.8, 3.9] # [3.5, 3.6, 3.7, 3.8]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

Expand All @@ -45,7 +45,7 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Install python dependencies
run: |
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
![build status](https://github.com/hughjackson/PeakRDL-verilog/actions/workflows/actions.yml/badge.svg)
![build status](https://github.com/bat52/PeakRDL-verilog/actions/workflows/actions.yml/badge.svg)

# PeakRDL-verilog
Generate Verilog register model from compiled SystemRDL input

## Installing
Install from github only at the moment.
Install from pypi:
```pip3 install peakrdl-verilog
```
Install from github:
```pip3 install git+https://github.com/bat52/PeakRDL-verilog.git@master
```

--------------------------------------------------------------------------------

Expand Down
33 changes: 16 additions & 17 deletions peakrdl/verilog/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ def __init__(self, **kwargs):
Additional context variables to load into the template namespace.
"""
user_template_dir = kwargs.pop("user_template_dir", None)
self.user_template_context = kwargs.pop("user_template_context", dict())
self.user_template_context = kwargs.pop("user_template_context", {})
self.signal_overrides = {}
self.strict = False # strict RDL rules rather than helpful impliciti behaviour

# Check for stray kwargs
if kwargs:
raise TypeError("got an unexpected keyword argument '%s'" % list(kwargs.keys())[0])
raise TypeError("got an unexpected keyword argument '%s'" % list(kwargs.keys())[0]) #pylint: disable=consider-using-f-string

if user_template_dir:
loader = jj.ChoiceLoader([
Expand Down Expand Up @@ -105,24 +105,23 @@ def export(self, node: Node, path: str, **kwargs):
bus_type: str
bus type for the SW interface (default: native)
"""
self.signal_overrides = kwargs.pop("signal_overrides") or dict()
self.signal_overrides = kwargs.pop("signal_overrides") or {}
bus_type = kwargs.pop("bus_type", "native")

try:
with open(os.path.join(os.path.dirname(__file__), "busses", "{}.ports.sv".format(bus_type))) as f:
with open(os.path.join(os.path.dirname(__file__), "busses", f"{bus_type}.ports.sv"),encoding="utf8") as f:
sw_ports = f.read()
with open(os.path.join(os.path.dirname(__file__), "busses", "{}.impl.sv".format(bus_type))) as f:
with open(os.path.join(os.path.dirname(__file__), "busses", f"{bus_type}.impl.sv"),encoding="utf8") as f:
sw_impl = f.read()
except FileNotFoundError as e:
raise TypeError("didn't recognise bus_type '{}'. Please check for typos.".format(bus_type)) from e
raise TypeError(f"didn't recognise bus_type '{bus_type}'. Please check for typos.") from e

if type(self.signal_overrides) != dict:
raise TypeError("got an unexpected signal_overrides argument of type {} instead of dict".format(
type(self.signal_overrides)))
raise TypeError(f"got an unexpected signal_overrides argument of type {type(self.signal_overrides)} instead of dict")

# Check for stray kwargs
if kwargs:
raise TypeError("got an unexpected keyword argument '%s'" % list(kwargs.keys())[0])
raise TypeError("got an unexpected keyword argument '%s'" % list(kwargs.keys())[0]) #pylint: disable=consider-using-f-string

# If it is the root node, skip to top addrmap
if isinstance(node, RootNode):
Expand Down Expand Up @@ -204,9 +203,9 @@ def _get_signal_name(self, node: Node, index: str = '', prop: str = '') -> str:
suffix = self.signal_overrides.get(prop, prop)

if prop:
return "{}_{}{}".format(prefix, suffix, index)
return f"{prefix}_{suffix}{index}"
else:
return "{}{}".format(prefix, index)
return f"{prefix}{index}"


# get property value where:
Expand Down Expand Up @@ -234,14 +233,14 @@ def _get_prop_value(self, node, index, prop, hw_on_true=True, hw_on_none=False,
elif isinstance(val, SignalNode):
return self._get_signal_name(val) # reference to signal
if type(val) == int:
return "{}'d{}".format(width, val) # specified value
return f"{width}'d{val}" # specified value
elif ((val is True and hw_on_true) or
(val is None and hw_on_none)):
return self._get_signal_name(node, index, prop) # hw input signal
elif val is True or val is None:
return "{}'d{}".format(width, default) # default value
return f"{width}'d{default}" # default value
else:
err = "ERROR: property {} of type {} not recognised".format(prop, type(val))
err = f"ERROR: property {prop} of type {type(val)} not recognised"
print(err)
return err

Expand Down Expand Up @@ -323,22 +322,22 @@ def full_array_indexes(self, node) -> list:
Get multi-dimensional array indexing for reg/field
"""
indexes = itertools.product(*[list(range(k)) for k in self.full_array_dimensions(node)])
return [''.join('[{}]'.format(k) for k in index) for index in indexes]
return [''.join(f'[{k}]' for k in index) for index in indexes]


def full_array_ranges(self, node, fmt='{:>20s}') -> str:
"""
Get multi-dimensional array indexing for reg/field as SV ranges
"""
return fmt.format(''.join('[{}:0]'.format(dim-1) for dim in self.full_array_dimensions(node)))
return fmt.format(''.join(f'[{dim-1}:0]' for dim in self.full_array_dimensions(node)))


def _full_idx(self, node) -> str:
"""
Get multi-dimensional array indexing for node instance
"""
l = self._full_idx_list(node)
return ''.join('[{}]'.format(k) for k in l)
return ''.join(f'[{k}]' for k in l)


def _full_idx_list(self, node) -> list:
Expand Down
36 changes: 18 additions & 18 deletions peakrdl/verilog/peakverilog.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ def __init__(self, arg):


def __str__(self):
return "{} => {}".format(self.prop, self.new)
return f'{self.prop} => {self.new}'


def __repr__(self):
return "overrideType('{}={}')".format(self.prop, self.new)
return f"overrideType('{self.prop}={self.new}')"


def parse_args():
Expand Down Expand Up @@ -58,7 +58,7 @@ def parse_args():

if temp.O and temp.simulate:
parser.print_usage()
print("{}: argument --override/-O: --simulate not currently supported when using override".format(os.path.basename(__file__)))
print(f"{os.path.basename(__file__)}: argument --override/-O: --simulate not currently supported when using override")
sys.exit(1)

return temp
Expand All @@ -73,58 +73,58 @@ def compile_rdl(infile, incl_search_paths=None, top=None):

def generate(root, outdir, signal_overrides=None, bus='native'):
'''generate the verilog'''
print('Info: Generating verilog for {} in {}'.format(root.inst_name, outdir))
print(f'Info: Generating verilog for {root.inst_name} in {outdir}')
modules = VerilogExporter().export(
root,
outdir,
signal_overrides=signal_overrides,
bus_type=bus,
)
for m in modules:
print(" - Generated: " + ' '.join(os.path.join(outdir, '{}_{}'.format(m, k)) for k in ('rf.sv', 'tb.sv', 'tb.cpp')))
print(" - Generated: " + ' '.join(os.path.join(outdir, f'{m}_{k}') for k in ('rf.sv', 'tb.sv', 'tb.cpp')))

return modules


def run_lint(modules, outdir):
for m in modules:
rf_file = os.path.join(outdir, '{}_rf.sv'.format(m))
rf_file = os.path.join(outdir, f'{m}_rf.sv')

print('Info: Linting {} ({})'.format(m, rf_file))
print(f'Info: Linting {m} ({rf_file})')
proc = subprocess.run(['verilator', '--lint-only', "-Wall", rf_file], check=True)

if proc.returncode:
print ("Error: verilator returned {}".format(proc.returncode))
print (f"Error: verilator returned {proc.returncode}")
sys.exit(1)
else:
print (" - Lint Passed")


def compile_verilog(modules, outdir, verbosity=0):
for m in modules:
rf_file = os.path.join(outdir, '{}_rf.sv'.format(m))
tb_file = os.path.join(outdir, '{}_tb.cpp'.format(m))
rf_file = os.path.join(outdir, f'{m}_rf.sv')
tb_file = os.path.join(outdir, f'{m}_tb.cpp')

print('Info: Compiling {} ({})'.format(m, rf_file))
proc = subprocess.run(['verilator', '--cc', rf_file, '--exe', tb_file], check=True, capture_output=(verbosity < 2))
proc = subprocess.run(['make', '-C', 'obj_dir', '-f', 'V{}_rf.mk'.format(m), 'V{}_rf'.format(m)], check=True, capture_output=(verbosity < 2))
print(f'Info: Compiling {m} ({rf_file})')
proc = subprocess.run(['verilator', '--cc', rf_file, '--exe', tb_file], check=True, capture_output=verbosity < 2)
proc = subprocess.run(['make', '-C', 'obj_dir', '-f', f'V{m}_rf.mk', f'V{m}_rf'], check=True, capture_output=verbosity < 2)

if proc.returncode:
print ("Error: make returned {}".format(proc.returncode))
print (f"Error: make returned {proc.returncode}")
sys.exit(2)
else:
print(" - Compiled into ./obj_dir")


def simulate(modules, verbosity=0):
for m in modules:
bin_file = os.path.join('obj_dir', 'V{}_rf'.format(m))
bin_file = os.path.join('obj_dir', f'V{m}_rf')

print('Info: Simulating {} ({})'.format(m, bin_file))
proc = subprocess.run([bin_file], check=True, capture_output=(verbosity < 1))
print(f'Info: Simulating {m} ({bin_file})')
proc = subprocess.run([bin_file], check=True, capture_output=verbosity < 1)

if proc.returncode:
print ("Error: sim returned {}".format(proc.returncode))
print (f"Error: sim returned {proc.returncode}")
sys.exit(4)
else:
print (" - Simulation Passed")
Expand Down
2 changes: 2 additions & 0 deletions peakrdl/verilog/templates/module.sv
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ module {{get_inst_name(top_node)}}_rf #(
input logic {{node.parent|full_array_ranges}} {{signal(node, '', 'we')}}, //! Control HW write (active high)
{%- endif %}

/* verilator lint_off SELRANGE */
{%- if node is hw_writable and not node.get_property('next') %}
input logic {{node.parent|full_array_ranges}}[{{node|bit_range(from_zero=True)}}] {{signal(node, '', 'wdata')}}, //! HW write data
{%- endif -%}
/* verilator lint_on SELRANGE */

{%- if node is hw_readable %}
output logic {{node.parent|full_array_ranges}}[{{node|bit_range(from_zero=True)}}] {{signal(node, '', 'q')}}, //! Current field value
Expand Down
32 changes: 32 additions & 0 deletions rdl2verilog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/python3

import sys
import os
from systemrdl import RDLCompiler, RDLCompileError
from peakrdl.verilog import VerilogExporter
import argparse

def cli(args):
parser = argparse.ArgumentParser(description='rdl2verilog')
# register format options
parser.add_argument("-f", "--fname", help="register file description .rdl", action='store', type = str, default="./test/testcases/basic.rdl")
return parser.parse_args(args)

def main(fname):
rdlc = RDLCompiler()

try:
rdlc.compile_file(fname)
root = rdlc.elaborate()
except RDLCompileError:
sys.exit(1)

exporter = VerilogExporter()
base = os.path.splitext(fname)[0]
print('output directory: ' + base)
exporter.export(root, base, signal_overrides = dict() )


if __name__ == '__main__':
p = cli(sys.argv[1:])
main(p.fname)
10 changes: 6 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
setuptools.setup(
name="peakrdl-verilog",
version=version,
author="Hugh Jackson",
author="Hugh Jackson, Marco Merlin",
description="Generate verilog register module from compiled SystemRDL input",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/SystemRDL/PeakRDL-verilog",
url="https://github.com/bat52/PeakRDL-verilog",
packages=['peakrdl.verilog'],
include_package_data=True,
install_requires=[
Expand All @@ -32,14 +32,16 @@
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3 :: Only",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Operating System :: OS Independent",
"Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
),
project_urls={
"Source": "https://github.com/SystemRDL/PeakRDL-verilog",
"Tracker": "https://github.com/SystemRDL/PeakRDL-verilog/issues"
"Source": "https://github.com/bat52/PeakRDL-verilog",
"Tracker": "https://github.com/bat52/PeakRDL-verilog/issues"
},
)
Loading