X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fvisitor%2Fhdsd%2Fscd%2Fscd_simulator.cpp;fp=dol%2Fsrc%2Fdol%2Fvisitor%2Fhdsd%2Fscd%2Fscd_simulator.cpp;h=86c2196b2cdbb5e56ec5134c8f3e9d5325b9b183;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/visitor/hdsd/scd/scd_simulator.cpp b/dol/src/dol/visitor/hdsd/scd/scd_simulator.cpp new file mode 100644 index 0000000..86c2196 --- /dev/null +++ b/dol/src/dol/visitor/hdsd/scd/scd_simulator.cpp @@ -0,0 +1,218 @@ +#include "scd_simulator.h" + +#include +#include + +#include "systemc" + +#include "scd_cont_man_master.h" +#include "scd_cont_man_slave.h" +#include "scd_init_listener.h" +#include "scd_logging.h" + + +scd_simulator::scd_simulator(const std::string& name, + const std::string &loc_host, uint16_t loc_port, bool master): + _name(name), _loc_host(loc_host), _loc_port(loc_port) +{ + _poller = new scd_sock_poller; + + if (master == SCD_MASTER) + _cont_man = new scd_cont_man_master(*this); + else + _cont_man = new scd_cont_man_slave(*this); + + _chan_man = new scd_chan_man(*this); +} + + +scd_simulator::scd_simulator(const std::string& name, uint16_t loc_port, + bool master): + _name(name), _loc_host(""), _loc_port(loc_port) +{ + _poller = new scd_sock_poller; + + if (master == SCD_MASTER) + _cont_man = new scd_cont_man_master(*this); + else + _cont_man = new scd_cont_man_slave(*this); + + _chan_man = new scd_chan_man(*this); +} + + +scd_simulator::~scd_simulator() +{ + delete _chan_man; + delete _cont_man; + delete _poller; +} + + +const std::string& scd_simulator::get_name() const { return _name; } + + +scd_sock_poller& scd_simulator::get_poller() { return *_poller; } + + +scd_chan_man& scd_simulator::get_chan_man() { return *_chan_man; } + + +scd_cont_man& scd_simulator::get_cont_man() { return *_cont_man; } + + +bool scd_simulator::init() +{ + scd_info("initialization start"); + + /* open port for incomming connections */ + scd_init_listener listener(*this, _loc_host, _loc_port); + listener.listen(); + + /* + * init until the initialization failed or chan_man and cont_man are + * successfully initiated + */ + while ( !_cont_man->failed() && + ( !_chan_man->ready() || !_cont_man->active() ) ) + { + // poll the sockets and execute callback handlers + _poller->process(); + + // connect channels + _chan_man->init_process(); + + // process state transitions + _cont_man->process(); + + /* as we might be waiting for a peer coming up we can not use + * a blocking poll as errors would always exist and the poller would + * wake up immediately + * => sleep some milliseconds + */ + usleep(50); + } + + listener.close(); + + if (_cont_man->failed()) + { + scd_error("initialization failed"); + return false; + } + else + { + scd_info("initialization done"); + return true; + } + +} // init() + + +bool scd_simulator::start() +{ + scd_info("simulation start"); + + /* first delta cycle to initialize the SystemC scheduler + * else the _pending*() functions would fail */ + sc_core::sc_start(sc_core::SC_ZERO_TIME); + + while (_cont_man->active()) + { + /* signalize the simulation state to the controller */ + if (_pending()) + { + if (_pending_now()) + { + // events in this time step + _cont_man->set_busy(); + } + else + { + // signalize time step until next event + sc_core::sc_time step; + step = _next_time() - sc_core::sc_time_stamp(); + _cont_man->set_idle(step); + } + } + else + _cont_man->set_done(); + + // check for state changes + _cont_man->process(); + + /* run simulation if something to do and in right state */ + if (_cont_man->busy()) + { + // simulate one delta cycle + sc_core::sc_start(sc_core::SC_ZERO_TIME); + + // check if we have to wait for new socket events + _chan_man->process(); + + // poll the sockets to induce transmissions + _poller->process(); + } + else + { + if (_cont_man->advance_time()) + { + sc_core::sc_time step = _cont_man->get_time_step(); + // advance simulation time, nothing should actually be simulated + sc_start(step); + scd_info("time advanced by " + step.to_string() + " to " + + sc_core::sc_time_stamp().to_string() ); + } + else if ( _cont_man->active() ) + { + // wait for activity on sockets + _poller->wait_process(); + } + } + + } // while simulation is running + + /* simulation terminated */ + + if (_cont_man->failed()) + { + scd_error("simulation failed"); + return false; + } + else + { + scd_info("simulation done"); + return true; + } + +} // start() + + +/** + * Returns true if events exist at current simulation time. + */ +bool scd_simulator::_pending_now() +{ + return sc_core::sc_pending_activity_at_current_time(); +} + + +/** + * Returns true if events exist at current or later simulation time. + */ +bool scd_simulator::_pending() +{ + sc_core::sc_time next = _next_time(); + return ( (next != sc_core::SC_ZERO_TIME) || _pending_now() ); +} + + +/** + * Returns the time of the next earliest timed event + * or SC_ZERO_TIME if no such event exists. + */ +const sc_core::sc_time scd_simulator::_next_time() +{ + return sc_core::sc_get_curr_simcontext()->next_time(); +} +