Получение имен сигналов в проекте (с использованием вызовов 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");
}

}
Другие вопросы по тегам