Overview
In the referenced RISC-V verification flow, DPI calls are the mechanism used from Verilog/RTL simulation to interact with software-side verification components. Dromajo is compiled as a shared library, linked into the simulator, and accessed through DPI wrapper functions from Verilog. The paper describes these DPI functions as mostly thin wrappers around Dromajo API functions. [C1]
DPI calls are also used to expose Logic Fuzzer functionality to the RTL. The Logic Fuzzer was embedded into the Dromajo infrastructure, and the API set was extended so RTL could access fuzzers through DPI calls. The fuzzer configuration is supplied through Dromajo's JSON configuration file. [C2]
Role in Dromajo co-simulation
The Dromajo integration uses DPI calls to keep a RISC-V RTL model and the Dromajo reference model synchronized during simulation. The cited flow identifies three DPI wrapper functions needed for integration: cosim_init(), step(), and raise_interrupt(). [C1]
cosim_init()
cosim_init() is invoked from an initial Verilog block. It calls Dromajo's initialization API, passes the path to the configuration file, and initializes the Dromajo reference model. The configuration includes checkpoint location and core-specific information such as the memory map. [C1][C3]
step()
step() is called whenever the RTL commits a valid instruction. It communicates the program counter, instruction, and store data to Dromajo. On each invocation, Dromajo commits one instruction on its side and compares the communicated data against its reference execution. If a mismatch is detected, the function returns a non-zero code and the simulation is aborted. [C3]
raise_interrupt()
Because co-simulation is synchronous while interrupts are asynchronous, the flow uses raise_interrupt() to log that the RTL core took an interrupt and to force Dromajo into the same control flow. The wrapper communicates the interrupt cause and sets the trap vector in Dromajo, enabling co-simulation of interrupt trap handler routines. [C3]
Role in Logic Fuzzer integration
Logic Fuzzer uses DPI calls to let RTL logic access software-managed fuzzer state. In the branch-predictor table-mutator example, the Dromajo fuzzer object allocates a table matching the branch predictor size. Instead of accessing the RTL memory model, the RTL implementation accesses the fuzzer table through DPI; during simulation, the tables are fuzzed randomly or with specified patterns. [C4]
The same DPI-based table-mutator pattern is applied to instruction-cache tag and data arrays: the arrays are replaced with table mutators, and instruction-cache logic reads and writes the tables through DPI. This enables random instruction streams to be supplied on a mispredicted path when a specific tag is observed. [C5]
Verification-flow context
In the cited Dromajo-based verification flow, checkpoint generation and co-simulation are separated. During co-simulation, Dromajo is instantiated and encapsulated with the RTL, and the RTL-side testbench includes a DPI-calls implementation. Checkpoints are loaded into both models so that both begin with identical architectural state before step-and-compare execution proceeds. [C6]