Skip to content

Commit

Permalink
Port VCS to Flow API
Browse files Browse the repository at this point in the history
  • Loading branch information
olofk committed Nov 26, 2024
1 parent 6632553 commit adfb86a
Show file tree
Hide file tree
Showing 18 changed files with 305 additions and 0 deletions.
197 changes: 197 additions & 0 deletions edalize/tools/vcs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# Copyright edalize contributors
# Licensed under the 2-Clause BSD License, see LICENSE for details.
# SPDX-License-Identifier: BSD-2-Clause

from pathlib import Path

from edalize.tools.edatool import Edatool
from edalize.utils import EdaCommands


class Vcs(Edatool):

description = "VCS simulator from Synopsys"

TOOL_OPTIONS = {
"32bit": {
"type": "bool",
"desc": "Disable 64-bit mode",
},
"vlogan_options": {
"type": "str",
"desc": "Additional options for analysis with vlogan",
"list": True,
},
"vhdlan_options": {
"type": "str",
"desc": "Additional options for analysis with vhdlan",
"list": True,
},
"vcs_options": {
"type": "str",
"desc": "Additional options for elaboration with vcs",
"list": True,
},
"run_options": {
"type": "str",
"desc": "Additional run-time options for the simulation",
"list": True,
},
}

def setup(self, edam):
super().setup(edam)

incdirs = []
include_files = []
unused_files = self.files.copy()
# Get all include dirs. Move include files to a separate list
for f in self.files:
if not "simulation" in f.get("tags", ["simulation"]):
continue
file_type = f.get("file_type", "")
if file_type.startswith("verilogSource") or file_type.startswith(
"systemVerilogSource"
):
if self._add_include_dir(f, incdirs, force_slash=True):
include_files.append(f["name"])
unused_files.remove(f)

user_files = []
commands = {}
libs = {}
has_sv = False
for f in unused_files.copy():
lib = f.get("logical_name", "work")

file_type = f.get("file_type", "")
if file_type.startswith("verilogSource") or file_type.startswith(
"systemVerilogSource"
):

if file_type.startswith("systemVerilogSource"):
has_sv = True

vlog_defines = self.vlogdefine.copy()
vlog_defines.update(f.get("define", {}))

_args = []
for k, v in vlog_defines.items():
_args.append(
"+define+{}={}".format(
k, self._param_value_str(v, str_quote_style='""')
)
)
defines = " ".join(_args)
cmd = "vlogan"
elif file_type.startswith("vhdlSource"):
cmd = "vhdlan"
elif file_type == "user":
user_files.append(f["name"])
cmd = None
else:
cmd = None

if not "simulation" in f.get("tags", ["simulation"]):
cmd = None

if cmd:
if not lib in libs:
libs[lib] = []
libs[lib].append((cmd, f["name"], defines))
if not commands.get((cmd, lib, defines)):
commands[(cmd, lib, defines)] = []
commands[(cmd, lib, defines)].append(f["name"])
unused_files.remove(f)

full64 = [] if self.tool_options.get("32bit") else ["-full64"]
self.commands = EdaCommands()
self.f_files = {}
for lib, files in libs.items():
cmds = {}
depfiles = []
has_vlog = False
# Group into individual commands
for (cmd, fname, defines) in files:
if not (cmd, defines) in cmds:
cmds[(cmd, defines)] = []
cmds[(cmd, defines)].append(fname)
depfiles.append(fname)
if cmd == "vlogan":
has_vlog = True
commands = [["mkdir", "-p", lib]]
i = 1
f_files = {}
for (cmd, defines), fnames in cmds.items():
options = []
if cmd == "vlogan":
if has_sv:
options.append("-sverilog")
options += self.tool_options.get("vlogan_options", [])
options += [defines]
options += ["+incdir+" + d for d in incdirs]
elif cmd == "vhdlan":
options += self.tool_options.get("vhdlan_options", [])
f_file = f"{lib}.{i}.f"
f_files[f_file] = options
i += 1
commands.append([cmd] + full64 + ["-f", f_file, "-work", lib] + fnames)
if has_vlog:
depfiles += include_files
self.commands.add(
commands, [lib + "/AN.DB"], depfiles + list(f_files.keys())
)
self.f_files.update(f_files)

