Skip to content

Commit

Permalink
Added support for additional Verilator modes (#389)
Browse files Browse the repository at this point in the history
  • Loading branch information
sifferman authored and olofk committed Nov 21, 2023
1 parent 2bf3994 commit 5429844
Show file tree
Hide file tree
Showing 13 changed files with 231 additions and 27 deletions.
41 changes: 31 additions & 10 deletions edalize/tools/verilator.py
Expand Up @@ -6,10 +6,10 @@

from edalize.tools.edatool import Edatool
from edalize.utils import EdaCommands
from edalize.verilator import Verilator as EdalizeVerilator


class Verilator(Edatool):

description = "Verilator, the fastest Verilog/SystemVerilog simulator"

TOOL_OPTIONS = {
Expand All @@ -23,7 +23,19 @@ class Verilator(Edatool):
},
"mode": {
"type": "str",
"desc": "Select compilation mode. Legal values are *cc* for C++ testbenches, *sc* for SystemC testbenches or *lint-only* to only perform linting on the Verilog code",
"desc": "Select compilation mode. Use *none* for no compilation mode. Legal values are *binary*, *cc*, *dpi-hdr-only*, *lint-only*, *none*, *preprocess-only*, *sc*, *xml-only*. See Verilator documentation for function: https://veripool.org/guide/latest/exe_verilator.html",
},
"gen-xml": {
"type": "bool",
"desc": "Generate XML output",
},
"gen-dpi-hdr": {
"type": "bool",
"desc": "Generate DPI header output",
},
"gen-preprocess": {
"type": "bool",
"desc": "Generate preprocessor output",
},
"verilator_options": {
"type": "str",
Expand All @@ -44,14 +56,12 @@ def setup(self, edam):
vc = []
vc.append("--Mdir .")

modes = ["sc", "cc", "lint-only"]

# Default to cc mode if not specified
mode = self.tool_options.get("mode", "cc")

if not mode in modes:
if mode not in EdalizeVerilator.modes:
_s = "Illegal verilator mode {}. Allowed values are {}"
raise RuntimeError(_s.format(mode, ", ".join(modes)))
raise RuntimeError(_s.format(mode, ", ".join(EdalizeVerilator.modes)))
vc.append("--" + mode)

vc += self.tool_options.get("verilator_options", [])
Expand Down Expand Up @@ -123,8 +133,14 @@ def setup(self, edam):
depfiles,
)

if mode == "lint-only":
commands.set_default_target(mk_file)
if mode in [
"binary",
"dpi-hdr-only",
"lint-only",
"preprocess-only",
"xml-only",
]:
commands.set_default_target(mode)
else:
commands.add(
["make", "-f", mk_file] + self.tool_options.get("make_options", []),
Expand All @@ -148,8 +164,13 @@ def run(self):
self.args += self.tool_options.get("run_options", [])

# Default to cc mode if not specified
if not "mode" in self.tool_options:
if "mode" not in self.tool_options:
self.tool_options["mode"] = "cc"
if self.tool_options["mode"] == "lint-only":
if self.tool_options["mode"] in [
"dpi-hdr-only",
"lint-only",
"preprocess-only",
"xml-only",
]:
return
return ("./V" + self.toplevel, self.args, self.work_root)
95 changes: 80 additions & 15 deletions edalize/verilator.py
Expand Up @@ -31,16 +31,37 @@
V$(TOP_MODULE): V$(TOP_MODULE).mk
$(MAKE) $(MAKE_OPTIONS) -f $<
V$(TOP_MODULE).mk:
$(EDALIZE_LAUNCHER) $(VERILATOR) -f $(VC_FILE) $(VERILATOR_OPTIONS)
.PHONY: binary dpi-hdr-only lint-only preprocess-only xml-only
binary:
$(EDALIZE_LAUNCHER) $(VERILATOR) --binary -f $(VC_FILE) $(VERILATOR_OPTIONS)
dpi-hdr-only:
$(EDALIZE_LAUNCHER) $(VERILATOR) --dpi-hdr-only -f $(VC_FILE) $(VERILATOR_OPTIONS)
lint-only:
$(EDALIZE_LAUNCHER) $(VERILATOR) --lint-only -f $(VC_FILE) $(VERILATOR_OPTIONS)
preprocess-only V$(TOP_MODULE).i:
$(EDALIZE_LAUNCHER) $(VERILATOR) -E -f $(VC_FILE) $(VERILATOR_OPTIONS) > V$(TOP_MODULE).i
xml-only V$(TOP_MODULE).xml:
$(EDALIZE_LAUNCHER) $(VERILATOR) --xml-only -f $(VC_FILE) $(VERILATOR_OPTIONS)
"""


class Verilator(Edatool):

argtypes = ["cmdlinearg", "plusarg", "vlogdefine", "vlogparam"]

modes = [
"binary",
"cc",
"dpi-hdr-only",
"lint-only",
"none",
"preprocess-only",
"sc",
"xml-only",
]

@classmethod
def get_doc(cls, api_ver):
if api_ver == 0:
Expand All @@ -50,7 +71,7 @@ def get_doc(cls, api_ver):
{
"name": "mode",
"type": "String",
"desc": "Select compilation mode. Legal values are *cc* for C++ testbenches, *sc* for SystemC testbenches or *lint-only* to only perform linting on the Verilog code",
"desc": "Select compilation mode. Legal values are *binary*, *cc*, *dpi-hdr-only*, *lint-only*, *none*, *preprocess-only*, *sc*, *xml-only*. See Verilator documentation for function: https://veripool.org/guide/latest/exe_verilator.html",
},
{
"name": "cli_parser",
Expand All @@ -62,6 +83,21 @@ def get_doc(cls, api_ver):
"type": "String",
"desc": "Controls whether to create an executable. Set to 'false' when something else will do the final linking",
},
{
"name": "gen-xml",
"type": "bool",
"desc": "Generate XML output",
},
{
"name": "gen-dpi-hdr",
"type": "bool",
"desc": "Generate DPI header output",
},
{
"name": "gen-preprocess",
"type": "bool",
"desc": "Generate preprocessor output",
},
],
"lists": [
{
Expand Down Expand Up @@ -117,19 +153,18 @@ def _write_config_files(self):

with open(os.path.join(self.work_root, self.verilator_file), "w") as f:
f.write("--Mdir .\n")
modes = ["sc", "cc", "lint-only"]

# Default to cc mode if not specified
if not "mode" in self.tool_options:
if "mode" not in self.tool_options:
self.tool_options["mode"] = "cc"

if self.tool_options["mode"] in modes:
f.write("--" + self.tool_options["mode"] + "\n")
else:
if self.tool_options["mode"] not in Verilator.modes:
_s = "Illegal verilator mode {}. Allowed values are {}"
raise RuntimeError(
_s.format(self.tool_options["mode"], ", ".join(modes))
_s.format(self.tool_options["mode"], ", ".join(Verilator.modes))
)
if self.tool_options["mode"] in ["cc", "sc"]:
f.write("--" + self.tool_options["mode"] + "\n")
if "libs" in self.tool_options:
for lib in self.tool_options["libs"]:
f.write("-LDFLAGS {}\n".format(lib))
Expand Down Expand Up @@ -203,12 +238,37 @@ def _write_config_files(self):

def build_main(self):
logger.info("Building simulation model")
if not "mode" in self.tool_options:
if "mode" not in self.tool_options:
self.tool_options["mode"] = "cc"
args = []
if self.tool_options["mode"] == "lint-only":
args.append("V" + self.toplevel + ".mk")
self._run_tool("make", args, quiet=True)

if self.tool_options["mode"] not in Verilator.modes:
_s = "Illegal verilator mode {}. Allowed values are {}"
raise RuntimeError(
_s.format(self.tool_options["mode"], ", ".join(Verilator.modes))
)

# PHONY Makefile targets
if self.tool_options["mode"] in [
"binary",
"dpi-hdr-only",
"lint-only",
"preprocess-only",
"xml-only",
]:
args.append(self.tool_options["mode"])

# Build mode
if self.tool_options["mode"] != "none":
self._run_tool("make", args, quiet=True)

# Additional builds
if str(self.tool_options.get("gen-xml")).lower() == "true":
self._run_tool("make", ["xml-only"], quiet=True)
if str(self.tool_options.get("gen-dpi-hdr")).lower() == "true":
self._run_tool("make", ["dpi-hdr-only"], quiet=True)
if str(self.tool_options.get("gen-preprocess")).lower() == "true":
self._run_tool("make", ["preprocess-only"], quiet=True)

def run_main(self):
self.check_managed_parser()
Expand All @@ -221,9 +281,14 @@ def run_main(self):
self.args += self.tool_options.get("run_options", [])

# Default to cc mode if not specified
if not "mode" in self.tool_options:
if "mode" not in self.tool_options:
self.tool_options["mode"] = "cc"
if self.tool_options["mode"] == "lint-only":
if self.tool_options["mode"] in [
"dpi-hdr-only",
"lint-only",
"preprocess-only",
"xml-only",
]:
return
logger.info("Running simulation")
self._run_tool("./V" + self.toplevel, self.args)
40 changes: 40 additions & 0 deletions tests/test_verilator.py
Expand Up @@ -44,3 +44,43 @@ def test_verilator_lint_only(make_edalize_test):

tf.compare_files(["Makefile"])
tf.compare_files(["config.mk", tf.test_name + ".vc"], ref_subdir=mode)


def test_verilator_binary(make_edalize_test):
mode = "binary"
tf = make_edalize_test("verilator", param_types=[], tool_options={"mode": mode})

tf.backend.configure()

tf.compare_files(["Makefile"])
tf.compare_files(["config.mk", tf.test_name + ".vc"], ref_subdir=mode)


def test_verilator_dpi_hdr_only(make_edalize_test):
mode = "dpi-hdr-only"
tf = make_edalize_test("verilator", param_types=[], tool_options={"mode": mode})

tf.backend.configure()

tf.compare_files(["Makefile"])
tf.compare_files(["config.mk", tf.test_name + ".vc"], ref_subdir=mode)


def test_verilator_preprocess_only(make_edalize_test):
mode = "preprocess-only"
tf = make_edalize_test("verilator", param_types=[], tool_options={"mode": mode})

tf.backend.configure()

tf.compare_files(["Makefile"])
tf.compare_files(["config.mk", tf.test_name + ".vc"], ref_subdir=mode)


def test_verilator_xml_only(make_edalize_test):
mode = "xml-only"
tf = make_edalize_test("verilator", param_types=[], tool_options={"mode": mode})

tf.backend.configure()

tf.compare_files(["Makefile"])
tf.compare_files(["config.mk", tf.test_name + ".vc"], ref_subdir=mode)
13 changes: 12 additions & 1 deletion tests/test_verilator/Makefile
Expand Up @@ -11,6 +11,17 @@ endif

V$(TOP_MODULE): V$(TOP_MODULE).mk
$(MAKE) $(MAKE_OPTIONS) -f $<

V$(TOP_MODULE).mk:
$(EDALIZE_LAUNCHER) $(VERILATOR) -f $(VC_FILE) $(VERILATOR_OPTIONS)

.PHONY: binary dpi-hdr-only lint-only preprocess-only xml-only
binary:
$(EDALIZE_LAUNCHER) $(VERILATOR) --binary -f $(VC_FILE) $(VERILATOR_OPTIONS)
dpi-hdr-only:
$(EDALIZE_LAUNCHER) $(VERILATOR) --dpi-hdr-only -f $(VC_FILE) $(VERILATOR_OPTIONS)
lint-only:
$(EDALIZE_LAUNCHER) $(VERILATOR) --lint-only -f $(VC_FILE) $(VERILATOR_OPTIONS)
preprocess-only V$(TOP_MODULE).i:
$(EDALIZE_LAUNCHER) $(VERILATOR) -E -f $(VC_FILE) $(VERILATOR_OPTIONS) > V$(TOP_MODULE).i
xml-only V$(TOP_MODULE).xml:
$(EDALIZE_LAUNCHER) $(VERILATOR) --xml-only -f $(VC_FILE) $(VERILATOR_OPTIONS)
6 changes: 6 additions & 0 deletions tests/test_verilator/binary/config.mk
@@ -0,0 +1,6 @@
#Auto generated by Edalize

TOP_MODULE := top_module
VC_FILE := test_verilator_0.vc
VERILATOR_OPTIONS :=
MAKE_OPTIONS :=
11 changes: 11 additions & 0 deletions tests/test_verilator/binary/test_verilator_0.vc
@@ -0,0 +1,11 @@
--Mdir .
+incdir+.
-CFLAGS -I.
sv_file.sv
vlog_file.v
vlog05_file.v
another_sv_file.sv
--top-module top_module
--exe
c_file.c
cpp_file.cpp
6 changes: 6 additions & 0 deletions tests/test_verilator/dpi-hdr-only/config.mk
@@ -0,0 +1,6 @@
#Auto generated by Edalize

TOP_MODULE := top_module
VC_FILE := test_verilator_0.vc
VERILATOR_OPTIONS :=
MAKE_OPTIONS :=
11 changes: 11 additions & 0 deletions tests/test_verilator/dpi-hdr-only/test_verilator_0.vc
@@ -0,0 +1,11 @@
--Mdir .
+incdir+.
-CFLAGS -I.
sv_file.sv
vlog_file.v
vlog05_file.v
another_sv_file.sv
--top-module top_module
--exe
c_file.c
cpp_file.cpp
1 change: 0 additions & 1 deletion tests/test_verilator/lint-only/test_verilator_0.vc
@@ -1,5 +1,4 @@
--Mdir .
--lint-only
+incdir+.
-CFLAGS -I.
sv_file.sv
Expand Down
6 changes: 6 additions & 0 deletions tests/test_verilator/preprocess-only/config.mk
@@ -0,0 +1,6 @@
#Auto generated by Edalize

TOP_MODULE := top_module
VC_FILE := test_verilator_0.vc
VERILATOR_OPTIONS :=
MAKE_OPTIONS :=
11 changes: 11 additions & 0 deletions tests/test_verilator/preprocess-only/test_verilator_0.vc
@@ -0,0 +1,11 @@
--Mdir .
+incdir+.
-CFLAGS -I.
sv_file.sv
vlog_file.v
vlog05_file.v
another_sv_file.sv
--top-module top_module
--exe
c_file.c
cpp_file.cpp
6 changes: 6 additions & 0 deletions tests/test_verilator/xml-only/config.mk
@@ -0,0 +1,6 @@
#Auto generated by Edalize

TOP_MODULE := top_module
VC_FILE := test_verilator_0.vc
VERILATOR_OPTIONS :=
MAKE_OPTIONS :=
11 changes: 11 additions & 0 deletions tests/test_verilator/xml-only/test_verilator_0.vc
@@ -0,0 +1,11 @@
--Mdir .
+incdir+.
-CFLAGS -I.
sv_file.sv
vlog_file.v
vlog05_file.v
another_sv_file.sv
--top-module top_module
--exe
c_file.c
cpp_file.cpp

0 comments on commit 5429844

Please sign in to comment.