Skip to content

VHPI/VHPIDIRECT not called/available for constant initialization #988

@NikLeberg

Description

@NikLeberg

When I try to initialize a constant in the declaration part of an architecture with a foreign function, regardless of type (VHPI or VHPIDIRECT [aka GHDL]), the simulations fails.

E.g. The following fails if init is a foreign function:

ARCHITECTURE arch OF ent IS
    CONSTANT var : INTEGER := init;
BEGIN
END ARCHITECTURE;

MWE:
file: issue.vhd

ENTITY issue_direct IS
END ENTITY;

ARCHITECTURE sim OF issue_direct IS
    IMPURE FUNCTION init RETURN INTEGER IS
    BEGIN
        REPORT "ERROR" SEVERITY failure;
    END;
    ATTRIBUTE foreign OF init : FUNCTION IS "VHPIDIRECT ./issue.so init";

    CONSTANT var : INTEGER := init;
BEGIN
    ASSERT var = 1 SEVERITY error;
END ARCHITECTURE;

ENTITY issue_indirect IS
END ENTITY;

ARCHITECTURE sim OF issue_indirect IS
    IMPURE FUNCTION init RETURN INTEGER IS
    BEGIN
        REPORT "ERROR" SEVERITY failure;
    END;
    ATTRIBUTE foreign OF init : FUNCTION IS "VHPI issue.so init_vhpi";

    SIGNAL var : INTEGER := init;
BEGIN
    ASSERT var = 1 SEVERITY error;
END ARCHITECTURE;

file: issue.c

int init(void)
{
    return 1;
}

#ifdef USE_VHPI
#include <vhpi_user.h>

static void init_vhpi(const vhpiCbDataT *cb_data)
{
    vhpiValueT value = {.format = vhpiIntVal, .value.intg = 1};
    vhpi_put_value(cb_data->obj, &value, vhpiDepositPropagate);
}

static void register_vhpi(const vhpiCbDataT *cb_data)
{
    vhpiForeignDataT foreign_init = {vhpiFuncF, "issue.so", "init_vhpi", NULL, init_vhpi};
    vhpiHandleT cb_h = vhpi_register_foreignf(&foreign_init);
    vhpi_release_handle(cb_h);
}

void (*vhpi_startup_routines[])() = {
    register_vhpi,
    NULL};
#endif // USE_VHPI

When using VHPIDIRECT:

gcc -shared -fPIC -o issue.so issue.c
nvc -L. -a issue.vhd
nvc -L. -e issue_direct
nvc -L. -r --load ./issue.so issue_direct
** Fatal: foreign function init not found
   Subprogram INIT [return INTEGER] at issue.vhd:9
   Process (init) at issue.vhd:11

When using VHPI:

gcc -shared -fPIC -DUSE_VHPI -o issue.so issue.c
nvc -L. -a issue.vhd
nvc -L. -e issue_indirect
nvc -L. -r --load ./issue.so issue_indirect

*** Caught signal 11 (SEGV_MAPERR) [address=0x60, ip=0x55fc09789e75] ***

[0x55fc09681f0d] ../src/util.c:872 signal_handler
[0x7ffae7ddb51f] (/usr/lib/x86_64-linux-gnu/libc.so.6)
[0x55fc09789e75] ../src/vhpi/vhpi-model.c:4472 __nvc_do_exit
[0x55fc0978afa6] ../src/jit/jit-interp.c:831 interp_loop
[0x55fc0978afa6] ../src/jit/jit-interp.c:1101 jit_interp
[0x55fc0978b7d3] ../src/jit/jit-interp.c:638 interp_loop
[0x55fc0978b7d3] ../src/jit/jit-interp.c:1101 jit_interp
[0x55fc09775a0b] ../src/jit/jit-core.c:666 jit_try_vcall.lto_priv.0
[0x55fc09776bdf] ../src/jit/jit-core.c:728 jit_try_call
[0x55fc096e4332] ../src/eval.c:424 eval_instance
[0x55fc096e4332] ../src/eval.c:1425 elab_lower.lto_priv.0
[0x55fc096e5ed1] ../src/elab.c:1536 elab_architecture.lto_priv.0
[0x55fc097c2f74] ../src/elab.c:2313 elab.constprop.0
[0x55fc09688d62] ../src/nvc.c:476 elaborate
[0x55fc096862ca] ../src/nvc.c:2115 process_command
[0x55fc0967e687] ../src/nvc.c:2257 main

nvc 1.14.0 (1.14.0.r0.g157b0f6) (Using LLVM 14.0.0) [x86_64-pc-linux-gnu]

Please report this bug at https://github.com/nickg/nvc/issues

In both cases, if I use the following structure as workaround, the simulation works fine:

ARCHITECTURE sim OF ent IS
   -- ...
    SIGNAL var : INTEGER := 0;
BEGIN
    PROCESS IS
    BEGIN
        var <= init;
        WAIT FOR 1 ns;
        ASSERT var = 1 SEVERITY error;
        WAIT;
    END PROCESS;
END ARCHITECTURE;
nvc --version
nvc 1.14.0 (1.14.0.r0.g157b0f6) (Using LLVM 14.0.0)
...

If I test with GHDL, the direct one is simulating correctly.

Thanks!

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions