Skip to content

Commit

Permalink
Added documentation for the handling of VHDL configurations.
Browse files Browse the repository at this point in the history
  • Loading branch information
LarsAsplund committed Jan 1, 2022
1 parent 6bc3001 commit d1330d6
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 13 deletions.
29 changes: 20 additions & 9 deletions docs/py/ui.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,31 @@ pre_config and post_check :ref:`callback functions <pre_and_post_hooks>`.
User :ref:`attributes <attributes>` can also be added as a part of a
configuration.

Configurations can either be unique for each test case or must be
common for the entire test bench depending on the situation. For test
benches without test such as `tb_example` in the User Guide the
configuration is common for the entire test bench. For test benches
containing tests such as `tb_example_many` the configuration is done
for each test case. If the ``run_all_in_same_sim`` attribute has been used
VHDL configurations for test bench entities are automatically discovered
and added to the set of configurations created in Python.

Python-defined configurations can either be unique for each test case or
must be common for the entire test bench depending on the situation.
For test benches without tests such as `tb_example` in the User Guide
the configuration is common for the entire test bench. For test benches
containing tests such as `tb_example_many` the configuration is done for
each test case. If the ``run_all_in_same_sim`` attribute has been used
configuration is performed at the test bench level even if there are
individual test within since they must run in the same simulation.

In a VUnit all test benches and test cases are created with an unnamed default
In VUnit all test benches and test cases are created with an unnamed default
configuration which is modified by different methods such as ``set_generic`` etc.
In addition to the unnamed default configuration multiple named configurations
can be derived from it by using the ``add_config`` method. The default
configuration is only run if there are no named configurations.
can be derived from it by using the ``add_config`` method or by defining a
VHDL configuration. The default configuration is only run if there are no
named configurations.

Named configurations can be retrieved from test benches and tests using the
``get_configs`` methods and then modified using methods such as ``set_pre_config``.
This is especially useful for VHDL configurations which are automatically
detected and added without any of the configuration capabilities provided
by the Python API. Note that generics can't be added to a VHDL-defined
configuration as that is not allowed in VHDL.

.. _attributes:

Expand Down
8 changes: 7 additions & 1 deletion docs/py/vunit.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ Test

.. autoclass:: vunit.ui.test.Test()

Configuration
-------------

.. autoclass:: vunit.ui.configuration.Configuration()
:inherited-members:

Results
-------

Expand All @@ -46,4 +52,4 @@ Results
The name of the simulation option (See :ref:`Simulation options <sim_options>`)

.. |configurations| replace::
:ref:`configurations <configurations>`
:ref:`configurations <configurations>`
42 changes: 39 additions & 3 deletions docs/run/user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ A (close to) minimal VUnit testbench looks like this
context vunit_lib.vunit_context;
entity tb_minimal is
generic (runner_cfg : string := runner_cfg_default);
generic (runner_cfg : string);
end entity;
architecture tb of tb_minimal is
Expand All @@ -40,8 +40,7 @@ It has the following important properties

- The VUnit functionality is located in the ``vunit_lib`` library and is included with the library and context
statements in the first two lines.
- The ``runner_cfg`` generic is used to control the testbench from PR. If the testbench is used standalone you will
need a default value, ``runner_cfg_default``, for the generic. Note that the generic **must** be named
- The ``runner_cfg`` generic is used to control the testbench from PR. Note that the generic **must** be named
``runner_cfg`` for the testbench to be recognized by PR (there is an exception which we'll get to later).
- Every VUnit testbench has a main controlling process. It's labelled ``test_runner`` in this example but the name
is not important. The process starts by setting up VUnit using the ``test_runner_setup`` procedure with
Expand Down Expand Up @@ -637,6 +636,43 @@ the ability to read error counters based on assert statements. Failures like div
operations are other examples that won't be handle gracefully in this mode and not something that VHDL-2017 will
solve.

Testbenches with VHDL Configurations
------------------------------------

If there are VHDL configurations defined for the testbench entity, each configuration, and not the testbench
entity, defines a top-level for the simulation. VUnit automatically detects these VHDL configurations and treat
them as a special case of the larger testbench configuration concept provided by VUnit, see
:ref:`configurations <configurations>`.

VHDL doesn't allow setting generics when the top-level is a VHDL configuration which prevents the `runner_cfg`
generic to be set by PR. To work around this limitation PR provides a `runner.cfg` file containing the same
information. This file is read by `test_runner_setup` whenever its `runner_cfg` parameter is set to
`null_runner_cfg`. An example is shown below.

.. code-block:: vhdl
library vunit_lib;
context vunit_lib.vunit_context;
entity tb_minimal is
generic (runner_cfg : string := null_runner_cfg);
end entity;
architecture tb of tb_minimal is
begin
test_runner : process
begin
test_runner_setup(runner, runner_cfg);
...
test_runner_cleanup(runner);
end process;
end architecture;
Note that the `runner_cfg` generic must remain present since this is the token used by VUnit test scanning
to distinguish testbench entities from other entities.

Special Paths
-------------

Expand Down
4 changes: 4 additions & 0 deletions vunit/ui/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def get_configuration_dicts(self):
return self._selected_cfg_dicts

def add_config(self, *args, **kwargs):
"""
This method is inherited from the superclass but not defined for this class. New
configurations are added to :class:`.TestBench` or :class:`.Test` objects.
"""
raise RuntimeError(
f"{type(self)} do not allow addition of new configurations, only modification of existing ones."
)
6 changes: 6 additions & 0 deletions vunit/ui/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ def add_config( # pylint: disable=too-many-arguments
)

def get_configs(self, pattern="*"):
"""
Get test configurations matching pattern.
:param pattern: A wildcard pattern matching the configuration name(s).
:returns: A :class:`.Configuration` object
"""
return Configuration(self._test_case, pattern)

def set_attribute(self, name, value):
Expand Down
6 changes: 6 additions & 0 deletions vunit/ui/testbench.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ def add_config( # pylint: disable=too-many-arguments
)

def get_configs(self, pattern="*"):
"""
Get test bench configurations matching pattern.
:param pattern: A wildcard pattern matching the configuration name(s).
:returns: A :class:`.Configuration` object
"""
return Configuration(self._test_bench, pattern)

def test(self, name):
Expand Down

0 comments on commit d1330d6

Please sign in to comment.