diff --git a/Changes b/Changes index 2ccef80e3..bcb162f96 100644 --- a/Changes +++ b/Changes @@ -14,6 +14,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Report interface ports connected to wrong interface, bug1294. [Todd Strader] +**** When tracing, use scalars on single bit arrays to appease vcddiff. + **** Fix parsing "output signed" in V2K port list, msg2540. [James Jung] **** Fix parsing error on bad missing #, bug1308. [Dan Kirkham] diff --git a/include/verilated.h b/include/verilated.h index 49b270a99..c9ebf8977 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -186,9 +186,7 @@ public: // METHODS /// Check that the current thread ID is the same as the construction thread ID void check() VL_MT_UNSAFE_ONE { - // Memoize results in local thread, to prevent slow get_id() call - VL_THREAD_LOCAL bool t_okThread = (m_threadid == VL_THREAD_ID()); - if (!VL_LIKELY(t_okThread)) { + if (!VL_LIKELY(m_threadid == VL_THREAD_ID())) { fatal_different(); } } diff --git a/include/verilated_vcd_c.cpp b/include/verilated_vcd_c.cpp index 8fb2701d4..9f3f5c72e 100644 --- a/include/verilated_vcd_c.cpp +++ b/include/verilated_vcd_c.cpp @@ -343,7 +343,7 @@ void VerilatedVcd::bufferResize(vluint64_t minsize) { memcpy(m_wrBufp, oldbufp, m_writep - oldbufp); m_writep = m_wrBufp + (m_writep - oldbufp); m_wrFlushp = m_wrBufp + m_wrChunkSize * 6; - delete oldbufp; oldbufp=NULL; + delete [] oldbufp; oldbufp=NULL; } } diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 7f37f52cb..158911a21 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -2405,14 +2405,20 @@ class EmitCTrace : EmitCStmts { string full = ((m_funcp->funcType() == AstCFuncType::TRACE_FULL || m_funcp->funcType() == AstCFuncType::TRACE_FULL_SUB) ? "full":"chg"); + bool emitWidth = false; if (nodep->dtypep()->basicp()->isDouble()) { puts("vcdp->"+full+"Double"); } else if (nodep->isWide() || emitTraceIsScBv(nodep) || emitTraceIsScBigUint(nodep)) { puts("vcdp->"+full+"Array"); + emitWidth = true; } else if (nodep->isQuad()) { puts("vcdp->"+full+"Quad "); - } else if (nodep->declp()->bitRange().ranged()) { + emitWidth = true; + } else if (nodep->declp()->bitRange().ranged() + // 1 element smaller to use Bit dump + && nodep->declp()->bitRange().elements() != 1) { puts("vcdp->"+full+"Bus "); + emitWidth = true; } else { puts("vcdp->"+full+"Bit "); } @@ -2420,8 +2426,7 @@ class EmitCTrace : EmitCStmts { + ((arrayindex<0) ? 0 : (arrayindex*nodep->declp()->widthWords())))); puts(","); emitTraceValue(nodep, arrayindex); - if (!nodep->dtypep()->basicp()->isDouble() // When float/double no longer have widths this can go - && (nodep->declp()->bitRange().ranged() || emitTraceIsScBv(nodep) || emitTraceIsScBigUint(nodep))) { + if (emitWidth) { puts(","+cvtToStr(nodep->declp()->widthMin())); } puts(");\n"); diff --git a/test_regress/t/t_vlcov_merge.pl b/test_regress/t/t_vlcov_merge.pl index 6a0e57121..72de4372c 100755 --- a/test_regress/t/t_vlcov_merge.pl +++ b/test_regress/t/t_vlcov_merge.pl @@ -19,6 +19,9 @@ run(cmd => ["../bin/verilator_coverage", # Older clib's didn't properly sort maps, but the coverage data doesn't # really care about ordering. So avoid false failures by sorting. +# Set LC_ALL as suggested in the sort manpage to avoid sort order +# changes from the locale. +$ENV{LC_ALL} = "C"; run(cmd => ["sort", "$Self->{obj_dir}/coverage.dat", "> $Self->{obj_dir}/coverage-sort.dat", diff --git a/test_regress/t/t_vpi_get.cpp b/test_regress/t/t_vpi_get.cpp index 4cd41d87a..066deaa87 100644 --- a/test_regress/t/t_vpi_get.cpp +++ b/test_regress/t/t_vpi_get.cpp @@ -156,20 +156,27 @@ struct params { unsigned int scalar; int type; } attributes, children; -} values[] = { - {"onebit", {1, vpiNoDirection, 1, vpiReg}, {0, 0, 0, 0}}, - {"twoone", {2, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}}, - {"onetwo", {2, vpiNoDirection, 0, TestSimulator::is_verilator() ? vpiReg : vpiMemory}, {0, 0, 0, 0}}, - {"fourthreetwoone", {2, vpiNoDirection, 0, vpiMemory}, {2, vpiNoDirection, 0, vpiMemoryWord}}, - {"clk", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}}, - {"testin", {16, vpiInput, 0, vpiPort}, {0, 0, 0, 0}}, - {"testout", {24, vpiOutput, 0, vpiPort}, {0, 0, 0, 0}}, - {"sub.subin", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}}, - {"sub.subout", {1, vpiOutput, 1, vpiPort}, {0, 0, 0, 0}}, - {NULL, {0, 0, 0, 0}, {0, 0, 0, 0}} }; int mon_check_props() { + // This table needs to be function-static. + // This avoids calling is_verilator() below at global-static init time. + // When global-static led to a race between the is_verilator call below, and + // the code that sets up the VerilatedAssertOneThread() check in + // verilated_vpi.cc, it was causing the check to falsely fail + // (due to m_threadid within the check not being initted yet.) + static struct params values[] = { + {"onebit", {1, vpiNoDirection, 1, vpiReg}, {0, 0, 0, 0}}, + {"twoone", {2, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}}, + {"onetwo", {2, vpiNoDirection, 0, TestSimulator::is_verilator() ? vpiReg : vpiMemory}, {0, 0, 0, 0}}, + {"fourthreetwoone", {2, vpiNoDirection, 0, vpiMemory}, {2, vpiNoDirection, 0, vpiMemoryWord}}, + {"clk", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}}, + {"testin", {16, vpiInput, 0, vpiPort}, {0, 0, 0, 0}}, + {"testout", {24, vpiOutput, 0, vpiPort}, {0, 0, 0, 0}}, + {"sub.subin", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}}, + {"sub.subout", {1, vpiOutput, 1, vpiPort}, {0, 0, 0, 0}}, + {NULL, {0, 0, 0, 0}, {0, 0, 0, 0}} + }; struct params* value = values; while (value->signal) { TestVpiHandle h = VPI_HANDLE(value->signal);