1#ifndef __SCC_TLM_QUANTUMKEEPER_MT_H__
2#define __SCC_TLM_QUANTUMKEEPER_MT_H__
4#include "qk/sc_time_syncronizer.h"
5#include <scc/async_thread.h>
6#include <sysc/kernel/sc_simcontext.h>
8#if SC_VERSION_MAJOR < 3
9#warning "Multithreaded quantum keeper is only supported with SystemC 3.0 and newer"
11#define DEBUG_MT_SCHEDULING
18struct quantumkeeper_mt : sc_core::sc_object {
24 : sc_core::sc_object(
"qk")
25 , gtk_idx(qk::sc_time_syncronizer::get().get_channel_index()) {
26 sc_core::sc_spawn_options opt;
28 opt.set_sensitivity(&keep_alive);
34 virtual ~quantumkeeper_mt() =
default;
36 void run_thread(std::function<sc_core::sc_time()> f) {
38 reset(sc_core::sc_time_stamp());
39 thread_executor.start([
this, f]() {
40 this->check_and_sync(sc_core::SC_ZERO_TIME);
45 wait(thread_executor.thread_finish_event());
52 inline void inc(sc_core::sc_time
const& core_inc) {
53 local_absolute_time += core_inc;
61 inline void check_and_sync(sc_core::sc_time
const& core_inc) {
65 while(local_absolute_time.value() > local_time_ticks_limit) {
66 std::this_thread::yield();
82 inline void execute_on_sysc(std::function<
void(
void)>& fct, sc_core::sc_time when) {
83 qk::callback_task task([
this, &fct]() {
84 auto t0 = sc_core::sc_time_stamp();
86 return sc_core::sc_time_stamp() - t0;
88 auto ret = task.get_future();
90 auto duration = ret.get();
91 check_and_sync(duration);
98 sc_core::sc_time get_local_time()
const {
return local_absolute_time - get_current_sc_time(); }
104 sc_core::sc_time get_local_absolute_time()
const {
return local_absolute_time; }
110 sc_core::sc_time get_current_sc_time()
const {
return sc_core::sc_time::from_value(
qk::global_time_keeper::get().get_sc_time_ticks()); }
115 void reset() { reset(get_current_sc_time()); }
121 void reset(sc_core::sc_time
const& abs_time) { local_absolute_time = sc_core::sc_time_stamp(); }
127 ::scc::async_thread thread_executor;
128 sc_core::sc_event keep_alive;
129 sc_core::sc_time local_absolute_time;
130 uint64_t local_time_ticks_limit{0};
uint64_t get_client_max_time_ticks(size_t idx)
Get the maximum time ticks a client thread is allowed to advance.
void update_client_time_ticks(size_t idx, uint64_t tick)
updates the global time keeper with the local time ticks of a clinet thread
static global_time_keeper & get()
the singleton getter
void schedule_task(size_t idx, std::packaged_task< sc_core::sc_time(void)> &&task, uint64_t when)
updates the global time keeper with the local time ticks of a clinet thread and schedules a task at t...
static sc_time_syncronizer & get()
the singleton getter
void execute_on_sysc(std::function< void(void)> fct)
execute the given function in the SystemC thread