diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml index a6f0853e..b81a7cca 100644 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -1,9 +1,9 @@ - - - + + + diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index bc65a145..40038097 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -165,7 +165,8 @@ HEADERS += \ src/controller/scheduler/FifoStrict.h \ src/controller/IController.h \ src/controller/core/configuration/ConfigurationLoader.h \ - src/error/errormodel.h + src/error/errormodel.h \ + src/simulation/exampleinitiator.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/src/simulation/MemoryManager.cpp b/DRAMSys/simulator/src/simulation/MemoryManager.cpp index 48611d40..736cae5b 100644 --- a/DRAMSys/simulator/src/simulation/MemoryManager.cpp +++ b/DRAMSys/simulator/src/simulation/MemoryManager.cpp @@ -75,8 +75,8 @@ gp* MemoryManager::allocate() void MemoryManager::free(gp* payload) { - unsigned char *dptr = payload->get_data_ptr(); - delete[] dptr; + //unsigned char *dptr = payload->get_data_ptr(); + //delete[] dptr; payload->reset(); //clears all extensions freePayloads.push_back(payload); } diff --git a/DRAMSys/simulator/src/simulation/Simulation.cpp b/DRAMSys/simulator/src/simulation/Simulation.cpp index 5105c29c..e842fa52 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.cpp +++ b/DRAMSys/simulator/src/simulation/Simulation.cpp @@ -114,6 +114,7 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT // The same instance will be accessed by all other modules. TemperatureController::getInstance(); +#if 0 for (size_t i = 0; i < Configuration::getInstance().NumberOfTracePlayers; i++) { std::string playerStr = "tracePlayer" + std::to_string(i); TracePlayer<> *player; @@ -138,7 +139,8 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT } remainingTransactions = totalTransactions; - //player->remainingTransactions = player->totalTransactions; + player->remainingTransactions = player->totalTransactions; +#endif // Create and properly initialize TLM recorders. They need to be ready before creating some modules. setupTlmRecorders(traceName, pathToResources, devices); @@ -146,6 +148,8 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT arbiter = new Arbiter<128>("arbiter"); arbiter->setTlmRecorders(tlmRecorders); + init = new ExampleInitiator<128>("init", this); + for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) { std::string str = "controller" + std::to_string(i); Controller<> *controller = new Controller<>(str.c_str(), tlmRecorders[i]); @@ -161,9 +165,11 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT void Simulation::bindSockets() { - for (auto player : players) { - player->iSocket.bind(arbiter->tSocket); - } + //for (auto player : players) { + // player->iSocket.bind(arbiter->tSocket); + //} + + init->socket.bind(arbiter->tSocket); for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) { arbiter->iSocket.bind(controllers[i]->tSocket); @@ -173,9 +179,9 @@ void Simulation::bindSockets() Simulation::~Simulation() { - for (auto player : players) { - delete player; - } + //for (auto player : players) { + // delete player; + //} delete arbiter; diff --git a/DRAMSys/simulator/src/simulation/Simulation.h b/DRAMSys/simulator/src/simulation/Simulation.h index 3b5d24fb..b38e31af 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.h +++ b/DRAMSys/simulator/src/simulation/Simulation.h @@ -50,6 +50,7 @@ #include "StlPlayer.h" #include "../controller/Controller.h" #include "../common/third_party/tinyxml2/tinyxml2.h" +#include "exampleinitiator.h" struct DramSetup { @@ -98,6 +99,7 @@ private: // and initiate transactions targeting the memory) std::vector*> players; // All transactions pass through the same arbiter + ExampleInitiator<> *init; Arbiter<> *arbiter; // Each DRAM unit has a controller std::vector*> controllers; diff --git a/DRAMSys/simulator/src/simulation/exampleinitiator.h b/DRAMSys/simulator/src/simulation/exampleinitiator.h new file mode 100644 index 00000000..c01d4fe0 --- /dev/null +++ b/DRAMSys/simulator/src/simulation/exampleinitiator.h @@ -0,0 +1,193 @@ +#ifndef EXAMPLEINITIATOR +#define EXAMPLEINITIATOR + +#include +#include + +#include "MemoryManager.h" +#include "../common/dramExtension.h" +#include "TracePlayer.h" + +using namespace std; + +template +struct ExampleInitiator: sc_module +{ + // TLM-2 socket, defaults to 32-bits wide, base protocol + tlm_utils::simple_initiator_socket socket; + + SC_CTOR(ExampleInitiator) + : socket("socket") // Construct and name socket + , request_in_progress(0) + , m_peq(this, &ExampleInitiator::peq_cb) + { + socket.register_nb_transport_bw(this, &ExampleInitiator::nb_transport_bw); + + SC_THREAD(thread_process); + } + + void thread_process() + { + tlm::tlm_generic_payload* trans; + tlm::tlm_phase phase; + sc_time delay; + + +#if 0 + // Make a call to b_transport + trans = m_mm.allocate(); + trans->acquire(); + + int adr = 0; + data[0] = adr; + + trans->set_command( tlm::TLM_WRITE_COMMAND ); + trans->set_address( adr ); + trans->set_data_ptr( reinterpret_cast(&data[0]) ); + trans->set_data_length( 4 ); + trans->set_streaming_width( 4 ); + trans->set_byte_enable_ptr( 0 ); + trans->set_dmi_allowed( false ); + trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); + + socket->b_transport( *trans, delay ); + + trans->release(); +#endif + + // Generate a sequence of random transactions + for (int i = 0; i < 1000; i++) + { + //int adr = rand(); + int adr = 0; + //tlm::tlm_command cmd = static_cast(rand() % 2); + tlm::tlm_command cmd = tlm::TLM_READ_COMMAND; + if (cmd == tlm::TLM_WRITE_COMMAND) data[i % 16] = adr; + + // Grab a new transaction from the memory manager + trans = m_mm.allocate(); + trans->acquire(); + + trans->set_command( cmd ); + trans->set_address( adr ); + trans->set_data_ptr( reinterpret_cast(&data[i % 16]) ); + trans->set_data_length( 4 ); + trans->set_streaming_width( 4 ); + trans->set_byte_enable_ptr( 0 ); + trans->set_dmi_allowed( false ); + trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); + + // ExampleInitiator must honor BEGIN_REQ/END_REQ exclusion rule + if (request_in_progress) + wait(end_request_event); + request_in_progress = trans; + phase = tlm::BEGIN_REQ; + + // Timing annotation models processing time of initiator prior to call + //delay = sc_time(rand_ps(), SC_PS); + delay = sc_time(100000, SC_PS); + + cout << hex << adr << " new, cmd=" << (cmd ? "write" : "read") + << ", data=" << hex << data[i % 16] << " at time " << sc_time_stamp() + << " in " << name() << endl; + + GenerationExtension* genExtension = new GenerationExtension(sc_time_stamp()); + trans->set_auto_extension(genExtension); + + + // Non-blocking transport call on the forward path + tlm::tlm_sync_enum status; + status = socket->nb_transport_fw( *trans, phase, delay ); + + // Check value returned from nb_transport_fw + if (status == tlm::TLM_UPDATED) + { + // The timing annotation must be honored + m_peq.notify( *trans, phase, delay ); + } + else if (status == tlm::TLM_COMPLETED) + { + // The completion of the transaction necessarily ends the BEGIN_REQ phase + request_in_progress = 0; + + // The target has terminated the transaction + check_transaction( *trans ); + + // Allow the memory manager to free the transaction object + trans->release(); + } + //wait( sc_time(rand_ps(), SC_PS) ); + wait( sc_time(50000, SC_PS) ); + } + } + + // TLM-2 backward non-blocking transport method + + virtual tlm::tlm_sync_enum nb_transport_bw( tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, sc_time& delay ) + { + m_peq.notify( trans, phase, delay ); + return tlm::TLM_ACCEPTED; + } + + // Payload event queue callback to handle transactions from target + // Transaction could have arrived through return path or backward path + + void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase) + { + if (phase == tlm::END_REQ || (&trans == request_in_progress && phase == tlm::BEGIN_RESP)) + { + // The end of the BEGIN_REQ phase + request_in_progress = 0; + end_request_event.notify(); + } + else if (phase == tlm::BEGIN_REQ || phase == tlm::END_RESP) + SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by initiator"); + + if (phase == tlm::BEGIN_RESP) + { + check_transaction( trans ); + + // Send final phase transition to target + tlm::tlm_phase fw_phase = tlm::END_RESP; + //sc_time delay = sc_time(rand_ps(), SC_PS); + sc_time delay = sc_time(60000, SC_PS); + socket->nb_transport_fw( trans, fw_phase, delay ); + // Ignore return value + + // Allow the memory manager to free the transaction object + trans.release(); + } + } + + // Called on receiving BEGIN_RESP or TLM_COMPLETED + void check_transaction(tlm::tlm_generic_payload& trans) + { + if ( trans.is_response_error() ) + { + char txt[100]; + sprintf(txt, "Transaction returned with error, response status = %s", + trans.get_response_string().c_str()); + SC_REPORT_ERROR("TLM-2", txt); + } + + tlm::tlm_command cmd = trans.get_command(); + sc_dt::uint64 adr = trans.get_address(); + int* ptr = reinterpret_cast( trans.get_data_ptr() ); + + cout << hex << adr << " check, cmd=" << (cmd ? "write" : "read") + << ", data=" << hex << *ptr << " at time " << sc_time_stamp() + << " in " << name() << endl; + + if (cmd == tlm::TLM_READ_COMMAND) + assert( *ptr == -int(adr) ); + } + + MemoryManager m_mm; + int data[16]; + tlm::tlm_generic_payload* request_in_progress; + sc_event end_request_event; + tlm_utils::peq_with_cb_and_phase m_peq; +}; + +#endif // EXAMPLEINITIATOR