diff --git a/Changes b/Changes index c8e12875b..71b46c9f1 100644 --- a/Changes +++ b/Changes @@ -9,6 +9,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix error on bad interface name, bug1097. [Todd Strader] +**** Fix error on referencing variable in parent, bug1099. [Ian Thompson] + **** Fix type parameters with low optimization, bug1101. [Stefan Wallentowitz] diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index a7ec049c9..bc42487b0 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -490,7 +490,7 @@ public: } } UINFO(8," id "<origModName() == ident)) {} // Move up and check cellname + modname else { + bool crossedCell = false; // Crossed a cell boundary while (lookupSymp) { lookupSymp = lookupSymp->parentp(); cellp = lookupSymp ? lookupSymp->nodep()->castCell() : NULL; // Replicated above inlinep = lookupSymp ? lookupSymp->nodep()->castCellInline() : NULL; // Replicated above if (lookupSymp) { UINFO(9,"\t\tUp to "<modp()->origName() == ident) || (inlinep && inlinep->origModName() == ident)) { break; } else if (VSymEnt* findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) { lookupSymp = findSymp; + if (crossedCell && lookupSymp->nodep()->castVar()) { + UINFO(9,"\t\tNot found but matches var name in parent "<{vlt} or $Self->skip("Verilator only test"); +compile ( + v_flags2 => ["--lint-only"], + fails => 1, + verilator_make_gcc => 0, + make_top_shell => 0, + make_main => 0, + expect=> +'%Error: t/t_param_up_bad.v:\d+: Can\'t find definition of scope/variable: bar +.*%Error: Exiting due to.*', + ); + +ok(1); +1; diff --git a/test_regress/t/t_param_up_bad.v b/test_regress/t/t_param_up_bad.v new file mode 100644 index 000000000..d69afcb6b --- /dev/null +++ b/test_regress/t/t_param_up_bad.v @@ -0,0 +1,31 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2016 by Ian Thompson. + +//bug1099 + +typedef struct packed { + logic foo; +} some_struct_t; + +module child (); + logic a_bad; + // bar is in the parent module, but illegal to reference without module name + assign a_bad = bar.foo; +endmodule + +module parent + #( + parameter PARAM = 0 + ) + ( + ); + some_struct_t bar; + child c (); +endmodule + +module t (); + // The parameter must be anything other than the default + parent #( 1 ) p (); +endmodule