From f2a17b9b70fc72dcca33ecd3ce2c74f772192042 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 24 Dec 2014 21:50:38 -0500 Subject: [PATCH] Fix $sccanf from string, bug866. --- Changes | 2 + include/verilated.cpp | 74 ++++++++++++++++++------------- include/verilated_heavy.h | 3 +- src/V3EmitC.cpp | 4 +- test_regress/t/t_sys_file_basic.v | 8 ++++ 5 files changed, 58 insertions(+), 33 deletions(-) diff --git a/Changes b/Changes index 4727bfad1..260eb34f1 100644 --- a/Changes +++ b/Changes @@ -11,6 +11,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix member select error broke in 3.868, bug867. [Iztok Jeras] +**** Fix $sccanf from string, bug866. [David Pierce] + * Verilator 3.868 2014-12-20 diff --git a/include/verilated.cpp b/include/verilated.cpp index af0c0a410..572dbfd66 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -476,7 +476,7 @@ static inline void _vl_vsss_advance(FILE* fp, int& floc) { if (fp) fgetc(fp); else floc -= 8; } -static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp) { +static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp, const string& fstr) { // Get a character without advancing if (fp) { int data = fgetc(fp); @@ -486,23 +486,27 @@ static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp) { } else { if (floc < 0) return EOF; floc = floc & ~7; // Align to closest character - int data = (fromp[VL_BITWORD_I(floc)] >> VL_BITBIT_I(floc)) & 0xff; - return data; + if (fromp == NULL) { + int c = fstr[fstr.length()-1 - (floc>>3)]; + return fstr[fstr.length()-1 - (floc>>3)]; + } else { + return (fromp[VL_BITWORD_I(floc)] >> VL_BITBIT_I(floc)) & 0xff; + } } } -static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp) { +static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp, const string& fstr) { while (1) { - int c = _vl_vsss_peek(fp, floc, fromp); + int c = _vl_vsss_peek(fp, floc, fromp, fstr); if (c==EOF || !isspace(c)) return; _vl_vsss_advance(fp, floc); } } -static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, +static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const string& fstr, char* tmpp, const char* acceptp) { // Read into tmp, consisting of characters from acceptp list char* cp = tmpp; while (1) { - int c = _vl_vsss_peek(fp, floc, fromp); + int c = _vl_vsss_peek(fp, floc, fromp, fstr); if (c==EOF || isspace(c)) break; if (acceptp!=NULL // String - allow anything && NULL==strchr(acceptp, c)) break; @@ -547,6 +551,7 @@ static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const IData _vl_vsscanf(FILE* fp, // If a fscanf int fbits, WDataInP fromp, // Else if a sscanf + const string& fstr, // if a sscanf to string const char* formatp, va_list ap) { // Read a Verilog $sscanf/$fscanf style format into the output list // The format must be pre-processed (and lower cased) by Verilator @@ -557,15 +562,15 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf bool inPct = false; const char* pos = formatp; for (; *pos && !_vl_vsss_eof(fp,floc); ++pos) { - //VL_PRINTF("_vlscan fmt='%c' floc=%d file='%c'\n", pos[0], floc, _vl_vsss_peek(fp,floc,fromp)); + //VL_PRINTF("_vlscan fmt='%c' floc=%d file='%c'\n", pos[0], floc, _vl_vsss_peek(fp,floc,fromp,fstr)); if (!inPct && pos[0]=='%') { inPct = true; } else if (!inPct && isspace(pos[0])) { // Format spaces while (isspace(pos[1])) pos++; - _vl_vsss_skipspace(fp,floc,fromp); + _vl_vsss_skipspace(fp,floc,fromp,fstr); } else if (!inPct) { // Expected Format - _vl_vsss_skipspace(fp,floc,fromp); - int c = _vl_vsss_peek(fp,floc,fromp); + _vl_vsss_skipspace(fp,floc,fromp,fstr); + int c = _vl_vsss_peek(fp,floc,fromp,fstr); if (c != pos[0]) goto done; else _vl_vsss_advance(fp,floc); } else { // Format character @@ -574,7 +579,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf char fmt = pos[0]; switch (fmt) { case '%': { - int c = _vl_vsss_peek(fp,floc,fromp); + int c = _vl_vsss_peek(fp,floc,fromp,fstr); if (c != '%') goto done; else _vl_vsss_advance(fp,floc); break; @@ -591,15 +596,15 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf for (int i=0; iisWide()?"W":(nodep->isQuad()?"Q":"I")); + puts (nodep->isString() ? "N" + : nodep->isWide() ? "W" + : nodep->isQuad() ? "Q" : "I"); } void emitScIQW(AstVar* nodep) { puts (nodep->isScBigUint() ? "SB" diff --git a/test_regress/t/t_sys_file_basic.v b/test_regress/t/t_sys_file_basic.v index df8fcda6e..f3631f4b6 100644 --- a/test_regress/t/t_sys_file_basic.v +++ b/test_regress/t/t_sys_file_basic.v @@ -14,6 +14,7 @@ module t; reg [16*8:1] letterw; reg [16*8:1] letterz; real r; + string s; reg [7:0] v_a,v_b,v_c,v_d; reg [31:0] v_worda; @@ -131,6 +132,13 @@ module t; if (r != 0.1) $stop; if (letterq != 64'hfffffffffffc65a5) $stop; + s = "r=0.2 d=-236124"; + chars = $sscanf(s, "r=%g d=%d", r, letterq); + if (`verbose) $write("c=%0d d=%d\n", chars, letterq); + if (chars != 2) $stop; + if (r != 0.2) $stop; + if (letterq != 64'hfffffffffffc65a4) $stop; + // $fscanf if ($fscanf(file,"")!=0) $stop;