Change control file `public_flat_*` and other signal attributes to support __ in names (#6140).
This commit is contained in:
parent
d1462f3120
commit
d89df33fcd
1
Changes
1
Changes
|
@ -14,6 +14,7 @@ Verilator 5.039 devel
|
|||
**Other:**
|
||||
|
||||
* Support disable dotted references (#6154). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Change control file `public_flat_*` and other signal attributes to support __ in names (#6140).
|
||||
* Fix class extends dotted error (#6162). [Igor Zaworski]
|
||||
* Fix genvar error with `-O0` (#6165). [Max Wipfli]
|
||||
|
||||
|
|
|
@ -2222,6 +2222,9 @@ public:
|
|||
// ACCESSORS
|
||||
virtual string name() const VL_MT_STABLE { return ""; }
|
||||
virtual string origName() const { return ""; }
|
||||
string prettyOrigOrName() const {
|
||||
return prettyName(origName().empty() ? name() : origName());
|
||||
}
|
||||
virtual void name(const string& name) {
|
||||
this->v3fatalSrc("name() called on object without name() method");
|
||||
}
|
||||
|
|
|
@ -2604,6 +2604,8 @@ void AstVar::dump(std::ostream& str) const {
|
|||
if (isPulldown()) str << " [PULLDOWN]";
|
||||
if (isUsedClock()) str << " [CLK]";
|
||||
if (isSigPublic()) str << " [P]";
|
||||
if (isSigUserRdPublic()) str << " [PRD]";
|
||||
if (isSigUserRWPublic()) str << " [PWR]";
|
||||
if (isInternal()) str << " [INTERNAL]";
|
||||
if (isLatched()) str << " [LATCHED]";
|
||||
if (isUsedLoopIdx()) str << " [LOOP]";
|
||||
|
|
|
@ -276,7 +276,7 @@ public:
|
|||
const VPragmaType pragma = VPragmaType::COVERAGE_BLOCK_OFF;
|
||||
if (!nodep->unnamed()) {
|
||||
for (const string& i : m_coverageOffBlocks) {
|
||||
if (VString::wildmatch(nodep->name(), i)) {
|
||||
if (VString::wildmatch(nodep->prettyOrigOrName(), i)) {
|
||||
nodep->addStmtsp(new AstPragma{nodep->fileline(), pragma});
|
||||
}
|
||||
}
|
||||
|
@ -732,7 +732,7 @@ void V3Control::applyCoverageBlock(AstNodeModule* modulep, AstBegin* nodep) {
|
|||
const string& filename = nodep->fileline()->filename();
|
||||
V3ControlFile* const filep = V3ControlResolver::s().files().resolve(filename);
|
||||
if (filep) filep->applyBlock(nodep);
|
||||
const string& modname = modulep->name();
|
||||
const string& modname = modulep->prettyOrigOrName();
|
||||
V3ControlModule* const modp = V3ControlResolver::s().modules().resolve(modname);
|
||||
if (modp) modp->applyBlock(nodep);
|
||||
}
|
||||
|
@ -744,29 +744,30 @@ void V3Control::applyIgnores(FileLine* filelinep) {
|
|||
}
|
||||
|
||||
void V3Control::applyModule(AstNodeModule* modulep) {
|
||||
const string& modname = modulep->origName();
|
||||
const string& modname = modulep->prettyOrigOrName();
|
||||
V3ControlModule* const modp = V3ControlResolver::s().modules().resolve(modname);
|
||||
if (modp) modp->apply(modulep);
|
||||
}
|
||||
|
||||
void V3Control::applyFTask(AstNodeModule* modulep, AstNodeFTask* ftaskp) {
|
||||
const string& modname = modulep->name();
|
||||
const string& modname = modulep->prettyOrigOrName();
|
||||
V3ControlModule* const modp = V3ControlResolver::s().modules().resolve(modname);
|
||||
if (!modp) return;
|
||||
const V3ControlFTask* const ftp = modp->ftasks().resolve(ftaskp->name());
|
||||
const V3ControlFTask* const ftp = modp->ftasks().resolve(ftaskp->prettyOrigOrName());
|
||||
if (ftp) ftp->apply(ftaskp);
|
||||
}
|
||||
|
||||
void V3Control::applyVarAttr(AstNodeModule* modulep, AstNodeFTask* ftaskp, AstVar* varp) {
|
||||
V3ControlVar* vp;
|
||||
V3ControlModule* const modp = V3ControlResolver::s().modules().resolve(modulep->name());
|
||||
V3ControlModule* const modp
|
||||
= V3ControlResolver::s().modules().resolve(modulep->prettyOrigOrName());
|
||||
if (!modp) return;
|
||||
if (ftaskp) {
|
||||
V3ControlFTask* const ftp = modp->ftasks().resolve(ftaskp->name());
|
||||
V3ControlFTask* const ftp = modp->ftasks().resolve(ftaskp->prettyOrigOrName());
|
||||
if (!ftp) return;
|
||||
vp = ftp->vars().resolve(varp->name());
|
||||
vp = ftp->vars().resolve(varp->prettyOrigOrName());
|
||||
} else {
|
||||
vp = modp->vars().resolve(varp->name());
|
||||
vp = modp->vars().resolve(varp->prettyOrigOrName());
|
||||
}
|
||||
if (vp) vp->apply(varp);
|
||||
}
|
||||
|
|
|
@ -8087,8 +8087,10 @@ vltDModule<strp>: // --module <arg>
|
|||
;
|
||||
|
||||
vltDModuleE<strp>: // [--module <arg>]
|
||||
/* empty */ { static string unit = "__024unit"; $$ = &unit; }
|
||||
| vltDModule { $$ = $1; }
|
||||
/* empty */
|
||||
{ static string unit = "$unit"; $$ = &unit; } // .vlt uses prettyName
|
||||
| vltDModule
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
vltDScope<strp>: // --scope <arg>
|
||||
|
|
|
@ -25,19 +25,18 @@ test.compile(make_top_shell=False,
|
|||
if test.vlt_all:
|
||||
test.file_grep(
|
||||
out_filename,
|
||||
r'{"type":"VAR","name":"formatted","addr":"[^"]*","loc":"\w,58:[^"]*",.*"origName":"formatted",.*"direction":"INPUT",.*"dtypeName":"string",.*"attrSFormat":true'
|
||||
r'{"type":"VAR","name":"formatted",.*"origName":"formatted",.*"direction":"INPUT",.*"attrSFormat":true'
|
||||
)
|
||||
test.file_grep(
|
||||
out_filename,
|
||||
r'{"type":"VAR","name":"t.sub.in","addr":"[^"]*","loc":"\w,81:[^"]*",.*"origName":"in",.*"dtypeName":"int",.*"isSigUserRdPublic":true'
|
||||
r'{"type":"VAR","name":"t.sub.in",.*"origName":"in",.*"isSigUserRdPublic":true')
|
||||
test.file_grep(
|
||||
out_filename,
|
||||
r'{"type":"VAR","name":"t.sub.fr_a",.*"origName":"fr_a",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true'
|
||||
)
|
||||
test.file_grep(
|
||||
out_filename,
|
||||
r'{"type":"VAR","name":"t.sub.fr_a","addr":"[^"]*","loc":"\w,82:[^"]*",.*"origName":"fr_a",.*"dtypeName":"int",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true'
|
||||
)
|
||||
test.file_grep(
|
||||
out_filename,
|
||||
r'{"type":"VAR","name":"t.sub.fr_b","addr":"[^"]*","loc":"\w,83:[^"]*",.*"origName":"fr_b",.*"dtypeName":"int",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true'
|
||||
r'{"type":"VAR","name":"t.sub.fr_b",.*"origName":"fr_b",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true'
|
||||
)
|
||||
|
||||
test.execute()
|
||||
|
|
|
@ -58,7 +58,13 @@ const char* _my_rooted(const char* obj) {
|
|||
return buf.c_str();
|
||||
}
|
||||
|
||||
#define MY_VPI_HANDLE(signal) vpi_handle_by_name(const_cast<PLI_BYTE8*>(_my_rooted(signal)), NULL);
|
||||
TestVpiHandle my_vpi_handle(const char* signal) {
|
||||
#ifdef TEST_VERBOSE
|
||||
printf("-my_vpi_handle(\"%s\")\n", _my_rooted(signal));
|
||||
#endif
|
||||
TestVpiHandle vh = vpi_handle_by_name(const_cast<PLI_BYTE8*>(_my_rooted(signal)), NULL);
|
||||
return vh;
|
||||
}
|
||||
|
||||
int _mon_check_var() {
|
||||
#ifdef TEST_VERBOSE
|
||||
|
@ -67,7 +73,7 @@ int _mon_check_var() {
|
|||
TestVpiHandle vh1 = vpi_handle_by_name(const_cast<PLI_BYTE8*>(_sim_top()), NULL);
|
||||
TEST_CHECK_NZ(vh1);
|
||||
|
||||
TestVpiHandle vh2 = MY_VPI_HANDLE("\\check;alias ");
|
||||
TestVpiHandle vh2 = my_vpi_handle("\\check;alias ");
|
||||
TEST_CHECK_NZ(vh2);
|
||||
|
||||
// scope attributes
|
||||
|
@ -107,15 +113,29 @@ int _mon_check_var() {
|
|||
TEST_CHECK_CSTR(p, "vpiNet");
|
||||
}
|
||||
|
||||
TestVpiHandle vh4 = MY_VPI_HANDLE("\\x.y ");
|
||||
TestVpiHandle vh4 = my_vpi_handle("\\x.y ");
|
||||
TEST_CHECK_NZ(vh4);
|
||||
|
||||
// Test that the toplevel TOP.xxxxx search is skipped
|
||||
// when the path to the scope has more than one level.
|
||||
TestVpiHandle vh5 = MY_VPI_HANDLE("\\mod.with_dot .\\b.c ");
|
||||
TEST_CHECK_NZ(vh5);
|
||||
p = vpi_get_str(vpiFullName, vh5);
|
||||
TEST_CHECK_CSTR(p, "\\t.has.dots .\\mod.with_dot .\\b.c ");
|
||||
{
|
||||
TestVpiHandle vh5 = my_vpi_handle("\\mod.with_dot .\\b.c ");
|
||||
TEST_CHECK_NZ(vh5);
|
||||
p = vpi_get_str(vpiFullName, vh5);
|
||||
TEST_CHECK_CSTR(p, "\\t.has.dots .\\mod.with_dot .\\b.c ");
|
||||
}
|
||||
{
|
||||
TestVpiHandle vh5 = my_vpi_handle("double__underscore");
|
||||
TEST_CHECK_NZ(vh5);
|
||||
p = vpi_get_str(vpiFullName, vh5);
|
||||
TEST_CHECK_CSTR(p, "TOP.double__underscore");
|
||||
}
|
||||
{
|
||||
TestVpiHandle vh5 = my_vpi_handle("double__underscore__vlt");
|
||||
TEST_CHECK_NZ(vh5);
|
||||
p = vpi_get_str(vpiFullName, vh5);
|
||||
TEST_CHECK_CSTR(p, "TOP.double__underscore__vlt");
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
@ -126,7 +146,7 @@ int _mon_check_iter() {
|
|||
#endif
|
||||
const char* p;
|
||||
|
||||
TestVpiHandle vh2 = MY_VPI_HANDLE("\\mod.with_dot ");
|
||||
TestVpiHandle vh2 = my_vpi_handle("\\mod.with_dot ");
|
||||
TEST_CHECK_NZ(vh2);
|
||||
p = vpi_get_str(vpiName, vh2);
|
||||
TEST_CHECK_CSTR(p, "\\mod.with_dot ");
|
||||
|
@ -135,12 +155,12 @@ int _mon_check_iter() {
|
|||
TEST_CHECK_CSTR(p, "sub");
|
||||
}
|
||||
|
||||
TestVpiHandle vh_null_name = MY_VPI_HANDLE("___0_");
|
||||
TestVpiHandle vh_null_name = my_vpi_handle("___0_");
|
||||
TEST_CHECK_NZ(vh_null_name);
|
||||
p = vpi_get_str(vpiName, vh_null_name);
|
||||
TEST_CHECK_CSTR(p, "___0_");
|
||||
|
||||
TestVpiHandle vh_hex_name = MY_VPI_HANDLE("___0F_");
|
||||
TestVpiHandle vh_hex_name = my_vpi_handle("___0F_");
|
||||
TEST_CHECK_NZ(vh_hex_name);
|
||||
p = vpi_get_str(vpiName, vh_hex_name);
|
||||
TEST_CHECK_CSTR(p, "___0F_");
|
||||
|
@ -198,7 +218,7 @@ int _mon_check_ports() {
|
|||
printf("-mon_check_ports()\n");
|
||||
#endif
|
||||
// test writing to input port
|
||||
TestVpiHandle vh1 = MY_VPI_HANDLE("a");
|
||||
TestVpiHandle vh1 = my_vpi_handle("a");
|
||||
TEST_CHECK_NZ(vh1);
|
||||
|
||||
PLI_INT32 d;
|
||||
|
@ -236,7 +256,7 @@ int _mon_check_ports() {
|
|||
TEST_CHECK_EQ(v.value.integer, 2);
|
||||
|
||||
// get handle of toplevel module
|
||||
TestVpiHandle vht = MY_VPI_HANDLE("");
|
||||
TestVpiHandle vht = my_vpi_handle("");
|
||||
TEST_CHECK_NZ(vht);
|
||||
|
||||
d = vpi_get(vpiType, vht);
|
||||
|
@ -263,7 +283,7 @@ int _mon_check_ports() {
|
|||
|
||||
TEST_CHECK_EQ(handleName1, handleName2);
|
||||
|
||||
TestVpiHandle vh2 = MY_VPI_HANDLE("\\b.c ");
|
||||
TestVpiHandle vh2 = my_vpi_handle("\\b.c ");
|
||||
TEST_CHECK_NZ(vh2);
|
||||
|
||||
if (TestSimulator::is_verilator()) {
|
||||
|
|
|
@ -18,7 +18,7 @@ test.compile(make_top_shell=False,
|
|||
sim_time=100,
|
||||
iv_flags2=["-g2005-sv -D USE_VPI_NOT_DPI -DWAVES"],
|
||||
v_flags2=["+define+USE_VPI_NOT_DPI"],
|
||||
verilator_flags2=["--exe --vpi --no-l2name --public-flat-rw", test.pli_filename])
|
||||
verilator_flags2=["--exe --vpi --no-l2name t/t_vpi_escape.vlt", test.pli_filename])
|
||||
|
||||
test.execute(
|
||||
# run_env = "VPI_TRACE=" . Cwd::getcwd() . "/" + test.obj_dir + "/" + test.name + "_vpi.log",
|
||||
|
|
|
@ -13,11 +13,12 @@ import "DPI-C" context function int mon_check();
|
|||
`endif
|
||||
|
||||
module \t.has.dots (/*AUTOARG*/
|
||||
// Outputs
|
||||
\escaped_normal , double__underscore, \9num , \bra[ket]slash/dash-colon:9backslash\done , \x.y ,
|
||||
// Inputs
|
||||
clk, \b.c , a
|
||||
);
|
||||
// Outputs
|
||||
\escaped_normal , double__underscore, double__underscore__vlt, \9num ,
|
||||
\bra[ket]slash/dash-colon:9backslash\done , \x.y ,
|
||||
// Inputs
|
||||
clk, a, \b.c
|
||||
);
|
||||
|
||||
`ifdef VERILATOR
|
||||
`systemc_header
|
||||
|
@ -26,16 +27,18 @@ extern "C" int mon_check();
|
|||
`endif
|
||||
|
||||
input clk;
|
||||
input [7:0] a;
|
||||
input \b.c ;
|
||||
input [7:0] a /*verilator public_flat_rw*/;
|
||||
input \b.c /*verilator public_flat_rw*/;
|
||||
|
||||
integer cyc; initial cyc=1;
|
||||
int cyc /*verilator public_flat_rd*/;
|
||||
|
||||
output \escaped_normal ;
|
||||
output \escaped_normal /*verilator public_flat_rd*/;
|
||||
wire \escaped_normal = cyc[0];
|
||||
|
||||
output double__underscore ;
|
||||
output double__underscore /*verilator public_flat_rd*/;
|
||||
wire double__underscore = cyc[0];
|
||||
output double__underscore__vlt; // public in .vlt
|
||||
wire double__underscore__vlt = cyc[0];
|
||||
|
||||
// C doesn't allow leading non-alpha, so must escape
|
||||
output \9num ;
|
||||
|
@ -44,14 +47,14 @@ extern "C" int mon_check();
|
|||
output \bra[ket]slash/dash-colon:9backslash\done ;
|
||||
wire \bra[ket]slash/dash-colon:9backslash\done = cyc[0];
|
||||
|
||||
output \x.y ;
|
||||
output \x.y /*verilator public_flat_rd*/;
|
||||
wire \x.y = cyc[0];
|
||||
|
||||
wire \wire = cyc[0];
|
||||
|
||||
wire \check_alias = cyc[0];
|
||||
wire \check:alias = cyc[0];
|
||||
wire \check;alias = !cyc[0];
|
||||
wire \check_alias /*verilator public_flat_rd*/ = cyc[0];
|
||||
wire \check:alias /*verilator public_flat_rd*/ = cyc[0];
|
||||
wire \check;alias /*verilator public_flat_rd*/ = !cyc[0];
|
||||
|
||||
// These are *different entities*, bug83
|
||||
wire [31:0] \a0.cyc = ~a0.cyc;
|
||||
|
@ -110,11 +113,11 @@ extern "C" int mon_check();
|
|||
endmodule
|
||||
|
||||
module sub (
|
||||
input [31:0] cyc
|
||||
input [31:0] cyc /*verilator public_flat_rd*/
|
||||
);
|
||||
reg \b.c ;
|
||||
reg subsig1;
|
||||
reg subsig2;
|
||||
reg \b.c /*verilator public_flat_rw*/;
|
||||
reg subsig1 /*verilator public_flat_rd*/;
|
||||
reg subsig2 /*verilator public_flat_rd*/;
|
||||
`ifdef IVERILOG
|
||||
// stop icarus optimizing signals away
|
||||
wire redundant = subsig1 | subsig2 | \b.c ;
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`verilator_config
|
||||
|
||||
public_flat_rd -module "*" -var "double__underscore__vlt"
|
Loading…
Reference in New Issue