From b1142c4796fdc1dcb04e2a1ed8d2a64f2337d608 Mon Sep 17 00:00:00 2001 From: Robert Gernhardt Date: Thu, 7 Aug 2014 12:06:04 +0200 Subject: [PATCH] traceplayer can now parse data of write commands. Reorder buffer inserted --- dram/resources/simulations/sim-batch.xml | 4 +- dram/src/simulation/Arbiter.h | 12 +- dram/src/simulation/Arbiter.h.autosave | 163 ------------------- dram/src/simulation/ReorderBuffer.h | 28 +++- dram/src/simulation/Simulation.cpp | 6 +- dram/src/simulation/Simulation.h | 1 + dram/src/simulation/TracePlayer.h | 192 ++++++++++++++++------- 7 files changed, 168 insertions(+), 238 deletions(-) delete mode 100644 dram/src/simulation/Arbiter.h.autosave diff --git a/dram/resources/simulations/sim-batch.xml b/dram/resources/simulations/sim-batch.xml index b8df13be..73734388 100644 --- a/dram/resources/simulations/sim-batch.xml +++ b/dram/resources/simulations/sim-batch.xml @@ -5,8 +5,8 @@ fr_fcfs.xml - grouper.xml - + diff --git a/dram/src/simulation/Arbiter.h b/dram/src/simulation/Arbiter.h index e21af2ec..b7421545 100644 --- a/dram/src/simulation/Arbiter.h +++ b/dram/src/simulation/Arbiter.h @@ -48,7 +48,7 @@ private: //used to account for the request_accept_delay in the dram controllers deque pendingRequests; //used to account for the response_accept_delay in the initiators (traceplayer,core etc.) - deque pendingResponses[NUMBER_OF_THREADS]; + deque receivedResponses[NUMBER_OF_THREADS]; // Initiated by dram side tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay) @@ -98,10 +98,10 @@ private: else if (phase == END_RESP) { sendToChannel(payload, phase, SC_ZERO_TIME); - pendingResponses[initiatorSocket].pop_front(); - if(!pendingResponses[initiatorSocket].empty()) + receivedResponses[initiatorSocket].pop_front(); + if(!receivedResponses[initiatorSocket].empty()) { - tlm_generic_payload* payloadToSend = pendingResponses[initiatorSocket].front(); + tlm_generic_payload* payloadToSend = receivedResponses[initiatorSocket].front(); sendToInitiator(initiatorSocket,*payloadToSend,BEGIN_RESP,SC_ZERO_TIME); } } @@ -122,9 +122,9 @@ private: } else if (phase == BEGIN_RESP) { - if(pendingResponses[initiatorSocket].empty()) + if(receivedResponses[initiatorSocket].empty()) sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME); - pendingResponses[initiatorSocket].push_back(&payload); + receivedResponses[initiatorSocket].push_back(&payload); } else diff --git a/dram/src/simulation/Arbiter.h.autosave b/dram/src/simulation/Arbiter.h.autosave deleted file mode 100644 index b7421545..00000000 --- a/dram/src/simulation/Arbiter.h.autosave +++ /dev/null @@ -1,163 +0,0 @@ -/* - * arbiter.h - * - * Created on: Mar 16, 2014 - * Author: robert - */ - -#ifndef ARBITER_H_ -#define ARBITER_H_ - - -#include -#include -#include -#include -#include -#include -#include "../common/xmlAddressdecoder.h" -#include "../common/dramExtension.h" -#include "../controller/core/TimingCalculation.h" -#include - - -using namespace std; -using namespace tlm; - -template -struct Arbiter: public sc_module -{ -public: - tlm_utils::simple_initiator_socket iSocket; - tlm_utils::simple_target_socket_tagged tSockets[NUMBER_OF_THREADS]; - - SC_CTOR(Arbiter) : - payloadEventQueue(this, &Arbiter::peqCallback), channelIsFree(true) - { - iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw); - - for (unsigned int i = 0; i < NUMBER_OF_THREADS; ++i) - { - tSockets[i].register_nb_transport_fw(this, &Arbiter::nb_transport_fw, i); - } - } - -private: - tlm_utils::peq_with_cb_and_phase payloadEventQueue; - bool channelIsFree; - //used to account for the request_accept_delay in the dram controllers - deque pendingRequests; - //used to account for the response_accept_delay in the initiators (traceplayer,core etc.) - deque receivedResponses[NUMBER_OF_THREADS]; - - // Initiated by dram side - tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay) - { - TlmRecorder::getInstance().recordPhase(payload, phase, bwDelay + sc_time_stamp()); - payloadEventQueue.notify(payload, phase, bwDelay); - return TLM_ACCEPTED; - } - - // Initiated by initiator side - tlm_sync_enum nb_transport_fw(int socketId, tlm_generic_payload& payload, tlm_phase& phase, - sc_time& fwDelay) - { - if(phase == BEGIN_REQ) - { - appendDramExtension(socketId, payload); - payload.acquire(); - } - else if(phase == END_RESP) - { - payload.release(); - } - - payloadEventQueue.notify(payload, phase, fwDelay); - return TLM_ACCEPTED; - } - - void peqCallback(tlm_generic_payload& payload, const tlm_phase& phase) - { - unsigned int initiatorSocket = DramExtension::getExtension(payload).getThread().ID()-1; - - - //Phases initiated by intiator side - if (phase == BEGIN_REQ) - { - if(channelIsFree) - { - channelIsFree = false; - sendToChannel(payload, phase, SC_ZERO_TIME ); - } - else - { - pendingRequests.push_back(&payload); - } - } - - else if (phase == END_RESP) - { - sendToChannel(payload, phase, SC_ZERO_TIME); - receivedResponses[initiatorSocket].pop_front(); - if(!receivedResponses[initiatorSocket].empty()) - { - tlm_generic_payload* payloadToSend = receivedResponses[initiatorSocket].front(); - sendToInitiator(initiatorSocket,*payloadToSend,BEGIN_RESP,SC_ZERO_TIME); - } - } - - //Phases initiated by dram side - else if (phase == END_REQ) - { - channelIsFree = true; - sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME); - - if(!pendingRequests.empty()) - { - tlm_generic_payload* payloadToSend = pendingRequests.front(); - pendingRequests.pop_front(); - sendToChannel(*payloadToSend, BEGIN_REQ, SC_ZERO_TIME ); - channelIsFree = false; - } - } - else if (phase == BEGIN_RESP) - { - if(receivedResponses[initiatorSocket].empty()) - sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME); - receivedResponses[initiatorSocket].push_back(&payload); - } - - else - { - SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase"); - } - } - - void sendToChannel(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay) - { - tlm_phase TPhase = phase; - sc_time TDelay = delay; - iSocket->nb_transport_fw(payload, TPhase, TDelay); - } - - void sendToInitiator(unsigned int id, tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay) - { - tlm_phase TPhase = phase; - sc_time TDelay = delay; - tSockets[id]->nb_transport_bw(payload, TPhase, TDelay); - } - - void appendDramExtension(int socketId, tlm_generic_payload& payload) - { - unsigned int burstlength = payload.get_streaming_width(); - DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(payload.get_address()); - DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(0), Bank(decodedAddress.bank), - BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength); - payload.set_auto_extension(extension); - } -}; - - - - -#endif /* ARBITER_H_ */ diff --git a/dram/src/simulation/ReorderBuffer.h b/dram/src/simulation/ReorderBuffer.h index d1ce1fff..82a74b4b 100644 --- a/dram/src/simulation/ReorderBuffer.h +++ b/dram/src/simulation/ReorderBuffer.h @@ -13,7 +13,7 @@ struct ReorderBuffer: public sc_module { public: tlm_utils::simple_initiator_socket iSocket; - tlm_utils::simple_target_socket_tagged tSocket; + tlm_utils::simple_target_socket tSocket; SC_CTOR(ReorderBuffer) : payloadEventQueue(this, &ReorderBuffer::peqCallback), responseIsPendingInInitator(false) @@ -24,7 +24,7 @@ public: private: tlm_utils::peq_with_cb_and_phase payloadEventQueue; - deque requestsInOrder; + deque pendingRequestsInOrder; set receivedResponses; bool responseIsPendingInInitator; @@ -59,13 +59,15 @@ private: //Phases initiated by initiator side if (phase == BEGIN_REQ) { - requestsInOrder.push_back(&payload); + pendingRequestsInOrder.push_back(&payload); sendToTarget(payload, phase, SC_ZERO_TIME ); } else if (phase == END_RESP) { responseIsPendingInInitator = false; + pendingRequestsInOrder.pop_front(); + receivedResponses.erase(&payload); sendNextResponse(); } @@ -81,6 +83,7 @@ private: sendNextResponse(); } + else { SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase"); @@ -96,6 +99,11 @@ private: void sendToInitiator(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay) { + + + sc_assert(phase == END_REQ || + (phase == BEGIN_RESP && pendingRequestsInOrder.front() == &payload && receivedResponses.count(&payload))); + tlm_phase TPhase = phase; sc_time TDelay = delay; tSocket->nb_transport_bw(payload, TPhase, TDelay); @@ -103,14 +111,18 @@ private: void sendNextResponse() { - if(!responseIsPendingInInitator && receivedResponses.count(requestsInOrder.front())) + //only send the next response when there response for the oldest pending request (requestsInOrder.front()) + //has been received + if(!responseIsPendingInInitator && receivedResponses.count(pendingRequestsInOrder.front())) { - tlm_generic_payload* payloadToSend = requestsInOrder.front(); - requestsInOrder.pop_front(); - receivedResponses.erase(payloadToSend); + tlm_generic_payload* payloadToSend = pendingRequestsInOrder.front(); responseIsPendingInInitator = true; - sendToInitiator(payloadToSend,BEGIN_RESP,SC_ZERO_TIME); + sendToInitiator(*payloadToSend,BEGIN_RESP,SC_ZERO_TIME); } +// else if(!responseIsPendingInInitator && receivedResponses.size()>0 && !receivedResponses.count(pendingRequestsInOrder.front())>0) +// { +// cout << "cant send this response, because we are still waiting for response of oldest pending request. Elemts in buffer: " << receivedResponses.size() << endl; +// } } }; diff --git a/dram/src/simulation/Simulation.cpp b/dram/src/simulation/Simulation.cpp index 7607bdbd..019fb56a 100644 --- a/dram/src/simulation/Simulation.cpp +++ b/dram/src/simulation/Simulation.cpp @@ -82,6 +82,7 @@ void Simulation::instantiateModules(const string &pathToResources, const std::ve dram = new Dram<>("dram"); arbiter = new Arbiter("arbiter"); controller = new Controller<>("controller"); + reorder = new ReorderBuffer<>("reorder"); player1 = new TracePlayer<>("player1", pathToResources + string("traces/") + devices[0].trace, devices[0].burstLength, devices[0].clkMhz, this); player2 = new TracePlayer<>("player2", pathToResources + string("traces/") + devices[1].trace, devices[1].burstLength, devices[1].clkMhz, this); @@ -91,7 +92,10 @@ void Simulation::instantiateModules(const string &pathToResources, const std::ve void Simulation::bindSockets() { - player1->iSocket.bind(arbiter->tSockets[0]); + //player1->iSocket.bind(arbiter->tSockets[0]); + player1->iSocket.bind(reorder->tSocket); + reorder->iSocket.bind(arbiter->tSockets[0]); + player2->iSocket.bind(arbiter->tSockets[1]); player3->iSocket.bind(arbiter->tSockets[2]); player4->iSocket.bind(arbiter->tSockets[3]); diff --git a/dram/src/simulation/Simulation.h b/dram/src/simulation/Simulation.h index 7e1017ed..8b4d5dc0 100644 --- a/dram/src/simulation/Simulation.h +++ b/dram/src/simulation/Simulation.h @@ -62,6 +62,7 @@ private: Dram<> *dram; Arbiter *arbiter; Controller<> *controller; + ReorderBuffer<> *reorder; TracePlayer<> *player1; TracePlayer<> *player2; diff --git a/dram/src/simulation/TracePlayer.h b/dram/src/simulation/TracePlayer.h index 0e604822..db699b53 100644 --- a/dram/src/simulation/TracePlayer.h +++ b/dram/src/simulation/TracePlayer.h @@ -33,7 +33,7 @@ struct TracePlayer: public sc_module public: tlm_utils::simple_initiator_socket iSocket; TracePlayer(sc_module_name /*name*/, string pathToTrace, unsigned int burstLength, unsigned int clkMhz, - simulation::ISimulation* simulationManager); + simulation::ISimulation* simulationManager); void start(); @@ -85,72 +85,148 @@ void TracePlayer::start() template void TracePlayer::generateNextPayload() { - if (file) + + if(file) { - string time, command, address, data; - file >> time >> command >> address; - - //if there is a newline at the end of the .stl - if (time.empty() || command.empty() || address.empty() ) - return; - - long parsedAdress = std::stoi(address.c_str(), 0, 16); - - gp* payload = memoryManager.allocate(); - payload->set_address(parsedAdress); - - // Set data pointer - unsigned char * dataElement = new unsigned char[16]; // TODO: column / burst breite - payload->set_data_length(16); // TODO: column / burst breite - payload->set_data_ptr(dataElement); - for(int i = 0; i < 16; i++) // TODO: column / burst breite - dataElement[i] = 0; - - if (command == "read") + string line; + if (std::getline(file, line)) { - payload->set_command(TLM_READ_COMMAND); - } - else if (command == "write") - { - payload->set_command(TLM_WRITE_COMMAND); + std::istringstream iss(line); + string time, command, address; + iss >> time >> command >> address; + if (time.empty() || command.empty() || address.empty() ) + return; + long parsedAdress = std::stoi(address.c_str(), 0, 16); - // Parse and set data -// file >> data; -// unsigned int counter = 0; -// for(int i = 0; i < 16*2-2; i=i+2) // TODO column / burst breite -// { -// std::string byteString = "0x"; -// byteString.append(data.substr(i+2, 2)); -// //cout << byteString << " " << std::stoi(byteString.c_str(), 0, 16) << endl; -// dataElement[counter++] = std::stoi(byteString.c_str(), 0, 16); -// } - } - else - { - SC_REPORT_FATAL(0, - (string("Corrupted tracefile, command ") + command + string(" unknown")).c_str()); - } + gp* payload = memoryManager.allocate(); + payload->set_address(parsedAdress); - payload->set_response_status(TLM_INCOMPLETE_RESPONSE); - payload->set_dmi_allowed(false); - payload->set_byte_enable_length(0); - payload->set_streaming_width(burstlenght); + // Set data pointer + unsigned char * dataElement = new unsigned char[16]; // TODO: column / burst breite + payload->set_data_length(16); // TODO: column / burst breite + payload->set_data_ptr(dataElement); + for(int i = 0; i < 16; i++) // TODO: column / burst breite + dataElement[i] = 0; - sc_time sendingTime = std::stoi(time.c_str())*clk; - GenerationExtension* genExtension = new GenerationExtension(sendingTime); - payload->set_auto_extension(genExtension); + if (command == "read") + { + payload->set_command(TLM_READ_COMMAND); + } + else if (command == "write") + { + payload->set_command(TLM_WRITE_COMMAND); + + // Parse and set data + string data; + iss >> data; + + if(!data.empty()) + { + //cout << "parsing write data: " << data << std::endl; + + for(int i = 0; i < 16; i++) // TODO column / burst breite + { + std::string byteString = "0x"; + byteString.append(data.substr(2*(i+1), 2)); + //cout << byteString << " " << std::stoi(byteString.c_str(), 0, 16) << endl; + dataElement[i] = std::stoi(byteString.c_str(), 0, 16); + } + } + } + else + { + SC_REPORT_FATAL(0, + (string("Corrupted tracefile, command ") + command + string(" unknown")).c_str()); + } + + payload->set_response_status(TLM_INCOMPLETE_RESPONSE); + payload->set_dmi_allowed(false); + payload->set_byte_enable_length(0); + payload->set_streaming_width(burstlenght); + + sc_time sendingTime = std::stoi(time.c_str())*clk; + GenerationExtension* genExtension = new GenerationExtension(sendingTime); + payload->set_auto_extension(genExtension); + + if (sendingTime <= sc_time_stamp()) + { + payloadEventQueue.notify(*payload, BEGIN_REQ, SC_ZERO_TIME); + } + else + { + payloadEventQueue.notify(*payload, BEGIN_REQ, sendingTime - sc_time_stamp()); + } + numberOfPendingTransactions++; - if (sendingTime <= sc_time_stamp()) - { - payloadEventQueue.notify(*payload, BEGIN_REQ, SC_ZERO_TIME); } - else - { - payloadEventQueue.notify(*payload, BEGIN_REQ, sendingTime - sc_time_stamp()); - } - numberOfPendingTransactions++; } } + // if (file) + // { + // string time, command, address, data; + // file >> time >> command >> address; + + // //if there is a newline at the end of the .stl + // if (time.empty() || command.empty() || address.empty() ) + // return; + + // long parsedAdress = std::stoi(address.c_str(), 0, 16); + + // gp* payload = memoryManager.allocate(); + // payload->set_address(parsedAdress); + + // // Set data pointer + // unsigned char * dataElement = new unsigned char[16]; // TODO: column / burst breite + // payload->set_data_length(16); // TODO: column / burst breite + // payload->set_data_ptr(dataElement); + // for(int i = 0; i < 16; i++) // TODO: column / burst breite + // dataElement[i] = 0; + + // if (command == "read") + // { + // payload->set_command(TLM_READ_COMMAND); + // } + // else if (command == "write") + // { + // payload->set_command(TLM_WRITE_COMMAND); + + // // Parse and set data + //// file >> data; + //// unsigned int counter = 0; + //// for(int i = 0; i < 16*2-2; i=i+2) // TODO column / burst breite + //// { + //// std::string byteString = "0x"; + //// byteString.append(data.substr(i+2, 2)); + //// //cout << byteString << " " << std::stoi(byteString.c_str(), 0, 16) << endl; + //// dataElement[counter++] = std::stoi(byteString.c_str(), 0, 16); + //// } + // } + // else + // { + // SC_REPORT_FATAL(0, + // (string("Corrupted tracefile, command ") + command + string(" unknown")).c_str()); + // } + + // payload->set_response_status(TLM_INCOMPLETE_RESPONSE); + // payload->set_dmi_allowed(false); + // payload->set_byte_enable_length(0); + // payload->set_streaming_width(burstlenght); + + // sc_time sendingTime = std::stoi(time.c_str())*clk; + // GenerationExtension* genExtension = new GenerationExtension(sendingTime); + // payload->set_auto_extension(genExtension); + + // if (sendingTime <= sc_time_stamp()) + // { + // payloadEventQueue.notify(*payload, BEGIN_REQ, SC_ZERO_TIME); + // } + // else + // { + // payloadEventQueue.notify(*payload, BEGIN_REQ, sendingTime - sc_time_stamp()); + // } + // numberOfPendingTransactions++; + // } +//} template tlm_sync_enum TracePlayer::nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay)