SystemVerilog: How to connect C function using DPI call in VCS simulator?

15.6k Views Asked by At

I have the following files:

C file with functions:

// funcs.c

#include <stdio.h>

void something() {
    printf("something\n");
    sayHello();
}

System verilog file:

// hello_world.v

module kuku;
    export "DPI-C" function sayHello;
    import "DPI-C" function void something();
    initial something();
    function int sayHello ();
        $display("hello world");
        sayHello = 1;
    endfunction
endmodule

How can I compile it and make this work so when I call something() from SV, it will call the C function, and when I call sayHello() from C, it will call the SV function?

4

There are 4 best solutions below

1
On BEST ANSWER

Answering myself:

When SV code is compiled using VCS, it is first translated into C code.

When exporting a function out of SV, it generates a C header file vc_hdrs.h that should be included by the C file.

So a change I made in the C file is to add the line:

#include "vc_hdrs.h"

Then, I just added the C functions file to the VCS compilation command:

> vcs -sverilog hello_world.v funcs.c

It works!

The output I get is:

something
hello world

.

0
On

A solution that works with all simulator that follow IEEE Std 1800-2012 is to have #include "svdpi.h" and prefix the extern keyword in front of all methods being exported to C. funcs.c should look like:

#include <stdio.h>
#include "svdpi.h"

extern int sayHello();

void something() {
    printf("something\n");
    sayHello();
}

Examples from IEEE Std 1800-2012

  • § H.10.2 Example 2—Simple packed array application
  • § H.10.3 Example 3—Application with complex mix of types
0
On

Hi I have provided a nice example under this post https://stackoverflow.com/a/46441794/5842403

Synopsys VCS

1) You compile the C code using flags and introducing the defines you want to add. In our case our C code need the define PYTHON_PATH

#GCC in two steps for shared object
gcc -g -D 'PYTHON_PATH="'$PYTHON_DIR'"'  -fPIC -Wall -I${VCS_HOME}/include -I/usr/include/python2.6/ -lpython2.6 -c ${PROJECTDIR}/verification/PVE/keycontrol/tb/keycontrol_C_code_wrapper.c 
gcc -fPIC -shared -o keycontrol_C_code_wrapper.so  keycontrol_C_code_wrapper.o 

2) You do the VCS elaboration linking the python lybrary with -LDFLAGS '-lpython2.6'

vcs -timescale=1ps/1ps -ntb_opts uvm -lca -kdb -full64 keycontrol_tb_top -debug_access+all+reverse  -LDFLAGS '-lpython2.6'

3) You run the created simulation file. You call simv including -sv_lib keycontrol_C_code_wrapper to import the C shared object.

#RUN C CODE
./simv -gui -ucli +DVE +UVM_NO_RELNOTES  -l simv.log  +UVM_TESTNAME=keycontrol_basic_test -do ../../verification/PVE/keycontrol/tools/keycontrol_ucli_init.synopsys -sv_lib keycontrol_C_code_wrapper
0
On

I see you've named SystemVerilog file as .v extension. Not sure if that works or not. But lets say if its hello_world.sv

Your command line should look like this (for Questa Simulator),

qverilog hello_world.sv funcs.c

"qverilog " is to compile and run SystemVerilog files.

That's all. No need to add extra header files