...
 
Commits (13)
...@@ -24,6 +24,9 @@ if [ -d /build ]; then ...@@ -24,6 +24,9 @@ if [ -d /build ]; then
else else
d="$(realpath "$(dirname "$0")")" d="$(realpath "$(dirname "$0")")"
#" #"
docker run --rm -ti -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v "$d:/build" --user $(id -u):$(id -g) registry.gitlab.com/canfd/server-tools/ghdl:gtkwave /build/run-docker-test "$@" docker run --rm -ti -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix \
-v "$d:/build" --user $(id -u):$(id -g) --memory 6G \
registry.gitlab.com/canfd/server-tools/ghdl:gtkwave \
/build/run-docker-test "$@"
fi fi
...@@ -16,6 +16,12 @@ Features: ...@@ -16,6 +16,12 @@ Features:
* `gtkw`: a path to GTKW file with waveform layout definition for gtkwave; if * `gtkw`: a path to GTKW file with waveform layout definition for gtkwave; if
set together with `wave`, this takes precedence. The specified gtkw set together with `wave`, this takes precedence. The specified gtkw
file is not modified. file is not modified.
* `dump_all_signals`: If true, dump all signals in GUI mode, not only these
included in the layout file. May be overriden by
`--dumpall` commandline option. By default, it is set to
true, but for long-lasting tests with lots of signals it
may be necessary to set it to false to prevent `gtkwave`
to run out of memory while loading waveforms.
* many more * many more
## Using waveform layout files ## Using waveform layout files
...@@ -23,8 +29,12 @@ Features: ...@@ -23,8 +29,12 @@ Features:
* Specify the file in YML config, either as `gtkw` or `wave` (tcl). Later, this * Specify the file in YML config, either as `gtkw` or `wave` (tcl). Later, this
might be extended to native gtkw-generating python files. might be extended to native gtkw-generating python files.
* Run the tests with `--create-ghws`. This generates signal and type hierarchy. * Run the tests with `--create-ghws`. This generates signal and type hierarchy.
You should run this each time you modify a signal in the layout (or add a signal both to code and to layout). You should run this each time you modify a signal in the layout (or add a
signal both to code and to layout).
* Run in gui mode, using the VUnit `-g` flag. * Run in gui mode, using the VUnit `-g` flag.
* If a layout file is specified and `dump_all_signals` is false (and
`--dumpall` is not used), only the signals specified in the layout file are
dumped.
# How it works # How it works
......
This diff is collapsed.
...@@ -27,7 +27,7 @@ setup_logging() ...@@ -27,7 +27,7 @@ setup_logging()
from . import vunit_ifc from . import vunit_ifc
from . import test_unit, test_sanity, test_feature, test_reference from . import test_unit, test_sanity, test_feature, test_reference
from vunit.ui import VUnit from vunit.ui import VUnit
from .test_common import add_common_sources, add_flags from .test_common import add_common_sources, get_compile_options
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
...@@ -80,10 +80,12 @@ def create(): ...@@ -80,10 +80,12 @@ def create():
@click.option('--strict', 'strict', flag_value=1, @click.option('--strict', 'strict', flag_value=1,
help='Return non-zero if an unconfigured test was found.') help='Return non-zero if an unconfigured test was found.')
@click.option('--no-strict', 'strict', flag_value=0) @click.option('--no-strict', 'strict', flag_value=0)
@click.option('--dumpall', is_flag=True, flag_value=True, default=False,
help='In GUI mode, dump all signals, not only these included in layout file.')
@click.option('--create-ghws/--no-create-ghws', default=False, @click.option('--create-ghws/--no-create-ghws', default=False,
help='Only elaborate and create basic GHW files necessary for converting TCL layout files to GTKW files for gtkwave..') help='Only elaborate and create basic GHW files necessary for converting TCL layout files to GTKW files for gtkwave..')
@click.pass_obj @click.pass_obj
def test(obj, *, config, strict, create_ghws, vunit_args): def test(obj, *, config, strict, create_ghws, dumpall, vunit_args):
"""Run the tests. Configuration is passed in YAML config file. """Run the tests. Configuration is passed in YAML config file.
You mas pass arguments directly to VUnit by appending them at the command end. You mas pass arguments directly to VUnit by appending them at the command end.
...@@ -143,14 +145,20 @@ def test(obj, *, config, strict, create_ghws, vunit_args): ...@@ -143,14 +145,20 @@ def test(obj, *, config, strict, create_ghws, vunit_args):
tests = [] tests = []
for cfg_key, factory in tests_classes: for cfg_key, factory in tests_classes:
if cfg_key in config: if cfg_key in config:
tests.append(factory(ui, lib, config[cfg_key], build, base, create_ghws=create_ghws)) tests.append(factory(ui, lib, config[cfg_key], build, base,
create_ghws=create_ghws,
force_unrestricted_dump_signals=dumpall))
(func_cov_dir / "html").mkdir(parents=True, exist_ok=True) (func_cov_dir / "html").mkdir(parents=True, exist_ok=True)
(func_cov_dir / "coverage_data").mkdir(parents=True, exist_ok=True) (func_cov_dir / "coverage_data").mkdir(parents=True, exist_ok=True)
for t in tests: for t in tests:
t.add_sources() t.add_sources()
add_flags(ui, lib, build)
c = get_compile_options()
for k, v in c.items():
lib.set_compile_option(k, v)
conf_ok = [t.configure() for t in tests] conf_ok = [t.configure() for t in tests]
# check for unknown tests # check for unknown tests
...@@ -198,27 +206,3 @@ def vunit_run(ui, build, out_basename) -> int: ...@@ -198,27 +206,3 @@ def vunit_run(ui, build, out_basename) -> int:
f.write(c) f.write(c)
out.unlink() out.unlink()
return res return res
"""
+ vunit configurations
+ pass modelsim gui file via ui.set_sim_option("modelsim.init_file.gui", ...)
+ include the standard library files in ui.set_sim_option("modelsim.init_files.after_load", [...])
+ set TCOMP global variable
- allow preprocessed calls to log()
- use some log from vunit?
- use random from unit?
+ use per-test default configurations (with set tcl files etc.), different sanity configurations
x pass encoded composite generics (sanity test)
+ use watchdog - pass the time in config: test_runner_watchdog(runner, 10 ms);
- bash completion for files & tests:
- click._bashcompletion.get_choices -> extend the if to check if the given argument is an instance of XXX
and implement completion method for that instance. Complete test names.
- feature tests
- sanity - optimize bus delay shift registers
"""
from vcd.gtkw import GTKWSave from vcd.gtkw import GTKWSave
import tkinter import tkinter
from typing import List from typing import List, Set
import logging import logging
import traceback import traceback
import functools import functools
...@@ -25,6 +25,7 @@ def logexc(f): ...@@ -25,6 +25,7 @@ def logexc(f):
class TclFuncs: class TclFuncs:
def __init__(self, gtkw: str, hierarchy): def __init__(self, gtkw: str, hierarchy):
self.gtkw = gtkw self.gtkw = gtkw
self.used_signals = set() # type: Set[str]
self.hierarchy = hierarchy self.hierarchy = hierarchy
# set up TCL # set up TCL
...@@ -65,6 +66,13 @@ class TclFuncs: ...@@ -65,6 +66,13 @@ class TclFuncs:
fqn = 'top.' + fqn fqn = 'top.' + fqn
return fqn.replace('(', '[').replace(')', ']').lower() return fqn.replace('(', '[').replace(')', ']').lower()
def convsig_wave_opt(self, sig: str) -> str:
sig = re.sub(r'__([0-9]+)', r'(\1)', sig)
sig = re.sub(r'\([^)]+\)', '', sig)
if sig[0] != '/':
sig = '/'+sig
return sig
def _add_trace(self, signal, type, *, label: str, datafmt: str, expand: bool, **kwds): def _add_trace(self, signal, type, *, label: str, datafmt: str, expand: bool, **kwds):
if ghw_parse.is_record(type): if ghw_parse.is_record(type):
with self.gtkw.group(label, closed=not expand): with self.gtkw.group(label, closed=not expand):
...@@ -72,6 +80,7 @@ class TclFuncs: ...@@ -72,6 +80,7 @@ class TclFuncs:
# do not pass label # do not pass label
self._add_trace(signal+'/'+iname, itype, datafmt=datafmt, expand=False, label=None, **kwds) self._add_trace(signal+'/'+iname, itype, datafmt=datafmt, expand=False, label=None, **kwds)
else: else:
self.used_signals.add(self.convsig_wave_opt(signal))
signal = self.convsig(signal) signal = self.convsig(signal)
self.gtkw.trace(signal, alias=label, datafmt=datafmt, **kwds) self.gtkw.trace(signal, alias=label, datafmt=datafmt, **kwds)
...@@ -170,7 +179,7 @@ class TclFuncs: ...@@ -170,7 +179,7 @@ class TclFuncs:
self.gtkw.end_group(o.group) self.gtkw.end_group(o.group)
def tcl2gtkw(tcl_wave, tcl_init_files: List[str], gtkw, ghw: Path): def tcl2gtkw(tcl_wave, tcl_init_files: List[str], gtkw, ghw: Path) -> List[str]:
hierarchy = ghw_parse.parse(ghw) hierarchy = ghw_parse.parse(ghw)
with open(gtkw, 'wt') as f: with open(gtkw, 'wt') as f:
gtkw = GTKWSave(f) gtkw = GTKWSave(f)
...@@ -183,3 +192,5 @@ def tcl2gtkw(tcl_wave, tcl_init_files: List[str], gtkw, ghw: Path): ...@@ -183,3 +192,5 @@ def tcl2gtkw(tcl_wave, tcl_init_files: List[str], gtkw, ghw: Path):
c.tcl.createcommand('run_simulation', lambda: None) c.tcl.createcommand('run_simulation', lambda: None)
c.source(tcl_wave) c.source(tcl_wave)
c.finalize() c.finalize()
used_signals = sorted(c.used_signals)
return used_signals
vunit_hdl #vunit_hdl
git+git://github.com/mjerabek/vunit@ghdl-gtkwave#egg=vunit_hdl
pyvcd pyvcd
attrs attrs
jinja2 jinja2
parsy parsy
pyyaml pyyaml
click click
yattag
json2html
This diff is collapsed.
import logging import logging
from pathlib import Path from pathlib import Path
from .test_common import add_sources, TestsBase, dict_merge, \ from .test_common import add_sources, TestsBase, dict_merge, \
get_common_modelsim_init_files, get_seed get_seed, OptionsDict
from textwrap import dedent from textwrap import dedent
import re import re
...@@ -26,25 +26,14 @@ class FeatureTests(TestsBase): ...@@ -26,25 +26,14 @@ class FeatureTests(TestsBase):
tb = self.lib.get_test_benches('*tb_feature')[0] tb = self.lib.get_test_benches('*tb_feature')[0]
tb.scan_tests_from_file(str(wrname)) tb.scan_tests_from_file(str(wrname))
def create_psl_cov_file_opt(self, name):
psl_path = "functional_coverage/coverage_data/psl_cov_feature_{}.json".format(name)
psl_flag = "--psl-report={}".format(psl_path)
return {"ghdl.sim_flags" : [psl_flag]}
def configure(self) -> bool: def configure(self) -> bool:
tb = self.lib.get_test_benches('*tb_feature')[0] tb = self.lib.get_test_benches('*tb_feature')[0]
default = self.config['default'] default = self.config['default']
sim_options = self.get_default_sim_options()
# generate & set per-test modelsim tcl file # generate & set per-test modelsim tcl file
tcl = self.build / 'modelsim_init_feature.tcl' sim_options += self.generate_init_tcl('modelsim_init_feature.tcl', 'tb_feature/test_comp')
with tcl.open('wt', encoding='utf-8') as f: sim_options += self.add_modelsim_gui_file(tb, default, 'feature', sim_options['modelsim.init_files.after_load'])
print(dedent('''\
global TCOMP
set TCOMP tb_feature/test_comp
'''), file=f)
init_files = get_common_modelsim_init_files()
init_files += [str(tcl)]
tb.set_sim_option("modelsim.init_files.after_load", init_files)
for name, cfg in self.config['tests'].items(): for name, cfg in self.config['tests'].items():
if cfg is None: if cfg is None:
...@@ -64,12 +53,13 @@ class FeatureTests(TestsBase): ...@@ -64,12 +53,13 @@ class FeatureTests(TestsBase):
'seed' : get_seed(cfg) 'seed' : get_seed(cfg)
} }
if (cfg['psl_coverage']): local_sim_options = OptionsDict()
psl_opts = self.create_psl_cov_file_opt(name) if cfg['psl_coverage']:
tb.add_config(name, generics=generics, sim_options=psl_opts) local_sim_options += self.add_psl_cov('{}.{}'.format(tb.name, name))
else:
tb.add_config(name, generics=generics) local_sim_options = sim_options + local_sim_options
self.add_modelsim_gui_file(tb, default, 'feature', init_files) tb.add_config(name, generics=generics, sim_options=local_sim_options)
return self._check_for_unconfigured() return self._check_for_unconfigured()
def _check_for_unconfigured(self) -> bool: def _check_for_unconfigured(self) -> bool:
......
This diff is collapsed.
import logging import logging
from pathlib import Path from pathlib import Path
from .test_common import add_sources, TestsBase, dict_merge, \ from .test_common import add_sources, TestsBase, dict_merge, \
get_common_modelsim_init_files, get_seed get_seed, OptionsDict
from textwrap import dedent
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -18,28 +17,20 @@ class ReferenceTests(TestsBase): ...@@ -18,28 +17,20 @@ class ReferenceTests(TestsBase):
sources.append('reference/vunit_reference_wrapper.vhd') sources.append('reference/vunit_reference_wrapper.vhd')
add_sources(self.lib, sources) add_sources(self.lib, sources)
def create_psl_cov_file_opt(self, name):
psl_path = "functional_coverage/coverage_data/psl_cov_reference_{}.json".format(name)
psl_flag = "--psl-report={}".format(psl_path)
return {"ghdl.sim_flags" : [psl_flag]}
def configure(self) -> bool: def configure(self) -> bool:
tb = self.lib.get_test_benches('*reference*')[0] tb = self.lib.get_test_benches('*reference*')[0]
default = self.config['default'] default = self.config['default']
tcl = self.build / 'modelsim_init_reference.tcl' # TODO: is this necessary?
with tcl.open('wt', encoding='utf-8') as f: tb.scan_tests_from_file(str(self.base / "reference/vunit_reference_wrapper.vhd"))
print(dedent('''\
global TCOMP
set TCOMP tb_reference_wrapper/i_test
'''), file=f)
init_files = get_common_modelsim_init_files() sim_options = self.get_default_sim_options()
init_files += [str(tcl)] # generate & set per-test modelsim tcl file
sim_options += self.generate_init_tcl('modelsim_init_reference.tcl', 'tb_reference_wrapper/i_test')
sim_options += self.add_modelsim_gui_file(tb, default, 'reference', sim_options['modelsim.init_files.after_load'])
for data_set, cfg in self.config['tests'].items(): for data_set, cfg in self.config['tests'].items():
dict_merge(cfg, default) dict_merge(cfg, default)
# bm = len_to_matrix(cfg['topology'], cfg['bus_len_v'])
generics = { generics = {
'timeout' : cfg['timeout'], 'timeout' : cfg['timeout'],
'iterations' : cfg['iterations'], 'iterations' : cfg['iterations'],
...@@ -48,13 +39,10 @@ class ReferenceTests(TestsBase): ...@@ -48,13 +39,10 @@ class ReferenceTests(TestsBase):
'seed' : get_seed(cfg), 'seed' : get_seed(cfg),
'data_path' : str(self.build) + '/../' + cfg['data_path'], 'data_path' : str(self.build) + '/../' + cfg['data_path'],
} }
local_sim_options = OptionsDict()
if cfg['psl_coverage']:
local_sim_options += self.add_psl_cov('{}.{}'.format(tb.name, data_set))
local_sim_options = sim_options + local_sim_options
tb.add_config(data_set, generics=generics, sim_options=local_sim_options)
if (cfg['psl_coverage']):
psl_opts = self.create_psl_cov_file_opt(data_set)
tb.add_config(data_set, generics=generics, sim_options=psl_opts)
else:
tb.add_config(data_set, generics=generics)
tb.set_sim_option("modelsim.init_files.after_load", init_files)
self.add_modelsim_gui_file(tb, default, 'reference', init_files)
return True return True
import logging import logging
from textwrap import dedent from textwrap import dedent
from .test_common import TestsBase, add_sources, dict_merge, vhdl_serialize, \ from .test_common import TestsBase, add_sources, dict_merge, vhdl_serialize, \
get_seed, get_common_modelsim_init_files get_seed, OptionsDict
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def len_to_matrix(topology, bus_len):
l = bus_len
if topology == 'bus':
bm = [[0.0, l[1], l[1]+l[2], l[1]+l[2]+l[3]],
[l[1], 0.0, l[2], l[2]+l[3]],
[l[1]+l[2], l[2], 0.0, l[3]],
[l[1]+l[2]+l[3], l[2]+l[3], l[3], 0.0]]
elif topology == 'star':
bm = [[0.0, l[1]+l[2], l[1]+l[3], l[1]+l[4]],
[l[1]+l[2], 0.0, l[2]+l[3], l[2]+l[4]],
[l[1]+l[3], l[2]+l[3], 0.0, l[3]+l[4]],
[l[1]+l[4], l[2]+l[4], l[3]+l[4], 0.0]]
elif topology == 'tree':
bm = [[0.0, l[1]+l[2], l[1]+l[3]+l[5], l[1]+l[4]+l[5]],
[l[1]+l[2], 0.0, l[2]+l[3]+l[5], l[2]+l[4]+l[5]],
[l[1]+l[3]+l[5], l[2]+l[3]+l[5], 0.0, l[3]+l[4]],
[l[1]+l[4]+l[5], l[2]+l[4]+l[5], l[3]+l[4], 0.0]]
elif topology == 'ring':
bm = [[0.0, min(l[1], l[2]+l[3]+l[4]), min(l[1]+l[2],l[3]+l[4]), min(l[4],l[1]+l[2]+l[3])],
[min(l[1], l[2]+l[3]+l[4]), 0.0, min(l[2], l[1]+l[3]+l[4]), min(l[2]+l[3],l[1]+l[4])],
[min(l[1]+l[2],l[3]+l[4]), min(l[2], l[1]+l[3]+l[4]), 0.0, min(l[3],l[1]+l[2]+l[4])],
[min(l[4],l[1]+l[2]+l[3]), min(l[2]+l[3],l[1]+l[4]), min(l[3],l[1]+l[2]+l[4]), 0.0]]
elif topology == 'custom':
bm = [[0.0, l[1], l[2], l[3]],
[l[1], 0.0, l[4], l[5]],
[l[2], l[4], 0.0, l[6]],
[l[3], l[6], l[6], 0.0]]
else:
raise ValueError("Invalid bus topology.")
return bm
class SanityTests(TestsBase): class SanityTests(TestsBase):
def add_sources(self): def add_sources(self):
add_sources(self.lib, ['sanity/**/*.vhd']) add_sources(self.lib, ['sanity/**/*.vhd'])
...@@ -48,25 +15,14 @@ class SanityTests(TestsBase): ...@@ -48,25 +15,14 @@ class SanityTests(TestsBase):
valid_name = valid_name.replace("/", "_") valid_name = valid_name.replace("/", "_")
return valid_name return valid_name
def create_psl_cov_file_opt(self, name):
test_name = "psl_cov_sanity_{}.json".format(self.format_valid_test_name(name))
psl_path = "functional_coverage/coverage_data/{}".format(test_name)
psl_flag = "--psl-report={}".format(psl_path)
return {"ghdl.sim_flags" : [psl_flag]}
def configure(self): def configure(self):
tb = self.lib.get_test_benches('*tb_sanity')[0] tb = self.lib.get_test_benches('*tb_sanity')[0]
default = self.config['default'] default = self.config['default']
tcl = self.build / 'modelsim_init_sanity.tcl' sim_options = self.get_default_sim_options()
with tcl.open('wt', encoding='utf-8') as f: # generate & set per-test modelsim tcl file
print(dedent('''\ sim_options += self.generate_init_tcl('modelsim_init_sanity.tcl', 'tb_sanity')
global TCOMP sim_options += self.add_modelsim_gui_file(tb, default, 'sanity', sim_options['modelsim.init_files.after_load'])
set TCOMP tb_sanity
'''), file=f)
init_files = get_common_modelsim_init_files()
init_files += [str(tcl)]
for name, cfg in self.config['tests'].items(): for name, cfg in self.config['tests'].items():
if 'wave' in cfg: if 'wave' in cfg:
...@@ -74,7 +30,6 @@ class SanityTests(TestsBase): ...@@ -74,7 +30,6 @@ class SanityTests(TestsBase):
' (set it in default instead)'.format(name)) ' (set it in default instead)'.format(name))
dict_merge(cfg, default) dict_merge(cfg, default)
# bm = len_to_matrix(cfg['topology'], cfg['bus_len_v'])
generics = { generics = {
'timeout' : cfg['timeout'], 'timeout' : cfg['timeout'],
'iterations' : cfg['iterations'], 'iterations' : cfg['iterations'],
...@@ -94,13 +49,9 @@ class SanityTests(TestsBase): ...@@ -94,13 +49,9 @@ class SanityTests(TestsBase):
'gauss_iter' : vhdl_serialize(cfg['gauss_iter']), 'gauss_iter' : vhdl_serialize(cfg['gauss_iter']),
} }
sanity_cfg_name = name.replace(" ", "_").replace("/", "_").strip('"') local_sim_options = OptionsDict()
if cfg['psl_coverage']: if cfg['psl_coverage']:
psl_opts = self.create_psl_cov_file_opt(name) local_sim_options += self.add_psl_cov('{}.{}'.format(tb.name, name))
tb.add_config(name, generics=generics, sim_options=psl_opts) local_sim_options = sim_options + local_sim_options
else: tb.add_config(name, generics=generics, sim_options=local_sim_options)
tb.add_config(name, generics=generics)
self.add_modelsim_gui_file(tb, default, 'sanity', init_files)
return True return True
...@@ -2,7 +2,7 @@ import re ...@@ -2,7 +2,7 @@ import re
import logging import logging
from textwrap import dedent from textwrap import dedent
from .test_common import add_sources, dict_merge, TestsBase, \ from .test_common import add_sources, dict_merge, TestsBase, \
get_common_modelsim_init_files, get_seed get_seed, OptionsDict
from pprint import pprint from pprint import pprint
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -13,15 +13,14 @@ class UnitTests(TestsBase): ...@@ -13,15 +13,14 @@ class UnitTests(TestsBase):
add_sources(self.lib, ['unit/**/*.vhd']) add_sources(self.lib, ['unit/**/*.vhd'])
self._create_wrapper(self.build / "tb_wrappers.vhd") self._create_wrapper(self.build / "tb_wrappers.vhd")
def add_psl_cov_file(self, tb, name):
psl_path = "functional_coverage/coverage_data/psl_cov_unit_{}.json".format(name)
psl_flag = "--psl-report={}".format(psl_path)
tb.set_sim_option("ghdl.sim_flags", [psl_flag])
def configure(self) -> bool: def configure(self) -> bool:
lib, config, build = self.lib, self.config, self.build lib, config, build = self.lib, self.config, self.build
default = config['default'] default = config['default']
unit_tests = lib.get_test_benches('*_unit_test') unit_tests = lib.get_test_benches('*_unit_test')
for ut in unit_tests:
ut.scan_tests_from_file(str(build / "../unit/vunittb_wrapper.vhd"))
for name, cfg in config['tests'].items(): for name, cfg in config['tests'].items():
dict_merge(cfg, default) dict_merge(cfg, default)
tb = lib.get_test_benches('*tb_{}_unit_test'.format(name), tb = lib.get_test_benches('*tb_{}_unit_test'.format(name),
...@@ -39,19 +38,15 @@ class UnitTests(TestsBase): ...@@ -39,19 +38,15 @@ class UnitTests(TestsBase):
tb.set_generic('error_tol', cfg['error_tolerance']) tb.set_generic('error_tol', cfg['error_tolerance'])
tb.set_generic('seed', get_seed(cfg)) tb.set_generic('seed', get_seed(cfg))
sim_options = self.get_default_sim_options()
# generate & set per-test modelsim tcl file # generate & set per-test modelsim tcl file
tcl = build / 'modelsim_init_{}.tcl'.format(name) sim_options += self.generate_init_tcl('modelsim_init_{}.tcl'.format(name), 'tb_{}_unit_test/tb/i_test'.format(name))
with tcl.open('wt', encoding='utf-8') as f: sim_options += self.add_modelsim_gui_file(tb, cfg, name, sim_options['modelsim.init_files.after_load'])
print(dedent('''\
global TCOMP if cfg['psl_coverage']:
set TCOMP tb_{}_unit_test/tb/i_test sim_options += self.add_psl_cov(tb.name)
'''.format(name)), file=f) self.set_sim_options(tb, sim_options)
init_files = get_common_modelsim_init_files()
init_files += [str(tcl)]
tb.set_sim_option("modelsim.init_files.after_load", init_files)
if (cfg['psl_coverage']):
self.add_psl_cov_file(tb, name)
self.add_modelsim_gui_file(tb, cfg, name, tcl_init_files=init_files)
return self._check_for_unconfigured() return self._check_for_unconfigured()
def _check_for_unconfigured(self) -> bool: def _check_for_unconfigured(self) -> bool:
......
...@@ -5,6 +5,8 @@ _default: &default ...@@ -5,6 +5,8 @@ _default: &default
psl_coverage: false psl_coverage: false
# seed: 0 # optional; use to reconstruct results from randomized runs # seed: 0 # optional; use to reconstruct results from randomized runs
# randomize: false # randomize: false
# In GUI mode, dump all signals, not only these included in layout file.
dump_all_signals: true
feature: feature:
default: default:
<<: *default <<: *default
......
...@@ -4,6 +4,8 @@ _default: &default ...@@ -4,6 +4,8 @@ _default: &default
error_tolerance: 0 error_tolerance: 0
# seed: 0 # optional; use to reconstruct results from randomized runs # seed: 0 # optional; use to reconstruct results from randomized runs
# randomize: false # randomize: false
# In GUI mode, dump all signals, not only these included in layout file.
dump_all_signals: true
unit: unit:
default: default:
<<: *default <<: *default
...@@ -109,6 +111,7 @@ sanity: ...@@ -109,6 +111,7 @@ sanity:
timeout: 2 sec timeout: 2 sec
gauss_iter: 40 gauss_iter: 40
wave: sanity/sanity_env_setup.tcl wave: sanity/sanity_env_setup.tcl
dump_all_signals: false
tests: tests:
"1Mb/10Mb 20 m Star": "1Mb/10Mb 20 m Star":
topology: star topology: star
......
...@@ -3,6 +3,8 @@ _default: &default ...@@ -3,6 +3,8 @@ _default: &default
psl_coverage: true psl_coverage: true
error_tolerance: 0 error_tolerance: 0
randomize: true randomize: true
# In GUI mode, dump all signals, not only these included in layout file.
dump_all_signals: true
unit: unit:
default: default:
<<: *default <<: *default
...@@ -109,6 +111,7 @@ sanity: ...@@ -109,6 +111,7 @@ sanity:
timeout: 2 sec timeout: 2 sec
gauss_iter: 40 gauss_iter: 40
wave: sanity/sanity_env_setup.tcl wave: sanity/sanity_env_setup.tcl
dump_all_signals: false
tests: tests:
"1Mb/10Mb 20 m Star": "1Mb/10Mb 20 m Star":
topology: star topology: star
......
...@@ -3,6 +3,8 @@ _default: &default ...@@ -3,6 +3,8 @@ _default: &default
error_tolerance: 0 error_tolerance: 0
# seed: 0 # optional; use to reconstruct results from randomized runs # seed: 0 # optional; use to reconstruct results from randomized runs
# randomize: false # randomize: false
# In GUI mode, dump all signals, not only these included in layout file.
dump_all_signals: true
reference: reference:
default: default:
<<: *default <<: *default
......