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

270 Views Asked by At

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?

1

There are 1 best solutions below

5
On BEST ANSWER

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++;
    }   
}