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)