diff --git a/Changes b/Changes index fd3cb4cf3..30d299c1f 100644 --- a/Changes +++ b/Changes @@ -20,6 +20,7 @@ Verilator 4.201 devel * Fix exceeding command-line ar limit (#2834). [Yinan Xu] * Fix false $dumpfile warning on model save (#2834). [Yinan Xu] * Fix --timescale-override not suppressing TIMESCALEMOD (#2838). [Kaleb Barrett] +* Fix false TIMESCALEMOD on generate-ignored instances (#2838). [Kaleb Barrett] Verilator 4.200 2021-03-12 diff --git a/bin/verilator b/bin/verilator index 96a44c640..d17a442a2 100755 --- a/bin/verilator +++ b/bin/verilator @@ -1509,8 +1509,8 @@ good value. =item --timescale I/I Sets default timescale, timeunit and timeprecision for when `timescale does -not occur in sources. Default is "1ps/1ps" (to match SystemC). This is -overridden by C<--timescale-override>. +not occur before a given module. Default is "1ps/1ps" (to match SystemC). +This is overridden by C<--timescale-override>. =item --timescale-override I/I diff --git a/src/V3Ast.h b/src/V3Ast.h index 3c838d9c4..abf9474cc 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -2880,6 +2880,7 @@ public: virtual void dump(std::ostream& str) const override; virtual bool maybePointedTo() const override { return true; } virtual string name() const override { return m_name; } + virtual bool timescaleMatters() const = 0; AstNode* stmtsp() const { return op2p(); } // op2 = List of statements AstActive* activesp() const { return VN_CAST(op3p(), Active); } // op3 = List of i/sblocks // METHODS diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 5da14deca..d0b37b1ea 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -290,6 +290,7 @@ public: ASTNODE_NODE_FUNCS(ClassPackage) virtual string verilogKwd() const override { return "/*class*/package"; } virtual const char* broken() const override; + virtual bool timescaleMatters() const override { return false; } AstClass* classp() const { return m_classp; } void classp(AstClass* classp) { m_classp = classp; } }; @@ -317,6 +318,7 @@ public: BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists()); return nullptr; } + virtual bool timescaleMatters() const override { return false; } // op1/op2/op3 in AstNodeModule AstClassPackage* classOrPackagep() const { return m_classOrPackagep; } void classOrPackagep(AstClassPackage* classpackagep) { m_classOrPackagep = classpackagep; } @@ -2559,6 +2561,7 @@ public: , m_isProgram{program} {} ASTNODE_NODE_FUNCS(Module) virtual string verilogKwd() const override { return m_isProgram ? "program" : "module"; } + virtual bool timescaleMatters() const override { return true; } }; class AstNotFoundModule final : public AstNodeModule { @@ -2568,6 +2571,7 @@ public: : ASTGEN_SUPER(fl, name) {} ASTNODE_NODE_FUNCS(NotFoundModule) virtual string verilogKwd() const override { return "/*not-found-*/ module"; } + virtual bool timescaleMatters() const override { return false; } }; class AstPackage final : public AstNodeModule { @@ -2577,6 +2581,7 @@ public: : ASTGEN_SUPER(fl, name) {} ASTNODE_NODE_FUNCS(Package) virtual string verilogKwd() const override { return "package"; } + virtual bool timescaleMatters() const override { return !isDollarUnit(); } static string dollarUnitName() { return AstNode::encodeName("$unit"); } bool isDollarUnit() const { return name() == dollarUnitName(); } }; @@ -2588,6 +2593,7 @@ public: : ASTGEN_SUPER(fl, name) {} ASTNODE_NODE_FUNCS(Primitive) virtual string verilogKwd() const override { return "primitive"; } + virtual bool timescaleMatters() const override { return false; } }; class AstPackageExportStarStar final : public AstNode { @@ -2653,6 +2659,9 @@ public: AstIface(FileLine* fl, const string& name) : ASTGEN_SUPER(fl, name) {} ASTNODE_NODE_FUNCS(Iface) + // Interfaces have `timescale applicability but lots of code seems to + // get false warnings if we enable this + virtual bool timescaleMatters() const override { return false; } }; class AstMemberSel final : public AstNodeMath { diff --git a/src/V3LinkLevel.cpp b/src/V3LinkLevel.cpp index de3eeff3e..add541016 100644 --- a/src/V3LinkLevel.cpp +++ b/src/V3LinkLevel.cpp @@ -101,13 +101,13 @@ void V3LinkLevel::timescaling(const ModVec& mods) { v3Global.rootp()->timeunit(unit); for (AstNodeModule* nodep : mods) { + if (!v3Global.opt.timeOverrideUnit().isNone()) nodep->timeunit(unit); if (nodep->timeunit().isNone()) { if (modTimedp // Got previous && ( // unit doesn't already include an override v3Global.opt.timeOverrideUnit().isNone() && v3Global.opt.timeDefaultUnit().isNone()) - && (!VN_IS(nodep, Iface) && !VN_IS(nodep, Primitive) - && !(VN_IS(nodep, Package) && VN_CAST(nodep, Package)->isDollarUnit()))) { + && nodep->timescaleMatters()) { nodep->v3warn(TIMESCALEMOD, "Timescale missing on this module as other modules have " "it (IEEE 1800-2017 3.14.2.3)\n" diff --git a/test_regress/t/t_flag_timescale_override.out b/test_regress/t/t_flag_timescale_override.out index b82ab0b9a..7ae0946dc 100644 --- a/test_regress/t/t_flag_timescale_override.out +++ b/test_regress/t/t_flag_timescale_override.out @@ -1,2 +1,3 @@ Time scale of t is 1ms / 1us +Time scale of sub is 1ms / 1us *-* All Finished *-* diff --git a/test_regress/t/t_flag_timescale_override.v b/test_regress/t/t_flag_timescale_override.v index 61ebcfd56..e66060f4c 100644 --- a/test_regress/t/t_flag_timescale_override.v +++ b/test_regress/t/t_flag_timescale_override.v @@ -7,9 +7,17 @@ `timescale 1s/1s module t; + sub sub (); initial begin $printtimescale; + sub.pts(); $write("*-* All Finished *-*\n"); $finish; end endmodule + +module sub; + task pts; + $printtimescale; + endtask +endmodule diff --git a/test_regress/t/t_flag_timescale_override2.out b/test_regress/t/t_flag_timescale_override2.out index 3a0d42216..d75101d0e 100644 --- a/test_regress/t/t_flag_timescale_override2.out +++ b/test_regress/t/t_flag_timescale_override2.out @@ -1,2 +1,3 @@ Time scale of t is 1s / 1us +Time scale of sub is 1s / 1us *-* All Finished *-* diff --git a/test_regress/t/t_hier_block.pl b/test_regress/t/t_hier_block.pl index fe743cb94..cffc7ba04 100755 --- a/test_regress/t/t_hier_block.pl +++ b/test_regress/t/t_hier_block.pl @@ -20,6 +20,7 @@ compile( v_flags2 => ['t/t_hier_block.cpp'], verilator_flags2 => ['--stats', ($Self->{vltmt} ? ' --threads 6' : ''), '--hierarchical', + '--Wno-TIMESCALEMOD', '--CFLAGS', '"-pipe -DCPP_MACRO=cplusplus"' ], ); diff --git a/test_regress/t/t_sv_cpu.pl b/test_regress/t/t_sv_cpu.pl index 6cc81f85a..5bc4f46a7 100755 --- a/test_regress/t/t_sv_cpu.pl +++ b/test_regress/t/t_sv_cpu.pl @@ -34,7 +34,8 @@ compile( "t/t_sv_cpu_code/cpu.sv", "t/t_sv_cpu_code/chip.sv"], vcs_flags2 => ["-R -sverilog +memcbk -y t/t_sv_cpu_code +libext+.sv+ +incdir+t/t_sv_cpu_code"], - verilator_flags2 => ["-y t/t_sv_cpu_code +libext+.sv+ +incdir+t/t_sv_cpu_code --top-module t"], + verilator_flags2 => ["-y t/t_sv_cpu_code +libext+.sv+ +incdir+t/t_sv_cpu_code --top-module t", + "--timescale-override 1ns/1ps"], iv_flags2 => ["-yt/t_sv_cpu_code -It/t_sv_cpu_code -Y.sv"], ); diff --git a/test_regress/t/t_timescale_udp.v b/test_regress/t/t_timescale_udp.v index 4b30c71ef..2b3bd9da9 100644 --- a/test_regress/t/t_timescale_udp.v +++ b/test_regress/t/t_timescale_udp.v @@ -7,10 +7,18 @@ `timescale 1ns/1ns module t; p p (); + + // Also check not-found modules + localparam NOT = 0; + if (NOT) begin + NotFound not_found(.*); + end + initial begin $write("*-* All Finished *-*\n"); $finish; end + endmodule `timescale 1ns/1ns