self.edam = edam.copy()
self.edam["files"] = unused_files

self.f_files["vcs.f"] = ["-top", self.toplevel] + self.tool_options.get(
"vcs_options", []
)
self.commands.add(
["vcs"]
+ full64
+ ["-o", self.name, "-file", "vcs.f", "-parameters", "parameters.txt"],
[self.name],
[x + "/AN.DB" for x in libs.keys()]
+ user_files
+ ["vcs.f", "parameters.txt"],
)

self.commands.add(
["./" + self.name, "$(EXTRA_OPTIONS)"]
+ self.tool_options.get("run_options", []),
["run"],
[self.name],
)
self.commands.set_default_target(self.name)
self.libs = libs.keys()

def write_config_files(self):
s = "WORK > DEFAULT\nDEFAULT : ./work\n"
for lib in self.libs:
if lib != "work":
s += f"{lib} : ./{lib}\n"
self.update_config_file("synopsys_sim.setup", s)
for k, v in self.f_files.items():
self.update_config_file(k, " ".join(v) + "\n")

_parameters = {**self.vlogparam, **self.generic}
s = ""
for key, value in _parameters.items():
_value = self._param_value_str(value, '"')
s += f"assign {_value} {key}\n"
self.update_config_file("parameters.txt", s)

def run(self):
args = ["run"]

# Set plusargs
if self.plusarg:
plusargs = []
for key, value in self.plusarg.items():
plusargs += ["+{}={}".format(key, self._param_value_str(value))]
args.append("EXTRA_OPTIONS=" + " ".join(plusargs))

return ("make", args, self.work_root)
48 changes: 48 additions & 0 deletions tests/test_tool_vcs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from .edalize_tool_common import tool_fixture

# TODO: File-specific defines
# Run / run-options
def test_tool_vcs(tool_fixture):

tool_options = {
"vlogan_options": ["a", "few", "vlogan", "options"],
"vhdlan_options": ["also", "vhdlan", "options"],
"vcs_options": ["some", "vcs", "options"],
"run_options": ["and", "some", "run", "options"],
}

tf = tool_fixture("vcs", tool_options=tool_options, ref_subdir="basic")

name = "design"

tf.tool.configure()
tf.compare_config_files(
[
"synopsys_sim.setup",
"libx.1.f",
"vcs.f",
"work.1.f",
"work.2.f",
"work.3.f",
"parameters.txt",
]
)


def test_tool_vcs_minimal(tool_fixture):
tf = tool_fixture("vcs", ref_subdir="minimal")

name = "design"

tf.tool.configure()
tf.compare_config_files(
[
"synopsys_sim.setup",
"libx.1.f",
"vcs.f",
"work.1.f",
"work.2.f",
"work.3.f",
"parameters.txt",
]
)
19 changes: 19 additions & 0 deletions tests/tools/vcs/basic/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#Auto generated by Edalize

all: design

work/AN.DB: sv_file.sv vlog_file.v vlog_with_define.v vlog05_file.v vhdl_file.vhd vhdl2008_file another_sv_file.sv vlog_incfile work.1.f work.2.f work.3.f
$(EDALIZE_LAUNCHER) mkdir -p work
$(EDALIZE_LAUNCHER) vlogan -full64 -f work.1.f -work work sv_file.sv vlog_file.v vlog05_file.v another_sv_file.sv
$(EDALIZE_LAUNCHER) vlogan -full64 -f work.2.f -work work vlog_with_define.v
$(EDALIZE_LAUNCHER) vhdlan -full64 -f work.3.f -work work vhdl_file.vhd vhdl2008_file

libx/AN.DB: vhdl_lfile libx.1.f
$(EDALIZE_LAUNCHER) mkdir -p libx
$(EDALIZE_LAUNCHER) vhdlan -full64 -f libx.1.f -work libx vhdl_lfile

design: work/AN.DB libx/AN.DB user_file vcs.f parameters.txt
$(EDALIZE_LAUNCHER) vcs -full64 -o design -file vcs.f -parameters parameters.txt

