Получение имен сигналов в проекте (с использованием вызовов VPI)
Я хотел бы получить список имен сигналов в данной иерархии дизайна из проекта Verilog с использованием vpi. Это простой интерфейс браузера сетевого имени из моего пользовательского инструмента, написанный на C и Python.
Как я могу получить список имен сигналов из дизайна Verilog и какие вызовы VPI я должен использовать для прохождения дизайна?
Любая информация будет принята с благодарностью.
1 ответ
В дополнение к ответу, который уже дан этот код, пройдитесь по вашей иерархии и сохраните объект дизайна типа vpiLogic
Вы можете адаптировать его к вашим потребностям. Он хранит полные имена реестра в unordered_map
который имеет хорошее время доступа O(1) во время симуляции.
Этот код был разработан для проектов, использующих как Verilog, так и VHDL.
Вы также обнаружите, что иногда некоторые IP-адреса защищены, что обрабатывается изящно, в дополнение к использованию областей видимости (vpiInternalScope
) вместо vpiModule
позволяет рекурсию внутри generate
заявления.
Это код 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");
}
}