获取设计中的信号名称(使用VPI调用)

时间:2018-03-06 19:00:29

标签: verilog vpi

我想从使用vpi的Verilog设计中获取给定设计层次结构中的信号名称列表。它是一个简单的网名浏览器界面,来自我的自定义工具,用C和Python编写。

如何从Verilog设计中获取信号名称列表以及我应该使用哪些VPI调用来完成设计?

任何信息都将不胜感激。

1 个答案:

答案 0 :(得分:0)

除了已经给出的答案,此代码遍历您的层次结构和类型vpiLogic的商店设计对象,您可以根据自己的需要进行调整。 它将寄存器的全名存储在unordered_map中,在模拟过程中具有良好的O(1)访问时间。

此代码是为使用verilog和VHDL的项目开发的。

您还会发现,有时一些IP受到保护,可以正常处理,此外,使用范围(vpiInternalScope)而不是vpiModule允许在generate语句中进行递归。< / p>

它是c ++代码,但extern "C"的使用使其可以从您的EDA工具调用(使用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");
}

}