diff --git a/include/verilated_random.cpp b/include/verilated_random.cpp index 4ed746e86..af5ff6a18 100644 --- a/include/verilated_random.cpp +++ b/include/verilated_random.cpp @@ -746,6 +746,12 @@ void VlRandomizer::soft(std::string&& constraint, const char* /*filename*/, uint m_softConstraints.emplace_back(std::move(constraint)); } +void VlRandomizer::disable_soft(std::string&& constraint) { + m_softConstraints.erase( + std::remove(m_softConstraints.begin(), m_softConstraints.end(), constraint), + m_softConstraints.end()); +} + void VlRandomizer::clearConstraints() { m_constraints.clear(); m_constraints_line.clear(); diff --git a/include/verilated_random.h b/include/verilated_random.h index 993778b55..4f13ddc5c 100644 --- a/include/verilated_random.h +++ b/include/verilated_random.h @@ -596,6 +596,7 @@ public: const char* source = ""); void soft(std::string&& constraint, const char* filename = "", uint32_t linenum = 0, const char* source = ""); + void disable_soft(std::string&& constraint); void clearConstraints(); void clearAll(); // Clear both constraints and variables void markRandc(const char* name); // Mark variable as randc for cyclic tracking diff --git a/src/V3AstAttr.h b/src/V3AstAttr.h index bfe9ba1fb..bf5ba0ae6 100644 --- a/src/V3AstAttr.h +++ b/src/V3AstAttr.h @@ -814,6 +814,7 @@ public: RANDOMIZER_BASIC_STD_RANDOMIZATION, RANDOMIZER_CLEARCONSTRAINTS, RANDOMIZER_CLEARALL, + RANDOMIZER_DISABLE_SOFT, RANDOMIZER_HARD, RANDOMIZER_SOFT, RANDOMIZER_UNIQUE, @@ -951,6 +952,7 @@ inline std::ostream& operator<<(std::ostream& os, const VCMethod& rhs) { {RANDOMIZER_BASIC_STD_RANDOMIZATION, "basicStdRandomization", false}, \ {RANDOMIZER_CLEARCONSTRAINTS, "clearConstraints", false}, \ {RANDOMIZER_CLEARALL, "clearAll", false}, \ + {RANDOMIZER_DISABLE_SOFT, "disable_soft", false}, \ {RANDOMIZER_HARD, "hard", false}, \ {RANDOMIZER_SOFT, "soft", false}, \ {RANDOMIZER_UNIQUE, "rand_unique", false}, \ diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index ac2776dc5..dc4b7c340 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -1920,35 +1920,38 @@ class ConstraintExprVisitor final : public VNVisitor { VL_DO_DANGLING(nodep->deleteTree(), nodep); return; } - // Emit as soft or hard constraint per IEEE 1800-2017 18.5.13 - const VCMethod method - = nodep->isSoft() ? VCMethod::RANDOMIZER_SOFT : VCMethod::RANDOMIZER_HARD; + // Emit as soft, hard, or disable_soft per IEEE 1800-2017 18.5.13 + const VCMethod method = nodep->isDisableSoft() ? VCMethod::RANDOMIZER_DISABLE_SOFT + : nodep->isSoft() ? VCMethod::RANDOMIZER_SOFT + : VCMethod::RANDOMIZER_HARD; AstCMethodHard* const callp = new AstCMethodHard{ nodep->fileline(), new AstVarRef{nodep->fileline(), VN_AS(m_genp->user2p(), NodeModule), m_genp, VAccess::READWRITE}, method, nodep->exprp()->unlinkFrBack()}; callp->dtypeSetVoid(); - // Pass filename, lineno, and source as separate arguments - // This allows EmitC to call protect() on filename, similar to VL_STOP - // Add filename parameter - callp->addPinsp(new AstCExpr{nodep->fileline(), AstCExpr::Pure{}, - "\"" + nodep->fileline()->filename() + "\""}); - // Add line number parameter - const uint32_t lineno = static_cast(nodep->fileline()->lineno()); - callp->addPinsp(new AstConst{nodep->fileline(), lineno}); - // Add source text parameter (empty if --protect-ids to avoid source leakage) - std::string prettyText; - if (!v3Global.opt.protectIds()) { - prettyText = nodep->fileline()->prettySource(); - size_t pos = 0; - while ((pos = prettyText.find('"', pos)) != std::string::npos) { - prettyText.insert(pos, "\\"); - pos += std::strlen("\\\""); + if (!nodep->isDisableSoft()) { + // Pass filename, lineno, and source as separate arguments + // This allows EmitC to call protect() on filename, similar to VL_STOP + // Add filename parameter + callp->addPinsp(new AstCExpr{nodep->fileline(), AstCExpr::Pure{}, + "\"" + nodep->fileline()->filename() + "\""}); + // Add line number parameter + const uint32_t lineno = static_cast(nodep->fileline()->lineno()); + callp->addPinsp(new AstConst{nodep->fileline(), lineno}); + // Add source text parameter (empty if --protect-ids to avoid source leakage) + std::string prettyText; + if (!v3Global.opt.protectIds()) { + prettyText = nodep->fileline()->prettySource(); + size_t pos = 0; + while ((pos = prettyText.find('"', pos)) != std::string::npos) { + prettyText.insert(pos, "\\"); + pos += std::strlen("\\\""); + } } + callp->addPinsp( + new AstCExpr{nodep->fileline(), AstCExpr::Pure{}, "\"" + prettyText + "\""}); } - callp->addPinsp( - new AstCExpr{nodep->fileline(), AstCExpr::Pure{}, "\"" + prettyText + "\""}); nodep->replaceWith(callp->makeStmt()); VL_DO_DANGLING(nodep->deleteTree(), nodep); } diff --git a/test_regress/t/t_randomize.v b/test_regress/t/t_randomize.v index e59787086..0a0231de6 100644 --- a/test_regress/t/t_randomize.v +++ b/test_regress/t/t_randomize.v @@ -44,8 +44,7 @@ class Packet; constraint dis { soft sublength; - // TODO: disable soft not yet supported, treated as hard constraint - // disable soft sublength; + disable soft sublength; sublength <= length; }