From 777f8adff449e68f0e8988f8c9d9d40bedeb10c7 Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Thu, 13 Aug 2026 09:06:37 +0200 Subject: [PATCH 1/3] corrects increase of mcycle if WFI is called --- src/sysc/core2sc_adapter.h | 4 +++- src/sysc/core_complex.h | 7 ++++++- src/sysc/core_complex_if.h | 4 +++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/sysc/core2sc_adapter.h b/src/sysc/core2sc_adapter.h index e3c9a4e..f9a189c 100644 --- a/src/sysc/core2sc_adapter.h +++ b/src/sysc/core2sc_adapter.h @@ -114,7 +114,7 @@ template class core2sc_adapter : public PLAT, public sc2core_if auto cycle_incr = owner->get_last_bus_cycles(); if(cycle_incr > 1) this->instr_if.update_last_instr_cycles(cycle_incr); - owner->sync(this->instr_if.get_total_cycles()); + owner->qk_sync(this->instr_if.get_total_cycles()); } first = false; } @@ -275,7 +275,9 @@ template class core2sc_adapter : public PLAT, public sc2core_if if(clk_if && duration > sc_core::SC_ZERO_TIME) { auto cycles = duration.value() / clk_if->read().value(); this->reg.cycle += cycles; + SCCINFO(owner->hier_name()) << "Increasing cycles by " << cycles << " after WFI"; } + owner->qk_reset(this->instr_if.get_total_cycles()); }; owner->exec_on_sysc(f); wfi_inst.store(false, std::memory_order_relaxed); diff --git a/src/sysc/core_complex.h b/src/sysc/core_complex.h index 5f5019b..016d455 100644 --- a/src/sysc/core_complex.h +++ b/src/sysc/core_complex.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -184,11 +185,15 @@ class core_complex : public sc_core::sc_module, public scc::traceable, public co return mem_incr > 1 ? mem_incr : 1; } - void sync(uint64_t cycle) override { + void qk_sync(uint64_t cycle) override { auto core_inc = curr_clk * (cycle - last_sync_cycle); quantum_keeper.check_and_sync(core_inc); last_sync_cycle = cycle; } + void qk_reset(uint64_t cycle) override { + quantum_keeper.reset(sc_core::sc_time_stamp()); + last_sync_cycle = cycle; + } bool read_mem(const iss::addr_t& a, unsigned length, uint8_t* const data) override; diff --git a/src/sysc/core_complex_if.h b/src/sysc/core_complex_if.h index 6eff667..2d39bea 100644 --- a/src/sysc/core_complex_if.h +++ b/src/sysc/core_complex_if.h @@ -61,7 +61,9 @@ struct core_complex_if { virtual unsigned get_last_bus_cycles() = 0; //! Allow quantum keeper handling - virtual void sync(uint64_t) = 0; + virtual void qk_sync(uint64_t) = 0; + + virtual void qk_reset(uint64_t) = 0; util::delegate&)> exec_on_sysc; From c464020e81c032618caf829b39525591ed6268d8 Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Thu, 13 Aug 2026 21:25:32 +0200 Subject: [PATCH 2/3] corrects cycle annotation of core for blocking transports --- src/sysc/core_complex.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index bcab159..6b9fa96 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -434,16 +434,18 @@ bool core_complex::read_mem(const addr_t& addr, unsigned length, u gp.set_extension>(nullptr); }; auto pre_delay = delay; + auto transport_start = sc_core::sc_time_stamp(); exec_b_transport(gp, delay, is_fetch); - if(pre_delay > delay) { + auto transport_time = sc_core::sc_time_stamp() - transport_start; + auto time_taken = (delay + sc_core::sc_time_stamp()) - (pre_delay + transport_start); + auto incr = time_taken.value() / curr_clk.read().value(); + if(is_fetch) + ibus_inc += incr; + else + dbus_inc += incr; + + if(transport_time.value()) quantum_keeper.reset(); - } else { - auto incr = (delay - quantum_keeper.get_local_time()) / curr_clk; - if(is_fetch) - ibus_inc += incr; - else - dbus_inc += incr; - } SCCTRACE(this->name()) << "[local offset: +" << delay << "]: finish read_mem(0x" << std::hex << addr.val << ") : 0x" << (length == 4 ? *(uint32_t*)data : length == 2 ? *(uint16_t*)data @@ -497,11 +499,15 @@ bool core_complex::write_mem(const addr_t& addr, unsigned length, gp.set_extension>(nullptr); }; auto pre_delay = delay; + auto transport_start = sc_core::sc_time_stamp(); exec_b_transport(gp, delay); - if(pre_delay > delay) + auto transport_time = sc_core::sc_time_stamp() - transport_start; + auto time_taken = (delay + sc_core::sc_time_stamp()) - (pre_delay + transport_start); + auto incr = time_taken.value() / curr_clk.read().value(); + dbus_inc += incr; + + if(transport_time.value()) quantum_keeper.reset(); - else - dbus_inc += (delay - quantum_keeper.get_local_time()) / curr_clk; SCCTRACE(this->name()) << "[local offset: +" << delay << "]: finish write_mem(0x" << std::hex << addr.val << ") : 0x" << (length == 4 ? *(uint32_t*)data : length == 2 ? *(uint16_t*)data From b19952c9887021077841e6027c739571f81ac501 Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Fri, 14 Aug 2026 08:05:45 +0200 Subject: [PATCH 3/3] corrects cycle annotation for transports --- src/sysc/core2sc_adapter.h | 4 ++-- src/sysc/core_complex.cpp | 18 ++++++++++++------ src/sysc/core_complex.h | 9 +++++++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/sysc/core2sc_adapter.h b/src/sysc/core2sc_adapter.h index f9a189c..5b93f22 100644 --- a/src/sysc/core2sc_adapter.h +++ b/src/sysc/core2sc_adapter.h @@ -270,12 +270,12 @@ template class core2sc_adapter : public PLAT, public sc2core_if if(is_debugger_stop_evt) break; } - SCCINFO(this->owner->hier_name()) << "Got WFI event"; + SCCDEBUG(this->owner->hier_name()) << "Got WFI event"; auto duration = sc_core::sc_time_stamp() - start; if(clk_if && duration > sc_core::SC_ZERO_TIME) { auto cycles = duration.value() / clk_if->read().value(); this->reg.cycle += cycles; - SCCINFO(owner->hier_name()) << "Increasing cycles by " << cycles << " after WFI"; + SCCDEBUG(owner->hier_name()) << "Increasing cycles by " << cycles << " after WFI"; } owner->qk_reset(this->instr_if.get_total_cycles()); }; diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index 6b9fa96..02f33ca 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -437,15 +437,18 @@ bool core_complex::read_mem(const addr_t& addr, unsigned length, u auto transport_start = sc_core::sc_time_stamp(); exec_b_transport(gp, delay, is_fetch); auto transport_time = sc_core::sc_time_stamp() - transport_start; - auto time_taken = (delay + sc_core::sc_time_stamp()) - (pre_delay + transport_start); + auto completion = delay + sc_core::sc_time_stamp(); + auto time_taken = (completion) - (pre_delay + transport_start); auto incr = time_taken.value() / curr_clk.read().value(); if(is_fetch) ibus_inc += incr; else dbus_inc += incr; - if(transport_time.value()) - quantum_keeper.reset(); + if(transport_time.value()) { + quantum_keeper.reset(completion); + qk_preaccounted_cycles += incr; + } SCCTRACE(this->name()) << "[local offset: +" << delay << "]: finish read_mem(0x" << std::hex << addr.val << ") : 0x" << (length == 4 ? *(uint32_t*)data : length == 2 ? *(uint16_t*)data @@ -502,12 +505,15 @@ bool core_complex::write_mem(const addr_t& addr, unsigned length, auto transport_start = sc_core::sc_time_stamp(); exec_b_transport(gp, delay); auto transport_time = sc_core::sc_time_stamp() - transport_start; - auto time_taken = (delay + sc_core::sc_time_stamp()) - (pre_delay + transport_start); + auto completion = delay + sc_core::sc_time_stamp(); + auto time_taken = (completion) - (pre_delay + transport_start); auto incr = time_taken.value() / curr_clk.read().value(); dbus_inc += incr; - if(transport_time.value()) - quantum_keeper.reset(); + if(transport_time.value()) { + quantum_keeper.reset(completion); + qk_preaccounted_cycles += incr; + } SCCTRACE(this->name()) << "[local offset: +" << delay << "]: finish write_mem(0x" << std::hex << addr.val << ") : 0x" << (length == 4 ? *(uint32_t*)data : length == 2 ? *(uint16_t*)data diff --git a/src/sysc/core_complex.h b/src/sysc/core_complex.h index 016d455..f76b44a 100644 --- a/src/sysc/core_complex.h +++ b/src/sysc/core_complex.h @@ -186,12 +186,16 @@ class core_complex : public sc_core::sc_module, public scc::traceable, public co } void qk_sync(uint64_t cycle) override { - auto core_inc = curr_clk * (cycle - last_sync_cycle); + auto cycle_delta = cycle - last_sync_cycle; + auto preaccounted = std::min(cycle_delta, qk_preaccounted_cycles); + qk_preaccounted_cycles -= preaccounted; + assert(qk_preaccounted_cycles <= cycle_delta); + auto core_inc = curr_clk * (cycle_delta - preaccounted); quantum_keeper.check_and_sync(core_inc); last_sync_cycle = cycle; } void qk_reset(uint64_t cycle) override { - quantum_keeper.reset(sc_core::sc_time_stamp()); + quantum_keeper.reset(quantum_keeper.get_local_absolute_time()); last_sync_cycle = cycle; } @@ -305,6 +309,7 @@ class core_complex : public sc_core::sc_module, public scc::traceable, public co // /////////////////////////////////////////////////////////////////////////////// uint64_t last_sync_cycle = 0; + uint64_t qk_preaccounted_cycles{0}; util::range_lut fetch_lut{tlm_dmi_ext()}; util::range_lut& get_read_lut(unsigned space) { return space < dmi_read_luts.size() ? dmi_read_luts[space] : get_lut(dmi_read_luts, space);