19#pragma GCC diagnostic push
20#pragma GCC diagnostic ignored "-Wconversion"
21 #include "sysc/kernel/sc_event.h"
22 #include "sysc/kernel/sc_time.h"
23 #include "sysc/kernel/sc_module.h"
24 #include "sysc/communication/sc_clock.h"
25#pragma GCC diagnostic pop
30 namespace sparta_sysc_utils {
57 sc_core::sc_time::value_type sysc_offset)
84 const auto current_sc_time = sc_core::sc_time_stamp().value();
86 const auto current_tick = sparta_sched->
isRunning() ?
87 sparta_sched->getCurrentTick() : sparta_sched->getElapsedTicks();
89 const auto final_relative_tick = current_sc_time - current_tick + sysc_offset;
90 return final_relative_tick;
96#define SC_SPARTA_SCHEDULER_NAME "SysCSpartaSchedulerAdapter"
100#define SC_SPARTA_STOP_EVENT_NAME "sc_ev_stop_simulation"
135 sc_wake_sparta_.notify();
139 &SysCSpartaSchedulerAdapter::wakeupAdapter_>(
this,
"item_scheduled");
150 sparta_scheduler_(scheduler),
152 sc_wake_sparta_(
"sc_ev_wake_sparta")
154 SC_THREAD(runScheduler_);
157 sensitive << sc_ev_stop_simulation_;
162 sparta_sc_time_ = sc_core::SC_PS;
165 sparta_sc_time_ = sc_core::SC_NS;
168 sparta_sc_time_ = sc_core::SC_US;
187 double convert_to_sysc_time = std::numeric_limits<double>::max();
189 convert_to_sysc_time = num_ticks;
191 sc_core::sc_start(sc_core::sc_time(convert_to_sysc_time, sparta_sc_time_));
201 if(!sysc_simulation_done_) {
202 std::cout <<
"SysCSpartaSchedulerAdapter: SystemC reports finished on tick "
203 << sc_core::sc_time_stamp().value() << std::endl;
204 sysc_simulation_done_ =
true;
228 sysc_query_event_ = sysc_query_event;
229 sysc_query_event_interval_ = interval;
230 next_sysc_event_fire_tick_ = sparta_scheduler_->
getCurrentTick() + interval;
232 "This event should be non-continuing");
239 return sc_stop_called_;
251 wait(sc_core::sc_time(
double(1), sparta_sc_time_));
258 &SysCSpartaSchedulerAdapter::wakeupAdapter_>(
this,
"item_scheduled");
259 wait(sc_wake_sparta_);
266 const sc_core::sc_time sysc_time = sc_core::sc_time_stamp();
267 if(sparta_scheduler_->
nextEventTick() >= sysc_time.value()) {
269 wait(sc_core::sc_time(
double(sparta_scheduler_->
nextEventTick() - sysc_time.value()),
274 wait(sc_core::SC_ZERO_TIME);
282 if(sysc_query_event_ && sparta_scheduler_->
getCurrentTick() >= next_sysc_event_fire_tick_)
284 next_sysc_event_fire_tick_ = sparta_scheduler_->
getCurrentTick() + sysc_query_event_interval_;
288 advanceSpartaScheduler_();
290 }
while(!sparta_scheduler_->
isFinished() || !sysc_simulation_done_);
294 sc_stop_called_ =
true;
297 void advanceSpartaScheduler_()
299 const sc_core::sc_time sysc_time = sc_core::sc_time_stamp();
308 constexpr bool exacting_run =
true;
309 constexpr bool measure_scheduler_time =
false;
312 exacting_run, measure_scheduler_time);
323 sc_core::sc_time_unit sparta_sc_time_ = sc_core::SC_PS;
327 bool sysc_simulation_done_ =
false;
330 sc_core::sc_event sc_ev_stop_simulation_;
331 bool sc_stop_called_ =
false;
334 sc_core::sc_event sc_wake_sparta_;
File that defines the Event class.
A simple time-based, event precedence based scheduler.
#define PS_PER_SECOND
Picoseconds per second constant.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
#define SC_SPARTA_STOP_EVENT_NAME
#define SC_SPARTA_SCHEDULER_NAME
Clock::Cycle calculateSpartaOffset(const sparta::Clock *sparta_clk, sc_core::sc_time::value_type sysc_offset)
A representation of simulated time.
Scheduler * getScheduler() const
A class that defines the basic scheduling interface to the Scheduler. Not intended to be used by mode...
virtual void scheduleRelativeTick(const Scheduler::Tick rel_tick, Scheduler *const scheduler)
Schedule this event on a relative scheduler tick.
bool isContinuing() const
Is this Event continuing?
A class that lets you schedule events now and in the future.
bool isFinished() const
Returns true if there are no more pending non-continuing events.
Tick getCurrentTick() const noexcept
The current tick the Scheduler is working on or just finished.
bool isRunning() const noexcept
Query if the scheduler is running.
Tick getFrequency() const
Returns the frequency (in ticks per simulated second) of this Scheduler.
Tick nextEventTick() const
Returns the next tick an event is pending.
uint64_t Tick
Typedef for our unit of time.
void run(Tick num_ticks=INDEFINITE, const bool exacting_run=false, const bool measure_run_time=true)
Enter running state and runs the scheduler until running is stopped (e.g. through a stop event) or th...
static const Tick INDEFINITE
Constant for infinite tick count.
Used to construct and throw a standard C++ exception. Inherits from std::exception.
Class that "connects" Sparta to SystemC.
bool wasScStopCalled() const
Return whether the schedule called sc_stop()
void setSystemCSimulationDone()
Set simulation complete on the SystemC side via the SC_Sparta_STOP_EVENT_NAME sc_event....
void run(Scheduler::Tick num_ticks=Scheduler::INDEFINITE)
Run simulation – all of it including SystemC.
SysCSpartaSchedulerAdapter(Scheduler *scheduler)
Initialized the sc_module this adapter is part of.
SC_HAS_PROCESS(SysCSpartaSchedulerAdapter)
Register the process for SystemC.
void registerSysCFinishQueryEvent(sparta::Scheduleable *sysc_query_event, const Scheduler::Tick interval)
Register a sparta::Event that is used to determine if the SystemC components are finished.
void registerForNotification(T *obj, const std::string &name, bool ensure_possible=true)
Registers a callback method to listen for all notifications having the specified data type DataT and ...
Macros for handling exponential backoff.