Is it possible to iterate systemverilog associative array with non-int index type through VPI c function?

302 Views Asked by At

For example

// test.sv

class cls;
    int b;
endclass

module m
    cls testObj;
    int map[cls];
    initial begin
      inst = new;
      inst.b = 10;
      map[cls] = 12;
      $VPIcall;
    end
endmoudle

// pseudocode vpi c

vpiHandle mapHandle = vpi_handle_by_name("m.map", 0); // return valid handle
vpiHandle valueHandle = vpi_handle_by_name("map[testObj]", mapHandle); // return zero

seems we could not get valueHandle like this and I wonder whether is it possible to iterate or get value stored in associative array through VPI?

1

There are 1 best solutions below

4
On

Notes:

  1. VPI capabilities are implemented differently by different tools. Your first line should work, depending on the tool and on the qualifiers used at compilation. For example, to make it work with 'vcs' I used -debug_all (there should be a better choice).
  2. The second line will never work, at least for object names, however you can scan over the elements of the array using vpi_iterate/vpi_scan. It seems that direct access with vip_handle_by_index does not work for associative arrays.
  3. Your code sample is not compilable.

Here is a sample that works for me with vcs:

verilog:

class cls;
   int b;
endclass

module m;
   
   cls testObj, obj1;
   
   int map[cls];
   initial begin
      testObj = new;
      testObj.b = 10;
      map[testObj] = 12;
      obj1 = new;
      obj1.b = 20;
      map[obj1] = 13;
      $testme;
   end
endmodule

vpi:

#include <stdio.h>
#include <vpi_user.h>

void testme() {
    vpiHandle mapHandle = vpi_handle_by_name("m.map", 0); // return valid handle
    vpi_printf("map: %p\n", mapHandle);

vpiHandle el;
    s_vpi_value val = {vpiIntVal};

    vpiHandle iterator = vpi_iterate(vpiReg, mapHandle);
    while ((el = vpi_scan(iterator))) {
        vpi_get_value(el, &val); 
        vpi_printf("%s: %d\n", vpi_get_str(vpiType, el),  val.value.integer); 
    }
    
}
    

Alternatively, for simpler associative arrays, like the once using strings for associations, it is easy to use an export dpi functions to do direct access, like in the following example:

module m;
   
   int map[string];
   initial begin
      map["testObj"] = 12;
      map["obj1"] = 13;
      $testme;
   end

   export "DPI" function getMap;
   function int getMap(string name);
      return map[name];
   endfunction
      
endmodule
============
#include <stdio.h>
#include <vpi_user.h>
#include <sv_vpi_user.h>
#include <svdpi.h>


void testme() {

    svScope scope = svGetScopeFromName("m");
    svSetScope(scope);
    
    int testObjVal = getMap("testObj");
    int obj1Val = getMap("obj1");
    vpi_printf(" ==> %d, %d\n", testObjVal, obj1Val);
    
}