run: design
$(EDALIZE_LAUNCHER) ./design $(EXTRA_OPTIONS) and some run options
1 change: 1 addition & 0 deletions tests/tools/vcs/basic/libx.1.f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
also vhdlan options
3 changes: 3 additions & 0 deletions tests/tools/vcs/basic/parameters.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
assign 1 vlogparam_bool
assign 42 vlogparam_int
assign "hello" vlogparam_str
3 changes: 3 additions & 0 deletions tests/tools/vcs/basic/synopsys_sim.setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
WORK > DEFAULT
DEFAULT : ./work
libx : ./libx
1 change: 1 addition & 0 deletions tests/tools/vcs/basic/vcs.f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-top top_module some vcs options
1 change: 1 addition & 0 deletions tests/tools/vcs/basic/work.1.f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-sverilog a few vlogan options +define+vlogdefine_bool=1 +define+vlogdefine_int=42 +define+vlogdefine_str=""hello"" +incdir+.
1 change: 1 addition & 0 deletions tests/tools/vcs/basic/work.2.f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-sverilog a few vlogan options +define+vlogdefine_bool=1 +define+vlogdefine_int=42 +define+vlogdefine_str=""hello"" +define+FD_KEY=""FD_VAL"" +incdir+.
1 change: 1 addition & 0 deletions tests/tools/vcs/basic/work.3.f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
also vhdlan options
19 changes: 19 additions & 0 deletions tests/tools/vcs/minimal/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#Auto generated by Edalize

all: design

work/AN.DB: sv_file.sv vlog_file.v vlog_with_define.v vlog05_file.v vhdl_file.vhd vhdl2008_file another_sv_file.sv vlog_incfile work.1.f work.2.f work.3.f
$(EDALIZE_LAUNCHER) mkdir -p work
$(EDALIZE_LAUNCHER) vlogan -full64 -f work.1.f -work work sv_file.sv vlog_file.v vlog05_file.v another_sv_file.sv
$(EDALIZE_LAUNCHER) vlogan -full64 -f work.2.f -work work vlog_with_define.v
$(EDALIZE_LAUNCHER) vhdlan -full64 -f work.3.f -work work vhdl_file.vhd vhdl2008_file

libx/AN.DB: vhdl_lfile libx.1.f
$(EDALIZE_LAUNCHER) mkdir -p libx
$(EDALIZE_LAUNCHER) vhdlan -full64 -f libx.1.f -work libx vhdl_lfile

design: work/AN.DB libx/AN.DB user_file vcs.f parameters.txt
$(EDALIZE_LAUNCHER) vcs -full64 -o design -file vcs.f -parameters parameters.txt

run: design
$(EDALIZE_LAUNCHER) ./design $(EXTRA_OPTIONS)
1 change: 1 addition & 0 deletions tests/tools/vcs/minimal/libx.1.f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

3 changes: 3 additions & 0 deletions tests/tools/vcs/minimal/parameters.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
assign 1 vlogparam_bool
assign 42 vlogparam_int
assign "hello" vlogparam_str
3 changes: 3 additions & 0 deletions tests/tools/vcs/minimal/synopsys_sim.setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
WORK > DEFAULT
DEFAULT : ./work
libx : ./libx
1 change: 1 addition & 0 deletions tests/tools/vcs/minimal/vcs.f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-top top_module
1 change: 1 addition & 0 deletions tests/tools/vcs/minimal/work.1.f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-sverilog +define+vlogdefine_bool=1 +define+vlogdefine_int=42 +define+vlogdefine_str=""hello"" +incdir+.
1 change: 1 addition & 0 deletions tests/tools/vcs/minimal/work.2.f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-sverilog +define+vlogdefine_bool=1 +define+vlogdefine_int=42 +define+vlogdefine_str=""hello"" +define+FD_KEY=""FD_VAL"" +incdir+.
1 change: 1 addition & 0 deletions tests/tools/vcs/minimal/work.3.f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

0 comments on commit adfb86a

Please sign in to comment.