Skip to content

Commit 7973178

Browse files
authored
Report integer_array_t arguments made during elaboration as a failure (#29)
Report integer_array_t arguments made during elaboration as a failure An integer_array_t argument is transferred to Python when it is made, which the bridge library cannot do during elaboration: NVC aborted with "foreign function vpy_push_array not found" and GHDL with a CONSTRAINT_ERROR. Before test_runner_setup, p_stage_array now reports a failure naming the call instead. See #17.
1 parent 4dd5183 commit 7973178

5 files changed

Lines changed: 65 additions & 2 deletions

File tree

‎docs/types.rst‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,11 @@ integer_array_t and NumPy
3737

3838
An ``integer_array_t`` argument is transferred to Python and referred to by
3939
the expression as a NumPy array of dtype ``int32``, so it can be reused in
40-
several calls. It is indexed like VUnit, so that elements correspond
41-
directly:
40+
several calls. Since it is transferred when the argument is made, the
41+
argument must be made after ``test_runner_setup``, not during elaboration, for
42+
example in a constant. Otherwise ``arg`` and ``kwarg`` report a failure, see
43+
`#17 <https://github.com/VUnit/vunit-python-bridge/issues/17>`__. It is
44+
indexed like VUnit, so that elements correspond directly:
4245

4346
============= ================================ ===========================
4447
Array VHDL Python

‎release_notes/news.d/29.bugfix.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
An `integer_array_t` argument made before `test_runner_setup`, for example in a constant during elaboration, is reported as a failure naming the call, instead of crashing the simulator (NVC: "foreign function vpy_push_array not found", GHDL: CONSTRAINT_ERROR). See #17.

‎src/vunit_python_bridge/hdl/src/python_ffi_pkg_bridge.vhd‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ use vunit_lib.id_pkg.all;
2626
use vunit_lib.integer_array_pkg.all;
2727
use vunit_lib.integer_vector_ptr_pkg.all;
2828
use vunit_lib.logger_pkg.all;
29+
use vunit_lib.run_pkg.get_phase;
30+
use vunit_lib.run_types_pkg.all;
2931
use work.python_bridge_pkg.all;
3032

3133
package python_ffi_pkg is
@@ -412,6 +414,14 @@ package body python_ffi_pkg is
412414
variable offset, n : natural := 0;
413415
variable staged_id : integer;
414416
begin
417+
if get_phase < test_runner_setup then
418+
failure(
419+
python_logger,
420+
operation & " failed:" & LF &
421+
"An integer_array_t argument cannot be made before test_runner_setup."
422+
);
423+
return -1;
424+
end if;
415425
if not p_succeeded(
416426
vpy_push_array(len, width(arr), height(arr), depth(arr), bit_width(arr), boolean'pos(is_signed(arr))),
417427
operation

‎tests/run.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
"lib.tb_python_pkg.Test eval of real with underflow from C to VHDL",
4040
]
4141

42+
# Fails during elaboration, with this error rather than a crash, see #17
43+
ELABORATION_ARRAY_TEST = "lib.tb_elaboration_array.all"
44+
ELABORATION_ARRAY_ERROR = "An integer_array_t argument cannot be made before test_runner_setup"
45+
4246
# Simulators where python_pkg is implemented by the VUnit Python bridge
4347
BRIDGE_SIMULATORS = ["nvc", "ghdl", "modelsim"]
4448

@@ -67,6 +71,11 @@ def verify(results, expected_failures):
6771
if missing:
6872
raise RuntimeError("Tests expected to fail but did not:\n" + "\n".join(missing))
6973

74+
if ELABORATION_ARRAY_TEST in expected and ELABORATION_ARRAY_ERROR not in (
75+
tests[ELABORATION_ARRAY_TEST].path / "output.txt"
76+
).read_text(encoding="utf-8"):
77+
raise RuntimeError(f"{ELABORATION_ARRAY_TEST} failed without the error: {ELABORATION_ARRAY_ERROR}")
78+
7079
if expected:
7180
print(f"Verified {len(expected)} expected failures: {', '.join(name.split('.')[-1] for name in expected)}")
7281

@@ -113,6 +122,8 @@ def main():
113122
if simulator_name in BRIDGE_SIMULATORS:
114123
# The operations implemented by the Python bridge
115124
lib.add_source_file(ROOT / "tb_python_pkg_bridge.vhd")
125+
lib.add_source_file(ROOT / "tb_elaboration_array.vhd")
126+
expected_failures.append(ELABORATION_ARRAY_TEST)
116127

117128
vu.set_compile_option("rivierapro.vcom_flags", ["-dbg"])
118129
vu.set_sim_option("rivierapro.vsim_flags", ["-interceptcoutput"])

‎tests/tb_elaboration_array.vhd‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
-- This Source Code Form is subject to the terms of the Mozilla Public
2+
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
3+
-- You can obtain one at http://mozilla.org/MPL/2.0/.
4+
--
5+
-- Copyright (c) 2014-2026, Lars Asplund lars.anders.asplund@gmail.com
6+
--
7+
-- An integer_array_t argument made during elaboration must fail with a clear
8+
-- error, not crash the simulator, see #17. tests/run.py expects it to fail
9+
-- and checks the error.
10+
11+
library vunit_lib;
12+
context vunit_lib.vunit_context;
13+
library python_bridge;
14+
context python_bridge.python_context;
15+
16+
entity tb_elaboration_array is
17+
generic(runner_cfg : string);
18+
end entity;
19+
20+
architecture tb of tb_elaboration_array is
21+
impure function one_to_four return integer_array_t is
22+
variable values : integer_array_t := new_1d(4);
23+
begin
24+
for idx in 0 to 3 loop
25+
set(values, idx, idx + 1);
26+
end loop;
27+
return values;
28+
end;
29+
30+
constant values_arg : arg_t := arg(one_to_four);
31+
begin
32+
main : process
33+
begin
34+
test_runner_setup(runner, runner_cfg);
35+
check_equal(integer'(call("sum", values_arg)), 10);
36+
test_runner_cleanup(runner);
37+
end process;
38+
end architecture;

0 commit comments

Comments
 (0)