The constructor passes its arguments to the base class,
Or1ksimSyncSC
. The quantum keeper for the
ISS thread is then initialized with the system global quantum and
the local quantum calculated and local time offset zeroed with a
call to reset
.
tgq = &(tlm::tlm_global_quantum::instance()); issQk.set_global_quantum( refTgq.get() ); issQk.reset();
Note | |
---|---|
The global quantum accessor function,
|
The main thread function, run
is reimplemented
to ensure that the ISS simulation does not run past the end of the
current quantum. Instead of running for ever
(or1ksim_run( -1.0 );
), the ISS is
run for the local time quantum, less the local time offset. This
means the ISS will return exactly at the point when it should need
to synchronize again.
The body of the program is a perpetual loop, which calculates the time left until the next global quantum then calls the ISS for that period.
while( true ) { sc_core::sc_time timeLeft = tgq->compute_local_quantum() - issQk.get_local_time();
On return, or1ksim_get_time_period
is used to
find out how much computation has actually been carried out and
advance local time accordingly. This may be different to the
duration requested, since an upcall may set a new time point and
adjusted the duration. A new time point is immediately set ready for
the next loop.
(void)or1ksim_run( timeLeft.to_seconds()); issQk.inc( sc_core::sc_time( or1ksim_get_time_period(), sc_core::SC_SEC )); or1ksim_set_time_point();
If the local time offset has reached the end of the global quantum,
the thread synchronizes. This replaces the call to
wait
in the synchronized version of the model
(Chapter 8).
if( issQk.need_sync() ) { issQk.sync();
The transport function, doTrans
has the same
structure as the synchronous version in the base class. However
instead of calling wait
to delay calculation,
it updates the local time offset. The time offset is advanced for
the ISS simulation since the last time point and a new time point
is set.
issQk.inc( sc_core::sc_time( or1ksim_get_time_period(), sc_core::SC_SEC )); or1ksim_set_time_point();
The delay argument to the blocking transport is the local time offset. This may be increased by the target (to model read/write delay), and the new value becomes the local time offset on return.
sc_core::sc_time delay = issQk.get_local_time(); dataBus->b_transport( trans, delay ); issQk.set( delay );
At this point synchronization could be required—the read/write delay could have pushed the local time offset past the global quantum.
if( issQk.need_sync() ) { issQk.sync(); }
The duration remaining for the ISS simulation is reset in the same way as in the main thread to be the local quantum less the local time offset. On return the ISS will continue for that period.
sc_core::sc_time timeLeft = tgq->compute_local_quantum() - issQk.get_local_time(); or1ksim_reset_duration ( timeLeft.to_seconds() );
The implementation of the Or1ksim ISS wrapper module class with
decoupled timing, Or1ksimDecoupSC
may be
found in
sys-models/decoup-soc/Or1ksimDecoupSC.cpp
in
the distribution.