verilogsimulationsystem-verilogverilatorvpi

How to read memory value at a specific location using VPI and verilator?


I want to trace the memory value at specific locations during simulation of a hierarchical design using Verilator. A short version of the memory model is defined as follows

`module tc_sram{

parameter int unsigned NumWords     = 32'd1024,

parameter int unsigned AddrWidth = (NumWords > 32'd1) ? $clog2(NumWords) : 32'd1,

parameter type         data_t    = logic [DataWidth-1:0],

}{

data_t sram [NumWords-1:0] /*verilator public*/;

}`

I want to use VPI interface in the design's C++ testbench to trace memory value at any location I want, meaning I provide the address of the memory location in the testbench, and the memory value at this location will return. Does anyone have any idea?


Solution

  • Your memory model is not represented by a verilog code. I am not familiar with vpi implementation in verilator. However, using a standard vpi you can use vpi_handle_by_index to access memory elements.

    I have an example below. First, some real System Verilog code:

    module tc_sram #(
                     parameter int NumWords = 32'd8,
                     parameter int AddrWidth = (NumWords > 32'd1) ? $clog2(NumWords) : 32'd1,
                     parameter int DataWidth = 4,
                     parameter type data_t = logic [DataWidth-1:0]
                     )();
       data_t sram [NumWords-1:0] /*verilator public*/;
    endmodule // tc_sram
    
    
    module top;
       tc_sram sram();
    
       initial begin
          $testme(); // one of the possible ways to invoke vpi from verilog.
       end
    endmodule // top
    

    here is an example of vpi code which you can use as a base. It prints types of the variables. You would need to use vip_get_value/vpi_get_value_array and vpi_put_value/vpi_put_value_array to read/write values to the memory.

    The following example only uses vpi_get_handle_by_index to print types.

    #include <stdio.h>
    #include <vpi_user.h>
    
    void testme() {
        // get sram handle using instance path.
        vpiHandle arr = vpi_handle_by_name("top.sram.sram", 0);
        printf("sram: %s\n", vpi_get_str(vpiType, arr));
    
    
        // traverse array elements by index. You can use vpi_iterat/vpi_scan instead. 
        int indx = 0;
        vpiHandle el;
        while ( (el = vpi_handle_by_index(arr, indx)) ){
            printf("   el[%d]: %s\n", indx, vpi_get_str(vpiType, el));
            indx++;
        }   
    }