DPI, Python, and Wireshark Integration

In previous blogs, we have explained the fundamentals of DPI and how to connect Wireshark to a testbench to obtain real-time visualization of stimuli. In this blog, we will detail a use case (real-life scenario) where DPI will be used with Python for stimulus generation, and Wireshark will be used for traffic visualization.

RTL Setup for Full-Duplex Ethernet MAC Communication

From the RTL side, we will use a tri-mode full-duplex Ethernet MAC sublayer developed in VHDL as an alternative to both commercial and open-source implementations for use on FPGAs.

Key Features:

  • Full-duplex IEEE 802.3 communication over copper at physical link speeds of 10 Mbps (10BASE-T), 100 Mbps (100BASE-TX), and 1000 Mbps (1000BASE-T).
  • Generation of Ethernet preamble and frame check sequence (FCS) during transmission.
  • Verification of received packets, including checking the preamble, packet size, and frame check sequence.
  • Filtering of received packets based on the destination MAC address.
  • Simple 8-bit wide FIFO user interface with support for arbitrary clock domains for both packet transmission and reception.
  • Media-Independent Interface (MII) for 10/100 Mbps and Gigabit Media-Independent Interface (GMII) for 1000 Mbps connectivity.

Usage of RTL in this Project

In this project, two DUTs, named Mac_host and Mac_client, are instantiated to communicate with each other. The GMII interface operates at a speed of 100 Gbps, utilizing 8 transmission lines at a frequency of 125 MHz. A GMII agent captures the traffic for Wireshark visualization.

The RTL manages FIFOs for both transmission and reception of packets. The testbench contains FIFO agents that handle the data flow: on one hand, they drive packets to be sent through the transmission FIFOs, and on the other hand, they monitor the packets stored in the reception FIFO. Also, a MAC_ETH layer is responsible for encapsulating and decapsulating the MAC packet fields. A predictor filters messages, discarding those with non-corresponding destination MAC addresses, except for those with a "group address packet" MAC address. The comparator compares the packets from the predictor with those captured in the RX FIFO.

Stimulus Generation and Visualization with DPI-C, Python, and Wireshark

The stimuli are randomized using Python and transferred to UVM via DPI-C. The Python Scapy library is used to sniff network traffic and capture packets, which are then injected into the DUT. These packets are encapsulated with specific protocols, enhancing the Wireshark visualization by enabling interaction with filtering fields and other features.

TLP Generation with Scapy

Once the DPI connection is established, we can generate Transaction Layer Packets (TLPs) using Scapy. This tool simplifies the crafting and manipulation of network packets. In the code, Scapy sniffs for Ethernet frames, processes the payload and length, and stores the information in a custom PacketInfo container. Scapy's access to various protocol layers makes it highly effective for network tasks in Python.
Additionally, the “sniff” function in Scapy allows you to specify the network interface you want to sniff on (i.e. Wi-Fi, Ethernet) and the number of packets to capture. The sniffed packets that match the required format are processed and returned to C for further handling. 

DPI Connection with Python and Code Explanation

Since SystemVerilog (UVM) cannot directly interact with Python, we need an intermediary—C code—that acts as a bridge between SystemVerilog and Python.

The process works as follows:

  1. Python Generates the Network Packet: A Python script, utilizing the Scapy library, dynamically generates the data packets required for simulation. The Python code encapsulates the packets and returns them in a suitable format.
  2. C as an Intermediary: C code serves as a bridge between SystemVerilog and Python. Using DPI-C, the C code communicates with SystemVerilog, while the C library python.h is used to interface with Python. The C code loads and executes the Python script, calling functions to generate the data packets. These packets are then retrieved by C and transferred to SystemVerilog via DPI-C.
    • C Code Execution: The C code initializes the Python interface, loads the Python module (e.g., packet_generator.py), and calls the packet generation function.
    • Data Transfer: The packet data generated by Python is extracted and converted into a format that SystemVerilog can use via DPI-C, allowing the simulation to continue with the generated data

Handling Datatype Conversions and Adaptations in DPI for SystemVerilog, C, and Python

One of the challenges in using DPI is managing datatype conversions between SystemVerilog, C, and Python, as each language has its own types and data representations.

SystemVerilog types, such as logic[31:0], are converted to C types like unsigned int or uint32_t, while complex types (e.g., structs) map to C structs. C primitive types (e.g., int, float, char) correspond to Python types (int, float, str).

To ensure smooth data transfer, the DPI interface must handle these type conversions—either implicitly or through explicit casting—while also managing memory correctly to avoid issues that could disrupt the simulation. Proper handling of these conversions is key to ensuring correct data transfer and functionality across the languages in a verification environment.


In our example, since the packet returned by Scapy has a variable length, the following data types were used:

  • In Python, a list is used, which is dynamic by nature.
  • In C, a linked list structure is utilized.
  • In SystemVerilog, a dynamic array is employed.

For memory allocation in the C and SystemVerilog structures, it was also necessary to pass a length variable of integer type, use pointers, and allocate memory in C using malloc (and free to release the memory) and new[] in SystemVerilog.

In conclusion, this blog highlighted the integration of DPI, Python, and Wireshark for generating and visualizing network traffic in a simulation environment. By utilizing Python’s Scapy library for stimulus generation, SystemVerilog for RTL communication, and Wireshark for real-time traffic visualization, we can efficiently model and verify Ethernet MAC communication. This integration provides a powerful toolset for network testing and verification, improving both the workflow and the results of FPGA-based projects.

References

MII-GMII: https://en.wikipedia.org/wiki/Media-independent_interface

Scapy library: https://scapy.net/

Wireshark: https://www.wireshark.org/

RTL MAC GitHub: https://github.com/yol/ethernet_mac/tree/ef0b59e1e2626509259f8b9acb4d796b0601edc4

RTL MAC Thesis: https://github.com/yol/ethernet_mac_doc/raw/master/Thesis.pdf

Written by Joaquin Lutri and Martin Sarasqueta Fierens

Design Verification Engineers at Emtech S.A.

Thanks Marcelo Pouso, Juan Doctorovich and  Lucas Diaz Miguez for their valuable feedback and insightful reviews.

If you have any questions, contact us: info@emtech.com.ar