DPI basics - Part 1

What is DPI and How is it Used in SystemVerilog?

DPI (Direct Programming Interface) is a mechanism in SystemVerilog that allows the integration of SystemVerilog with other programming languages like C, Python, MATLAB scripts, and more. It enables bidirectional communication between SystemVerilog testbenches and external applications, enabling more advanced and flexible testing setups, especially in the context of UVM (Universal Verification Methodology).

In UVM, DPI can be particularly useful for tasks such as:

  • Running algorithms that cannot be easily written in SystemVerilog, like complex mathematical models, data manipulation processes, machine learning algorithms, cryptographic functions, signal processing techniques, or simulations involving large datasets and statistical analysis. These types of algorithms are often more efficiently implemented in languages like C, Python, or MATLAB, and can be integrated into SystemVerilog using DPI.
  • Accessing external libraries that provide functionalities SystemVerilog itself might lack.
  • Interfacing with simulation tools, enhancing the flexibility and capabilities of the verification environment. For example, integrating with Simulink allows for system-level modeling and simulation of dynamic systems, while LabVIEW enables interaction with real-time hardware for data acquisition and control. Additionally, connecting with Wireshark provides the ability to capture and analyze network packets, enriching the testing of communication protocols and network interactions within the simulation..

By using DPI, we can extend the SystemVerilog environment with custom functions written in other languages. Although there may be some performance overhead, it provides an easy-to-apply solution.

C as a Bridge for Non-C Languages

While DPI is designed for native interaction with C, integrating other languages requires an intermediary approach. To communicate with Python, for instance, C acts as a "bypass." Here's why:

  • DPI only natively supports C: For languages that do not have a direct interface with SystemVerilog, C acts as a bridge. You write your Python (or another language) logic, expose the necessary functionality through C interfaces, and then use DPI to connect SystemVerilog to the C code.

This approach may seem like an additional step, but it ensures compatibility and stability, as DPI relies on the robustness of C for cross-language communication.

How Do Imports and Exports Work in DPI?

Import and export are used to facilitate communication between SystemVerilog and external languages.

  • import:
    • The import statement in SystemVerilog is used to bring in functions or tasks defined in external programming languages into the SystemVerilog environment. When you use import, you're essentially telling SystemVerilog to recognize and use a function that resides outside of SystemVerilog's native environment. This enables you to access complex functionality, such as custom algorithms or data manipulation logic, written in another language.
    • Example: You can import a C function into your SystemVerilog testbench to execute a specific task that SystemVerilog cannot easily handle, like performing complex mathematical calculations, or processing large datasets that would be inefficient to implement directly in SystemVerilog. 
  • export:
    • The export statement is the opposite of import. It allows SystemVerilog to make its own functions or tasks available to the external environment. By exporting a SystemVerilog function, you allow external programs to call and interact with that function. This is how you provide a way for external languages to interact with and control your SystemVerilog simulation or testbench.
    • Example: If you want a C application to trigger a specific SystemVerilog task, you can export that task, and then the C code can invoke it using the appropriate DPI interface. For instance, you could export a task that configures the testbench's state, and then the C code can call the exported task to change the testbench parameters or initiate a simulation event.

In short, import brings external functionality into SystemVerilog, and export allows SystemVerilog functionality to be accessed externally. These mechanisms are essential for enabling the interaction between SystemVerilog and other programming languages through DPI.

Example Code for Imports and Exports

In this section, we will demonstrate how to use imports and exports to integrate SystemVerilog with C code. We will provide a simple example where SystemVerilog imports a C function to perform a mathematical operation, while also exporting a function from SystemVerilog that can be called by the external C program.

 

Systemverilog code:

import "DPI-C" context function void divide_by_two(inout int b);

export "DPI-C" function display_message;

 

initial begin

      int random_number;

      if (!std::randomize (random_number)) begin

        `uvm_error("random_number ", "Failed to randomize var!");

      end

      divide_by_two(random_number);

end

 

  function void display_message(input string message);

      $display("C message: %s", message);

endfunction

C code: “c_algorithms.c”:

#include "svdpi.h"

#include <stdio.h>

 

void divide_by_two(int *A)

{

  char message[100];

  *A = *A / 2;

  sprintf(message, "The result is %d", *A);

  display_message(message);

}

Compilation with vlog and gcc

For the compilation, if you're using QuestaSim, you can use the following commands:

vlog "$lib_path/c_algorithms.c"

vsim +UVM_TESTNAME=$uvm_testname project_tb_top

Alternatively, you can use GCC for compilation, which makes the process independent of the simulation tool you're using. On Windows, the command would be:

gcc -I C:\\questasim64_10.7c\\include -shared -o c_algorithms.dll c_algorithms.c

vsim +UVM_TESTNAME=$uvm_testname -sv_lib c_algorithms project_tb_top

When compiling with vlog, it's integrated with ModelSim/QuestaSim, ensuring compatibility with their simulation environment. Choose vlog if you're working within this ecosystem. On the other hand, gcc is a more general approach, ideal for cross-platform compilation or when you're not tied to a specific simulator. Use gcc if you're looking for broader flexibility.

Conclusion

DPI is a powerful feature in SystemVerilog and UVM that allows interaction with external languages like C and Python. Through the use of imports and exports, you can extend the functionality of your UVM testbenches, making them more powerful and flexible. The ability to compile and link external code with vlog and gcc makes the integration process efficient and straightforward.

By understanding DPI and its mechanisms, you can significantly enhance your verification environment, enabling more complex test scenarios and improving simulation accuracy.

In upcoming blog posts, we will dive deeper into these concepts by exploring how to integrate Wireshark for network packet analysis and capture, as well as how to build a TLP (Transaction Layer Packet) generator in Python, and connect it with SystemVerilog via DPI. These topics will expand the scope of your verification environment, enabling more sophisticated, real-world test scenarios and providing greater flexibility and control over your simulations.

Joaquin Lutri and Martin Sarasqueta Fierens

Design Verification Engineers at Emtech S.A.

Thanks Marcelo Pouso for their valuable feedback and insightful reviews.

If you need further info, contact us: info@emtech.com.ar