From a19dddf05eb029fa20e7b65ebc61b55782b08a09 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 28 Jan 2023 22:11:09 -0500 Subject: [PATCH] Fix real parameters of infinity and NaN. --- Changes | 1 + src/V3EmitCFunc.cpp | 6 ++++++ test_regress/t/t_math_real.v | 21 ++++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Changes b/Changes index a4e2ea12d..8782e98b2 100644 --- a/Changes +++ b/Changes @@ -16,6 +16,7 @@ Verilator 5.007 devel * Support unpacked unions. * Support interface classes and class implements. * Support global clocking and $global_clock. +* Fix real parameters of infinity and NaN. Verilator 5.006 2022-01-22 diff --git a/src/V3EmitCFunc.cpp b/src/V3EmitCFunc.cpp index 2922d6706..885392513 100644 --- a/src/V3EmitCFunc.cpp +++ b/src/V3EmitCFunc.cpp @@ -541,6 +541,12 @@ void EmitCFunc::emitConstant(AstConst* nodep, AstVarRef* assigntop, const string if (int(nodep->num().toDouble()) == nodep->num().toDouble() && nodep->num().toDouble() < 1000 && nodep->num().toDouble() > -1000) { ofp()->printf("%3.1f", nodep->num().toDouble()); // Force decimal point + } else if (std::isinf(nodep->num().toDouble())) { + if (std::signbit(nodep->num().toDouble())) puts("-"); + ofp()->puts("std::numeric_limits::infinity()"); + } else if (std::isnan(nodep->num().toDouble())) { + if (std::signbit(nodep->num().toDouble())) puts("-"); + ofp()->puts("std::numeric_limits::quiet_NaN()"); } else { // Not %g as will not always put in decimal point, so not obvious to compiler // is a real number diff --git a/test_regress/t/t_math_real.v b/test_regress/t/t_math_real.v index 856547a66..8798f1cdb 100644 --- a/test_regress/t/t_math_real.v +++ b/test_regress/t/t_math_real.v @@ -6,7 +6,9 @@ // Version 2.0. // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -`define checkr(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); +`define stop $stop +`define checkr(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +`define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); `define is_near_real(a,b) (( ((a)<(b)) ? (b)-(a) : (a)-(b)) < (((a)/(b))*0.0001)) module t (/*AUTOARG*/ @@ -29,6 +31,7 @@ module t (/*AUTOARG*/ reg signed [95:0] cis96; real r, r2; integer cyc = 0; + string s; realtime uninit; initial if (uninit != 0.0) $stop; @@ -134,6 +137,22 @@ module t (/*AUTOARG*/ if (r != 74276402357122816493947453440.0) $stop; r = real'(96'shf0000000_00000000_00000000); if (r != -4951760157141521099596496896.0) $stop; + + r = 1.23456; + s = $sformatf("%g", r); + `checks(s, "1.23456"); + r = 1.0/0; // inf + s = $sformatf("%g", r); + `checks(s, "inf"); + r = -1.0/0; // -inf + s = $sformatf("%g", r); + `checks(s, "-inf"); + r = $sqrt(-1.0); // NaN + s = $sformatf("%g", r); + `checks(s, "-nan"); + r = -$sqrt(-1.0); // NaN + s = $sformatf("%g", r); + `checks(s, "nan"); end // Test loop