From e6f5a0495f50f5f1583d223b9cc48642f44a45f5 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 7 May 2023 08:25:10 -0400 Subject: [PATCH] Fix $fscanf of decimals overflowing variables (#4174). --- Changes | 1 + include/verilated.cpp | 10 ++++++---- src/V3EmitCFunc.h | 2 +- test_regress/t/t_sys_file_basic.v | 8 ++++++++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Changes b/Changes index 98018b690..c60a56374 100644 --- a/Changes +++ b/Changes @@ -28,6 +28,7 @@ Verilator 5.011 devel * Fix linking AstRefDType if it has parameterized class ref (#4164) (#4170). [Ryszard Rozak, Antmicro Ltd] * Fix crash caused by $display() optimization (#4165) (#4166). [Tudor Timi] * Fix arrays of unpacked structs (#4173). [Risto Pejašinović] +* Fix $fscanf of decimals overflowing variables (#4174). [Ahmed El-Mahmoudy] * Fix detection of wire/reg duplicates. * Fix false IMPLICITSTATIC on package functions. diff --git a/include/verilated.cpp b/include/verilated.cpp index 7b080f498..3b7a90de2 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -1373,16 +1373,18 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf *p = t_tmp; } else if (obits <= VL_BYTESIZE) { CData* const p = va_arg(ap, CData*); - *p = owp[0]; + *p = VL_CLEAN_II(obits, obits, owp[0]); } else if (obits <= VL_SHORTSIZE) { SData* const p = va_arg(ap, SData*); - *p = owp[0]; + *p = VL_CLEAN_II(obits, obits, owp[0]); } else if (obits <= VL_IDATASIZE) { IData* const p = va_arg(ap, IData*); - *p = owp[0]; + *p = VL_CLEAN_II(obits, obits, owp[0]); } else if (obits <= VL_QUADSIZE) { QData* const p = va_arg(ap, QData*); - *p = VL_SET_QW(owp); + *p = VL_CLEAN_QQ(obits, obits, VL_SET_QW(owp)); + } else { + _vl_clean_inplace_w(obits, owp); } } } // switch diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index 1149c728f..540b1ea13 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -792,7 +792,7 @@ public: void visit(AstSysFuncAsTask* nodep) override { if (!nodep->lhsp()->isWide()) puts("(void)"); iterateAndNextConstNull(nodep->lhsp()); - if (!nodep->lhsp()->isWide()) puts(";"); + if (!nodep->lhsp()->isWide()) puts(";\n"); } void visit(AstStackTraceF* nodep) override { puts("VL_STACKTRACE_N()"); } void visit(AstStackTraceT* nodep) override { puts("VL_STACKTRACE();\n"); } diff --git a/test_regress/t/t_sys_file_basic.v b/test_regress/t/t_sys_file_basic.v index 7a0f0bda6..ac276d9a4 100644 --- a/test_regress/t/t_sys_file_basic.v +++ b/test_regress/t/t_sys_file_basic.v @@ -33,6 +33,9 @@ module t; integer v_length, v_off; + wire signed [16:0] wire17 = 17'h1ffff; + logic signed [16:0] scan17; + `ifdef TEST_VERBOSE `define verbose 1'b1 `else @@ -309,6 +312,11 @@ module t; $fclose(file); end + begin + $sscanf("-1", "%d", scan17); + if (scan17 !== wire17) $stop; + end + $write("*-* All Finished *-*\n"); $finish(0); // Test arguments to finish end