Using DPI-C with UVM Framework

Hi,
I have a small contrived example of using DPI-c (without UVMF) just to illustrate later what I am trying to do with UVMF. I have 5 files: one C file, two SV files, a do file and a Makefile.

The C file c.c has this simple content:

#include <stdio.h>
#include <stdlib.h>
extern void c_method() {
  printf("     Hello World...!\n");
}

The first SV file contains a package that imports this C file, the file name is p_dpi.sv

package p_dpi;
  import "DPI-C" function void c_method();
endpackage

The second SV file is the top module, top.sv:

module dpi_tb;
  import p_dpi::*;
  initial
  begin
    $display("Before calling C Method");
    p_dpi::c_method();
    $display("After calling C Method");
  end
endmodule

The do file do.do is this:

set SVFLAGS "-quiet -work work -lint=full "
set PWD [pwd]
vlib work
vmap work
vlog {*}$SVFLAGS $PWD/p_dpi.sv
vlog {*}$SVFLAGS $PWD/top.sv
vlog -work work -mfcu $PWD/c.c -dpicpppath /usr/bin/gcc -ccflags "-c -Werror-implicit-function-declaration -O2"
vsim -batch -t 1ps work.dpi_tb -dpicpppath /usr/bin/gcc -voptargs=+acc
run 10 us
exit

The Makefile:

build:
        @vsim -batch -do ./do.do -t 1ps -quiet -l log.log -wlfdeleteonquit

When I run “make build”, everything compiles and in simulation I see that the C file was called (see the Hello World line):

Loading sv_std.std

Loading work.p_dpi(fast)

Loading work.dpi_tb(fast)

** Note: (vsim-7082) For C/C++ auto compile, choosing compiler /usr/bin/gcc set by the -dpicpppath switch.

Loading /tmp/bmalnar@epis3dev_dpi_24737/linux_x86_64_gcc-4.8.5/vsim_auto_compile.so

Before calling C Method

 Hello World...!

After calling C Method

End time: 14:19:31 on Aug 31,2020, Elapsed time: 0:00:02

Errors: 0, Warnings: 0

As the next step, I am trying to reuse this same C file in the UVMF generator tutorial. The baseline complete solution can be run using the command: “make cli”, where cli step is defined in the Makefile as:
cli: libs build link optimize cli_run
I define my own target similar to this:

mycli: libs mydpi build link optimize cli_run
mydpi:
        @vsim -batch -do ./do.do -t 1ps -quiet -l log.log -wlfdeleteonquit

Here, I am re-using the do file from above, as well as the package p_dpi and the C file. The do file is:

set SVFLAGS "-quiet -work work -lint=full "
set PWD [pwd]
vmap work
vlog {*}$SVFLAGS $PWD/p_dpi.sv
vlog -work work -mfcu $PWD/c.c -dpicpppath /usr/bin/gcc -ccflags "-c -Werror-implicit-function-declaration -O2"
exit

To test this, I added a couple of lines in the file: project_benches/ALU/tb/testbench/hdl_top.sv

I added this import at the top:

import p_dpi::*;

And at the bottom in the initial block, I added the call to the C finction:

...
  initial begin      // tbx vif_binding_block
    import uvm_pkg::uvm_config_db;
    // The monitor_bfm and driver_bfm for each interface is placed into the uvm_config_db.
    // They are placed into the uvm_config_db using the string names defined in the parameters package.
    // The string names are passed to the agent configurations by test_top through the top level configuration.
    // They are retrieved by the agents configuration class for use by the agent.
    uvm_config_db #( virtual ALU_in_monitor_bfm  )::set( null , UVMF_VIRTUAL_INTERFACES , ALU_in_agent_BFM , ALU_in_agent_mon_bfm );
    uvm_config_db #( virtual ALU_out_monitor_bfm  )::set( null , UVMF_VIRTUAL_INTERFACES , ALU_out_agent_BFM , ALU_out_agent_mon_bfm );
    uvm_config_db #( virtual ALU_in_driver_bfm  )::set( null , UVMF_VIRTUAL_INTERFACES , ALU_in_agent_BFM , ALU_in_agent_drv_bfm  );
    c_method();
  end
endmodule

When running “make mycli”, I am getting a warning and an error that says that my C function cannot be found. What should I do to fix that?

Loading /eda/mentor/2019.4/questasim/uvm-1.1d/linux_x86_64/uvm_dpi.so

** Warning: (vsim-16074) No C/C++ auto compile object files are found for the current platform ‘linux_x86_64_gcc-5.3.0’.

However some C/C++ auto compile objects are found on the following platform(s):

linux_x86_64_gcc-4.8.5

Please check whether you are missing the C/C++ auto compile step on the current platform.

Time: 0 ns Iteration: 0 Region: /p_dpi File: /home/bmalnar/epi/UVM_Framework/UVMF_2020.1.tar/UVMF_2020.1/docs/generator_tutorial/uvmf_template_output_dpi/project_benches/ALU/sim/p_dpi.sv

** Warning: (vsim-3770) Failed to find user specified function ‘c_method’ in DPI precompiled library search list "/eda/mentor/2019.4/questasim/uvm-1.1d/linux_x86_64/uvm_dpi.so ".

Time: 0 ns Iteration: 0 Region: /p_dpi File: /home/bmalnar/epi/UVM_Framework/UVMF_2020.1.tar/UVMF_2020.1/docs/generator_tutorial/uvmf_template_output_dpi/project_benches/ALU/sim/p_dpi.sv

** Fatal: (vsim-160) /home/bmalnar/epi/UVM_Framework/UVMF_2020.1.tar/UVMF_2020.1/docs/generator_tutorial/uvmf_template_output_dpi/project_benches/ALU/sim/p_dpi.sv(3): Null foreign function pointer encountered when calling ‘c_method’

Time: 0 ns Iteration: 0 Process: /hdl_top/#INITIAL#97(#ublk#246573824#97) File: /home/bmalnar/epi/UVM_Framework/UVMF_2020.1.tar/UVMF_2020.1/docs/generator_tutorial/uvmf_template_output_dpi/project_benches/ALU/sim/p_dpi.sv

Fatal error at /home/bmalnar/epi/UVM_Framework/UVMF_2020.1.tar/UVMF_2020.1/docs/generator_tutorial/uvmf_template_output_dpi/project_benches/ALU/sim/p_dpi.sv line 3

In the meantime I managed to get this simple test case running. This is what I did in addition to the steps above:

  1. Add the compilation of the C code to the shared object library (as another target in the Makefile). This creates the shared object file c.so:

comp_so:
gcc -c -fPIC -o c.o c.c
gcc -shared -fPIC -Wl,-soname,c.so.1 -o c.so c.o -lc

  1. Add this comp_so target to mycli in the Makefile, which is now:
    mycli: libs mydpi comp_so build link optimize cli_run

  2. Finally, make sure that vsim picks up this shared object library by adding this to the Makefile:
    COMMON_VSIM_ARGS += -sv_lib c

When I run “make mycli”, the entire thing compiles and runs and I see the “Hello World…” message printed at the screen.
Does this look as a good solution to you, or would you recommend taking a different approach?
Many thanks for your help.

In reply to Branex:

Hi Branex,

Good work.  Those steps are what you need.  Compiling the C source and inclusion of the shared object in vsim using -sv_lib should be automatically done by UVMF for the c source associated with any environment package and interface package.  Can you send me the YAML used to generate the test bench and DPI-C?  Please use the email I contacted you with earlier today.