diff --git a/src/V3Number.cpp b/src/V3Number.cpp index ca092ef53..4a4a757ac 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -1907,7 +1907,8 @@ V3Number& V3Number::opBufIf1(const V3Number& ens, const V3Number& if1s) { return *this; } -V3Number& V3Number::opAssign(const V3Number& lhs) { +V3Number& V3Number::opAssign(const V3Number& lhs) { return opAssignNonXZ(lhs, false); } +V3Number& V3Number::opAssignNonXZ(const V3Number& lhs, bool ignoreXZ) { // Note may be a width change during the assign. // Special case: opAssign unlike other ops, allows this an assignment // to itself; V3Simulate does this when hits "foo=foo;" @@ -1918,8 +1919,8 @@ V3Number& V3Number::opAssign(const V3Number& lhs) { m_stringVal = lhs.m_stringVal; } else { // Also handles double as is just bits - for (int bit=0; bitwidth(); bit++) { - setBit(bit, lhs.bitIs(bit)); + for (int bit = 0; bit < this->width(); bit++) { + setBit(bit, ignoreXZ ? lhs.bitIs1(bit) : lhs.bitIs(bit)); } } } @@ -2042,7 +2043,10 @@ V3Number& V3Number::opCond(const V3Number& lhs, const V3Number& if1s, const V3Nu V3Number& V3Number::opIToRD(const V3Number& lhs) { NUM_ASSERT_OP_ARGS1(lhs); NUM_ASSERT_LOGIC_ARGS1(lhs); - return setDouble(lhs.toSInt()); + // IEEE says we ignore x/z in real conversions + V3Number noxz(lhs); + noxz.opAssignNonXZ(lhs); + return setDouble(noxz.toSInt()); } V3Number& V3Number::opRToIS(const V3Number& lhs) { NUM_ASSERT_OP_ARGS1(lhs); diff --git a/src/V3Number.h b/src/V3Number.h index 5c1645842..541d92360 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -273,6 +273,7 @@ public: V3Number& opBitsNonZ(const V3Number& lhs); // Z->0, 0/1/X->1 // V3Number& opAssign (const V3Number& lhs); + V3Number& opAssignNonXZ(const V3Number& lhs, bool ignoreXZ = true); V3Number& opExtendS (const V3Number& lhs, uint32_t lbits); // Sign extension V3Number& opExtendXZ(const V3Number& lhs, uint32_t lbits); // X/Z extension V3Number& opRedOr (const V3Number& lhs); diff --git a/test_regress/t/t_math_real.v b/test_regress/t/t_math_real.v index 2bcf884e7..17bc0221c 100644 --- a/test_regress/t/t_math_real.v +++ b/test_regress/t/t_math_real.v @@ -82,6 +82,9 @@ module t (/*AUTOARG*/ // bug r = $bitstoreal($realtobits(1.414)); if (r != 1.414) $stop; + // bug + r = 32'bxz000_111; // 7 accoding to IEEE + if (r != 7) $stop; end // Test loop