From 24ff3155ae07e731759d1e4bbd0c89c9e3a50539 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 18 Sep 2023 21:17:21 -0400 Subject: [PATCH] Support randc (#4349). --- Changes | 1 + docs/guide/warnings.rst | 5 +- include/verilated_types.h | 64 +++++++++++++++++++++- src/V3AstNodeDType.h | 35 +++++++++++++ src/V3AstNodeOther.h | 11 ++++ src/V3AstNodes.cpp | 8 +++ src/V3Common.cpp | 2 +- src/V3EmitCFunc.cpp | 2 + src/V3Hasher.cpp | 5 ++ src/V3ParseImp.h | 5 +- src/V3Randomize.cpp | 70 ++++++++++++++++++++++--- src/V3Unknown.cpp | 12 +++++ test_regress/t/t_randc.out | 12 ----- test_regress/t/t_randc.pl | 10 ++-- test_regress/t/t_randc_ignore_unsup.pl | 24 --------- test_regress/t/t_randc_oversize_bad.out | 7 ++- test_regress/t/t_randc_oversize_bad.v | 7 ++- test_regress/t/t_uvm_todo.pl | 1 - 18 files changed, 220 insertions(+), 61 deletions(-) delete mode 100644 test_regress/t/t_randc.out delete mode 100755 test_regress/t/t_randc_ignore_unsup.pl diff --git a/Changes b/Changes index 6a13b022b..a23881b92 100644 --- a/Changes +++ b/Changes @@ -13,6 +13,7 @@ Verilator 5.017 devel **Minor:** +* Support randc (#4349). * Support resizing function call inout arguments (#4467). diff --git a/docs/guide/warnings.rst b/docs/guide/warnings.rst index 7f0898b5d..b7cf29a81 100644 --- a/docs/guide/warnings.rst +++ b/docs/guide/warnings.rst @@ -1360,7 +1360,10 @@ List Of Warnings .. option:: RANDC - Warns that the :code:`randc` keyword is unsupported and being converted + Historical, never issued since version 5.018, when :code:`randc` became + fully supported. + + Warned that the :code:`randc` keyword was unsupported and was converted to :code:`rand`. diff --git a/include/verilated_types.h b/include/verilated_types.h index bce36f258..00ffbedb1 100644 --- a/include/verilated_types.h +++ b/include/verilated_types.h @@ -74,8 +74,18 @@ extern std::string VL_TO_STRING_W(int words, const WDataInP obj); #define VL_OUTW(name, msb, lsb, words) VlWide name ///< Declare output signal, 65+ bits //=================================================================== -// VlProcess stores metadata of running processes +// Functions needed here +constexpr IData VL_CLOG2_CE_Q(QData lhs) VL_PURE { + if (VL_UNLIKELY(!lhs)) return 0; + --lhs; + int shifts = 0; + for (; lhs != 0; ++shifts) lhs = lhs >> 1ULL; + return shifts; +} + +//=================================================================== +// VlProcess stores metadata of running processes class VlProcess final { // MEMBERS int m_state; // Current state of the process @@ -210,6 +220,58 @@ public: size_t operator()() { return VL_MASK_I(31) & vl_rand64(); } }; +template +class VlRandC final { + T_Value m_remaining = 0; // Number of values to pull before re-randomize + T_Value m_lfsr = 1; // LFSR state + // Polynomials are first listed at https://users.ece.cmu.edu/~koopman/lfsr/ + static constexpr uint64_t s_polynomials[] = { + 0x0ULL, // 0 never used (constant, no randomization) + 0x0ULL, // 1 + 0x3ULL, 0x5ULL, 0x9ULL, 0x12ULL, 0x21ULL, + 0x41ULL, 0x8eULL, 0x108ULL, 0x204ULL, 0x402ULL, + 0x829ULL, 0x100dULL, 0x2015ULL, 0x4001ULL, + 0x8016ULL, // 16 + 0x10004ULL, 0x20040ULL, 0x40013ULL, 0x80004ULL, 0x100002ULL, + 0x200001ULL, 0x400010ULL, 0x80000dULL, 0x1000004ULL, 0x2000023ULL, + 0x4000013ULL, 0x8000004ULL, 0x10000002ULL, 0x20000029ULL, 0x40000004ULL, + 0x80000057ULL, // 32 + 0x100000029ULL // 33 + }; + +public: + // CONSTRUCTORS + VlRandC() { + static_assert(T_numValues >= 1, ""); + static_assert(sizeof(T_Value) == 8 || (T_numValues < (1ULL << (8 * sizeof(T_Value)))), ""); + } + // METHODS + T_Value randomize(VlRNG& rngr) { + if (VL_UNLIKELY(!m_remaining)) reseed(rngr); + constexpr uint32_t clogWidth = VL_CLOG2_CE_Q(T_numValues) + 1; + constexpr uint32_t lfsrWidth = (clogWidth < 2) ? 2 : clogWidth; + constexpr T_Value polynomial = static_cast(s_polynomials[lfsrWidth]); + // printf(" numV=%ld w=%d poly=%x\n", T_numValues, lfsrWidth, polynomial); + // Loop until get reasonable value. Because we picked a LFSR of at most one + // extra bit in width, this will only require at most on average 1.5 loops + do { + m_lfsr = (m_lfsr & 1ULL) ? ((m_lfsr >> 1ULL) ^ polynomial) : (m_lfsr >> 1ULL); + } while (m_lfsr > T_numValues); // Note if == then output value 0 + --m_remaining; + T_Value result = (m_lfsr == T_numValues) ? 0 : m_lfsr; + // printf(" result=%x (numv=%ld, rem=%d)\n", result, T_numValues, m_remaining); + return result; + } + void reseed(VlRNG& rngr) { + constexpr uint32_t lfsrWidth = VL_CLOG2_CE_Q(T_numValues) + 1; + m_remaining = T_numValues; + do { + m_lfsr = rngr.rand64() & VL_MASK_Q(lfsrWidth); + // printf(" lfsr.reseed=%x\n", m_lfsr); + } while (!m_lfsr); // 0 not a legal seed + } +}; + // These require the class object to have the thread safety lock inline IData VL_RANDOM_RNG_I(VlRNG& rngr) VL_MT_UNSAFE { return rngr.rand64(); } inline QData VL_RANDOM_RNG_Q(VlRNG& rngr) VL_MT_UNSAFE { return rngr.rand64(); } diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 180d14cca..b8ee2c72e 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -494,6 +494,41 @@ public: int widthTotalBytes() const override { V3ERROR_NA_RETURN(0); } bool isCompound() const override { return true; } }; +class AstCDType final : public AstNodeDType { + // Raw "C" data type passed directly to output + string m_name; // Name of data type, printed when do V3EmitC +public: + AstCDType(FileLine* fl, const string& name) + : ASTGEN_SUPER_CDType(fl) + , m_name{name} { + this->dtypep(this); + } + +public: + ASTGEN_MEMBERS_AstCDType; + bool same(const AstNode* samep) const override { + const AstCDType* const asamep = static_cast(samep); + return m_name == asamep->m_name; + } + bool similarDType(const AstNodeDType* samep) const override { return same(samep); } + string name() const override VL_MT_STABLE { return m_name; } + string prettyDTypeName() const override { return m_name; } + const char* broken() const override { return nullptr; } + // METHODS + AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } + AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } + AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } + AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } + int widthAlignBytes() const override { return 8; } // Assume + int widthTotalBytes() const override { return 8; } // Assume + bool isCompound() const override { return true; } + static string typeToHold(uint64_t maxItem) { + return (maxItem < (1ULL << 8)) ? "CData" + : (maxItem < (1ULL << 16)) ? "SData" + : (maxItem < (1ULL << 32)) ? "IData" + : "QData"; + } +}; class AstClassRefDType final : public AstNodeDType { // Reference to a class // @astgen op1 := paramsp: List[AstPin] diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 23e1b0891..8d4622164 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -1684,6 +1684,7 @@ class AstVar final : public AstNode { bool m_attrSplitVar : 1; // declared with split_var metacomment bool m_fileDescr : 1; // File descriptor bool m_isRand : 1; // Random variable + bool m_isRandC : 1; // Random cyclic variable (isRand also set) bool m_isConst : 1; // Table contains constant data bool m_isContinuously : 1; // Ever assigned continuously (for force/release) bool m_hasStrengthAssignment : 1; // Is on LHS of assignment with strength specifier @@ -1691,6 +1692,7 @@ class AstVar final : public AstNode { bool m_isPulldown : 1; // Tri0 bool m_isPullup : 1; // Tri1 bool m_isIfaceParent : 1; // dtype is reference to interface present in this module + bool m_isInternal : 1; // Internal state, don't add to method pinter bool m_isDpiOpenArray : 1; // DPI import open array bool m_isHideLocal : 1; // Verilog local bool m_isHideProtected : 1; // Verilog protected @@ -1728,6 +1730,7 @@ class AstVar final : public AstNode { m_attrSplitVar = false; m_fileDescr = false; m_isRand = false; + m_isRandC = false; m_isConst = false; m_isContinuously = false; m_hasStrengthAssignment = false; @@ -1735,6 +1738,7 @@ class AstVar final : public AstNode { m_isPulldown = false; m_isPullup = false; m_isIfaceParent = false; + m_isInternal = false; m_isDpiOpenArray = false; m_isHideLocal = false; m_isHideProtected = false; @@ -1880,10 +1884,15 @@ public: void scSensitive(bool flag) { m_scSensitive = flag; } void primaryIO(bool flag) { m_primaryIO = flag; } void isRand(bool flag) { m_isRand = flag; } + void isRandC(bool flag) { + m_isRandC = flag; + if (flag) isRand(true); + } void isConst(bool flag) { m_isConst = flag; } void isContinuously(bool flag) { m_isContinuously = flag; } void isStatic(bool flag) { m_isStatic = flag; } void isIfaceParent(bool flag) { m_isIfaceParent = flag; } + void isInternal(bool flag) { m_isInternal = flag; } void funcLocal(bool flag) { m_funcLocal = flag; if (flag) m_funcLocalSticky = true; @@ -1929,6 +1938,7 @@ public: bool isPrimaryInish() const { return isPrimaryIO() && isNonOutput(); } bool isIfaceRef() const { return (varType() == VVarType::IFACEREF); } bool isIfaceParent() const { return m_isIfaceParent; } + bool isInternal() const { return m_isInternal; } bool isSignal() const { return varType().isSignal(); } bool isNet() const { return varType().isNet(); } bool isTemp() const { return varType().isTemp(); } @@ -1964,6 +1974,7 @@ public: bool isSigUserRWPublic() const { return m_sigUserRWPublic; } bool isTrace() const { return m_trace; } bool isRand() const { return m_isRand; } + bool isRandC() const { return m_isRandC; } bool isConst() const VL_MT_SAFE { return m_isConst; } bool isStatic() const VL_MT_SAFE { return m_isStatic; } bool isLatched() const { return m_isLatched; } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 29fbf3902..d28692165 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -799,6 +799,8 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound) const { const CTypeRecursed key = adtypep->keyDTypep()->cTypeRecurse(true); const CTypeRecursed val = adtypep->subDTypep()->cTypeRecurse(true); info.m_type = "VlAssocArray<" + key.m_type + ", " + val.m_type + ">"; + } else if (const auto* const adtypep = VN_CAST(dtypep, CDType)) { + info.m_type = adtypep->name(); } else if (const auto* const adtypep = VN_CAST(dtypep, WildcardArrayDType)) { const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(true); info.m_type = "VlAssocArray"; @@ -2187,8 +2189,14 @@ void AstVar::dump(std::ostream& str) const { if (isPulldown()) str << " [PULLDOWN]"; if (isUsedClock()) str << " [CLK]"; if (isSigPublic()) str << " [P]"; + if (isInternal()) str << " [INTERNAL]"; if (isLatched()) str << " [LATCHED]"; if (isUsedLoopIdx()) str << " [LOOP]"; + if (isRandC()) { + str << " [RANDC]"; + } else if (isRand()) { + str << " [RAND]"; + } if (noReset()) str << " [!RST]"; if (attrIsolateAssign()) str << " [aISO]"; if (attrFileDescr()) str << " [aFD]"; diff --git a/src/V3Common.cpp b/src/V3Common.cpp index 4dc587a10..e4cddae9d 100644 --- a/src/V3Common.cpp +++ b/src/V3Common.cpp @@ -116,7 +116,7 @@ static void makeToStringMiddle(AstClass* nodep) { std::string comma; for (AstNode* itemp = nodep->membersp(); itemp; itemp = itemp->nextp()) { if (const auto* const varp = VN_CAST(itemp, Var)) { - if (!varp->isParam()) { + if (!varp->isParam() && !varp->isInternal()) { string stmt = "out += \""; stmt += comma; comma = ", "; diff --git a/src/V3EmitCFunc.cpp b/src/V3EmitCFunc.cpp index 644aa9b78..0264059a3 100644 --- a/src/V3EmitCFunc.cpp +++ b/src/V3EmitCFunc.cpp @@ -667,6 +667,8 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, const string& varNameP const string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : ""); return emitVarResetRecurse(varp, varNameProtected, adtypep->subDTypep(), depth + 1, suffix + ".atDefault()" + cvtarray); + } else if (VN_IS(dtypep, CDType)) { + return ""; // Constructor does it } else if (VN_IS(dtypep, ClassRefDType)) { return ""; // Constructor does it } else if (VN_IS(dtypep, IfaceRefDType)) { diff --git a/src/V3Hasher.cpp b/src/V3Hasher.cpp index 9169d06bd..f0a4d2bfa 100644 --- a/src/V3Hasher.cpp +++ b/src/V3Hasher.cpp @@ -147,6 +147,11 @@ private: m_hash += nodep->nrange().right(); }); } + void visit(AstCDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // + m_hash += nodep->name(); + }); + } void visit(AstConstDType* nodep) override { m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { // iterateConstNull(nodep->virtRefDTypep()); diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index bba341102..9017c0ae6 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -83,11 +83,8 @@ struct VMemberQualifiers { } void applyToNodes(AstVar* nodesp) const { for (AstVar* nodep = nodesp; nodep; nodep = VN_AS(nodep->nextp(), Var)) { - if (m_randc) { - nodep->v3warn(RANDC, "Unsupported: Converting 'randc' to 'rand'"); - nodep->isRand(true); - } if (m_rand) nodep->isRand(true); + if (m_randc) nodep->isRandC(true); if (m_local) nodep->isHideLocal(true); if (m_protected) nodep->isHideProtected(true); if (m_automatic) nodep->lifetime(VLifetime::AUTOMATIC); diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 95c4ce2e9..983ecf98a 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -144,6 +144,7 @@ private: const AstNodeFTask* m_ftaskp = nullptr; // Current function/task size_t m_enumValueTabCount = 0; // Number of tables with enum values created int m_randCaseNum = 0; // Randcase number within a module for var naming + std::map m_randcDtypes; // RandC data type deduplication // METHODS AstVar* enumValueTabp(AstEnumDType* nodep) { @@ -172,8 +173,49 @@ private: nodep->user2p(varp); return varp; } - AstNodeStmt* newRandStmtsp(FileLine* fl, AstNodeVarRef* varrefp, int offset = 0, - AstMemberDType* memberp = nullptr) { + + AstCDType* findVlRandCDType(FileLine* fl, uint64_t items) { + // For 8 items we need to have a 9 item LFSR so items is max count + const std::string type = AstCDType::typeToHold(items); + const std::string name = "VlRandC<" + type + ", " + cvtToStr(items) + "ULL>"; + // Create or reuse (to avoid duplicates) randomization object dtype + auto it = m_randcDtypes.find(name); + if (it != m_randcDtypes.end()) return it->second; + AstCDType* newp = new AstCDType{fl, name}; + v3Global.rootp()->typeTablep()->addTypesp(newp); + m_randcDtypes.emplace(std::make_pair(name, newp)); + return newp; + } + + AstVar* newRandcVarsp(AstVar* varp) { + // If a randc, make a VlRandC object to hold the state + if (!varp->isRandC()) return nullptr; + uint64_t items = 0; + + if (AstEnumDType* const enumDtp = VN_CAST(varp->dtypep()->skipRefToEnump(), EnumDType)) { + items = static_cast(enumDtp->itemCount()); + } else { + AstBasicDType* const basicp = varp->dtypep()->skipRefp()->basicp(); + UASSERT_OBJ(basicp, varp, "Unexpected randc variable dtype"); + if (basicp->width() > 32) { + varp->v3error("Maxiumum implemented width for randc is 32 bits, " + << varp->prettyNameQ() << " is " << basicp->width() << " bits"); + varp->isRandC(false); + varp->isRand(true); + return nullptr; + } + items = 1ULL << basicp->width(); + } + AstCDType* newdtp = findVlRandCDType(varp->fileline(), items); + AstVar* newp + = new AstVar{varp->fileline(), VVarType::MEMBER, varp->name() + "__Vrandc", newdtp}; + newp->isInternal(true); + varp->addNextHere(newp); + UINFO(9, "created " << varp << endl); + return newp; + } + AstNodeStmt* newRandStmtsp(FileLine* fl, AstNodeVarRef* varrefp, AstVar* randcVarp, + int offset = 0, AstMemberDType* memberp = nullptr) { if (const auto* const structDtp = VN_CAST(memberp ? memberp->subDTypep()->skipRefp() : varrefp->dtypep()->skipRefp(), StructDType)) { @@ -182,7 +224,7 @@ private: for (AstMemberDType* smemberp = structDtp->membersp(); smemberp; smemberp = VN_AS(smemberp->nextp(), MemberDType)) { AstNodeStmt* const randp = newRandStmtsp( - fl, stmtsp ? varrefp->cloneTree(false) : varrefp, offset, smemberp); + fl, stmtsp ? varrefp->cloneTree(false) : varrefp, nullptr, offset, smemberp); if (stmtsp) { stmtsp->addNext(randp); } else { @@ -198,15 +240,15 @@ private: AstVarRef* const tabRefp = new AstVarRef{fl, enumValueTabp(enumDtp), VAccess::READ}; tabRefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp()); - AstRandRNG* const randp - = new AstRandRNG{fl, varrefp->findBasicDType(VBasicDTypeKwd::UINT32)}; + AstNodeExpr* const randp + = newRandValue(fl, randcVarp, varrefp->findBasicDType(VBasicDTypeKwd::UINT32)); AstNodeExpr* const moddivp = new AstModDiv{ fl, randp, new AstConst{fl, static_cast(enumDtp->itemCount())}}; moddivp->dtypep(enumDtp); valp = new AstArraySel{fl, tabRefp, moddivp}; } else { - valp = new AstRandRNG{fl, - (memberp ? memberp->dtypep() : varrefp->varp()->dtypep())}; + valp = newRandValue(fl, randcVarp, + (memberp ? memberp->dtypep() : varrefp->varp()->dtypep())); } return new AstAssign{fl, new AstSel{fl, varrefp, offset + (memberp ? memberp->lsb() : 0), @@ -214,6 +256,17 @@ private: valp}; } } + AstNodeExpr* newRandValue(FileLine* fl, AstVar* randcVarp, AstNodeDType* dtypep) { + if (randcVarp) { + AstNode* argsp = new AstVarRef{fl, randcVarp, VAccess::READWRITE}; + argsp->addNext(new AstText{fl, ".randomize(__Vm_rng)"}); + AstCExpr* newp = new AstCExpr{fl, argsp}; + newp->dtypep(dtypep); + return newp; + } else { + return new AstRandRNG{fl, dtypep}; + } + } void addPrePostCall(AstClass* classp, AstFunc* funcp, const string& name) { if (AstTask* userFuncp = VN_CAST(m_memberMap.findMember(classp, name), Task)) { AstTaskRef* const callp @@ -271,8 +324,9 @@ private: if (!memberVarp || !memberVarp->isRand()) continue; const AstNodeDType* const dtypep = memberp->dtypep()->skipRefp(); if (VN_IS(dtypep, BasicDType) || VN_IS(dtypep, StructDType)) { + AstVar* const randcVarp = newRandcVarsp(memberVarp); AstVarRef* const refp = new AstVarRef{fl, memberVarp, VAccess::WRITE}; - AstNodeStmt* const stmtp = newRandStmtsp(fl, refp); + AstNodeStmt* const stmtp = newRandStmtsp(fl, refp, randcVarp); funcp->addStmtsp(stmtp); } else if (const auto* const classRefp = VN_CAST(dtypep, ClassRefDType)) { if (classRefp->classp() == nodep) { diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 66a6c78c4..5a5c6d969 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -452,6 +452,18 @@ private: } if (debug() >= 9) nodep->dumpTree("- arraysel_old: "); + // If value MODDIV constant, where constant <= declElements, known ok + // V3Random makes these to intentionally prevent exceeding enum array bounds. + if (const AstModDiv* const moddivp = VN_CAST(nodep->bitp(), ModDiv)) { + if (const AstConst* const modconstp = VN_CAST(moddivp->rhsp(), Const)) { + if (modconstp->width() <= 32 + && modconstp->toUInt() <= static_cast(declElements)) { + UINFO(9, "arraysel mod const " << declElements + << " >= " << modconstp->toUInt() << endl); + return; + } + } + } // See if the condition is constant true AstNodeExpr* condp = new AstGte{nodep->fileline(), diff --git a/test_regress/t/t_randc.out b/test_regress/t/t_randc.out deleted file mode 100644 index f83777149..000000000 --- a/test_regress/t/t_randc.out +++ /dev/null @@ -1,12 +0,0 @@ -%Warning-RANDC: t/t_randc.v:8:26: Unsupported: Converting 'randc' to 'rand' - 8 | randc bit [WIDTH-1:0] m_var; - | ^~~~~ - ... For warning description see https://verilator.org/warn/RANDC?v=latest - ... Use "/* verilator lint_off RANDC */" and lint_on around source to disable this message. -%Warning-RANDC: t/t_randc.v:46:26: Unsupported: Converting 'randc' to 'rand' - 46 | randc bit [WIDTH-1:0] m_var; - | ^~~~~ -%Warning-RANDC: t/t_randc.v:76:17: Unsupported: Converting 'randc' to 'rand' - 76 | randc enum_t m_var; - | ^~~~~ -%Error: Exiting due to diff --git a/test_regress/t/t_randc.pl b/test_regress/t/t_randc.pl index 66fa61649..aabcde63e 100755 --- a/test_regress/t/t_randc.pl +++ b/test_regress/t/t_randc.pl @@ -8,11 +8,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(linter => 1); +scenarios(simulator => 1); -lint( - fails => $Self->{vlt_all}, - expect_filename => $Self->{golden_filename}, +compile( + ); + +execute( + check_finished => 1, ); ok(1); diff --git a/test_regress/t/t_randc_ignore_unsup.pl b/test_regress/t/t_randc_ignore_unsup.pl deleted file mode 100755 index af711b6c9..000000000 --- a/test_regress/t/t_randc_ignore_unsup.pl +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env perl -if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } -# DESCRIPTION: Verilator: Verilog Test driver/expect definition -# -# Copyright 2020 by Wilson Snyder. This program is free software; you -# can redistribute it and/or modify it under the terms of either the GNU -# Lesser General Public License Version 3 or the Perl Artistic License -# Version 2.0. -# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 - -scenarios(vlt => 1); - -top_filename("t/t_randc.v"); - -compile( - verilator_flags2 => ['-Wno-RANDC -DTEST_IGNORE_RANDC'], - ); - -execute( - check_finished => 1, - ); - -ok(1); -1; diff --git a/test_regress/t/t_randc_oversize_bad.out b/test_regress/t/t_randc_oversize_bad.out index 293258c1f..61f0030e3 100644 --- a/test_regress/t/t_randc_oversize_bad.out +++ b/test_regress/t/t_randc_oversize_bad.out @@ -1,6 +1,5 @@ -%Warning-RANDC: t/t_randc_oversize_bad.v:8:21: Unsupported: Converting 'randc' to 'rand' - 8 | randc bit [33:0] i; +%Error: t/t_randc_oversize_bad.v:8:21: Maxiumum implemented width for randc is 32 bits, 'i' is 38 bits + : ... In instance t + 8 | randc bit [37:0] i; | ^ - ... For warning description see https://verilator.org/warn/RANDC?v=latest - ... Use "/* verilator lint_off RANDC */" and lint_on around source to disable this message. %Error: Exiting due to diff --git a/test_regress/t/t_randc_oversize_bad.v b/test_regress/t/t_randc_oversize_bad.v index 852f4743c..c687f61df 100644 --- a/test_regress/t/t_randc_oversize_bad.v +++ b/test_regress/t/t_randc_oversize_bad.v @@ -5,8 +5,13 @@ // SPDX-License-Identifier: CC0-1.0 class Cls; - randc bit [33:0] i; + randc bit [37:0] i; endclass module t (/*AUTOARG*/); + Cls c; + initial begin + c = new; + c.randomize; + end endmodule diff --git a/test_regress/t/t_uvm_todo.pl b/test_regress/t/t_uvm_todo.pl index b71e06d09..9fb3de36f 100755 --- a/test_regress/t/t_uvm_todo.pl +++ b/test_regress/t/t_uvm_todo.pl @@ -15,7 +15,6 @@ compile( "-Wno-PKGNODECL -Wno-IMPLICITSTATIC -Wno-CONSTRAINTIGN -Wno-MISINDENT", "-Wno-CASEINCOMPLETE -Wno-CASTCONST -Wno-SYMRSVDWORD -Wno-WIDTHEXPAND -Wno-WIDTHTRUNC", "-Wno-REALCVT", # TODO note mostly related to $realtime - could suppress or fix upstream - "-Wno-RANDC", # TODO issue #4349, add support "-Wno-ZERODLY", # TODO issue #4494, add support ], verilator_make_gmake => 0,