Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/python_bridge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ jobs:
python -m venv "$RUNNER_TEMP/venv with space"
echo "$RUNNER_TEMP/venv with space/bin" >> "$GITHUB_PATH"
"$RUNNER_TEMP/venv with space/bin/pip" install -e . pytest --progress-bar off
# TEMPORARY: VUnit with dict_pkg get_key/get_value_type, until VUnit/vunit#1229 is released
"$RUNNER_TEMP/venv with space/bin/pip" install "vunit_hdl @ git+https://github.com/VUnit/vunit.git@refs/pull/1229/head" --progress-bar off

- name: '🚧 Python unit tests'
run: python -m pytest tests/test_python_bridge.py
Expand Down Expand Up @@ -173,6 +175,8 @@ jobs:
python -m venv "$RUNNER_TEMP/venv with space"
echo "$RUNNER_TEMP/venv with space/Scripts" >> "$GITHUB_PATH"
"$RUNNER_TEMP/venv with space/Scripts/pip" install -e . --progress-bar off
# TEMPORARY: VUnit with dict_pkg get_key/get_value_type, until VUnit/vunit#1229 is released
"$RUNNER_TEMP/venv with space/Scripts/pip" install "vunit_hdl @ git+https://github.com/VUnit/vunit.git@refs/pull/1229/head" --progress-bar off

