Direct Programming Interface (DPI)
Definition
The Direct Programming Interface (DPI) is a SystemVerilog feature that allows SystemVerilog code to directly invoke functions implemented in C or C++ (and vice versa). In the reusable RISC-V vector accelerator verification environment, DPI is used as the inter-language bridge between the SystemVerilog/UVM testbench and the Spike Instruction Set Simulator (ISS), which is implemented in C++.
Role in the Verification Environment
Communication between the SystemVerilog UVM environment and the Spike ISS is accomplished via DPI. Because the ISS is written in C++, its routines are imported into SystemVerilog using DPI declarations of the form import "DPI-C" function .... The imported Spike functions are then called from the SystemVerilog class that extends the iss_wrapper, i.e., the concrete class that implements the pure virtual methods declared in the base ISS-wrapper abstraction. This pattern lets the verification environment treat any C/C++-based ISS through a common wrapper interface while delegating the actual ISS interaction to DPI-imported calls.
Imported Spike ISS Functions
The following functions are imported from the Spike C++ implementation into SystemVerilog using import "DPI-C":
spike_setup(input longint argc, input string argv)— initializes Spike with command-line arguments.run_and_inject(input int instr, output iss_state_t iss_state)— runs Spike and injects an instruction.exit_code()— returns the ISS exit code.set_tohost_addr(input longint tohost_addr, input longint fromhost_addr)— configures the tohost/fromhost addresses used by Spike.get_memory_data(output longint mem_element, input longint mem_addr)— reads a memory element from Spike's memory space.start_execution()— begins instruction execution in Spike.set_memory_data(input int unsigned data, input longint unsigned address, input int size)— writes data into Spike's memory.do_step(input int unsigned n)— advances Spike byninstructions.spike_set_external_interrupt(int mip_val)— injects an external interrupt into Spike.spike_run_until_vector_ins(inout iss_state_t iss_state)— runs Spike until a vector instruction is encountered and returns its state.
Project-Specific Versioning
Because each project targets a different version of the RISC-V vector extension, a different version of Spike is used per project (e.g., version 0.7.1 of the vector extension required modifications to the original Spike repository). To support this in a seamless way, Spike's library file is kept project-dependent, and a dedicated branch of the ISS repository is maintained to generate the library accordingly.
Related Components
iss_wrapper(CodeArtifact): the SystemVerilog wrapper class declaring the pure virtual methods that the SPIKE-specific class implements; this is where the DPI-imported functions are called from.- Reusable Verification Environment for a RISC-V Vector Accelerator (Paper): the verification environment that employs DPI to integrate the Spike ISS as the reference model.