csystem-verilogvpi

SystemVerilog looping through hierarchy


I have registers instantiated in a Register block Regblock as such:

DUT.Regblock.Register1
DUT.Regblock.RegisterA
DUT.Regblock.RegisterABC
...

All these registers have the same inner structure. I would like to simulate the effects of bit flips in these registers.

//Here an attempt to do bit flips
bitFlipLocation = $random;
force  DUT.RegBlock.Register1.reg[bitFlipLocation] = ~DUT.RegBlock.Register1.reg[bitFlipLocation];
release DUT.ABCStar1.RegBlock.Register1.reg[bitFlipLocation];

Is there a way to create a loop over all DUT.Regblock.Register1, RegisterA, RegisterABC, ... inside RegBlock and create these bit flips?


Solution

  • Following dave's answer I implemented the VPI code in C to loop over all register within RegBlock and randomly force bit flips at some positions (register is 32 bit wide).

    #include <sv_vpi_user.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    #define NULL 0
    
    void reg_flips() {
      vpiHandle module_iter;
      vpiHandle module_obj;
      vpiHandle module_regblk;
      vpiHandle reg_nets;
      vpiHandle net;
      //Starting from the RegBlock
      module_regblk = vpi_handle_by_name("DUT.RegBlock",NULL);
      //Iterator over all register in RegBlock
      module_iter = vpi_iterate(vpiModule,module_regblk);
      while (module_iter) {
        module_obj = vpi_scan(module_iter);
        if (module_obj) {
          reg_nets = vpi_iterate(vpiReg,module_obj);
            while (reg_nets) {
              net = vpi_scan(reg_nets);
              if (net) {
                s_vpi_value val;
                val.format = vpiIntVal;
                val.value.integer = rand()%2;
                int position = rand()%32;
                //Forcing the value at a given position.
                vpi_put_value(vpi_handle_by_index(net,position),&val,NULL,vpiNoDelay);
              }
              else {
                reg_nets = NULL;
              }
            }
          }
        }
        else {
          module_iter = NULL;
        }
    }