mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Support VPI parameter iteration (#4765)
This commit is contained in:
parent
668dbb25ab
commit
1066f06ec1
@ -382,10 +382,12 @@ class VerilatedVpioVarIter final : public VerilatedVpio {
|
||||
VerilatedVarNameMap::const_iterator m_it;
|
||||
bool m_started = false;
|
||||
const VerilatedScope* m_topscopep = nullptr;
|
||||
bool m_onlyParams;
|
||||
|
||||
public:
|
||||
explicit VerilatedVpioVarIter(const VerilatedVpioScope* vop)
|
||||
: m_scopep{vop->scopep()} {
|
||||
explicit VerilatedVpioVarIter(const VerilatedVpioScope* vop, bool onlyParams = false)
|
||||
: m_scopep{vop->scopep()}
|
||||
, m_onlyParams{onlyParams} {
|
||||
if (VL_UNLIKELY(vop->toplevel()))
|
||||
// This is a toplevel, so get TOP scope to search for ports during vpi_scan.
|
||||
m_topscopep = Verilated::threadContextp()->scopeFind("TOP");
|
||||
@ -396,7 +398,11 @@ public:
|
||||
}
|
||||
uint32_t type() const override { return vpiIterator; }
|
||||
vpiHandle dovpi_scan() override {
|
||||
if (VL_LIKELY(m_scopep->varsp())) {
|
||||
if (VL_UNLIKELY(!m_scopep->varsp())) {
|
||||
delete this; // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
|
||||
return nullptr; // End of list - only one deep
|
||||
}
|
||||
while (true) {
|
||||
const VerilatedVarNameMap* const varsp = m_scopep->varsp();
|
||||
if (VL_UNLIKELY(!m_started)) {
|
||||
m_it = varsp->begin();
|
||||
@ -411,14 +417,13 @@ public:
|
||||
delete this; // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
|
||||
return nullptr;
|
||||
}
|
||||
if (m_onlyParams && !m_it->second.isParam()) continue;
|
||||
if (VL_UNLIKELY(m_topscopep)) {
|
||||
if (const VerilatedVar* topvarp = m_topscopep->varFind(m_it->second.name()))
|
||||
return ((new VerilatedVpioVar{topvarp, m_topscopep})->castVpiHandle());
|
||||
}
|
||||
return ((new VerilatedVpioVar{&(m_it->second), m_scopep})->castVpiHandle());
|
||||
}
|
||||
delete this; // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
|
||||
return nullptr; // End of list - only one deep
|
||||
}
|
||||
};
|
||||
|
||||
@ -1922,6 +1927,11 @@ vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle object) {
|
||||
if (VL_UNLIKELY(!vop)) return nullptr;
|
||||
return ((new VerilatedVpioVarIter{vop})->castVpiHandle());
|
||||
}
|
||||
case vpiParameter: {
|
||||
const VerilatedVpioScope* const vop = VerilatedVpioScope::castp(object);
|
||||
if (VL_UNLIKELY(!vop)) return nullptr;
|
||||
return ((new VerilatedVpioVarIter{vop, true})->castVpiHandle());
|
||||
}
|
||||
case vpiModule: {
|
||||
const VerilatedVpioModule* const vop = VerilatedVpioModule::castp(object);
|
||||
const VerilatedHierarchyMap* const map = VerilatedImp::hierarchyMap();
|
||||
|
@ -68,12 +68,29 @@
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
int count_params(TestVpiHandle& handle, int expectedParams) {
|
||||
TestVpiHandle it = vpi_iterate(vpiParameter, handle);
|
||||
CHECK_RESULT_NZ(it)
|
||||
|
||||
int params = 0;
|
||||
while (true) {
|
||||
TestVpiHandle handle = vpi_scan(it);
|
||||
if (handle == NULL) break;
|
||||
params++;
|
||||
}
|
||||
it.freed();
|
||||
CHECK_RESULT(params, expectedParams);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mon_check() {
|
||||
#ifdef TEST_VERBOSE
|
||||
printf("-mon_check()\n");
|
||||
#endif
|
||||
|
||||
TestVpiHandle it = vpi_iterate(vpiModule, NULL);
|
||||
CHECK_RESULT_NZ(it)
|
||||
|
||||
bool found_t = false;
|
||||
while (true) {
|
||||
@ -87,10 +104,11 @@ int mon_check() {
|
||||
CHECK_RESULT_NZ(found_t);
|
||||
|
||||
it = vpi_iterate(vpiInstance, NULL);
|
||||
CHECK_RESULT_NZ(it)
|
||||
|
||||
found_t = false;
|
||||
bool found_somepackage = false;
|
||||
bool found_dollar_unit = false;
|
||||
TestVpiHandle pkgHandle = NULL;
|
||||
TestVpiHandle tHandle = NULL;
|
||||
TestVpiHandle unitHandle = NULL;
|
||||
while (true) {
|
||||
TestVpiHandle handle = vpi_scan(it);
|
||||
if (handle == NULL) break;
|
||||
@ -98,24 +116,31 @@ int mon_check() {
|
||||
const char* fullname = vpi_get_str(vpiFullName, handle);
|
||||
if (!strcmp("t", name)) {
|
||||
CHECK_RESULT_CSTR("t", fullname)
|
||||
CHECK_RESULT_Z(found_t)
|
||||
found_t = true;
|
||||
CHECK_RESULT_Z(tHandle)
|
||||
tHandle = handle;
|
||||
handle.freed();
|
||||
} else if (!strcmp("somepackage", name)) {
|
||||
CHECK_RESULT_CSTR("somepackage::", fullname)
|
||||
CHECK_RESULT_Z(found_somepackage)
|
||||
found_somepackage = true;
|
||||
CHECK_RESULT_Z(pkgHandle)
|
||||
pkgHandle = handle;
|
||||
handle.freed();
|
||||
} else if (!strcmp("$unit", name)) {
|
||||
CHECK_RESULT_CSTR("$unit::", fullname)
|
||||
CHECK_RESULT_Z(found_dollar_unit)
|
||||
found_dollar_unit = true;
|
||||
CHECK_RESULT_Z(unitHandle)
|
||||
unitHandle = handle;
|
||||
handle.freed();
|
||||
} else {
|
||||
CHECK_RESULT_NZ(0)
|
||||
}
|
||||
}
|
||||
it.freed();
|
||||
CHECK_RESULT_NZ(found_t)
|
||||
CHECK_RESULT_NZ(found_somepackage)
|
||||
CHECK_RESULT_NZ(found_dollar_unit)
|
||||
CHECK_RESULT_NZ(pkgHandle)
|
||||
CHECK_RESULT_NZ(tHandle)
|
||||
CHECK_RESULT_NZ(unitHandle)
|
||||
|
||||
CHECK_RESULT_Z(count_params(unitHandle, 1));
|
||||
CHECK_RESULT_Z(count_params(pkgHandle, 2));
|
||||
CHECK_RESULT_Z(count_params(tHandle, 3));
|
||||
|
||||
return 0; // Ok
|
||||
}
|
||||
|
@ -12,12 +12,15 @@ parameter int dollarUnitInt /*verilator public_flat_rd*/ = 3;
|
||||
|
||||
package somepackage;
|
||||
parameter int someInt /*verilator public_flat_rd*/ = 5;
|
||||
parameter int anotherInt /*verilator public_flat_rd*/ = 6;
|
||||
endpackage
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
); /*verilator public_module*/
|
||||
|
||||
parameter int someOtherInt /* verilator public_flat_rd*/ = 7;
|
||||
parameter int yetAnotherInt /* verilator public_flat_rd*/ = 9;
|
||||
parameter int stillAnotherInt /* verilator public_flat_rd*/ = 17;
|
||||
|
||||
integer status;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user