From 206a0b4fd2b2f8632859adca12a47db411cd9140 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Thu, 12 Jun 2025 11:53:10 -0400 Subject: [PATCH] Fix casting reals to large integrals (#6085) --- src/V3Width.cpp | 4 ++-- test_regress/t/t_real_cast.py | 18 ++++++++++++++++ test_regress/t/t_real_cast.v | 39 +++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_real_cast.py create mode 100644 test_regress/t/t_real_cast.v diff --git a/src/V3Width.cpp b/src/V3Width.cpp index ef28884e3..86e7ef5b1 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2168,7 +2168,7 @@ class WidthVisitor final : public VNVisitor { // Note we don't sign fromp() that would make the algorithm O(n^2) if lots of casting. AstNodeExpr* newp = nullptr; if (bad) { - } else if (const AstBasicDType* const basicp = toDtp->basicp()) { + } else if (AstBasicDType* const basicp = toDtp->basicp()) { if (!basicp->isString() && fromDtp->isString()) { newp = new AstNToI{nodep->fileline(), nodep->fromp()->unlinkFrBack(), toDtp}; } else if (!basicp->isDouble() && !fromDtp->isDouble()) { @@ -2192,7 +2192,7 @@ class WidthVisitor final : public VNVisitor { } } else if (!basicp->isDouble() && nodep->fromp()->isDouble()) { newp = new AstRToIRoundS{nodep->fileline(), nodep->fromp()->unlinkFrBack()}; - newp->dtypeChgSigned(basicp->isSigned()); + newp->dtypep(basicp); } else if (basicp->isSigned() && !nodep->fromp()->isSigned()) { newp = new AstSigned{nodep->fileline(), nodep->fromp()->unlinkFrBack()}; } else if (!basicp->isSigned() && nodep->fromp()->isSigned()) { diff --git a/test_regress/t/t_real_cast.py b/test_regress/t/t_real_cast.py new file mode 100755 index 000000000..0e36f03cc --- /dev/null +++ b/test_regress/t/t_real_cast.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios("vlt") + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_real_cast.v b/test_regress/t/t_real_cast.v new file mode 100644 index 000000000..bd698541e --- /dev/null +++ b/test_regress/t/t_real_cast.v @@ -0,0 +1,39 @@ +// DESCRIPTION: Verilator: Confirm x randomization stability +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + + typedef logic [85:0] big_t; + localparam big_t foo = big_t'(8.531630271583128e+16); + + big_t bar; + int cyc; + real some_real; + + initial begin + cyc = 0; + some_real = 5.123; + end + + always_comb bar = big_t'(some_real); + + always @(posedge clk) begin + cyc <= cyc + 1; + some_real <= some_real * 1.234e4; + if (cyc == 6) begin + if (foo != 86'd85316302715831280) $stop(); + if (bar != 86'd18089031459271914704338944) $stop(); + $write("*-* All Finished *-*\n"); + $finish; + end + end + +endmodule