diff --git a/analyzer/analyzer/paths.pro b/analyzer/analyzer/paths.pro
index 102db5af..b19fe4eb 100644
--- a/analyzer/analyzer/paths.pro
+++ b/analyzer/analyzer/paths.pro
@@ -8,8 +8,8 @@ CONFIG(qwt){
CONFIG(python){
-# LIBS += -L/opt/python/lib -lpython3.4m
-# INCLUDEPATH += /opt/python/include/python3.4m
- LIBS += -lpython3.3m
- INCLUDEPATH += /usr/include/python3.3
+ LIBS += -L/opt/python/lib -lpython3.4m
+ INCLUDEPATH += /opt/python/include/python3.4m
+# LIBS += -lpython3.3m
+# INCLUDEPATH += /usr/include/python3.3
}
diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro
index c4693944..78ebe06a 100644
--- a/dram/dramSys/dramSys.pro
+++ b/dram/dramSys/dramSys.pro
@@ -1,4 +1,4 @@
- TEMPLATE = app
+TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
@@ -8,7 +8,7 @@ LIBS += -L/opt/systemc/lib-linux64 -lsystemc
LIBS += -L/opt/boost/lib -lboost_filesystem -lboost_system
LIBS += -L/opt/sqlite3/lib -lsqlite3
LIBS += -lpthread
-LIBS += -L/opt/xerces-c-3.1.1/lib -lxerces-c
+LIBS += -L/opt/xerces/lib -lxerces-c
LIBS += -L../src/common/third_party/DRAMPower/src/ -ldrampowerxml
LIBS += -L../src/common/third_party/DRAMPower/src/ -ldrampower
@@ -122,5 +122,6 @@ HEADERS += \
../src/simulation/Arbiter.h \
../src/common/libDRAMPower.h \
../src/controller/core/RowBufferStates.h \
- ../src/controller/scheduler/readwritegrouper.h
+ ../src/controller/scheduler/readwritegrouper.h \
+ ../src/simulation/ReorderBuffer.h
diff --git a/dram/resources/configs/amconfigs/am_ddr4 (4th copy).xml b/dram/resources/configs/amconfigs/am_ddr4 (4th copy).xml
deleted file mode 100755
index 73d9cb36..00000000
--- a/dram/resources/configs/amconfigs/am_ddr4 (4th copy).xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/dram/resources/configs/memconfigs/fr_fcfs.xml b/dram/resources/configs/memconfigs/fr_fcfs.xml
index b126adb1..8aa70731 100644
--- a/dram/resources/configs/memconfigs/fr_fcfs.xml
+++ b/dram/resources/configs/memconfigs/fr_fcfs.xml
@@ -1,6 +1,6 @@
-
+
@@ -9,7 +9,6 @@
-
diff --git a/dram/resources/simulations/sim-batch.xml b/dram/resources/simulations/sim-batch.xml
index 89adea06..516578e6 100644
--- a/dram/resources/simulations/sim-batch.xml
+++ b/dram/resources/simulations/sim-batch.xml
@@ -1,22 +1,17 @@
WideIO.xml
-
-
am_wideio.xml
-
- fifo.xml
-
-
+
+ grouper.xml
+
+
- small.stl
+ mediabench-fractal_32.stl
diff --git a/dram/src/controller/Controller.h b/dram/src/controller/Controller.h
index 8a6b9115..e40f8ade 100644
--- a/dram/src/controller/Controller.h
+++ b/dram/src/controller/Controller.h
@@ -119,10 +119,7 @@ void Controller::buildScheduler()
if (selectedScheduler == "FR_FCFS")
{
-
- Scheduler* s = new FR_FCFS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling,
- Configuration::getInstance().AdaptiveOpenPagePolicy);
- scheduler = new ReadWriteGrouper(s);
+ scheduler = new FR_FCFS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling,Configuration::getInstance().AdaptiveOpenPagePolicy);
}
else if (selectedScheduler == "PAR_BS")
{
@@ -130,7 +127,13 @@ void Controller::buildScheduler()
Configuration::getInstance().Capsize);
}
else if (selectedScheduler == "FIFO")
+ {
scheduler = new Fifo(*controllerCore);
+ }
+ else if (selectedScheduler == "Grouper")
+ {
+ scheduler = new ReadWriteGrouper(*controllerCore);
+ }
else
reportFatal(name(), "unsupported scheduler: " + selectedScheduler);
}
diff --git a/dram/src/controller/core/configuration/TimingConfiguration.h b/dram/src/controller/core/configuration/TimingConfiguration.h
index e990c6fd..cb080c94 100644
--- a/dram/src/controller/core/configuration/TimingConfiguration.h
+++ b/dram/src/controller/core/configuration/TimingConfiguration.h
@@ -15,8 +15,8 @@ namespace core{
struct RefreshTiming
{
- RefreshTiming() {};
- RefreshTiming(sc_time tRFC, sc_time tREFI) : tRFC(tRFC), tREFI(tREFI) {};
+ RefreshTiming() {}
+ RefreshTiming(sc_time tRFC, sc_time tREFI) : tRFC(tRFC), tREFI(tREFI) {}
sc_time tRFC;
sc_time tREFI;
};
diff --git a/dram/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp b/dram/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp
index 112d4f90..92820e76 100644
--- a/dram/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp
+++ b/dram/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp
@@ -53,6 +53,12 @@ void PrechargeAllChecker::delayToSatisfyConstraints(ScheduledCommand& command) c
}
}
+ ScheduledCommand lastActivate = state.getLastCommand(Command::Activate, command.getBank());
+ if (lastActivate.isValidCommand())
+ {
+ command.delayToMeetConstraint(lastActivate.getStart(), config.Timings.tRAS);
+ }
+
state.bus.moveCommandToNextFreeSlot(command);
}
diff --git a/dram/src/controller/scheduler/Fr_Fcfs.cpp b/dram/src/controller/scheduler/Fr_Fcfs.cpp
index 5635cc33..b0b6c159 100644
--- a/dram/src/controller/scheduler/Fr_Fcfs.cpp
+++ b/dram/src/controller/scheduler/Fr_Fcfs.cpp
@@ -97,6 +97,19 @@ unsigned int FR_FCFS::getNumberOfQueuedPayloads()
return numberOfQueuedPaylods;
}
+bool FR_FCFS::containsPayloadTragetingSameAddress(gp *payload)
+{
+ Bank bank = DramExtension::getExtension(payload).getBank();
+ Row row = DramExtension::getExtension(payload).getRow();
+
+ for(gp* bufferedPayload: buffer[bank])
+ {
+ if(DramExtension::getExtension(bufferedPayload).getRow() == row)
+ return true;
+ }
+ return false;
+}
+
std::vector FR_FCFS::findRowHits(Bank bank, Row row)
{
vector found;
diff --git a/dram/src/controller/scheduler/Fr_Fcfs.h b/dram/src/controller/scheduler/Fr_Fcfs.h
index ccfbf718..39446120 100644
--- a/dram/src/controller/scheduler/Fr_Fcfs.h
+++ b/dram/src/controller/scheduler/Fr_Fcfs.h
@@ -25,6 +25,8 @@ public:
gp* popOldest(Bank bank);
unsigned int getNumberOfQueuedPayloads();
+ //used by read/write grouper
+ bool containsPayloadTragetingSameAddress(gp* payload);
private:
std::vector findRowHits(Bank bank, Row row);
std::map> buffer;
diff --git a/dram/src/controller/scheduler/Scheduler.cpp b/dram/src/controller/scheduler/Scheduler.cpp
index b7bbbbb4..a872e821 100644
--- a/dram/src/controller/scheduler/Scheduler.cpp
+++ b/dram/src/controller/scheduler/Scheduler.cpp
@@ -1,12 +1,16 @@
#include "Scheduler.h"
#include "../../common/DebugManager.h"
+#include
+
+using namespace std;
using namespace scheduler;
std::string Scheduler::sendername = "scheduler";
void Scheduler::printDebugMessage(std::string message)
{
+ //cout << "scheduler: " << message << std::endl;
DebugManager::getInstance().printDebugMessage(Scheduler::sendername, message);
}
diff --git a/dram/src/controller/scheduler/readwritegrouper.cpp b/dram/src/controller/scheduler/readwritegrouper.cpp
index 5797fddb..6c2d9306 100644
--- a/dram/src/controller/scheduler/readwritegrouper.cpp
+++ b/dram/src/controller/scheduler/readwritegrouper.cpp
@@ -1,121 +1,150 @@
#include "readwritegrouper.h"
+#include "../../common/DebugManager.h"
namespace scheduler{
using namespace tlm;
+using namespace std;
-ReadWriteGrouper::ReadWriteGrouper(Scheduler *scheduler):
- scheduler(scheduler), mode(Mode::read)
+ReadWriteGrouper::ReadWriteGrouper(core::ControllerCore& controllerCore): controllerCore(controllerCore)
{
-
+ batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false)));
+ batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false)));
}
ReadWriteGrouper::~ReadWriteGrouper()
{
- delete scheduler;
+
+}
+
+void ReadWriteGrouper::schedule(gp *payload)
+{
+ tlm_command command = payload->get_command();
+
+ if(batches.size() > 2)
+ {
+ if(command == TLM_READ_COMMAND)
+ {
+ //printDebugMessage("Scheduling read");
+
+ if(schedulingReadCausesHazardWithQueuedWrite(payload))
+ {
+ printDebugMessage("Scheduling read causes hazard with queued write");
+ batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false)));
+ batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false)));
+ }
+
+ getLatestReadBatch().schedule(payload);
+ }
+ else if(command == TLM_WRITE_COMMAND)
+ {
+ //printDebugMessage("Scheduling write");
+ getLatestWriteBatch().schedule(payload);
+ }
+ }
+ else if(batches.size() == 2)
+ {
+ if(command == TLM_READ_COMMAND)
+ {
+ //printDebugMessage("Scheduling read");
+
+ if(getLatestReadBatch().hasPayloads() && schedulingReadCausesHazardWithQueuedWrite(payload))
+ {
+ printDebugMessage("Scheduling read causes hazard with queued write");
+ batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false)));
+ batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false)));
+ }
+ else if(!getLatestReadBatch().hasPayloads() && getLatestWriteBatch().hasPayloads())
+ {
+ printDebugMessage("Scheduling read, but there are writes to be processed first");
+ batches.erase(batches.begin());
+ batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false)));
+ batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false)));
+ }
+ getLatestReadBatch().schedule(payload);
+
+ }
+ else if(command == TLM_WRITE_COMMAND)
+ {
+ //printDebugMessage("Scheduling write");
+ getLatestWriteBatch().schedule(payload);
+ }
+ }
+ else
+ {
+ sc_assert(false);
+ }
+}
+
+gp *ReadWriteGrouper::getNextPayload()
+{
+ if(batches.size() > 2)
+ {
+ return batches.front()->getNextPayload();
+ }
+ else if(batches.size() == 2)
+ {
+ if(getLatestReadBatch().hasPayloads())
+ return getLatestReadBatch().getNextPayload();
+ else if(getLatestWriteBatch().hasPayloads())
+ return getLatestWriteBatch().getNextPayload();
+ else
+ return NULL;
+ }
+ else
+ {
+ sc_assert(false);
+ }
}
void ReadWriteGrouper::removePayload(gp *payload)
{
- scheduler->removePayload(payload);
-
- //if scheduler is empty now
- if(!scheduler->hasPayloads())
+ if(batches.size() > 2)
{
- if(mode == Mode::read && !writeQueue.empty())
- switchToWriteMode();
- else if(mode == Mode::readToWrite)
- switchToWriteMode();
+ batches.front()->removePayload(payload);
+ if(!batches.front()->hasPayloads())
+ batches.erase(batches.begin());
+ }
+ else if(batches.size() == 2)
+ {
+ if(payload->is_read())
+ getLatestReadBatch().removePayload(payload);
else
- switchToReadMode();
- }
-}
-
-void ReadWriteGrouper::schedule(gp *payload)
-{
-tlm_command command = payload->get_command();
-
-//in read mode hazards could occur by letting a read pass a queued write
-if(mode == Mode::read)
-{
- if(command == TLM_READ_COMMAND)
- {
- //if scheduling the read would cause a hazard switch to readToWriteMode and put the read into the readQueue
- if(schedulingReadCausesHazard(payload))
- {
- switchToReadToWriteMode();
- readQueue.push_back(payload);
- }
- else
- scheduler->schedule(payload);
+ getLatestWriteBatch().removePayload(payload);
}
else
{
- writeQueue.push_back(payload);
- if(!scheduler->hasPayloads())
- //there are no reads in the scheduler, so switch directly to write mode
- switchToWriteMode();
+ sc_assert(false);
}
}
-else if(mode == Mode::readToWrite)
-{
- if(command == TLM_READ_COMMAND)
- readQueue.push_back(payload);
- else
- writeQueue.push_back(payload);
-}
-else if(mode == Mode::write)
-{
- if(command == TLM_READ_COMMAND)
- readQueue.push_back(payload);
- else
- scheduler->schedule(payload);
-}
-}
-
-gp *ReadWriteGrouper::getNextPayload()
-{
- return scheduler->getNextPayload();
-}
bool ReadWriteGrouper::hasPayloads()
{
- return scheduler->hasPayloads();
+ if(batches.size() > 2)
+ return true;
+ else if(batches.size() == 2)
+ return (getLatestReadBatch().hasPayloads() || getLatestWriteBatch().hasPayloads());
+ else
+ sc_assert(false);
}
-bool ReadWriteGrouper::schedulingReadCausesHazard(gp *payload)
+bool ReadWriteGrouper::schedulingReadCausesHazardWithQueuedWrite(gp *payload)
{
sc_assert(payload->is_read());
- for(gp* write: writeQueue)
- {
- if(payload->get_address()==write->get_address())
- return true;
- }
- return false;
+ return getLatestWriteBatch().containsPayloadTragetingSameAddress(payload);
}
-void ReadWriteGrouper::switchToReadMode()
+FR_FCFS &ReadWriteGrouper::getLatestWriteBatch()
{
- mode = Mode::read;
- for(gp* read: readQueue)
- scheduler->schedule(read);
- readQueue.clear();
+ return *batches[batches.size()-1];
}
-void ReadWriteGrouper::switchToWriteMode()
+FR_FCFS &ReadWriteGrouper::getLatestReadBatch()
{
- mode = Mode::write;
- for(gp* write: writeQueue)
- scheduler->schedule(write);
- writeQueue.clear();
-}
-
-void ReadWriteGrouper::switchToReadToWriteMode()
-{
- mode = Mode::readToWrite;
+ return *batches[batches.size()-2];
}
}
diff --git a/dram/src/controller/scheduler/readwritegrouper.h b/dram/src/controller/scheduler/readwritegrouper.h
index 4e8b359f..dedd0c5d 100644
--- a/dram/src/controller/scheduler/readwritegrouper.h
+++ b/dram/src/controller/scheduler/readwritegrouper.h
@@ -1,19 +1,18 @@
#ifndef READWRITEGROUPER_H
#define READWRITEGROUPER_H
#include "Scheduler.h"
+#include "Fr_Fcfs.h"
+#include "../core/ControllerCore.h"
+#include
#include
+
namespace scheduler{
-/* Scheduler that batches reads and writes to reduce the overhead when switching from
- * read to write mode (read-to-write constraints)
- * The scheduler prioritizes reads. It switches to write mode, when stalling a write would induce a data-hazard
- * or when there are no reads to process.
- */
class ReadWriteGrouper : public Scheduler
{
public:
- ReadWriteGrouper(Scheduler *scheduler);
+ ReadWriteGrouper(core::ControllerCore& controllerCore);
~ReadWriteGrouper();
virtual void schedule(gp* payload) override;
virtual bool hasPayloads() override;
@@ -21,17 +20,19 @@ public:
virtual void removePayload(gp* payload) override;
private:
- Scheduler *scheduler;
- std::vector readQueue, writeQueue;
- //Mode readToWrite is used to process the remaining reads in the readScheduler before
- //switching to write mode (this is used when a potential hazard causes the scheduler to switch modes)
- enum class Mode{read,readToWrite, write};
- Mode mode;
+ // contains batches of requests
+ // last element always contains writes
+ // next-to-last element always contains reads
+ // there are always at least two batches
+ // if there are more than two batches, batches[0] is never empty and
+ // getNextPayload and removePayload are forwarded to batches[0]
+ std::vector> batches;
+ core::ControllerCore& controllerCore;
+
+ bool schedulingReadCausesHazardWithQueuedWrite(gp* payload);
+ FR_FCFS& getLatestWriteBatch();
+ FR_FCFS& getLatestReadBatch();
- bool schedulingReadCausesHazard(gp* payload);
- void switchToReadMode();
- void switchToWriteMode();
- void switchToReadToWriteMode();
};
diff --git a/dram/src/simulation/Arbiter.h b/dram/src/simulation/Arbiter.h
index 410ea46c..b7421545 100644
--- a/dram/src/simulation/Arbiter.h
+++ b/dram/src/simulation/Arbiter.h
@@ -45,10 +45,12 @@ public:
private:
tlm_utils::peq_with_cb_and_phase payloadEventQueue;
bool channelIsFree;
- deque backpressure;
+ //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
+ // 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());
@@ -56,7 +58,7 @@ private:
return TLM_ACCEPTED;
}
- // Initiated by senders
+ // Initiated by initiator side
tlm_sync_enum nb_transport_fw(int socketId, tlm_generic_payload& payload, tlm_phase& phase,
sc_time& fwDelay)
{
@@ -66,7 +68,9 @@ private:
payload.acquire();
}
else if(phase == END_RESP)
+ {
payload.release();
+ }
payloadEventQueue.notify(payload, phase, fwDelay);
return TLM_ACCEPTED;
@@ -74,6 +78,9 @@ private:
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)
{
@@ -84,32 +91,40 @@ private:
}
else
{
- backpressure.push_back(&payload);
+ pendingRequests.push_back(&payload);
}
}
else if (phase == END_RESP)
{
- sendToChannel(payload, phase, SC_ZERO_TIME );
+ 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(DramExtension::getExtension(payload).getThread().ID()-1, payload, phase, SC_ZERO_TIME);
+ sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME);
- if(!backpressure.empty())
+ if(!pendingRequests.empty())
{
- tlm_generic_payload* payloadToSend = backpressure.front();
- backpressure.pop_front();
+ tlm_generic_payload* payloadToSend = pendingRequests.front();
+ pendingRequests.pop_front();
sendToChannel(*payloadToSend, BEGIN_REQ, SC_ZERO_TIME );
channelIsFree = false;
}
}
else if (phase == BEGIN_RESP)
- {
- sendToInitiator(DramExtension::getExtension(payload).getThread().ID()-1, payload, phase, SC_ZERO_TIME);
+ {
+ if(receivedResponses[initiatorSocket].empty())
+ sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME);
+ receivedResponses[initiatorSocket].push_back(&payload);
}
else
@@ -136,7 +151,7 @@ private:
{
unsigned int burstlength = payload.get_streaming_width();
DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(payload.get_address());
- DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(decodedAddress.channel), Bank(decodedAddress.bank),
+ 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);
}
diff --git a/dram/src/simulation/Dram.h b/dram/src/simulation/Dram.h
index 22e48d74..9b306f27 100644
--- a/dram/src/simulation/Dram.h
+++ b/dram/src/simulation/Dram.h
@@ -30,7 +30,7 @@ using namespace core;
using namespace Data;
-#define POWER
+#define POWER //not better to define in simulation xml? also flag for storage simulation
#ifdef POWER
#define IFPOW(x) x
@@ -39,43 +39,6 @@ using namespace Data;
#endif
-class column
-{
- private:
-
- unsigned char * data;
- unsigned int bytes;
-
- public:
-
- column()
- {
- bytes = 0;
- data = NULL;
- }
-
- column(int bytes)
- {
- this->bytes = bytes;
- data = new unsigned char[bytes];
- }
-
- ~column()
- {
- delete data;
- }
-
- void set(unsigned char * payloadDataPtr)
- {
- memcpy(data, payloadDataPtr, bytes);
- }
-
- void get(unsigned char * payloadDataPtr)
- {
- memcpy(payloadDataPtr, data, bytes);
- }
-};
-
template
struct Dram: sc_module
@@ -83,7 +46,7 @@ struct Dram: sc_module
tlm_utils::simple_target_socket tSocket;
IFPOW(libDRAMPower *DRAMPower);
- map< unsigned long int, column * > memory;
+ map< unsigned long int, unsigned char[BUSWIDTH/2] > memory;
SC_CTOR(Dram) : tSocket("socket")
{
@@ -128,28 +91,24 @@ struct Dram: sc_module
else if (phase == BEGIN_WR)
{
IFPOW(DRAMPower->doCommand(MemCommand::WR, bank, cycle));
+ //save data:
+ memcpy(&memory[payload.get_address()], payload.get_data_ptr(), BUSWIDTH/8);
sendToController(payload, END_WR, delay + getExecutionTime(Command::Write, payload));
-
- // Save:
- //column * c = new column(16);
- //c->set(payload.get_data_ptr());
- //memory[payload.get_address()] = c;
}
else if (phase == BEGIN_RD)
{
IFPOW(DRAMPower->doCommand(MemCommand::RD, bank, cycle));
sendToController(payload, END_RD, delay + getExecutionTime(Command::Read, payload));
- // Load:
- //if(memory.count(payload.get_address()) == 1)
- //{
- // column * c = memory[payload.get_address()];
- // c->get(payload.get_data_ptr());
- //}
- //else
- //{
- // SC_REPORT_WARNING ("DRAM", "Reading from an empty memory location");
- //}
+ // Load data:
+ if(memory.count(payload.get_address()) == 1)
+ {
+ memcpy(payload.get_data_ptr(), &memory[payload.get_address()], BUSWIDTH/8);
+ }
+ else
+ {
+ //SC_REPORT_WARNING ("DRAM", "Reading from an empty memory location.");
+ }
}
else if (phase == BEGIN_WRA)
{
diff --git a/dram/src/simulation/ReorderBuffer.h b/dram/src/simulation/ReorderBuffer.h
new file mode 100644
index 00000000..82a74b4b
--- /dev/null
+++ b/dram/src/simulation/ReorderBuffer.h
@@ -0,0 +1,133 @@
+#ifndef REORDERBUFFER_H
+#define REORDERBUFFER_H
+
+#include
+#include
+#include
+
+using namespace std;
+using namespace tlm;
+
+template
+struct ReorderBuffer: public sc_module
+{
+public:
+ tlm_utils::simple_initiator_socket iSocket;
+ tlm_utils::simple_target_socket tSocket;
+
+ SC_CTOR(ReorderBuffer) :
+ payloadEventQueue(this, &ReorderBuffer::peqCallback), responseIsPendingInInitator(false)
+ {
+ iSocket.register_nb_transport_bw(this, &ReorderBuffer::nb_transport_bw);
+ tSocket.register_nb_transport_fw(this, &ReorderBuffer::nb_transport_fw);
+ }
+
+private:
+ tlm_utils::peq_with_cb_and_phase payloadEventQueue;
+ deque pendingRequestsInOrder;
+ set receivedResponses;
+
+ bool responseIsPendingInInitator;
+
+
+ // Initiated by dram side
+ tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay)
+ {
+ payloadEventQueue.notify(payload, phase, bwDelay);
+ return TLM_ACCEPTED;
+ }
+
+ // Initiated by initator side (players)
+ tlm_sync_enum nb_transport_fw(tlm_generic_payload& payload, tlm_phase& phase,
+ sc_time& fwDelay)
+ {
+ if (phase == BEGIN_REQ)
+ {
+ 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)
+ {
+ //Phases initiated by initiator side
+ if (phase == BEGIN_REQ)
+ {
+ pendingRequestsInOrder.push_back(&payload);
+ sendToTarget(payload, phase, SC_ZERO_TIME );
+ }
+
+ else if (phase == END_RESP)
+ {
+ responseIsPendingInInitator = false;
+ pendingRequestsInOrder.pop_front();
+ receivedResponses.erase(&payload);
+ sendNextResponse();
+ }
+
+ //Phases initiated by dram side
+ else if (phase == END_REQ)
+ {
+ sendToInitiator(payload, phase, SC_ZERO_TIME);
+ }
+ else if (phase == BEGIN_RESP)
+ {
+ sendToTarget(payload, END_RESP, SC_ZERO_TIME);
+ receivedResponses.emplace(&payload);
+ sendNextResponse();
+ }
+
+
+ else
+ {
+ SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase");
+ }
+ }
+
+ void sendToTarget(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(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);
+ }
+
+ void sendNextResponse()
+ {
+ //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 = pendingRequestsInOrder.front();
+ responseIsPendingInInitator = true;
+ 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;
+// }
+ }
+
+};
+
+
+
+
+#endif // REORDERBUFFER_H
diff --git a/dram/src/simulation/Simulation.cpp b/dram/src/simulation/Simulation.cpp
index 31507a77..019fb56a 100644
--- a/dram/src/simulation/Simulation.cpp
+++ b/dram/src/simulation/Simulation.cpp
@@ -44,14 +44,14 @@ void Simulation::setupDebugManager(const string& traceName)
{
auto& dbg = DebugManager::getInstance();
-// dbg.addToWhiteList(controller->name());
-// dbg.addToWhiteList(player2->name());
-// dbg.addToWhiteList(player1->name());
-// dbg.addToWhiteList(this->name());
-// dbg.addToWhiteList(Scheduler::sendername);
-// dbg.addToWhiteList(TlmRecorder::senderName);
-// dbg.addToWhiteList(ControllerCore::senderName);
-// dbg.addToWhiteList(PowerDownManagerBankwise::senderName);
+ dbg.addToWhiteList(controller->name());
+ dbg.addToWhiteList(player2->name());
+ dbg.addToWhiteList(player1->name());
+ dbg.addToWhiteList(this->name());
+ dbg.addToWhiteList(Scheduler::sendername);
+ dbg.addToWhiteList(TlmRecorder::senderName);
+ dbg.addToWhiteList(ControllerCore::senderName);
+ dbg.addToWhiteList(PowerDownManagerBankwise::senderName);
dbg.writeToConsole = true;
dbg.writeToFile = true;
@@ -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 1075291f..8b4d5dc0 100644
--- a/dram/src/simulation/Simulation.h
+++ b/dram/src/simulation/Simulation.h
@@ -11,6 +11,7 @@
#include "Dram.h"
#include "Arbiter.h"
#include "TracePlayer.h"
+#include "ReorderBuffer.h"
#include "../controller/Controller.h"
#include "ISimulation.h"
#include
@@ -61,6 +62,7 @@ private:
Dram<> *dram;
Arbiter *arbiter;
Controller<> *controller;
+ ReorderBuffer<> *reorder;
TracePlayer<> *player1;
TracePlayer<> *player2;
diff --git a/dram/src/simulation/SimulationManager.cpp b/dram/src/simulation/SimulationManager.cpp
index 3e2fb5de..d5201ed7 100644
--- a/dram/src/simulation/SimulationManager.cpp
+++ b/dram/src/simulation/SimulationManager.cpp
@@ -1,4 +1,4 @@
-/*
+ /*
* SimulationManager.cpp
*
* Created on: Apr 12, 2014
diff --git a/dram/src/simulation/TracePlayer.h b/dram/src/simulation/TracePlayer.h
index 5581ed6c..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
+ 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")
{
- 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);
+ payload->set_command(TLM_READ_COMMAND);
}
- }
- else
- {
- SC_REPORT_FATAL(0,
- (string("Corrupted tracefile, command ") + command + string(" unknown")).c_str());
- }
+ else if (command == "write")
+ {
+ payload->set_command(TLM_WRITE_COMMAND);
- payload->set_response_status(TLM_INCOMPLETE_RESPONSE);
- payload->set_dmi_allowed(false);
- payload->set_byte_enable_length(0);
- payload->set_streaming_width(burstlenght);
+ // Parse and set data
+ string data;
+ iss >> data;
- sc_time sendingTime = std::stoi(time.c_str())*clk;
- GenerationExtension* genExtension = new GenerationExtension(sendingTime);
- payload->set_auto_extension(genExtension);
+ 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)