SystemVerilog DPI Tutorial

[The C-Layer]

Previous: Pure and Context functions | Next: Representation of basic types

SystemVerilog (SV) Direct Programming interface (DPI) brings in the convenience of inter-language function call with no or very little extra overhead. Earlier, we saw how SystemVerilog can call a C function. In the current two part series, our focus will be the C Layer of DPI - how DPI looks from the C side.

Back to Basics

Let us first recapitulate some of the definitions from the DPI SystemVerilog Layer.

  • Thanks to DPI, SystemVerilog side can call a C function when an appropriate import declaration is present at the SystemVerilog side. Such a C function is called imported function.

DPI also provides mechanism that allows SystemVerilog task and function to be called from the C side. There are few possible cases (and new definitions) when the C side calls a SystemVerilog task or function.

  • The C side can call a SystemVerilog function when a proper extern declaration is present at the C side and an export declaration is available on the SystemVerilog side. This function will be called exported function.
  • The C side can also invoke a SystemVerilog task as long as a proper extern declaration is present at the C side and an export declaration is made available on the SystemVerilog side. Note that, unlike exported function, such an exported task can consume simulation time before the program control goes back to the C domain. Since C functions can not consume simulation time, this is the only way to create a time delay from the C side.
  • Lastly, consider the following case: an imported C function called from the SystemVerilog side can, in turn, call an exported SystemVerilog task. In such a case, the SystemVerilog task is called an imported task.

Let us see an example of an extern declaration and how an exported SystemVerilog function is called from the C side.

SystemVerilog:

export "DPI" function exported_sv_function;

module SV_side (...);
...
function void exported_sv_function;
   begin 
      $display("Hello from SV function");
      ...
   end
endfunction
endmodule

C:

extern void exported_sv_func;
...
   printf("Hello from C function");
   exported_sv_function();
...   

How About Some Arguments?

A relevant question to ask at this point is, how does one pass arguments to a SystemVerilog exported task or function when calling it from the C-side? This is indeed one of the core issues of DPI C layer and we will spend a considerable part of this tutorial on this topic.

The value of an argument on the C side is specified by a C type (i.e. data types that C allows - int, float, double, etc.) whereas the same value is represented by a SystemVerilog type on the SystemVerilog side. In order for the data to be interpreted correctly by either side, the C type and SystemVerilog type should match with each other.

DPI leaves the responsibility of matching the data types on two sides to the user. The user needs to define the data types for the SystemVerilog and C side that match with each other.

Since SystemVerilog and C data types are different, of course, it is natural to ask how does one find a matching pair of data types from both sides?

To start with, most of the SystemVerilog basic types already have C compatible representations. While passing simple argument types (int, float, and so on) from the C side, it is easy to find their SystemVerilog counterparts. We will see this in details in the next section on the next page.

Previous: Pure and Context functions | Next: Representation of basic types

Share/Save/Bookmark



Verification Management
Join Verification Management Group


Shop Amazon - Contract Cell Phones & Service Plans

Book of the Month