Co-authored-by: Christian Hecken <christian.hecken@ibm.com>
This commit is contained in:
parent
3097df46fa
commit
0019c12242
|
|
@ -2233,11 +2233,6 @@ static bool vl_vpi_parse_indices(std::string& name, std::vector<PLI_INT32>& indi
|
|||
VlVpiBitRange* bitRange = nullptr) {
|
||||
if (name.empty() || name.back() != ']') return false;
|
||||
|
||||
// Collapse consecutive spaces into single spaces
|
||||
name.erase(
|
||||
std::unique(name.begin(), name.end(), [](char a, char b) { return a == ' ' && b == ' '; }),
|
||||
name.end());
|
||||
|
||||
// Only parse brackets after the last escaped identifier's terminating space
|
||||
size_t escapeSpacePos = std::string::npos;
|
||||
const size_t backslashPos = name.rfind('\\');
|
||||
|
|
@ -2307,12 +2302,16 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
|
|||
if (VL_UNLIKELY(!namep)) return nullptr;
|
||||
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_handle_by_name %s %p\n", namep, scope););
|
||||
|
||||
// Parse any array indices and optional bit range from the name
|
||||
// e.g., "mem[0][3][2]" or "signal[15:8]" or "mem[0][3][15:8]"
|
||||
std::string scopeAndName = namep;
|
||||
|
||||
// Collapse consecutive spaces into single spaces (can occur with escaped identifiers)
|
||||
scopeAndName.erase(std::unique(scopeAndName.begin(), scopeAndName.end(),
|
||||
[](char a, char b) { return a == ' ' && b == ' '; }),
|
||||
scopeAndName.end());
|
||||
|
||||
static thread_local std::vector<PLI_INT32> indices;
|
||||
VlVpiBitRange bitRange;
|
||||
const bool hasIndices = vl_vpi_parse_indices(scopeAndName, indices, &bitRange);
|
||||
bool hasIndices = false;
|
||||
|
||||
const VerilatedVar* varp = nullptr;
|
||||
const VerilatedScope* scopep;
|
||||
|
|
@ -2328,6 +2327,9 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
|
|||
{
|
||||
// This doesn't yet follow the hierarchy in the proper way
|
||||
bool isPackage = false;
|
||||
|
||||
// Scopes in generate blocks can also end with an index, so look it up first before
|
||||
// interpreting the trailing brackets as array indices or bit selects.
|
||||
scopep = Verilated::threadContextp()->scopeFind(scopeAndName.c_str());
|
||||
if (scopep) { // Whole thing found as a scope
|
||||
if (scopep->type() == VerilatedScope::SCOPE_MODULE) {
|
||||
|
|
@ -2367,6 +2369,11 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
|
|||
scopename = scopeAndName.substr(0, pos);
|
||||
if (scopename == "$unit") scopename = "\\$unit ";
|
||||
}
|
||||
|
||||
// Parse any array indices and optional bit range from the name
|
||||
// e.g., "mem[0][3][2]" or "signal[15:8]" or "mem[0][3][15:8]"
|
||||
hasIndices = vl_vpi_parse_indices(basename, indices, &bitRange);
|
||||
|
||||
if (prevpos == std::string::npos) {
|
||||
// scopename is a toplevel (no '.' separator), so search in our TOP ports first.
|
||||
scopep = Verilated::threadContextp()->scopeFind("TOP");
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "vpi_user.h"
|
||||
#ifdef IS_VPI
|
||||
|
||||
#include "sv_vpi_user.h"
|
||||
|
|
@ -1215,6 +1216,38 @@ int _mon_check_multi_index() {
|
|||
CHECK_RESULT(vpi_get(vpiSize, vh_two_escapes_ps), 4);
|
||||
}
|
||||
|
||||
// vpi_handle_by_name with generated signal
|
||||
{
|
||||
// Retrieve signal
|
||||
TestVpiHandle vh_generated = vpi_handle_by_name((PLI_BYTE8*)"t.gen[0].gen_sig", NULL);
|
||||
CHECK_RESULT_NZ(vh_generated);
|
||||
CHECK_RESULT(vpi_get(vpiType, vh_generated), vpiReg);
|
||||
CHECK_RESULT(vpi_get(vpiSize, vh_generated), 8);
|
||||
vpi_get_value(vh_generated, &v);
|
||||
CHECK_RESULT(v.value.integer, 0xAB);
|
||||
|
||||
// Single bit indexing
|
||||
TestVpiHandle vh_generated_bit
|
||||
= vpi_handle_by_name((PLI_BYTE8*)"t.gen[0].gen_sig[3]", NULL);
|
||||
CHECK_RESULT_NZ(vh_generated_bit);
|
||||
CHECK_RESULT(vpi_get(vpiType, vh_generated_bit), vpiReg);
|
||||
CHECK_RESULT(vpi_get(vpiSize, vh_generated_bit), 1);
|
||||
vpi_get_value(vh_generated_bit, &v);
|
||||
CHECK_RESULT(v.value.integer, 1);
|
||||
|
||||
// Generated scope
|
||||
TestVpiHandle vh_generated_scope = vpi_handle_by_name((PLI_BYTE8*)"t.subs[1]", NULL);
|
||||
CHECK_RESULT_NZ(vh_generated_scope);
|
||||
CHECK_RESULT(vpi_get(vpiType, vh_generated_scope), vpiGenScope);
|
||||
|
||||
// Signal in generated instance
|
||||
TestVpiHandle vh_generated_inst
|
||||
= vpi_handle_by_name((PLI_BYTE8*)"t.subs[1].subsub.subsig1", NULL);
|
||||
CHECK_RESULT_NZ(vh_generated_inst);
|
||||
CHECK_RESULT(vpi_get(vpiType, vh_generated_inst), vpiReg);
|
||||
CHECK_RESULT(vpi_get(vpiSize, vh_generated_inst), 1);
|
||||
}
|
||||
|
||||
// vpi_handle_by_name with array indexing
|
||||
{
|
||||
TestVpiHandle vh_1d = vpi_handle_by_name((PLI_BYTE8*)"t.quads[2]", nullptr);
|
||||
|
|
|
|||
|
|
@ -76,6 +76,12 @@ extern "C" int mon_check();
|
|||
|
||||
logic [31:0] some_mem [4] /* verilator public_flat_rd */ = {0, 0, 0, 432};
|
||||
|
||||
generate
|
||||
for (genvar i = 0; i < 1; i++) begin : gen
|
||||
wire [7:0] gen_sig /*verilator public_flat_rw*/ = 8'hAB;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
sub sub();
|
||||
|
||||
// Test loop
|
||||
|
|
|
|||
|
|
@ -94,6 +94,12 @@ extern "C" int mon_check();
|
|||
logic [31:0] some_mem [4] = {0, 0, 0, 432};
|
||||
/*verilator public_off*/
|
||||
|
||||
generate
|
||||
for (genvar i = 0; i < 1; i++) begin : gen
|
||||
wire [7:0] gen_sig /*verilator public_flat_rw*/ = 8'hAB;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
sub sub();
|
||||
|
||||
// Test loop
|
||||
|
|
|
|||
|
|
@ -74,6 +74,12 @@ extern "C" int mon_check();
|
|||
localparam int nullptr = 123;
|
||||
logic [31:0] some_mem [4] = {0, 0, 0, 432};
|
||||
|
||||
generate
|
||||
for (genvar i = 0; i < 1; i++) begin : gen
|
||||
wire [7:0] gen_sig /*verilator public_flat_rw*/ = 8'hAB;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
sub sub();
|
||||
|
||||
// Test loop
|
||||
|
|
|
|||
Loading…
Reference in New Issue