From bdcdc109663a3f6d7409803f9aeb81c171d021b0 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 11 May 2026 19:22:24 -0400 Subject: [PATCH] Fix floating point compile warning on min/max delays. --- Changes | 1 + src/V3Timing.cpp | 52 +++++++++++++++++-------------- test_regress/t/t_risefall_delay.v | 2 +- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/Changes b/Changes index dbe8b8b17..ac83df4af 100644 --- a/Changes +++ b/Changes @@ -46,6 +46,7 @@ Verilator 5.049 devel * Fix regression rejecting boolean `!x` inside sequence expressions (#7549) (#7551). [Yilou Wang] * Fix exponential expansion in V3Gate (#7550). [Geza Lore, Testorrent USA, Inc.] * Fix display of %m in non-first argument (#7574). +* Fix floating point compile warning on min/max delays. Verilator 5.048 2026-04-26 diff --git a/src/V3Timing.cpp b/src/V3Timing.cpp index ac48b4032..a0e935ffb 100644 --- a/src/V3Timing.cpp +++ b/src/V3Timing.cpp @@ -849,6 +849,30 @@ class TimingControlVisitor final : public VNVisitor { } } + AstNodeExpr* delayToIntegral(AstDelay* nodep, AstNodeExpr* valuep) { + FileLine* const flp = nodep->fileline(); + AstConst* const constp = VN_CAST(valuep, Const); + const bool isForkSentinel + = constp && (constp->toUQuad() == std::numeric_limits::max()); + if (!isForkSentinel && (!constp || !constp->isZero())) { + // Scale the delay + const double timescaleFactorD = calculateTimescaleFactor(nodep, nodep->timeunit()); + if (valuep->dtypep()->skipRefp()->isDouble()) { + AstConst* const tsfp = new AstConst{flp, AstConst::RealDouble{}, timescaleFactorD}; + valuep = new AstMulD{flp, valuep, tsfp}; + valuep = new AstRToIRoundS{flp, valuep}; + valuep->dtypeSetBitSized(64, VSigning::UNSIGNED); + } else { + valuep->dtypeSetBitSized(64, VSigning::UNSIGNED); + const uint64_t timescaleFactorU = static_cast(timescaleFactorD); + AstConst* const tsfp = new AstConst{flp, AstConst::Unsized64{}, timescaleFactorU}; + valuep = new AstMul{flp, valuep, tsfp}; + } + valuep = V3Const::constifyEdit(valuep); // Simplify + } + return valuep; + } + // VISITORS void visit(AstNodeModule* nodep) override { UASSERT_OBJ(!m_classp, nodep, "Module or class under class"); @@ -982,28 +1006,7 @@ class TimingControlVisitor final : public VNVisitor { valuep = new AstConst{flp, AstConst::Unsized64{}, 1}; valuep->dtypeSetBitSized(64, VSigning::UNSIGNED); } else { - AstConst* const constp = VN_CAST(valuep, Const); - const bool isForkSentinel - = constp && (constp->toUQuad() == std::numeric_limits::max()); - if (!isForkSentinel && (!constp || !constp->isZero())) { - // Scale the delay - const double timescaleFactorD = calculateTimescaleFactor(nodep, nodep->timeunit()); - if (valuep->dtypep()->skipRefp()->isDouble()) { - AstConst* const tsfp - = new AstConst{flp, AstConst::RealDouble{}, timescaleFactorD}; - valuep = new AstMulD{flp, valuep, tsfp}; - valuep = new AstRToIRoundS{flp, valuep}; - valuep->dtypeSetBitSized(64, VSigning::UNSIGNED); - } else { - valuep->dtypeSetBitSized(64, VSigning::UNSIGNED); - const uint64_t timescaleFactorU = static_cast(timescaleFactorD); - AstConst* const tsfp - = new AstConst{flp, AstConst::Unsized64{}, timescaleFactorU}; - valuep = new AstMul{flp, valuep, tsfp}; - } - // Simplify - valuep = V3Const::constifyEdit(valuep); - } + valuep = delayToIntegral(nodep, valuep); } // Statistics @@ -1270,10 +1273,13 @@ class TimingControlVisitor final : public VNVisitor { if (AstDelay* const delayp = VN_CAST(controlp, Delay)) { if (AstNodeExpr* fallDelayp = delayp->fallDelay()) { fallDelayp = fallDelayp->unlinkFrBack(); + AstNodeExpr* lhsp = delayp->lhsp()->unlinkFrBack(); // Use fall only for an all-zero value, rise otherwise. + lhsp = delayToIntegral(delayp, lhsp); + fallDelayp = delayToIntegral(delayp, fallDelayp); delayp->lhsp( new AstCond{flp, new AstEq{flp, rhs1p->cloneTree(false), new AstConst{flp, 0}}, - fallDelayp, delayp->lhsp()->unlinkFrBack()}); + fallDelayp, lhsp}); } } AstAssign* const assignp = new AstAssign{nodep->fileline(), lhs1p, rhs1p, controlp}; diff --git a/test_regress/t/t_risefall_delay.v b/test_regress/t/t_risefall_delay.v index 496149a61..5e9e76f46 100644 --- a/test_regress/t/t_risefall_delay.v +++ b/test_regress/t/t_risefall_delay.v @@ -13,7 +13,7 @@ module t; logic [3:0] in_vec = 4'h0; wire out_assign; wire out_buf; - wire #(5,3) out_net; + wire #(5,3.3) out_net; wire [3:0] out_vec_assign; assign #(5,3) out_assign = in;