# The simulator is accepted as x64, and a 32-bit executable of Windows itself is detected
- name: '🔍 64-bit check'
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/wheel_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ jobs:
scripts="$RUNNER_TEMP/venv/$([ "$RUNNER_OS" = Windows ] && echo Scripts || echo bin)"
echo "$scripts" >> "$GITHUB_PATH"
"$scripts/pip" install dist/*.whl --progress-bar off
# TEMPORARY: VUnit with dict_pkg get_key/get_value_type, until VUnit/vunit#1229 is released
"$scripts/pip" install "vunit_hdl @ git+https://github.com/VUnit/vunit.git@refs/pull/1229/head" --progress-bar off

- name: '🚧 Feature tests against the installed wheel'
run: |
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ the selected simulator by a foreign language interface the package builds itself
called through VHPIDIRECT (NVC, GHDL) or the FLI (Questa/ModelSim), or a VHPI application built with
the simulator's own compiler driver (Riviera-PRO/Active-HDL). Values cross the interface with their
VHDL types: `integer`, `real`, `string`, `boolean`, `std_ulogic`, `unsigned`/`signed`, the vector
types, and `integer_array_t` as a NumPy array.
types, `integer_array_t` as a NumPy array, and VUnit's `dict_t` as a Python `dict`.

## Installation

Expand Down
48 changes: 45 additions & 3 deletions docs/user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ bridge, ``eval`` has more result types:
* ``eval_std_ulogic_vector``, returning an unconstrained ``std_ulogic_vector``.
* ``eval_integer_array``, returning ``integer_array_t``, see
:ref:`python_bridge:integer_array`.
* ``eval_dict``, returning ``dict_t``, see :ref:`python_bridge:dict`.

``eval_boolean`` and ``eval_std_ulogic`` are aliased ``eval`` like the other
result types. ``eval_std_ulogic_vector`` and ``eval_integer_array`` are not,
Expand Down Expand Up @@ -330,6 +331,7 @@ VHDL Python
``unsigned`` ``int``, passed as ``arg_unsigned``/``kwarg_unsigned``
``signed`` ``int``, passed as ``arg_signed``/``kwarg_signed``
``integer_array_t`` NumPy array, not on Riviera-PRO/Active-HDL
``dict_t`` ``dict`` with ``str`` keys, see :ref:`python_bridge:dict`
========================== ========================================================

An ``unsigned`` or ``signed`` value of any width becomes an exact Python
Expand Down Expand Up @@ -367,7 +369,7 @@ passed as a number or as the string of its characters:

On NVC, GHDL and Questa, ``call`` returns the same types as ``eval``:
``call_boolean``, ``call_std_ulogic``, ``call_std_ulogic_vector``,
``call_integer_array``, ``call_string``, ``call_real_vector`` and
``call_integer_array``, ``call_dict``, ``call_string``, ``call_real_vector`` and
``call_integer_vector_ptr``, plus the procedures ``call_std_ulogic_vector``,
``call_signed`` and ``call_unsigned`` taking the result as an ``out``
parameter. All of the functions but ``call_std_ulogic_vector`` are aliased
Expand Down Expand Up @@ -490,6 +492,8 @@ Type mapping
* ``signed``/``unsigned`` ↔ ``int`` (procedure results only, Python bridge).
* ``integer_array_t`` ↔ ``numpy.ndarray`` (Python bridge), see
:ref:`python_bridge:integer_array`.
* ``dict_t`` ↔ ``dict`` (results need the Python bridge), see
:ref:`python_bridge:dict`.

The types marked as needing the Python bridge are available on NVC, GHDL and
Questa, but not on Riviera-PRO/Active-HDL.
Expand Down Expand Up @@ -524,6 +528,44 @@ the failure.
Output of ``print`` is written to the simulator output and flushed after
every operation.

.. _python_bridge:dict:

dict_t and dict
---------------

A ``dict_t`` from VUnit's ``dict_pkg`` (string keys, values of mixed types) is
a Python ``dict``. As an argument, ``arg(dict)`` and ``kwarg("name", dict)``
write the ``dict`` as the Python literal ``{"key": value, ...}``, which works
on all simulators. The values are ``integer``, ``real``, ``string``,
``boolean``, ``std_ulogic``, ``integer_vector``, ``real_vector``,
``integer_vector_ptr_t`` and nested ``dict_t``. Any other value type is
reported like any other argument that cannot be converted. The keys are
visited in the order of ``get_key``, which VUnit does not specify.

.. code-block:: vhdl

constant cfg : dict_t := new_dict;
set_integer(cfg, "taps", 8);
set_real(cfg, "gain", 0.5);
call("model.configure", arg(cfg));

``eval_dict`` and ``call_dict`` (aliased ``eval`` and ``call``) convert a
Python ``dict`` with ``str`` keys to a new ``dict_t`` that the caller owns and
deallocates. The values are converted strictly: ``int`` to ``integer``,
``float`` to ``real``, ``str`` to ``string``, ``bool`` to ``boolean``, a
``list`` of ``int`` to ``integer_vector_ptr_t`` and a ``dict`` to a nested
``dict_t``, the last two stored with ``set_integer_vector_ptr_t_ref`` and
``set_dict_t_ref``. ``None``, an ``int`` outside the VHDL integer range, a key
that is not a ``str`` or any other value is an error, and ``eval_dict`` then
returns an empty ``dict_t`` after reporting it. ``eval_dict`` and ``call_dict``
are implemented by the Python bridge: Riviera-PRO/Active-HDL reports that they require NVC, GHDL or
Questa.

.. code-block:: vhdl

constant result : dict_t := eval("{'name': 'fir', 'taps': [1, 2, 1], 'gain': 0.5}");
check_equal(get_string(result, "name"), "fir");

.. _python_bridge:integer_array:

integer_array_t and NumPy
Expand Down Expand Up @@ -629,8 +671,8 @@ simulator installation change, so a run script needs nothing beyond

This application differs from the Python bridge in a few ways: only the
default session exists, the operations implemented by the bridge
(``integer_array_t`` values, the ``boolean``, ``std_ulogic``, vector and
``integer_array_t`` results, ``exec_file``) report that they require NVC, GHDL
(``integer_array_t`` values, the ``boolean``, ``std_ulogic``, vector,
``integer_array_t`` and ``dict_t`` results, ``exec_file``) report that they require NVC, GHDL
or Questa, a Python error stops the simulation with the message printed by the
application rather than through the logger of the session, and ``real`` values
outside the single precision float range are rejected.
Expand Down
1 change: 1 addition & 0 deletions src/vunit_python_bridge/hdl/src/python_ffi_pkg_bridge.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ package python_ffi_pkg is
constant p_kind_integer_array : integer := 8;
constant p_kind_integer_vector : integer := 9;
constant p_kind_real_vector : integer := 10;
constant p_kind_dict : integer := 11;

-- Names of the operations, used in the error messages
impure function p_exec_operation(session : python_session_t := default_session) return string;
Expand Down
Loading
Loading