Skip to content

Commit

Permalink
Merge branch 'VUnit:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Unike267 authored Dec 12, 2024
2 parents 30ce81e + 2210608 commit 64b08d3
Show file tree
Hide file tree
Showing 11 changed files with 697 additions and 97 deletions.
11 changes: 0 additions & 11 deletions docs/news.d/1002.feature.rst

This file was deleted.

2 changes: 0 additions & 2 deletions docs/news.d/1054.feature.rst

This file was deleted.

13 changes: 13 additions & 0 deletions docs/py/opts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,19 @@ The following simulation options are known.
Additionally, the ``vunit_tb_name`` variable is defined as the name of the test bench.
Must be a string.

``modelsim.three_step_flow``
Enable 3-step flow where a separate ``vopt`` step is executed before ``vsim`` is called.
Must be a boolean value. Default is False.

``modelsim.vopt_flags``
Extra arguments passed to ``vopt`` when ``modelsim.three_step_flow`` is ``True``.
Must be a list of strings.

``modelsim.vsim_flags.gui``
Extra arguments passed to ``vopt`` when ``modelsim.three_step_flow`` is ``True`` and
GUI mode is enabled. Takes precedence over ``modelsim.vopt_flags``. Must be a list of
strings.

``rivierapro.vsim_flags``
Extra arguments passed to ``vsim`` when loading the design.
Must be a list of strings.
Expand Down
29 changes: 29 additions & 0 deletions docs/release_notes/5.0.0.dev4.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

Features
~~~~~~~~

- [Questa/Modelsim] Added support for 3-step flow and the Visualizer debugger.

The 3-step flow is enabled by setting the simulation option ``modelsim.three_step_flow`` to ``True``. Extra
flags to the ``vopt`` step can be provided with the simulation flags ``modelsim.vopt_flags`` and
``modelsim.vopt_flags.gui`` in normal and GUI mode, respectively.

The Visualizer debugger is enabled from the command line using the ``--debugger=visualizer`` option (in
addition to the ``--gui`` option for GUI mode). The 3-step flow must be enabled for this feature while
the default ``original`` debugger works with or without the 3-step flow.

Note: There is a bug in Visualizer preventing the normal ``restart`` command from being used. Please use the
``vunit_restart`` command instead. (:vunit_issue:`899`)
- [GHDL/NVC] Arbitrary waveform viewers are now supported by passing the ``--viewer``
command line argument. As a consequence, ``ghdl.gtkwave_script.gui`` and
``nvc.gtkwave_script.gui`` are deprecated in favour of ``ghdl.viewer_script.gui``
and ``nvc.viewer_script.gui``, respectively. The ``--gtkwave-args`` and
``--gtkwave-fmt`` command line arguments are deprecated in favour of ``--viewer-args``
and ``--viewer-fmt``, respectively. ``ghdl.viewer.gui`` and ``nvc.viewer.gui`` can
be used to set the preferred viewer from the run-file. If no viewer is explicitly
requested, ``gtkwave`` or ``surfer`` is used, in that order. This also means that
VUnit now uses ``surfer`` if ``gtkwave`` is not installed.

[NVC] It is possible to get VCD waveform files by passing ``--viewer-fmt=vcd``. (:vunit_issue:`1002`)
- Added timeout parameter to the `wait_until_idle` procedure in the synchronization verification component interface.
A timeout will result in a failure. (:vunit_issue:`1054`)
69 changes: 69 additions & 0 deletions tests/unit/test_modelsim_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from vunit.sim_if.modelsim import ModelSimInterface
from vunit.project import Project
from vunit.ostools import renew_path, write_file
from vunit.test.bench import Configuration
from vunit.vhdl_standard import VHDL


Expand Down Expand Up @@ -316,14 +317,61 @@ def test_overwrites_modelsim_ini_file_from_user(self):
with open(modelsim_ini, "r") as fptr:
self.assertEqual(fptr.read(), "user")

