Skip to content

integer_array_t argument made during elaboration crashes the simulation #17

Description

@ru551n

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions