DPI-C and SystemVerilog External Compilation flow issue

1.9k Views Asked by At

ModelSim User's manual (v10.1c), in page 660, talks about the default autocompile flow (using vlog) and external compilation flow to get the the DPI-C to work in ModelSim. I'm able to get the auto-compile flow to work. I'm stuck with the external compilation flow.

Problem Summary: I get an "undefined reference" error in when I try to create the .dll file in-spite of using the right export and import statements in my system verilog file.

Here are the files that make up this project:

file 1: mytest.cpp

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

int mymain() {
   printf("---starting test in c-domain---\n");
   PrintHelloWorld();
   return 0;
}

file 2: experiment3.h

#ifndef INCLUDED_EXPERIMENT3
#define INCLUDED_EXPERIMENT3

#ifdef __cplusplus
#define DPI_LINK_DECL  extern "C" 
#else
#define DPI_LINK_DECL 
#endif

#include "svdpi.h"

DPI_LINK_DECL DPI_DLLESPEC
int
mymain();

DPI_LINK_DECL void
PrintHelloWorld();

#endif

file 3: mytb.sv

module mytb;
   timeunit 1ns/1ps;
   export "DPI-C" function PrintHelloWorld;
   import "DPI-C" context task mymain();

   function void PrintHelloWorld();
      $display("HelloWorld\n");
   endfunction

   //start test
   initial begin
      #10ns;
      mymain();
   end
endmodule

Here are the command that I am using:

command 1   :g++ -c -IC:\intelFPGA\17.0\modelsim_ase\include -o ./mytest.o ./mytest.cpp
comments    :command 1 executes without any problem
key-words   :MinGW, GCC
command 2   :g++ -shared -Bsymbolic -o ./mytest.dll ./mytest.o -LC:\intelFPGA\17.0\modelsim_ase\win32aloem
comments    :[1] command 2 fails when I use the mytest.cpp showed above
             [2] command 2 passes when I comment out "PrintHelloWorld()" in mytest.cpp
error       :c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: 
             ./mytest.o:mytest.cpp:(.text+0x2d): undefined 
             reference to '`PrintHelloWorld' collect2.exe:error:ld
             returned 1 exit status
key-words   :MinGW, GCC, dll
command 3  : vsim -sv_lib ../src_cpp/mytest work.mytb
comments   : [1] executed in console in ModelSim
             [2] works when I don't have "PrintHelloWorld()" in mytest.cpp

Most of the online DPI-C examples deal with running (CPP and .SV) everything in ModelSim. I don't want that. I want to keep the HW and SW flow separate. And, this separation does work to some extent (I have no issues with calling C functions from SV (import works fine). The roadblock is with trying to call SystemVerilog function from the C function (something seems to be wrong with the export).

Any thoughts on how I can get past this hurdle ?

2

There are 2 best solutions below

2
Greg On

Based on looking at examples, try adding -fPIC to your command 1. Then command 2 should work as is.

From my experience the final file should be a shared object (.so); not a dynamic link library (.dll). I run SystemVerilog on unix based systems, so maybe windows is different. If you run into an issue, that could be something to try.

1
gatecat On

Try changing

DPI_LINK_DECL void
PrintHelloWorld();

to

DPI_LINK_DECL DPI_DLLISPEC void
PrintHelloWorld();

(if DPI_DLLISPEC doesn't work replace it directly with __declspec(dllimport))