Summary
An integer_array_t argument made during elaboration crashes the simulation before it starts. arg(value : integer_array_t) and kwarg(kw, value : integer_array_t) transfer the array to Python when the argument is made, by calling into the bridge library. During elaboration, for example in a constant declaration, the library isn't loaded and the interpreter can't run, so the simulator aborts.
Reproduction
library vunit_lib;
context vunit_lib.vunit_context;
library python_bridge;
context python_bridge.python_context;
entity tb_elaboration_array is
generic(runner_cfg : string);
end entity;
architecture tb of tb_elaboration_array is
impure function one_to_four return integer_array_t is
variable values : integer_array_t := new_1d(4);
begin
for idx in 0 to 3 loop
set(values, idx, idx + 1);
end loop;
return values;
end;
-- The array is transferred here, during elaboration
constant values_arg : arg_t := arg(one_to_four);
begin
main : process
begin
test_runner_setup(runner, runner_cfg);
check_equal(integer'(call("sum", values_arg)), 10);
test_runner_cleanup(runner);
end process;
end architecture;
Observed
Every test case of the testbench fails before simulation starts:
- NVC:
** Fatal: (init): foreign function vpy_push_array not found
- GHDL (mcode):
raised CONSTRAINT_ERROR : synth-vhdl_foreign.adb:267 index check failed
Making the same argument in a process, at run time, works.
Expected
Either it works, or there's a clear error naming the argument. A crash with a simulator-internal message is hard to trace back to arg.
Notes
- Affected: every elaboration-time use of
arg/kwarg with an integer_array_t, for example constants in an architecture or a package, and generics computed from them. The other value types build Python source text only and are fine during elaboration.
- Possible fix: defer the transfer.
p_arg_value(integer_array_t) could put a reference to the VHDL array in the argument's text instead of staging it, and the send path (p_exec/p_eval) could stage the referenced arrays just before the text is sent. Arguments would then work wherever they're made. Every use would transfer its own copy, which matches the documented "every use gets its own copy" behaviour.
- Simpler alternative: document the restriction and report it clearly. It's hard to detect elaboration from VHDL, though, so the deferred transfer looks like the better fix.
🤖 Generated with Claude Code
Summary
An
integer_array_targument made during elaboration crashes the simulation before it starts.arg(value : integer_array_t)andkwarg(kw, value : integer_array_t)transfer the array to Python when the argument is made, by calling into the bridge library. During elaboration, for example in a constant declaration, the library isn't loaded and the interpreter can't run, so the simulator aborts.Reproduction
Observed
Every test case of the testbench fails before simulation starts:
** Fatal: (init): foreign function vpy_push_array not foundraised CONSTRAINT_ERROR : synth-vhdl_foreign.adb:267 index check failedMaking the same argument in a process, at run time, works.
Expected
Either it works, or there's a clear error naming the argument. A crash with a simulator-internal message is hard to trace back to
arg.Notes
arg/kwargwith aninteger_array_t, for example constants in an architecture or a package, and generics computed from them. The other value types build Python source text only and are fine during elaboration.p_arg_value(integer_array_t)could put a reference to the VHDL array in the argument's text instead of staging it, and the send path (p_exec/p_eval) could stage the referenced arrays just before the text is sent. Arguments would then work wherever they're made. Every use would transfer its own copy, which matches the documented "every use gets its own copy" behaviour.🤖 Generated with Claude Code