0

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?

Sarah_lan
  • 1
  • 3

1 Answers1

0

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++;
    }   
}
Serge
  • 11,616
  • 3
  • 18
  • 28
  • thank you for your answer, but for some reason I cannot even get a vpi handle. The hierarchy of the design is below and I add a warning hint if the handle doesn't exit. The warning always pops up meaning even the handle is not achieved :` vpiHandle vh1 = vpi_handle_by_name("TOP.ariane_testharness.i_sram.i_tc_sram_wrapper.i_tc_sram.sram", NULL); if (!vh1) vl_fatal(__FILE__, __LINE__, "ariane_testharness", "No handle found");` – Sarah_lan Jul 22 '23 at 22:05
  • Most likely it means that you did not specify a correct path. Unfortunately, without a reproducer no one can help you here. – Serge Jul 23 '23 at 02:40
  • I understand, thank you. Just to let you know I think the path is right. Because I once got the path wrong, and the error was different, saying something like "..... doesn't exist in the hierarchy" / "wrong path" or whatsoever, instead of "no handle found". – Sarah_lan Jul 23 '23 at 07:48
  • there could be something verilator specific, like missing compilation quals. – Serge Jul 23 '23 at 15:35
  • hi, just an update on this issue. It took me days to figure out the problem. Notwithstanding verilator does support accessing the memory, it creates a hierarchy that differs from the one that's instantiated by us in HDL. It just adds additional modules inbetween our HDL modules in some cases. So when we try to get a vpiHandle given the hierarchy we think it is, the path is just wrong, as mentioned above, verilator creates a different hierarchy. – Sarah_lan Jul 25 '23 at 11:55