diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro
index 6ba44ef5..b521d493 100644
--- a/dram/dramSys/dramSys.pro
+++ b/dram/dramSys/dramSys.pro
@@ -8,15 +8,15 @@ 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 += -lxerces-c
-#LIBS += -L../src/common/third_party/DRAMPower/src/ -ldrampowerxml
-#LIBS += -L../src/common/third_party/DRAMPower/src/ -ldrampower
+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
INCLUDEPATH += /opt/systemc/include
INCLUDEPATH += /opt/boost/include
INCLUDEPATH += /opt/sqlite3/include
-#INCLUDEPATH += ../src/common/third_party/DRAMPower/src
-#INCLUDEPATH += ../src/common/third_party/DRAMPower/src/libdrampower
+INCLUDEPATH += ../src/common/third_party/DRAMPower/src
+INCLUDEPATH += ../src/common/third_party/DRAMPower/src/libdrampower
DEFINES += TIXML_USE_STL
DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES
diff --git a/dram/resources/configs/memconfigs/fr_fcfs.xml b/dram/resources/configs/memconfigs/fr_fcfs.xml
index b126adb1..9dd3c80c 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 a9e88a0b..f0aa5a30 100644
--- a/dram/resources/simulations/sim-batch.xml
+++ b/dram/resources/simulations/sim-batch.xml
@@ -10,7 +10,7 @@
- chstone-sha_32.stl
+ mediabench-epic_32.stl
diff --git a/dram/src/controller/Controller.h b/dram/src/controller/Controller.h
index 4c0f5a7d..ea8adc02 100644
--- a/dram/src/controller/Controller.h
+++ b/dram/src/controller/Controller.h
@@ -116,13 +116,10 @@ template
void Controller::buildScheduler()
{
string selectedScheduler = Configuration::getInstance().Scheduler;
+ //selectedScheduler == "ReadWriteGrouper";
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")
@@ -131,7 +128,13 @@ void Controller::buildScheduler()
Configuration::getInstance().Capsize);
}
else if (selectedScheduler == "FIFO")
+ {
scheduler = new Fifo(*controllerCore);
+ }
+ else if (selectedScheduler == "ReadWriteGrouper")
+ {
+ scheduler = new ReadWriteGrouper(*controllerCore);
+ }
else
reportFatal(name(), "unsupported scheduler: " + selectedScheduler);
}
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/readwritegrouper.cpp b/dram/src/controller/scheduler/readwritegrouper.cpp
index efb202d4..b28057db 100644
--- a/dram/src/controller/scheduler/readwritegrouper.cpp
+++ b/dram/src/controller/scheduler/readwritegrouper.cpp
@@ -6,130 +6,139 @@ namespace scheduler{
using namespace tlm;
using namespace std;
-string ReadWriteGrouper::senderName = "ReadWriteGrouper";
-
-ReadWriteGrouper::ReadWriteGrouper(Scheduler *scheduler):
- scheduler(scheduler), mode(Mode::read)
+ReadWriteGrouper::ReadWriteGrouper(core::ControllerCore& controllerCore): controllerCore(controllerCore)
{
- printDebugMessage("In read mode");
+ 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();
+ printDebugMessage("Scheduling new payload");
+
+ if(batches.size() > 2)
+ {
+ if(command == TLM_READ_COMMAND)
+ {
+ 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)
+ {
+ getLatestWriteBatch().schedule(payload);
+ }
+ }
+ else if(batches.size() == 2)
+ {
+ if(command == TLM_READ_COMMAND)
+ {
+ 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())
+ {
+ 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)
+ {
+ 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)
{
- printDebugMessage("No more transactions in scheduler");
-
- if((mode == Mode::read && !writeQueue.empty()) || 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();
+ getLatestWriteBatch().removePayload(payload);
}
-}
-
-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)
+ else
{
- //if scheduling the read would cause a hazard switch to readToWriteMode and put the read into the readQueue
- if(schedulingReadCausesHazardWithQueuedWrite(payload))
- {
- switchToReadToWriteMode();
- readQueue.push_back(payload);
- }
- else
- scheduler->schedule(payload);
- }
- else if(command == TLM_WRITE_COMMAND)
- {
- 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 if(command == TLM_WRITE_COMMAND)
- writeQueue.push_back(payload);
-}
-else if(mode == Mode::write)
-{
- if(command == TLM_READ_COMMAND)
- readQueue.push_back(payload);
- else if(command == TLM_WRITE_COMMAND)
- 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::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()
{
- printDebugMessage("Switching to read mode");
- sc_assert(!scheduler->hasPayloads());
- mode = Mode::read;
- for(gp* read: readQueue)
- scheduler->schedule(read);
- readQueue.clear();
+ return *batches[batches.size()-1];
}
-void ReadWriteGrouper::switchToWriteMode()
+FR_FCFS &ReadWriteGrouper::getLatestReadBatch()
{
- printDebugMessage("Switching to write mode");
- sc_assert(!scheduler->hasPayloads());
- mode = Mode::write;
- for(gp* write: writeQueue)
- scheduler->schedule(write);
- writeQueue.clear();
-}
-
-void ReadWriteGrouper::switchToReadToWriteMode()
-{
- printDebugMessage("Switching to read-to-write-mode");
- mode = Mode::readToWrite;
-}
-
-void printDebugMessage(string message)
-{
- DebugManager::getInstance().printDebugMessage(ReadWriteGrouper::senderName, message);
+ return *batches[batches.size()-2];
}
}
diff --git a/dram/src/controller/scheduler/readwritegrouper.h b/dram/src/controller/scheduler/readwritegrouper.h
index 9f5945f1..dedd0c5d 100644
--- a/dram/src/controller/scheduler/readwritegrouper.h
+++ b/dram/src/controller/scheduler/readwritegrouper.h
@@ -1,40 +1,37 @@
#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;
virtual gp* getNextPayload() override;
virtual void removePayload(gp* payload) override;
- static std::string senderName;
-
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);
- void switchToReadMode();
- void switchToWriteMode();
- void switchToReadToWriteMode();
- void printDebugMessage(std::string message);
+ FR_FCFS& getLatestWriteBatch();
+ FR_FCFS& getLatestReadBatch();
};
diff --git a/dram/src/simulation/Simulation.cpp b/dram/src/simulation/Simulation.cpp
index 48158a40..7607bdbd 100644
--- a/dram/src/simulation/Simulation.cpp
+++ b/dram/src/simulation/Simulation.cpp
@@ -52,7 +52,6 @@ void Simulation::setupDebugManager(const string& traceName)
dbg.addToWhiteList(TlmRecorder::senderName);
dbg.addToWhiteList(ControllerCore::senderName);
dbg.addToWhiteList(PowerDownManagerBankwise::senderName);
- dbg.addToWhiteList(ReadWriteGrouper::senderName);
dbg.writeToConsole = true;
dbg.writeToFile = true;