diff --git a/src/V3Broken.cpp b/src/V3Broken.cpp index 7ca71dfff..5fa7df17a 100644 --- a/src/V3Broken.cpp +++ b/src/V3Broken.cpp @@ -329,3 +329,13 @@ void V3Broken::brokenAll(AstNetlist* nodep) { void V3Broken::addNewed(AstNode* nodep) { BrokenTable::addNewed(nodep); } void V3Broken::deleted(AstNode* nodep) { BrokenTable::deleted(nodep); } bool V3Broken::isAllocated(AstNode* nodep) { return BrokenTable::isAllocated(nodep); } +void V3Broken::selfTest() { + // Warmup addNewed and deleted for coverage, as otherwise only with VL_LEAK_CHECKS + FileLine* fl = new FileLine(FileLine::commandLineFilename()); + auto* newp = new AstBegin(fl, "[EditWrapper]", nullptr); +#ifndef VL_LEAK_CHECKS + addNewed(newp); + deleted(newp); +#endif + VL_DO_DANGLING(delete newp, newp); +} diff --git a/src/V3Broken.h b/src/V3Broken.h index ee7d718f6..c447d9591 100644 --- a/src/V3Broken.h +++ b/src/V3Broken.h @@ -31,6 +31,7 @@ public: static void addNewed(AstNode* nodep); static void deleted(AstNode* nodep); static bool isAllocated(AstNode* nodep); + static void selfTest(); }; #endif // Guard diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index 16665c9e9..c1b9b1c3f 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -608,6 +608,11 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { puts(")"); } virtual void visit(AstArg* nodep) override { iterateAndNextNull(nodep->exprp()); } + virtual void visit(AstPrintTimeScale* nodep) override { + puts(nodep->verilogKwd()); + puts(";\n"); + } + // Terminals virtual void visit(AstVarRef* nodep) override { if (nodep->varScopep()) { diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 9a27791a5..ad2dc5c76 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -151,10 +151,11 @@ private: cleanFileline(nodep); iterateChildren(nodep); if (nodep->rangep()) { - if (!VN_IS(nodep->rangep()->leftp(), Const) // - || !VN_IS(nodep->rangep()->rightp(), Const)) { + if (VL_UNCOVERABLE(!VN_IS(nodep->rangep()->leftp(), Const) // LCOV_EXCL_START + || !VN_IS(nodep->rangep()->rightp(), Const))) { + // We check this rule in the parser, so shouldn't fire nodep->v3error("Enum ranges must be integral, per spec"); - } + } // LCOV_EXCL_STOP int left = nodep->rangep()->leftConst(); int right = nodep->rangep()->rightConst(); int increment = (left > right) ? -1 : 1; diff --git a/src/V3Number.cpp b/src/V3Number.cpp index 2f8fb2544..e0af838c3 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -1687,34 +1687,6 @@ V3Number& V3Number::opLte(const V3Number& lhs, const V3Number& rhs) { return opG V3Number& V3Number::opLtS(const V3Number& lhs, const V3Number& rhs) { return opGtS(rhs, lhs); } V3Number& V3Number::opLteS(const V3Number& lhs, const V3Number& rhs) { return opGteS(rhs, lhs); } -V3Number& V3Number::opRotR(const V3Number& lhs, const V3Number& rhs) { - // L(lhs) bit return - NUM_ASSERT_OP_ARGS2(lhs, rhs); - NUM_ASSERT_LOGIC_ARGS2(lhs, rhs); - if (rhs.isFourState()) return setAllBitsX(); - setZero(); - uint32_t rhsval = rhs.toUInt(); - for (int bit = 0; bit < this->width(); bit++) { - setBit(bit, lhs.bitIs((bit + rhsval) % this->width())); - } - return *this; -} - -V3Number& V3Number::opRotL(const V3Number& lhs, const V3Number& rhs) { - // L(lhs) bit return - NUM_ASSERT_OP_ARGS2(lhs, rhs); - NUM_ASSERT_LOGIC_ARGS2(lhs, rhs); - if (rhs.isFourState()) return setAllBitsX(); - setZero(); - uint32_t rhsval = rhs.toUInt(); - for (int bit = 0; bit < this->width(); bit++) { - if (bit >= static_cast(rhsval)) { - setBit(bit, lhs.bitIs((bit - rhsval) % this->width())); - } - } - return *this; -} - V3Number& V3Number::opShiftR(const V3Number& lhs, const V3Number& rhs) { // L(lhs) bit return NUM_ASSERT_OP_ARGS2(lhs, rhs); diff --git a/src/V3Number.h b/src/V3Number.h index e07b13c34..45d8c0f3d 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -377,8 +377,6 @@ public: V3Number& opXor(const V3Number& lhs, const V3Number& rhs); V3Number& opXnor(const V3Number& lhs, const V3Number& rhs); V3Number& opOr(const V3Number& lhs, const V3Number& rhs); - V3Number& opRotR(const V3Number& lhs, const V3Number& rhs); - V3Number& opRotL(const V3Number& lhs, const V3Number& rhs); V3Number& opShiftR(const V3Number& lhs, const V3Number& rhs); V3Number& opShiftRS(const V3Number& lhs, const V3Number& rhs, // Arithmetic w/carry uint32_t lbits); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 75a1e2b54..3056c40c1 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -5549,7 +5549,8 @@ private: case AstType::atMulS: newp = new AstMul(fl, lhsp, rhsp); break; case AstType::atShiftR: newp = new AstShiftRS(fl, lhsp, rhsp); break; case AstType::atShiftRS: newp = new AstShiftR(fl, lhsp, rhsp); break; - default: nodep->v3fatalSrc("Node needs sign change, but bad case: " << nodep); break; + default: // LCOV_EXCL_LINE + nodep->v3fatalSrc("Node needs sign change, but bad case: " << nodep); break; } UINFO(6, " ReplaceWithUOrSVersion: " << nodep << " w/ " << newp << endl); nodep->replaceWith(newp); @@ -5586,7 +5587,7 @@ private: case AstType::atDivS: newp = new AstDivD(fl, lhsp, rhsp); break; case AstType::atMul: case AstType::atMulS: newp = new AstMulD(fl, lhsp, rhsp); break; - default: + default: // LCOV_EXCL_LINE nodep->v3fatalSrc("Node needs conversion to double, but bad case: " << nodep); break; } @@ -5618,7 +5619,7 @@ private: case AstType::atLtS: newp = new AstLtN(fl, lhsp, rhsp); break; case AstType::atLte: case AstType::atLteS: newp = new AstLteN(fl, lhsp, rhsp); break; - default: + default: // LCOV_EXCL_LINE nodep->v3fatalSrc("Node needs conversion to string, but bad case: " << nodep); break; } @@ -5637,7 +5638,7 @@ private: AstNodeUniop* newp = nullptr; switch (nodep->type()) { case AstType::atNegate: newp = new AstNegateD(fl, lhsp); break; - default: + default: // LCOV_EXCL_LINE nodep->v3fatalSrc("Node needs conversion to double, but bad case: " << nodep); break; } @@ -5732,7 +5733,7 @@ private: if (adtypep->isRanged()) declRange = adtypep->declRange(); break; } - break; + break; // LCOV_EXCL_LINE } AstConst* valp = nullptr; // If nullptr, construct from val int val = 0; @@ -5762,7 +5763,7 @@ private: } else { val = bits; } - break; + break; // LCOV_EXCL_LINE } case AstAttrType::DIM_HIGH: val = !declRange.ranged() ? 0 : declRange.hi(); break; case AstAttrType::DIM_LEFT: val = !declRange.ranged() ? 0 : declRange.left(); break; diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 2dc857cff..0fa13e583 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -23,6 +23,7 @@ #include "V3AssertPre.h" #include "V3Begin.h" #include "V3Branch.h" +#include "V3Broken.h" #include "V3CCtors.h" #include "V3CUse.h" #include "V3Case.h" @@ -574,6 +575,7 @@ static void verilate(const string& argString) { V3TSP::selfTest(); V3ScoreboardBase::selfTest(); V3Partition::selfTest(); + V3Broken::selfTest(); } // Read first filename diff --git a/test_regress/t/t_debug_emitv.out b/test_regress/t/t_debug_emitv.out index dc1d81c5a..bd159e042 100644 --- a/test_regress/t/t_debug_emitv.out +++ b/test_regress/t/t_debug_emitv.out @@ -78,8 +78,8 @@ module Vt_debug_emitv; end t.sum = __Vfunc_t.sub.f__3__Vfuncout; $display("[%0t] sum = %~", $timet.sum, t.sum); - $display("a?= $d%d", ($c(32'sh1) ? $c(32'sh14) - : $c(32'sh1e))); + $display("a?= %d", ($c(32'sh1) ? $c(32'sh14) + : $c(32'sh1e))); $c(;); $display("%d", $c(0)); $fopen(72'h2f6465762f6e756c6c); @@ -172,6 +172,7 @@ module Vt_debug_emitv; $time, $time); $sscanf(40'h666f6f3d35, "foo=%d", t.i); ; + $printtimescale; if ((32'sh5 != t.i)) begin $stop; end @@ -207,3 +208,23 @@ module Vt_debug_emitv; int signed int [31:0] __Vdly__t._Vpast_0_0; int signed int [31:0] __Vdly__t._Vpast_1_0; endmodule +package Vt_debug_emitv___024unit; +endpackage +package Vt_debug_emitv_Pkg; +endpackage +class Vt_debug_emitv___024unit__03a__03aCls; +int signed int [31:0] member; + +???? // CFUNC '__VnoInFunc_method' +$_CSTMT(Vt_debug_emitv* const __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp; +); + +???? // CFUNC 'new' +$_CSTMT(_ctor_var_reset(vlSymsp); +); +$_CSTMT(Vt_debug_emitv* const __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp; +); +$unit::Cls.member = 32'sh1; +endclass +/*class*/package Vt_debug_emitv___024unit__03a__03aCls__Vclpkg; +end/*class*/package diff --git a/test_regress/t/t_debug_emitv.v b/test_regress/t/t_debug_emitv.v index 5764cedcf..9ab85d288 100644 --- a/test_regress/t/t_debug_emitv.v +++ b/test_regress/t/t_debug_emitv.v @@ -5,6 +5,25 @@ // without warranty, 2020 by Wilson Snyder. // SPDX-License-Identifier: CC0-1.0 +package Pkg; + localparam PKG_PARAM = 1; +endpackage +package PkgImp; + import Pkg::*; + export Pkg::*; +endpackage + +class Cls; + int member = 1; + function void method; + endfunction +endclass + +interface Iface; + logic ifsig; + modport mp(input ifsig); +endinterface + module t (/*AUTOARG*/ // Inputs clk, in @@ -43,6 +62,10 @@ module t (/*AUTOARG*/ int fd; int i; + int q[$]; + int assoc[string]; + int dyn[]; + task t; $display("stmt"); endtask @@ -91,7 +114,7 @@ module t (/*AUTOARG*/ sub.inc(fo, sum); sum = sub.f(sum); $display("[%0t] sum = %d", $time, sum); - $display("a?= $d", $c(1) ? $c32(20) : $c32(30)); + $display("a?= %d", $c(1) ? $c32(20) : $c32(30)); $c(";"); $display("%d", $c("0")); @@ -143,12 +166,16 @@ module t (/*AUTOARG*/ $display("str = %s", str); $display("%% [%t] [%t] to=%o td=%d", $time, $realtime, $time, $time); $sscanf("foo=5", "foo=%d", i); + $printtimescale; if (i != 5) $stop; sum = $random; sum = $random(10); sum = $urandom; sum = $urandom(10); + + if (Pkg::PKG_PARAM != 1) $stop; + sub.r = 62.0; end endmodule diff --git a/test_regress/t/t_debug_graph_test.pl b/test_regress/t/t_debug_graph_test.pl index 5ae25d7f3..961994545 100755 --- a/test_regress/t/t_debug_graph_test.pl +++ b/test_regress/t/t_debug_graph_test.pl @@ -13,7 +13,7 @@ $ENV{VERILATOR_TEST_NO_GDB} and skip("Skipping due to VERILATOR_TEST_NO_GDB"); lint( # Check we can call dump() on graph, and other things - v_flags => ["--lint-only --debug --debugi-V3GraphTest 9 --debugi-V3GraphDfa 9"], + v_flags => ["--lint-only --debug --debugi-V3GraphTest 9 --debugi-V3GraphDfa 9 --debug-self-test"], ); ok(1); diff --git a/test_regress/t/t_sys_sformat.v b/test_regress/t/t_sys_sformat.v index d4da7ac54..bce43cb5e 100644 --- a/test_regress/t/t_sys_sformat.v +++ b/test_regress/t/t_sys_sformat.v @@ -65,9 +65,12 @@ module t; `ifdef TEST_VERBOSE $display("chku %s", str3); `endif if (str3 !== "u=dcba") $stop; - str3 = $sformatf("v=%v", {"a","b","c","d"}); // Value selected so is printable + str3 = $sformatf("v=%v", 4'b01xz); // Value selected so is printable `ifdef TEST_VERBOSE $display("chkv %s", str3); `endif + str3 = $sformatf("z=%z", {"a","b","c","d"}); // Value selected so is printable +`ifdef TEST_VERBOSE $display("chkz %s", str3); `endif + $sformat(ochar,"%s","c"); if (ochar != "c") $stop;