diff --git a/Changes b/Changes index fc6f1462f..1b34dfc80 100644 --- a/Changes +++ b/Changes @@ -24,13 +24,15 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Add --flatten for use with --xml-only, #2270. [James Hanlon] +**** Greatly improve FST/VCD dump performance, #2244, #2246, #2250, #2257. [Geza Lore] + **** Support $ferror, and $fflush without arguments, #1638. **** Support event data type (with some restrictions). -**** Add error if use SystemC 2.2 and earlier (pre-2011) as is deprecated. +**** Support $root, #2150. [Keyi Zhang] -**** Greatly improve FST/VCD dump performance, #2244, #2246, #2250, #2257. [Geza Lore] +**** Add error if use SystemC 2.2 and earlier (pre-2011) as is deprecated. **** Fix build of fast path tracing code to use OPT_FAST, #2245. [Geza Lore] diff --git a/src/V3Ast.h b/src/V3Ast.h index 68b7993d3..ae501831e 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -900,6 +900,7 @@ class VParseRefExp { public: enum en { PX_NONE, // Used in V3LinkParse only + PX_ROOT, PX_TEXT // Unknown ID component }; enum en m_e; @@ -912,7 +913,7 @@ public: : m_e(static_cast(_e)) {} operator en() const { return m_e; } const char* ascii() const { - static const char* const names[] = {"", "TEXT", "PREDOT"}; + static const char* const names[] = {"", "$root", "TEXT", "PREDOT"}; return names[m_e]; } }; diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 3a8adca4b..f113607b7 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -2812,8 +2812,8 @@ private: string m_name; public: - AstParseRef(FileLine* fl, VParseRefExp expect, const string& name, AstNode* lhsp, - AstNodeFTaskRef* ftaskrefp) + AstParseRef(FileLine* fl, VParseRefExp expect, const string& name, AstNode* lhsp = NULL, + AstNodeFTaskRef* ftaskrefp = NULL) : ASTGEN_SUPER(fl) , m_expect(expect) , m_name(name) { @@ -8401,6 +8401,7 @@ public: BROKEN_RTN(m_evalp && !m_evalp->brokeExists()); return NULL; } + virtual string name() const { return "$root"; } virtual void dump(std::ostream& str) const; AstNodeModule* modulesp() const { // op1 = List of modules return VN_CAST(op1p(), NodeModule); diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index d5c821922..9b080c9c4 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -587,6 +587,18 @@ public: else if ((cellp && cellp->modp()->origName() == ident) || (inlinep && inlinep->origModName() == ident)) { } + // $root we walk up to Netlist + else if (ident == "$root") { + lookupSymp = rootEntp(); + // We've added TOP module, now everything else is one lower + if (!m_forPrearray) { + VSymEnt* topSymp = lookupSymp->findIdFlat("TOP"); + if (!topSymp) { + topSymp->nodep()->v3fatalSrc("TOP not found under netlist for $root"); + } + lookupSymp = topSymp; + } + } // Move up and check cellname + modname else { bool crossedCell = false; // Crossed a cell boundary @@ -2079,6 +2091,7 @@ private: bool ok = false; if (!foundp) { } else if (VN_IS(foundp->nodep(), Cell) || VN_IS(foundp->nodep(), Begin) + || VN_IS(foundp->nodep(), Netlist) // for $root || VN_IS(foundp->nodep(), Module)) { // if top if (allowScope) { ok = true; diff --git a/src/verilog.l b/src/verilog.l index 239912a5f..77b30e29d 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -448,6 +448,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "$onehot0" { FL; return yD_ONEHOT0; } "$past" { FL; return yD_PAST; } "$right" { FL; return yD_RIGHT; } + "$root" { FL; return yD_ROOT; } "$size" { FL; return yD_SIZE; } "$unpacked_dimensions" { FL; return yD_UNPACKED_DIMENSIONS; } "$warning" { FL; return yD_WARNING; } @@ -527,7 +528,6 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "void" { FL; return yVOID; } /* Generic unsupported warnings */ /* Note assert_strobe was in SystemVerilog 3.1, but removed for SystemVerilog 2005 */ - "$root" { ERROR_RSVD_WORD("SystemVerilog 2005"); } "before" { ERROR_RSVD_WORD("SystemVerilog 2005"); } "bins" { ERROR_RSVD_WORD("SystemVerilog 2005"); } "binsof" { ERROR_RSVD_WORD("SystemVerilog 2005"); } diff --git a/src/verilog.y b/src/verilog.y index 2274068e9..d61235675 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -613,6 +613,7 @@ class AstSenTree; %token yD_REALTOBITS "$realtobits" %token yD_REWIND "$rewind" %token yD_RIGHT "$right" +%token yD_ROOT "$root" %token yD_RTOI "$rtoi" %token yD_SAMPLED "$sampled" %token yD_SFORMAT "$sformat" @@ -4008,6 +4009,7 @@ exprScope: // scope and variable for use to inside an expression // // See also varRefClassBit, which is the non-expr version of most of this yTHIS { $$ = new AstConst($1, AstConst::LogicFalse()); BBUNSUP($1, "Unsupported: this"); } + | yD_ROOT { $$ = new AstParseRef($1, VParseRefExp::PX_ROOT, "$root"); } | idArrayed { $$ = $1; } | package_scopeIdFollows idArrayed { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); } | class_scopeIdFollows idArrayed { $$ = $2; BBUNSUP($1, "Unsupported: scoped class reference"); } @@ -4471,8 +4473,9 @@ idClassSel: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged va ; idDotted: - //UNSUP yD_ROOT '.' idDottedMore { UNSUP } - idDottedMore { $$ = $1; } + yD_ROOT '.' idDottedMore + { $$ = new AstDot($2, new AstParseRef($1, VParseRefExp::PX_ROOT, "$root"), $3); } + | idDottedMore { $$ = $1; } ; idDottedMore: diff --git a/test_regress/t/t_var_dotted1.v b/test_regress/t/t_var_dotted1.v index dd6e79fce..2b0f1318b 100644 --- a/test_regress/t/t_var_dotted1.v +++ b/test_regress/t/t_var_dotted1.v @@ -35,6 +35,8 @@ module t (/*AUTOARG*/ if (cyc==2) begin if (global_cell.globali != 32'hf00d) $stop; if (global_cell2.globali != 32'hf22d) $stop; + if ($root.t.global_cell.globali != 32'hf00d) $stop; + if ($root.t.global_cell2.globali != 32'hf22d) $stop; if (outb0c0 != 32'h00) $stop; if (outb0c1 != 32'h01) $stop; if (outb1c0 != 32'h10) $stop;