Fix casting reals to large integrals (#6085)

This commit is contained in:
Todd Strader 2025-06-12 11:53:10 -04:00 committed by GitHub
parent dc307270f7
commit 206a0b4fd2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 59 additions and 2 deletions

View File

@ -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()) {

18
test_regress/t/t_real_cast.py Executable file
View File

@ -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()

View File

@ -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