diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml
index c3ed7cbd..fbd50bf4 100644
--- a/DRAMSys/simulator/resources/simulations/sim-batch.xml
+++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml
@@ -34,7 +34,7 @@
-
+
diff --git a/DRAMSys/simulator/src/controller/Controller.h b/DRAMSys/simulator/src/controller/Controller.h
index 9889a697..01cf7c2a 100644
--- a/DRAMSys/simulator/src/controller/Controller.h
+++ b/DRAMSys/simulator/src/controller/Controller.h
@@ -151,7 +151,7 @@ void Controller::buildScheduler()
}
else if (selectedScheduler == "FIFO_STRICT")
{
- scheduler = new FifoStrict(*this, *controllerCore);
+ scheduler = new FifoStrict(*controllerCore);
}
else if (selectedScheduler == "FR_FCFS")
{
@@ -316,16 +316,7 @@ void Controller::controllerCorePEQCallback(tlm_generic_payload &payloa
if (phase == BEGIN_RD || phase == BEGIN_WR)
{
- if(Configuration::getInstance().Scheduler == "FIFO_STRICT")
- {
- // special case for the Fifo_strict scheduler, because it may have to unblock
- // the current front element
- dynamic_cast(scheduler)->NotifyBeginRDWR();
- }
- else
- {
- scheduleNextFromScheduler(DramExtension::getBank(payload));
- }
+ scheduleNextFromScheduler(DramExtension::getBank(payload));
}
else if (phase == BEGIN_REFB)
printDebugMessage("Entering REFB on bank " + to_string(bank.ID()));
diff --git a/DRAMSys/simulator/src/controller/scheduler/FifoStrict.cpp b/DRAMSys/simulator/src/controller/scheduler/FifoStrict.cpp
index 6b6244b4..4897b796 100644
--- a/DRAMSys/simulator/src/controller/scheduler/FifoStrict.cpp
+++ b/DRAMSys/simulator/src/controller/scheduler/FifoStrict.cpp
@@ -37,77 +37,83 @@
#include "FifoStrict.h"
-void FifoStrict::schedule(gp *payload)
+void FifoStrict::schedule(tlm::tlm_generic_payload *payload)
{
- buffer.push_back(payload);
- printDebugMessage("New payload scheduled. Total number " + std::to_string(buffer.size()) + "\n");
-}
-
-void FifoStrict::printFrontElementState()
-{
- if(buffer.size() > 0)
- {
- printDebugMessage("Front element state - Bank: " + DramExtension::getBank(buffer.front()).toString() + " Operation: " +
- commandToString(getNextCommand(*buffer.front())) + "\n");
- }
- else
- {
- printDebugMessage("No fron element. Buffer is empty \n ");
- }
-}
-
-void FifoStrict::NotifyBeginRDWR()
-{
- buffer.erase(buffer.begin());
- printDebugMessage("Front element finished. New front Element: ");
- printFrontElementState();
-
- if(buffer.size() > 0)
- {
- // If the new front element was orginally blocked, because it had to wait on the old front element, we have to call
- // controller.scheduleNextFromScheduler explicitly, otherwise there will be a deadlock in the system
- controller.scheduleNextFromScheduler(DramExtension::getBank(buffer.front()));
- }
+ Bank bank = DramExtension::getExtension(payload).getBank();
+ buffer.push_back(std::pair(bank, payload));
}
std::pair FifoStrict::getNextRequest(Bank bank)
{
- if(buffer.empty())
- {
- return pair(Command::NOP, NULL);
- }
+ if (!buffer.empty()) {
- else if(DramExtension::getBank(buffer.front()) == bank)
- {
- Command command = getNextCommand(*buffer.front());
- pair result(command, buffer.front());
- printDebugMessage("Operation for front Element scheduled. ");
- printFrontElementState();
+ if (buffer.front().first == bank) {
+ // The next request in the FIFO is for the bank passed as parameter
- return result;
- }
- else
- {
- for(unsigned int i = 1; i < buffer.size(); ++i)
- {
- if(DramExtension::getBank(buffer[i]) == bank)
- {
- Command command = getNextCommand(*buffer[i]);
+ tlm::tlm_generic_payload *payload = buffer.front().second;
- // RD/WR operations have to be strictly in order across banks, so only allow progress on commands
- // other than RD/WR commands.
- if(commandIsIn(command, {Command::Read, Command::Write, Command::ReadA, Command::WriteA}))
- {
- printDebugMessage("Current queue element " + std::to_string(i) + " blocked. Waiting for earlier rd/wr to finish\n");
- return pair(Command::NOP, NULL);
- }
- else
- {
- return pair(command, buffer[i]);
+ // For a given request (a given payload) one or more commands will
+ // be sent to the DRAM in order to process it.
+ //
+ // getNextRequest() may be called more than once for the same
+ // enqueued request until the appropriate sequence of commands is
+ // sent to the DRAM.
+ //
+ // Every time getNextRequest() it is called it calls
+ // getNextCommand() that returns the suitable command to be sent
+ // to the DRAM.
+ //
+ // getNextCommand() returns the proper command based on the
+ // internal status of the DRAM.
+ //
+ // In the worst case getNextCommand() need to be called three
+ // times for a given element in the requests queue: first for
+ // precharge, second for activate and finally for read or write
+ // (accordingly the nature of the request). In contrast, for the
+ // case of an already open row (due to a previous request) the
+ // command itself could be directly issued.
+ //
+ Command command = IScheduler::getNextCommand(*payload);
+
+ if(commandIsIn(command, {Command::Read, Command::Write, Command::ReadA, Command::WriteA})) {
+ buffer.pop_front();
+ }
+
+ return pair(command, payload);
+
+ } else {
+ // The next request in the FIFO is NOT for the bank passed as parameter.
+
+ // Search for the next request related to the bank passed as parameter.
+ for (auto req = buffer.begin(); req != buffer.end(); req++) {
+ if (req->first == bank) {
+ // Found a request to this bank in the queue
+ tlm::tlm_generic_payload *payload = req->second;
+
+ // Get the appropriate command to be sent to the DRAM
+ // regarding this request.
+ //
+ // Commands other than read and write will be issued.
+ // Reads and writes will not be issued since this
+ // scheduler executes all read and writes in a strict
+ // order.
+ Command command = getNextCommand(*payload);
+ if(commandIsIn(command, {Command::Read, Command::Write, Command::ReadA, Command::WriteA})) {
+ // Reads and writes must be executed in order. Then if
+ // the next command for this request is read or write
+ // NOP will be returned and no operation will be
+ // performed.
+ return pair(Command::NOP, NULL);
+ } else {
+ // Commands other than read and write are issued normally.
+ return pair(command, payload);
+ }
}
}
}
-
- return pair(Command::NOP, NULL);
}
+
+ // The FIFO is empty
+ return pair(Command::NOP, NULL);
}
+
diff --git a/DRAMSys/simulator/src/controller/scheduler/FifoStrict.h b/DRAMSys/simulator/src/controller/scheduler/FifoStrict.h
index e46add42..43f45d73 100644
--- a/DRAMSys/simulator/src/controller/scheduler/FifoStrict.h
+++ b/DRAMSys/simulator/src/controller/scheduler/FifoStrict.h
@@ -38,33 +38,26 @@
#ifndef FIFOSTRICT_H
#define FIFOSTRICT_H
-#include "../core/ControllerCore.h"
-#include "../Command.h"
-#include "../../common/dramExtension.h"
-#include "IScheduler.h"
#include
#include