diff --git a/DRAMSys/simulator/library.pro b/DRAMSys/simulator/library.pro
index fcbdeb0a..a81a8976 100644
--- a/DRAMSys/simulator/library.pro
+++ b/DRAMSys/simulator/library.pro
@@ -118,7 +118,8 @@ SOURCES += \
src/error/ECC/Word.cpp \
src/error/eccbaseclass.cpp \
src/error/ecchamming.cpp \
- src/controller/scheduler/Fr_Fcfs_read_priority.cpp
+ src/controller/scheduler/Fr_Fcfs_read_priority.cpp \
+ src/controller/scheduler/Fr_Fcfs_grouper.cpp
HEADERS += \
src/common/third_party/tinyxml2/tinyxml2.h \
@@ -188,7 +189,8 @@ HEADERS += \
src/error/ECC/Word.h \
src/error/eccbaseclass.h \
src/error/ecchamming.h \
- src/controller/scheduler/Fr_Fcfs_read_priority.h
+ src/controller/scheduler/Fr_Fcfs_read_priority.h \
+ src/controller/scheduler/Fr_Fcfs_grouper.h
thermalsim = $$(THERMALSIM)
isEmpty(thermalsim) {
diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs_grp.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs_grp.xml
new file mode 100644
index 00000000..44d5db18
--- /dev/null
+++ b/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs_grp.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri
index f240b193..e2e85724 100644
--- a/DRAMSys/simulator/resources/resources.pri
+++ b/DRAMSys/simulator/resources/resources.pri
@@ -150,3 +150,8 @@ OTHER_FILES += resources/configs/thermalsim/config.xml
# Error Simulation data
OTHER_FILES += resources/error/wideio.csv
+
+DISTFILES += \
+ $$PWD/traces/read_write_switch.stl \
+ $$PWD/configs/mcconfigs/fr_fcfs_rp.xml \
+ $$PWD/configs/mcconfigs/fr_fcfs_grp.xml
diff --git a/DRAMSys/simulator/src/common/Utils.h b/DRAMSys/simulator/src/common/Utils.h
index 9d97e8dc..78dc85ed 100644
--- a/DRAMSys/simulator/src/common/Utils.h
+++ b/DRAMSys/simulator/src/common/Utils.h
@@ -94,7 +94,10 @@ bool isIn(const T& value, const std::vector& collection)
constexpr const char headline[] = "=========================================================";
-static inline void loadbar(unsigned int x, unsigned int n, unsigned int w = 50, unsigned int granularity = 1)
+static inline void loadbar(unsigned int x,
+ unsigned int n,
+ unsigned int w = 50,
+ unsigned int granularity = 1)
{
if ((n < 100) || ((x != n) && (x % (n / 100 * granularity) != 0)))
return;
@@ -106,7 +109,7 @@ static inline void loadbar(unsigned int x, unsigned int n, unsigned int w = 50,
for (unsigned int x = 0; x < c; x++)
std::cout << "█";
- if(rest > 0 && rest < 0.125)
+ if(rest >= 0 && rest < 0.125 && c != w)
std::cout << " ";
if(rest >= 0.125 && rest < 2*0.125)
std::cout << "▏";
diff --git a/DRAMSys/simulator/src/controller/Controller.cpp b/DRAMSys/simulator/src/controller/Controller.cpp
index e9686617..0f7ebbf3 100644
--- a/DRAMSys/simulator/src/controller/Controller.cpp
+++ b/DRAMSys/simulator/src/controller/Controller.cpp
@@ -36,10 +36,12 @@
*/
#include "Controller.h"
+#include
void Controller::buildScheduler()
{
string selectedScheduler = Configuration::getInstance().Scheduler;
+ std::cout << "Selected Scheduler: " << selectedScheduler << std::endl;
if (selectedScheduler == "FIFO")
{
@@ -57,6 +59,10 @@ void Controller::buildScheduler()
{
scheduler = new FR_FCFS_RP(*controllerCore);
}
+ else if (selectedScheduler == "FR_FCFS_GRP")
+ {
+ scheduler = new FR_FCFS_GRP(*controllerCore);
+ }
else if (selectedScheduler == "SMS")
{
scheduler = new SMS("SMS", *controllerCore, Configuration::getInstance().SJFProbability);
diff --git a/DRAMSys/simulator/src/controller/Controller.h b/DRAMSys/simulator/src/controller/Controller.h
index cc833aae..184cb445 100644
--- a/DRAMSys/simulator/src/controller/Controller.h
+++ b/DRAMSys/simulator/src/controller/Controller.h
@@ -68,6 +68,7 @@
#include "scheduler/FifoStrict.h"
#include "scheduler/Fr_Fcfs.h"
#include "scheduler/Fr_Fcfs_read_priority.h"
+#include "scheduler/Fr_Fcfs_grouper.h"
#include "scheduler/SMS.h"
#include "scheduler/IScheduler.h"
diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_grouper.cpp b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_grouper.cpp
new file mode 100644
index 00000000..8f1e80a6
--- /dev/null
+++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_grouper.cpp
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2017, University of Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors:
+ * Matthias Jung
+ */
+
+#include "Fr_Fcfs_grouper.h"
+
+// The FR_FCFS_Read_Priority works exactly like the FR_FCFS_RP.
+// However writes are grouped! For detailed documentation look into the FR_FCFS.
+// TODO: what is missed is a check if the buffers are full. This will only work
+// if we have buffers with a fixed size (Prado's future patch).
+
+std::pair FR_FCFS_GRP::getNextRequest(Bank bank)
+{
+ // If the bank is empty we do nothing:
+ if(buffer[bank].empty())
+ {
+ return pair(Command::NOP, NULL);
+ }
+
+ // If we are in write mode we should check if we should switch to read mode
+ // because there are no writes anymore in the buffer.
+ if(readMode == false)
+ {
+ if(getNumberOfRequest(tlm::TLM_WRITE_COMMAND) == 0)
+ {
+ readMode = true;
+ }
+ }
+ else // If we are in read mode but all reads are served we switch to write
+ {
+ if(getNumberOfRequest(tlm::TLM_READ_COMMAND) == 0)
+ {
+ readMode = false;
+ }
+ }
+
+ // Now lets search for read and write commands. However keep in mind that
+ // readMode is a shared variable for all the banks!
+ if(readMode == true)
+ {
+ // 1. Seach for read hit:
+ for(auto it = buffer[bank].begin(); it!=buffer[bank].end(); it++)
+ {
+ gp* read = *it;
+
+ if(read->get_command() == tlm::TLM_READ_COMMAND)
+ {
+ // If there is a row hit:
+ if(DramExtension::getRow(read)
+ == controllerCore.getRowBufferStates()
+ .getRowInRowBuffer(bank))
+ {
+ if(hazardDetection(bank, it) == false)
+ {
+ buffer[bank].erase(it);
+ printDebugMessage("Read Hit found");
+ return pair(getReadWriteCommand(*read),
+ read);
+ }
+ else
+ {
+ // If there was a hazard, switch the mode and try again:
+ readMode = false;
+ return getNextRequest(bank);
+ }
+ }
+ }
+ }
+
+ // 2. Search for read miss:
+ for(auto it = buffer[bank].begin(); it!=buffer[bank].end(); it++)
+ {
+ gp* read = *it;
+
+ if(read->get_command() == tlm::TLM_READ_COMMAND)
+ {
+ if(hazardDetection(bank, it) == false)
+ {
+ printDebugMessage("Read miss found");
+ return pair(getNextCommand(read),read);
+ }
+ else
+ {
+ // If there was a hazard, switch the mode and try again:
+ readMode = false;
+ return getNextRequest(bank);
+ }
+ }
+ }
+ }
+ else // write mode:
+ {
+ // 3. Search for write hit:
+ for(auto it = buffer[bank].begin(); it!=buffer[bank].end(); it++)
+ {
+ gp* write = *it;
+
+ if(write->get_command() == tlm::TLM_WRITE_COMMAND)
+ {
+ // If there is a row hit:
+ if(DramExtension::getRow(write)
+ == controllerCore.getRowBufferStates()
+ .getRowInRowBuffer(bank))
+ {
+ buffer[bank].erase(it);
+ printDebugMessage("Write Hit found");
+ return pair(getReadWriteCommand(*write),
+ write);
+ }
+ }
+ }
+
+ // 4. Search for write miss:
+ for(auto it = buffer[bank].begin(); it!=buffer[bank].end(); it++)
+ {
+ gp* write = *it;
+
+ if(write->get_command() == tlm::TLM_WRITE_COMMAND)
+ {
+ printDebugMessage("Write miss found");
+ return pair(getNextCommand(write),write);
+ }
+ }
+ }
+
+ // If nothing was found in the current mode, switch the mode and try again:
+ readMode = !readMode;
+ return getNextRequest(bank);
+
+ reportFatal("FR_FCFS_RP", "Never should go here ...");
+}
+
+// There is a hazard if a read is found which will be scheduled before a write
+// to the same column and the same row of the same bank:
+bool FR_FCFS_GRP::hazardDetection(Bank bank, std::deque::iterator ext)
+{
+ gp* read = *ext;
+
+ //for(unsigned long i=0; i < id; i++)
+ for(auto it = buffer[bank].begin(); it!=ext; it++)
+ {
+ gp* write = *it;
+ if(write->get_command() == tlm::TLM_WRITE_COMMAND)
+ {
+ if((DramExtension::getExtension(read).getColumn()
+ == DramExtension::getExtension(write).getColumn())
+ && (DramExtension::getExtension(read).getRow()
+ == DramExtension::getExtension(write).getRow()))
+ {
+ printDebugMessage("Hazard Detected");
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// Estimate the number of writes/reads in all bank buffers:
+unsigned int FR_FCFS_GRP::getNumberOfRequest(tlm::tlm_command cmd)
+{
+ unsigned int numberOfRequests = 0;
+ for(unsigned int i = 0;
+ i < Configuration::getInstance().memSpec.NumberOfBanks;
+ i++)
+ {
+ for(auto it = buffer[i].begin(); it!=buffer[i].end(); it++)
+ {
+ gp* trans = *it;
+ if(trans->get_command()==cmd)
+ {
+ numberOfRequests++;
+ }
+ }
+ }
+
+ return numberOfRequests;
+}
+
+void FR_FCFS_GRP::printDebugMessage(std::string message)
+{
+ DebugManager::getInstance().printDebugMessage("FR_FCFS_GRP", message);
+}
diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_grouper.h b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_grouper.h
new file mode 100644
index 00000000..bf13341f
--- /dev/null
+++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_grouper.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, University of Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors:
+ * Matthias Jung
+ */
+
+#ifndef FR_FCFS_GROUPER_H
+#define FR_FCFS_GROUPER_H
+
+#include "Fr_Fcfs.h"
+
+class FR_FCFS_GRP : public FR_FCFS
+{
+public:
+ FR_FCFS_GRP(ControllerCore &controllerCore) : FR_FCFS(controllerCore),
+ readMode(true)
+ {}
+
+ std::pair
+ getNextRequest(Bank bank) override;
+
+private:
+
+ bool hazardDetection(Bank bank, std::deque::iterator ext);
+ unsigned int getNumberOfRequest(tlm::tlm_command cmd);
+ void printDebugMessage(std::string message);
+ bool readMode;
+};
+
+#endif // FR_FCFS_GROUPER_H