diff --git a/include/verilated_threads.cpp b/include/verilated_threads.cpp index 76a6367b0..8258343d6 100644 --- a/include/verilated_threads.cpp +++ b/include/verilated_threads.cpp @@ -146,7 +146,7 @@ void VlThreadPool::profileAppendAll(const VlProfileRec& rec) VL_MT_SAFE_EXCLUDES } } -void VlThreadPool::profileDump(const char* filenamep, vluint64_t ticksElapsed) +void VlThreadPool::profileDump(const char* filenamep, vluint64_t tickStart, vluint64_t tickEnd) VL_MT_SAFE_EXCLUDES(m_mutex) { const VerilatedLockGuard lock{m_mutex}; VL_DEBUG_IF(VL_DBG_MSGF("+prof+threads writing to '%s'\n", filenamep);); @@ -194,14 +194,14 @@ void VlThreadPool::profileDump(const char* filenamep, vluint64_t ticksElapsed) "VLPROF mtask %d" " start %" VL_PRI64 "u end %" VL_PRI64 "u elapsed %" VL_PRI64 "u" " predict_time %u cpu %u on thread %u\n", - ei.m_mtaskId, ei.m_startTime, ei.m_endTime, + ei.m_mtaskId, ei.m_startTime - tickStart, ei.m_endTime - tickStart, (ei.m_endTime - ei.m_startTime), ei.m_predictTime, ei.m_cpu, thread_id); break; default: assert(false); break; // LCOV_EXCL_LINE } } } - fprintf(fp, "VLPROF stat ticks %" VL_PRI64 "u\n", ticksElapsed); + fprintf(fp, "VLPROF stat ticks %" VL_PRI64 "u\n", tickEnd - tickStart); std::fclose(fp); } diff --git a/include/verilated_threads.h b/include/verilated_threads.h index 150168f80..bdb99b816 100644 --- a/include/verilated_threads.h +++ b/include/verilated_threads.h @@ -292,7 +292,8 @@ public: return &(t_profilep->back()); } void profileAppendAll(const VlProfileRec& rec) VL_MT_SAFE_EXCLUDES(m_mutex); - void profileDump(const char* filenamep, vluint64_t ticksElapsed) VL_MT_SAFE_EXCLUDES(m_mutex); + void profileDump(const char* filenamep, vluint64_t tickStart, vluint64_t tickEnd) + VL_MT_SAFE_EXCLUDES(m_mutex); // In profiling mode, each executing thread must call // this once to setup profiling state: void setupProfilingClientThread() VL_MT_SAFE_EXCLUDES(m_mutex); diff --git a/src/V3EmitCModel.cpp b/src/V3EmitCModel.cpp index 334824df1..786207f3c 100644 --- a/src/V3EmitCModel.cpp +++ b/src/V3EmitCModel.cpp @@ -435,10 +435,11 @@ class EmitCModel final : public EmitCFunc { puts(/**/ "}\n"); puts(/**/ "else if (vlSymsp->__Vm_profile_window_ct == 0) {\n"); // Ending file. - puts(/****/ "vluint64_t elapsed" - " = VL_RDTSC_Q() - vlSymsp->__Vm_profile_cycle_start;\n"); - puts(/****/ "vlSymsp->__Vm_threadPoolp->profileDump(vlSymsp->_vm_contextp__->" - "profThreadsFilename().c_str(), elapsed);\n"); + puts(/****/ "vluint64_t tick_end = VL_RDTSC_Q();\n"); + puts(/****/ "vlSymsp->__Vm_threadPoolp->profileDump(" + "vlSymsp->_vm_contextp__->profThreadsFilename().c_str(), " + "vlSymsp->__Vm_profile_cycle_start, " + "tick_end);\n"); // This turns off the test to enter the profiling code, but still // allows the user to collect another profile by changing // profThreadsStart diff --git a/src/V3Partition.cpp b/src/V3Partition.cpp index f12a1bce3..6883df7c3 100644 --- a/src/V3Partition.cpp +++ b/src/V3Partition.cpp @@ -2711,8 +2711,7 @@ static void addMTaskToFunction(const ThreadSchedule& schedule, const uint32_t th // Leave this if() here, as don't want to call VL_RDTSC_Q unless profiling addStrStmt("if (VL_UNLIKELY(vlSymsp->__Vm_profile_cycle_start)) {\n" + // recName + " = vlSymsp->__Vm_threadPoolp->profileAppend();\n" + // - recName + "->startRecord(VL_RDTSC_Q() - vlSymsp->__Vm_profile_cycle_start," - + // + recName + "->startRecord(VL_RDTSC_Q()," + // " " + cvtToStr(mtaskp->id()) + "," + // " " + cvtToStr(mtaskp->cost()) + ");\n" + // "}\n"); @@ -2727,8 +2726,7 @@ static void addMTaskToFunction(const ThreadSchedule& schedule, const uint32_t th if (v3Global.opt.profThreads()) { // Leave this if() here, as don't want to call VL_RDTSC_Q unless profiling addStrStmt("if (VL_UNLIKELY(" + recName + ")) {\n" + // - recName + "->endRecord(VL_RDTSC_Q() - vlSymsp->__Vm_profile_cycle_start);\n" - + "}\n"); + recName + "->endRecord(VL_RDTSC_Q());\n" + "}\n"); } // Flush message queue