Obtaining signal names in the design (using VPI calls)

1.4k Views Asked by At

I would like to get a list of signal names in a given design hierarchy from a Verilog design using vpi. It is a simple net name browser interface from my custom tool that is written in C and Python.

How can I get a list of signal names from a Verilog design and which VPI calls I should use to walk through the design?

Any info would be greatly appreciated.

1

There are 1 best solutions below

0
On

In addition to the answer already given this code walk through your hierarchy and store design object of type vpiLogic you can adapt it to your needs. It stores the full names of the register in an unordered_map which has nice O(1) access time during simulation.

This code was developed for projects using both verilog and VHDL.

You'll also find that sometimes some IP's are protected which is handled gracefully, in addition the usage of scopes (vpiInternalScope) instead of vpiModule allows recursion inside generate statements.

It is c++ code but usage of extern "C" makes it callable from your EDA tools (tested using IUS).

#include "vhpi_user.h"
#include "vpi_user.h"
#include "vpi_user_cds.h"
#include "sv_vpi_user.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unordered_map>

extern "C" {

static std::unordered_map<int , std::string> reg_map;

#define check_verilog(scopeH)  (vpi_get(vpiLanguage,scopeH) == vpiVerilog)
#define check_is_protected(scopeH)  (vpi_get(vpiIsProtected,scopeH))
#define check_protected(scopeH)  (vpi_get(vpiProtected,scopeH))
#define check_vhdl(scopeH)  (vpi_get(vpiLanguage,scopeH) == vpiVHDL)

bool is_vpi_protected(vpiHandle scopeH) {
  switch(vpi_get(vpiType, scopeH)) {
    case vpiClockingBlock:
    case vpiNamedBegin:
    case vpiTask:
    return check_is_protected(scopeH);
    default: {
      return check_protected(scopeH);
    }
  }
}

bool is_valid_scope(vpiHandle scopeH) {
  switch (vpi_get(vpiType, scopeH)) {
    case vpiInstance:
    case vpiModule:
    case vpiGenScope:
    case vpiGenScopeArray:
    case vpiInstanceArray:
    return true;
    default:
    return false;
  }
}

void vpi_get_reg(vpiHandle module) {
  vpiHandle itr_reg, reg;
  if ((itr_reg = vpi_iterate(vpiReg,module))) {
    while ((reg = vpi_scan(itr_reg))) {
      std::string reg_name(vpi_get_str(vpiFullLSName, reg));
      vpi_printf("** Verilog register Full Name:\t%s[%d]\n",reg_name.c_str(),vpi_get(vpiSize, reg));
      reg_map[(int)reg_map.size()+1] = reg_name;
    }
  }
}

void vhpi_get_reg(vpiHandle module) {
  vhpiHandleT itr_reg, reg;
  if (vhpi_get(vhpiKindP,module) == vhpiCompInstStmtK) {
    if ((itr_reg = vhpi_iterator(vhpiSigDecls,module))) {
      while (reg = vhpi_scan(itr_reg)) {
        std::string reg_name(vhpi_get_str(vhpiFullLSNameP, reg));
        vhpi_printf("** VHDL register Full LS Name:\t%s[%d]\n",reg_name.c_str(),vhpi_get(vhpiSizeP, reg));
        reg_map[(int)reg_map.size()+1] = reg_name;
      }
    }
  }
}

void walk_down(vpiHandle parentScope) {
  vpiHandle subScopeI, subScopeH;
  if (check_verilog(parentScope) && is_valid_scope(parentScope)) {
    vpi_get_reg(parentScope);
    if ((subScopeI = vpi_iterate(vpiInternalScope, parentScope))) {
      while ((subScopeH = vpi_scan(subScopeI))) {
        if (is_vpi_protected(subScopeH)) {
          if (vpi_get(vpiType, parentScope)!= vpiGenScope)
            vpi_printf("** Verilog scope %s in %s is protected \n",vpi_get_str(vpiFullLSName, subScopeH),vpi_get_str(vpiDefFile,parentScope));
          else
            vpi_printf("** Verilog scope %s in %s is protected \n",vpi_get_str(vpiFullLSName, subScopeH),vpi_get_str(vpiFile,subScopeH));
        }
        else {
          walk_down(subScopeH);
        }
      }
    }
  }
  else if(check_vhdl(parentScope)) {
    vhpi_get_reg(parentScope);
    subScopeI = vhpi_iterator(vhpiInternalRegions, parentScope);
    if (subScopeI) {
      while ((subScopeH = vhpi_scan(subScopeI)))
        walk_down(subScopeH);
    }
  }
}

void navigate_mixed(const char * scope) {
  reg_map.clear();
  vpiHandle topScopeI, topScopeH;
  vpi_printf(".........Starting register discovery \n");
  if ((topScopeH = vpi_handle_by_name((PLI_BYTE8 *)scope, NULL))) {
    topScopeI = vpi_iterate(vpiModule, topScopeH);
    while ((topScopeH = vpi_scan(topScopeI)))
      walk_down(topScopeH);
  }
  if ((topScopeH = vhpi_handle_by_name((PLI_BYTE8 *)scope, NULL)))
    walk_down(topScopeH);
  vpi_printf("Completed register discovery........\n");
}

}