Support packages in vpi_handle_by_name() (#4768)

This commit is contained in:
Todd Strader 2023-12-15 17:32:23 -05:00 committed by GitHub
parent 1066f06ec1
commit 5ec9bfc47d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 3 deletions

View File

@ -1744,15 +1744,19 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
const VerilatedVpioScope* const voScopep = VerilatedVpioScope::castp(scope);
std::string scopeAndName = namep;
if (voScopep) {
scopeAndName = std::string{voScopep->fullname()} + "." + namep;
const bool scopeIsPackage = VerilatedVpioPackage::castp(scope) != nullptr;
scopeAndName = std::string{voScopep->fullname()} + (scopeIsPackage ? "" : ".") + namep;
namep = const_cast<PLI_BYTE8*>(scopeAndName.c_str());
}
{
// This doesn't yet follow the hierarchy in the proper way
bool isPackage = false;
scopep = Verilated::threadContextp()->scopeFind(namep);
if (scopep) { // Whole thing found as a scope
if (scopep->type() == VerilatedScope::SCOPE_MODULE) {
return (new VerilatedVpioModule{scopep})->castVpiHandle();
} else if (scopep->type() == VerilatedScope::SCOPE_PACKAGE) {
return (new VerilatedVpioPackage{scopep})->castVpiHandle();
} else {
return (new VerilatedVpioScope{scopep})->castVpiHandle();
}
@ -1768,17 +1772,23 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
while (i < scopeAndName.length() && scopeAndName[i] != ' ') ++i;
++i; // Proc ' ', it should always be there. Then grab '.' on next cycle
} else {
while (i < scopeAndName.length() && scopeAndName[i] != '.') ++i;
while (i < scopeAndName.length()
&& (scopeAndName[i] != '.'
&& (i + 1 >= scopeAndName.length() || scopeAndName[i] != ':'
|| scopeAndName[i + 1] != ':')))
++i;
if (i < scopeAndName.length()) {
prevpos = pos;
pos = i++;
if (scopeAndName[i - 1] == ':') isPackage = true;
}
}
}
// Do the split
if (VL_LIKELY(pos != std::string::npos)) {
basename.erase(0, pos + 1);
basename.erase(0, pos + (isPackage ? 2 : 1));
scopename = scopeAndName.substr(0, pos);
if (scopename == "$unit") scopename = "\\$unit ";
}
if (prevpos == std::string::npos) {
// scopename is a toplevel (no '.' separator), so search in our TOP ports first.

View File

@ -84,6 +84,12 @@ int count_params(TestVpiHandle& handle, int expectedParams) {
return 0;
}
int check_handle(char* name, vpiHandle scopeHandle) {
const TestVpiHandle handle = vpi_handle_by_name(name, scopeHandle);
CHECK_RESULT_NZ(handle)
return 0;
}
int mon_check() {
#ifdef TEST_VERBOSE
printf("-mon_check()\n");
@ -142,6 +148,14 @@ int mon_check() {
CHECK_RESULT_Z(count_params(pkgHandle, 2));
CHECK_RESULT_Z(count_params(tHandle, 3));
CHECK_RESULT_Z(check_handle(const_cast<PLI_BYTE8*>("someOtherInt"), tHandle))
CHECK_RESULT_Z(check_handle(const_cast<PLI_BYTE8*>("t.someOtherInt"), NULL))
CHECK_RESULT_Z(check_handle(const_cast<PLI_BYTE8*>("someInt"), pkgHandle))
CHECK_RESULT_Z(check_handle(const_cast<PLI_BYTE8*>("somepackage::someInt"), NULL))
CHECK_RESULT_Z(check_handle(const_cast<PLI_BYTE8*>("dollarUnitInt"), unitHandle))
CHECK_RESULT_Z(check_handle(const_cast<PLI_BYTE8*>("$unit::dollarUnitInt"), NULL))
CHECK_RESULT_Z(check_handle(const_cast<PLI_BYTE8*>("somepackage"), NULL))
return 0; // Ok
}
}