@mock.patch("vunit.sim_if.modelsim.LOGGER", autospec=True)
@mock.patch("vunit.sim_if.check_output", autospec=True, return_value="")
@mock.patch("vunit.sim_if.modelsim.Process", autospec=True)
@mock.patch("vunit.sim_if.vsim_simulator_mixin.Process", autospec=True)
def test_optimize(self, vsim_simulator_mixin_process, modelsim_process, check_output, LOGGER):
simif = ModelSimInterface(prefix=self.prefix_path, output_path=self.output_path, persistent=False)
project = Project()
project.add_library("lib", str(Path(self.libraries_path) / "lib"))
write_file("file.vhd", "")
project.add_source_file("file.vhd", "lib", file_type="vhdl", vhdl_standard=VHDL.standard("2008"))
simif.compile_project(project)
config = make_config(sim_options={"modelsim.three_step_flow": True})

# First call should optimize design
simif.simulate(self.simulation_output_path, "test_suite_name", config, False)
design_to_optimize = "lib.tb(test)"
expected_calls = [
mock.call("%s scheduled for optimization.", design_to_optimize),
mock.call("Acquired library lock for %s to optimize %s.", "lib", design_to_optimize),
mock.call("Optimizing %s.", design_to_optimize),
mock.call("%s optimization completed.", design_to_optimize),
]
self.assertEqual(LOGGER.debug.call_count, len(expected_calls))
LOGGER.debug.assert_has_calls(expected_calls)

# Second call should reuse the already optimized design
LOGGER.reset_mock()
simif.simulate(self.simulation_output_path, "test_suite_name", config, False)
LOGGER.debug.assert_called_once_with("Reusing optimized %s.", "lib.tb(test)")

# Fake that design is being optimized and that it is being waited for
LOGGER.reset_mock()
simif._optimized_designs[design_to_optimize]["optimized_design"] = None
simif.simulate(self.simulation_output_path, "test_suite_name", config, False)
expected_debug_calls = [mock.call("Waiting for %s to be optimized.", design_to_optimize)]
self.assertEqual(LOGGER.debug.call_count, len(expected_debug_calls))
LOGGER.debug.assert_has_calls(expected_debug_calls)
expected_error_calls = [
mock.call("Failed waiting for %s to be optimized (optimization failed).", design_to_optimize)
]
self.assertEqual(LOGGER.error.call_count, len(expected_error_calls))
LOGGER.error.assert_has_calls(expected_error_calls)

def setUp(self):
self.test_path = str(Path(__file__).parent / "test_modelsim_out")

self.output_path = str(Path(self.test_path) / "modelsim")
self.prefix_path = str(Path(self.test_path) / "prefix" / "bin")
self.libraries_path = str(Path(self.output_path) / "libraries")
self.simulation_output_path = str(Path(self.test_path) / "test_output" / "lib.tb")
renew_path(self.test_path)
renew_path(self.output_path)
renew_path(self.prefix_path)
renew_path(self.libraries_path)
renew_path(self.simulation_output_path)
installed_modelsim_ini = str(Path(self.prefix_path) / ".." / "modelsim.ini")
write_file(installed_modelsim_ini, "[Library]")
self.project = Project()
Expand All @@ -334,3 +382,24 @@ def tearDown(self):
os.chdir(self.cwd)
if Path(self.test_path).exists():
rmtree(self.test_path)


def make_config(sim_options=None, generics=None, verilog=False):
"""
Utility to reduce boiler plate in tests
"""
cfg = mock.Mock(spec=Configuration)
cfg.library_name = "lib"

if verilog:
cfg.entity_name = "tb"
cfg.architecture_name = None
else:
cfg.entity_name = "tb"
cfg.architecture_name = "test"

cfg.sim_options = {} if sim_options is None else sim_options
cfg.generics = {} if generics is None else generics
cfg.vhdl_configuration_name = None
cfg.vhdl_assert_stop_level = "error"
return cfg
2 changes: 1 addition & 1 deletion vunit/about.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,4 @@ def version():
return VERSION


VERSION = "5.0.0.dev4"
VERSION = "5.0.0.dev5"
2 changes: 1 addition & 1 deletion vunit/persistent_tcl_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def read_var(self, varname):
return consumer.var

def read_bool(self, varname):
result = self.read_var(varname)
result = self.read_var(varname).lower()
assert result in ("true", "false")
return result == "true"

Expand Down
Loading

0 comments on commit 64b08d3

Please sign in to comment.