SystemVerilog DPI usage process based on Questasim

1. Preface

DPI is the abbreviation of Direct Programming Interface, which provides an interface for SystemVerilog to interact with other programming languages (especially C language). It allows programmers to easily call C functions from SystemVerilog, and C functions can also call Systemverilog functions.

DPI greatly facilitates the use of existing C code. You can use the import “DPI-C” statement to call C-implemented functions from SystemVerilog. Such functions are called imported tasks or functions, and all imported tasks or functions must be declared. Functions or tasks implemented in SystemVerilog and exported through export “DPI-C” can be called by C. These tasks and functions are called exported tasks or functions. I won’t go into details about other specific DPI syntax here. This article describes how to compile and use Systemverilog’s DPI process in Questasim. The correct usage process is as follows:

2. Code example

Let’s take a simple Questasim DPI example to demonstrate how to object to each other’s functions in SystemVerilog and C language.

First, we need to create a C function and place it in a file called “dpi_example.c”:

#include "dpi_example.h"
void c_func(int a, int b, int* c) {
    *c = a + b;
    sv_func();
}

The first line of the include file will be automatically generated from the export/import “DPI-C” content using Questasim’s vlog. We only need to specify the generated file name dpi_example.h in the vlog parameter -dpiheader. Of course, it can also It’s another name, as long as it matches the file name after include in the c file. The fourth line of sv_func() will be introduced later. It is a SystemVerilog function that is provided to C function calls through export “DPI-C”. The c_func function calculates the value of a plus b and calls the sv_func function.

Next, call the C function using DPI in SystemVerilog. Place the following code in a file named “dpi_example.sv”:

module dpi_example;
    import "DPI-C" context function void c_func(int a, int b, output int c);
    export "DPI-C" function sv_func;
    initial begin
        int a = 600;
        int b = 66;
        int c;
        c_func(a, b, c);
        $display("c_func result: The sum of a(\r) and b(\r) is c(\r)", a, b, c);
    end
    function void sv_func();
        $display("sv_func is called by c code");
    endfunction
endmodule

Lines 2 and 3 are the key to DPI. import “DPI-C” imports C functions into the scope of SystemVerilog, and export “DPI-C” exports SystemVerilog functions or tasks into the scope of C. In line 8, the C function c_func is called to calculate the addition of variable a and variable b, and the result is passed to variable c. Line 9 prints out the result of c_func. The sv_func here is exported to the previous C code through export “DPI-C”.

3. Run command

Make sure that the workstation has a license for Questasim and the C compiler, use Questasim for simulation, and run the following command in the terminal:

Step 1: Run the vlog command to generate the dpi_example.h header file

vlog -dpiheader dpi_example.h dpi_example.sv

This file defines the interface between C and Questasim for exporting and importing tasks and functions. dpi_example.h is not actually a required file, but including dpi_example.h in your C code can resolve problems caused by incorrectly defined interfaces more quickly. An example command to create dpi_example.h is:

vlog will automatically extract the export/import “DPI-C” content in dpi_example.sv to generate the dpi_example.h header file. After generating it, you can open this file and take a look.

Questasim recommends that any user DPI C code that exports/imports “DPI-C” should be included in dpi_example.h to facilitate the C compiler to verify the interface between C and Questasim.

Step 2: Run the vlog command to compile C code

vlog dpi_example.c

C/C++ files can be specified on the vlog command line, which invokes the correct C/C++ compiler based on the file type passed in. The vlog command compiles all Systemverilog files and c/c++ files into the work library. The vsim command automatically loads the compiled C code during the elaboration phase. Specified C compiler options can be passed to vlog using the -ccflags option, vlog will not check the validity of the options you specify with -ccflags. These options are passed directly to the compiler, and if they are invalid, an error message is generated by the C compiler. C/C++ files and options can also be specified in -f files and they will be processed in the same way as Systemverilog files and options in -f files. You can also use the -ldflags option to pass the specified c/c++ linker options to vsim, and vsim will pass the specified options to the linker for resolution.

Step 3: Start simulation and run vsim command

vsim dpi_example -c -do “run -all; quit”

Step 4: Summarize the above steps and results

# Execute command:
vlib work
vlog -dpiheader dpi_example.h dpi_example.sv
vlogdpi_example.c
vsim dpi_example -c -do "run -all; quit"
# operation result:
run-all
sv_func is called by c code
c_func: The sum of a(600) and b(66) is c(666)
quit

4. Others

As an additional topic, Questasim supports passing external compiled C code directly to vsim for simulation, without the need for vlog to be compiled again. The DPI library can be specified to the vsim command using the following vsim parameters.

Parameters Description
-sv_lib Specifies the library name to search and use. There is no need to specify a filename extension. (Questasim expected extensions are: .dll for Win32/Win64, .so for all other platforms.)
-sv_root Specify a new prefix for the shared object, specified by -sv_lib
-sv_liblist Specify the The “bootstrap file” used, the format of is as follows:
#!SV_LIBRARIES /// //

No extensions are required on the shared library.

When the emulator discovers an imported task or function, it looks for it in the collection of shared objects specified using these parameters. For example you can specify the following DPI library:

vsim -sv_lib dpiapp1 -sv_lib dpiapp2 -sv_lib dpiappn top

In addition, it is an error to specify the functions and tasks imported by DPI in the PLI/VPI shared object. However, DPI import functions and tasks can call PLI/VPI code, provided that vsim -gblso is used to mark the PLI/VPI shared object in a globally visible manner.