3

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.

user2756376
  • 117
  • 9
  • there are ports, there are local variables in modules, there are local variables in always blocks, functions, tasks. Which ones are you interested in? There are multiple scan functions in vpi to go through different entities. – Serge Mar 07 '18 at 22:40
  • I think getting a list of port names (w/ hierarchy) is a good starting point. Once I understand the concept, I could expand it if necessary. – user2756376 Mar 08 '18 at 23:41
  • You can traverse ports as in here https://stackoverflow.com/a/48997284/1143850. You can then get port names with vpi_get_str() – Serge Mar 09 '18 at 02:41
  • Serge, Thank you for your response. Yes, your example code gave me enough info to start. Thanks!! – user2756376 Mar 09 '18 at 03:43

1 Answers1

0

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");
}

}
vrleboss
  • 463
  • 4
  • 24