logo elektroda
logo elektroda
X
logo elektroda

QuestaSim SystemVerilog DPI-C: How to Call and Run C Functions in Testbenches

User question

add c function call and run with questa

Artificial Intelligence Response

Direct answer to the question

• Use the SystemVerilog Direct-Programming-Interface for C (DPI-C).
• Write your C function, compile it into a 64-bit position-independent shared object (*.so on Linux, *.dll on Windows).
• Declare the function in your SystemVerilog test-bench using import "DPI-C" ….
• Compile both the C and SV files with Questa vlog, link (or autolink) the shared object, and start the simulation with vsim … -sv_lib <lib_name>.

Key commands (Linux, Questa 2023.3 or newer):

vlib work
vlog -dpiheader dpi_hdr.h dpi_func.c tb_top.sv # compile & autolink
vsim -c work.tb_top -do "run -all; quit" # or vsim -sv_lib dpi_func …

Detailed problem analysis

  1. Why DPI-C
    • Lowest overhead: no VPI start-up registration, direct function call semantics.
    • Part of IEEE-1800-2023; supported by all current Questa/ModelSim editions.

  2. Data type ­mapping (extract of the official table) SystemVerilog type C type in svdpi.h Notes
    byte signed char / PLI_INT8 8-bit
    int int / PLI_INT32 32-bit
    bit/logic [31:0] unsigned int ≤32
    dynamic / unpacked array const svOpenArrayHandle use helper accessors
  3. Complete minimal example

    3.1 C domain (dpi_func.c)

    #include <stdio.h>
    #include "svdpi.h" // always include!
    /* Simple checksum over byte array */
    unsigned char calc_cksum(const svOpenArrayHandle data, int n)
    {
    unsigned char crc = 0;
    for (int i = 0; i < n; ++i) {
    unsigned char *b = (unsigned char *) svGetArrElemPtr1(data,i);
    crc ^= *b;
    }
    printf("[C] calc_cksum(%d) returns 0x%02X\n", n, crc);
    return crc;
    }

    3.2 SystemVerilog domain (tb_top.sv)

    import "DPI-C" function byte calc_cksum(input byte pkt[], input int n);
    module tb_top;
    byte pkt[]; // dynamic array
    byte sv_crc, c_crc;
    initial begin
    pkt = new[8]; pkt = '{8'hA1,8'hB2,8'hC3,8'hD4,8'hE5,8'hF6,8'h01,8'h02};
    sv_crc = ^pkt; // SV side reference
    c_crc = calc_cksum(pkt, pkt.size()); // DPI-C call
    $display("[SV] crc(SV)=0x%02h crc(C)=0x%02h", sv_crc, c_crc);
    if (sv_crc!==c_crc) $fatal(1,"Mismatch");
    $finish;
    end
    endmodule
  4. Build + run (Linux, gcc):

    export MTI_HOME=/opt/questa # adjust
    vlib work
    vlog -cc gcc \ # let Questa invoke gcc
    -dpiheader dpi_hdr.h \
    -sv tb_top.sv dpi_func.c # both sources
    vsim -c work.tb_top -do "run -all; quit"

    Output excerpt:

    [C] calc_cksum(8) returns 0x5E
    [SV] crc(SV)=0x5e crc(C)=0x5e

    The same flow works on Windows by replacing gcc with cl and the shared object with a .dll.

  5. Alternative linking method (manual)

    gcc -fPIC -shared -I$MTI_HOME/include -o libdpi.so dpi_func.c
    vlog tb_top.sv
    vsim work.tb_top -sv_lib libdpi
  6. Debugging & stepping
    • From Questa 2022.4 upwards the GUI can single-step into imported DPI functions when they were compiled with -g and vsim –debugdb.
    • Use setenv LD_PRELOAD or export MTI_DPI_DEBUG=1 for run-time symbol diagnostics.

  7. Typical pitfalls
    • Signature mismatch (wrong types/order) → linker error: “undefined import”.
    • 32-bit versus 64-bit library mismatch; make sure to compile with -m64 if your Questa is 64-bit.
    • Blocking forever inside C code stalls the whole simulator time wheel.
    • Forgetting #include "svdpi.h" means you lose the portable typedefs.

  8. When DPI-C is not enough
    • Need callback into simulation time or hierarchical access → use VPI (PLI-1) or FLI (VHDL).
    • Mixed-language with SystemC → use SLI (vsim -sc), or co-simulation tools.


Current information and trends

• Siemens EDA (Questa 2023.4) adds automatic C++ name-mangling resolution (-dpicpp).
• The new -dpi_tb_compile switch lets you pre-compile DPI code once and cache it for regressions.
• Growing adoption of portable test-benches that re-use DPI models inside cocotb / Verilator → keep your API clean and stateless.


Supporting explanations and details

svGetArrElemPtr1 is zero-copy: the C code manipulates the simulator’s memory directly—fast but dangerous; never keep a dangling pointer after the call returns.
svOpenArrayHandle can handle multi-dimensional arrays via svDimensions(handle) and svLeft/Right/Size.
• To export a SystemVerilog task to C, write export "DPI-C" task sv_task; and call it from C, remembering to set the correct scope with svSetScope.


Ethical and legal aspects

• Proprietary IP inside C models may require encryption or obfuscation—ensure your usage complies with NDAs and export regulations.
• Simulator licences (Questa Core vs. Questa Prime) have different DPI capability levels; distributing pre-compiled .so to partners might violate EULA.
• Always disclose in safety-critical projects that parts of the functional model execute outside strict RTL semantics.


Practical guidelines

• Keep DPI libraries modular: one shared object per verification domain (e.g. math, codec, crypto).
• Version-stamp your library (printf("Build: %s %s\n", __DATE__,__TIME__)).
• Add -Wextra -Wall -pedantic -g while developing; drop -g for regression speed.
• Use CI scripts (Makefile, CMake, pyflow) to rebuild automatically whenever SV imports change.

Potential challenges & mitigation Issue Mitigation
Simulator cannot find .so LD_LIBRARY_PATH=. vsim -sv_lib …
Mixed stdc++ ABI Compile with the same gcc major version as the simulator.
Memory leaks Run under valgrind --tool=memcheck vsim …

Possible disclaimers or additional notes

• Examples assume Linux 64-bit. File extensions .so.dll (Win) ↔ .dylib (macOS, limited support).
• Older ModelSim PE (<= 10.5) lacks the integrated gcc front-end; use manual compilation.
• Some university editions disable DPI entirely.


Suggestions for further research

• IEEE 1800-2023 Clause 35 (DPI): definitive reference.
• Siemens App-Note UG900720 “DPI-C Cookbook” (2023).
• Explore co-simulation frameworks (SystemC TLM-2.0, Python cocotb) that reuse the same DPI mechanism.
• Investigate the foreign_lib mechanism in VHDL-2008 for mixed VHDL/C designs within Questa.


Brief summary

Directly call C from SystemVerilog in Questa by

  1. writing the C code,
  2. compiling it into a shared object with svdpi.h,
  3. importing the function in SV (import "DPI-C"),
  4. compiling/linking with vlog, and
  5. running with vsim while loading the shared object.
    DPI-C offers high performance, minimal boiler-plate, and is the industry-standard mechanism in current Siemens EDA tools; follow the signature rules, keep data types consistent, and compile for the same word size as the simulator.

Ask additional question

Wait...(2min)
Disclaimer: The responses provided by artificial intelligence (language model) may be inaccurate and misleading. Elektroda is not responsible for the accuracy, reliability, or completeness of the presented information. All responses should be verified by the user.