diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro
index fc25e98b..c589a80d 100644
--- a/DRAMSys/library/library.pro
+++ b/DRAMSys/library/library.pro
@@ -126,7 +126,7 @@ SOURCES += \
src/controller/RecordableController.cpp \
src/common/AddressDecoder.cpp \
src/common/jsonAddressDecoder.cpp \
- src/controller/scheduler/Fifo_grouper.cpp
+ src/controller/scheduler/grp.cpp
HEADERS += \
src/common/third_party/tinyxml2/tinyxml2.h \
@@ -206,7 +206,8 @@ HEADERS += \
src/controller/RecordableController.h \
src/simulation/RecordableDram.h \
src/common/AddressDecoder.h \
- src/common/jsonAddressDecoder.h
+ src/common/jsonAddressDecoder.h \
+ src/controller/scheduler/grp.h
#src/common/third_party/json/include/nlohmann/json.hpp \
thermalsim = $$(THERMALSIM)
diff --git a/DRAMSys/library/resources/configs/mcconfigs/grp.xml b/DRAMSys/library/resources/configs/mcconfigs/grp.xml
new file mode 100644
index 00000000..d5474610
--- /dev/null
+++ b/DRAMSys/library/resources/configs/mcconfigs/grp.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DRAMSys/library/resources/resources.pri b/DRAMSys/library/resources/resources.pri
index aed0437f..6552a741 100644
--- a/DRAMSys/library/resources/resources.pri
+++ b/DRAMSys/library/resources/resources.pri
@@ -56,6 +56,7 @@ OTHER_FILES += resources/simulations/ddr3-ecc.xml
OTHER_FILES += resources/simulations/sms-example.xml
OTHER_FILES += resources/simulations/ddr3_postpone_ref_test.xml
OTHER_FILES += resources/simulations/rgrsim.xml
+OTHER_FILES += resources/simulations/lpddr4-single-device.xml
# Simulator Files
OTHER_FILES += resources/configs/simulator/wideio.xml
@@ -66,6 +67,7 @@ OTHER_FILES += resources/configs/simulator/wideio_ecc.xml
OTHER_FILES += resources/configs/simulator/ddr3_ecc.xml
OTHER_FILES += resources/configs/simulator/sms.xml
OTHER_FILES += resources/configs/simulator/rgrsimcfg.xml
+OTHER_FILES += resources/configs/simulator/lpddr4.xml
# Scripts
OTHER_FILES += resources/scripts/address_scrambler.pl
@@ -81,6 +83,7 @@ OTHER_FILES += resources/scripts/DRAMSylva/DRAMSylva.patch
OTHER_FILES += resources/scripts/DRAMSylva/DRAMSylva.sh
OTHER_FILES += resources/scripts/DRAMSylva/DRAMSylvaCSVPlot.py
OTHER_FILES += resources/scripts/trace_gen.py
+OTHER_FILES += resources/scripts/traceGenerationForNNTraining.pl
# Trace Files
OTHER_FILES += resources/traces/chstone-aes_32.stl
@@ -131,6 +134,7 @@ OTHER_FILES += resources/traces/ddr3_postpone_ref_test_2.stl
OTHER_FILES += resources/traces/ddr3_postpone_ref_test_3.stl
OTHER_FILES += resources/traces/ip*.stl
OTHER_FILES += resources/traces/rgr*.stl
+OTHER_FILES += resources/traces/read_write_switch.stl
# Memory Controller Configs
OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml
@@ -140,6 +144,9 @@ OTHER_FILES += resources/configs/mcconfigs/par_bs.xml
OTHER_FILES += resources/configs/mcconfigs/fifo_ecc.xml
OTHER_FILES += resources/configs/mcconfigs/sms.xml
OTHER_FILES += resources/configs/mcconfigs/rgrmccfg.xml
+OTHER_FILES += resources/configs/mcconfigs/grp.xml
+OTHER_FILES += resources/configs/mcconfigs/fr_fcfs_rp.xml
+OTHER_FILES += resources/configs/mcconfigs/fr_fcfs_grp.xml
# Memspecs
OTHER_FILES += resources/configs/memspecs/memspec.dtd
@@ -186,6 +193,7 @@ OTHER_FILES += resources/configs/memspecs/wideio.xml
OTHER_FILES += resources/configs/memspecs/wideio_less_refresh.xml
OTHER_FILES += resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml
OTHER_FILES += resources/configs/memspecs/rgrspec.xml
+OTHER_FILES += resources/configs/memspecs/MICRON_6Gb_LPDDR4-3200_NDA_NDA_NDA.xml
# Address Mapping Configs
OTHER_FILES += resources/configs/amconfigs/am_ddr3.xml
@@ -206,6 +214,8 @@ OTHER_FILES += resources/configs/amconfigs/am_ddr3_1Gbx8_p1KB_brc.xml
OTHER_FILES += resources/configs/amconfigs/am_ddr3_4x4Gbx16_dimm_p2KB_brc.xml
OTHER_FILES += resources/configs/amconfigs/am_ddr3_4x4Gbx16_dimm_p2KB_rbc.xml
OTHER_FILES += resources/configs/amconfigs/rgram.xml
+OTHER_FILES += resources/configs/amconfigs/am_test_congen_output.json
+OTHER_FILES += resources/configs/amconfigs/am_lpddr4.xml
# Thermal Simulation configs
OTHER_FILES += resources/configs/thermalsim/core.flp
@@ -220,14 +230,3 @@ OTHER_FILES += src/common/third_party/DRAMPower/src/*
# 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 \
- $$PWD/configs/simulator/lpddr4.xml \
- $$PWD/simulations/lpddr4-single-device.xml \
- $$PWD/configs/amconfigs/am_lpddr4.xml \
- $$PWD/configs/memspecs/MICRON_6Gb_LPDDR4-3200_NDA_NDA_NDA.xml \
- $$PWD/scripts/traceGenerationForNNTraining.pl \
- $$PWD/configs/amconfigs/am_test_congen_output.json
diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp
index ad4879a3..5c93b209 100644
--- a/DRAMSys/library/src/controller/Controller.cpp
+++ b/DRAMSys/library/src/controller/Controller.cpp
@@ -53,6 +53,8 @@ void Controller::buildScheduler()
scheduler = new FR_FCFS_RP(*controllerCore);
} else if (selectedScheduler == "FR_FCFS_GRP") {
scheduler = new FR_FCFS_GRP(*controllerCore, this);
+ } else if (selectedScheduler == "GRP") {
+ scheduler = new GRP(*controllerCore, this);
} else if (selectedScheduler == "SMS") {
scheduler = new SMS("SMS", *controllerCore,
Configuration::getInstance().SJFProbability);
@@ -209,8 +211,7 @@ void Controller::controllerCorePEQCallback(tlm_generic_payload &payload,
else if (containsPhase(phase, { BEGIN_RD, BEGIN_WR, BEGIN_ACTB, BEGIN_ACT, BEGIN_PREB, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA })) {
printDebugMessage("Controller has sent to DRAM this: " + phaseNameToString(
phase) + " bank " + to_string(bank.ID()));
- }
- else
+ } else
SC_REPORT_FATAL(0,
"Controller Core PEQ in controller wrapper was triggered with unsupported phase");
}
@@ -433,8 +434,7 @@ void Controller::dramPEQCallback(tlm_generic_payload &payload,
scheduleNextFromScheduler(bank);
} else if (containsPhase(phase, {END_PREB, END_PRE, END_ACTB, END_ACT})) {
scheduleNextFromScheduler(bank);
- }
- else if (phase == END_PRE_ALL) {
+ } else if (phase == END_PRE_ALL) {
// No need to trigger anything for a END_PRE_ALL. It is followed by a AUTO_REFRESH anyway (in our current
// scheduler implementation)
} else {
diff --git a/DRAMSys/library/src/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h
index f09fedfa..efaae49e 100644
--- a/DRAMSys/library/src/controller/Controller.h
+++ b/DRAMSys/library/src/controller/Controller.h
@@ -65,6 +65,7 @@
#include "core/scheduling/Trigger.h"
#include "core/TimingCalculation.h"
#include "scheduler/Fifo.h"
+#include "scheduler/grp.h"
#include "scheduler/FifoStrict.h"
#include "scheduler/Fr_Fcfs.h"
#include "scheduler/Fr_Fcfs_read_priority.h"
diff --git a/DRAMSys/library/src/controller/scheduler/grp.cpp b/DRAMSys/library/src/controller/scheduler/grp.cpp
new file mode 100644
index 00000000..652405aa
--- /dev/null
+++ b/DRAMSys/library/src/controller/scheduler/grp.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2018, 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 "grp.h"
+
+// GRP just reorders w.r.t. read write grouping, however is not aware of the
+// row buffer. For a row buffer aware grouper refer to FR_FCFS_GRP.
+// 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 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);
+ }
+ } else { // if there is a row miss:
+ 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);
+ } else {
+ printDebugMessage("Write miss found");
+ return pair(getNextCommand(write), write);
+ }
+ }
+ }
+ }
+
+ // If nothing was found we check the other banks before we switch the mode:
+ pair other(Command::NOP, NULL);
+ unsigned int B = Configuration::getInstance().memSpec.NumberOfBanks;
+
+ for (unsigned int i = 1; i < B; i++) {
+ Bank nextBank((bank.ID() + i) % B);
+ ctrl->scheduleNextFromScheduler(nextBank);
+ }
+
+ // If nothing was found in the current mode, switch the mode and try again:
+ // FIXME: this is in my opinion not so clever yet, because we switch maybe
+ // even though there are still reads/writes request on other banks ...
+ readMode = !readMode;
+ return getNextRequest(bank);
+
+ reportFatal("GRP", "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 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 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 GRP::printDebugMessage(std::string message)
+{
+ DebugManager::getInstance().printDebugMessage("FR_FCFS_GRP", message);
+}
diff --git a/DRAMSys/library/src/controller/scheduler/Fifo_grouper.cpp b/DRAMSys/library/src/controller/scheduler/grp.h
similarity index 65%
rename from DRAMSys/library/src/controller/scheduler/Fifo_grouper.cpp
rename to DRAMSys/library/src/controller/scheduler/grp.h
index fe041319..2ffc46e0 100644
--- a/DRAMSys/library/src/controller/scheduler/Fifo_grouper.cpp
+++ b/DRAMSys/library/src/controller/scheduler/grp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, University of Kaiserslautern
+ * Copyright (c) 2018, University of Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,38 +30,37 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
- * Robert Gernhardt
* Matthias Jung
*/
-#include "Fifo.h"
+#ifndef GROUPER_H
+#define GROUPER_H
-using namespace std;
+#include "Fr_Fcfs.h"
+#include "../Controller.h"
-void Fifo::schedule(gp *payload)
+class Controller;
+
+class GRP : public FR_FCFS
{
- buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload);
-}
-
-pair Fifo::getNextRequest(Bank bank)
-{
- if (!buffer[bank].empty()) {
- gp *payload = buffer[bank].front();
- Command command = IScheduler::getNextCommand(*payload);
- if (command == Command::Read || command == Command::ReadA
- || command == Command::Write || command == Command::WriteA) {
- buffer[bank].pop_front();
- }
-
- return pair(command, payload);
+public:
+ GRP(ControllerCore &controllerCore, Controller *c) :
+ FR_FCFS(controllerCore),
+ ctrl(c),
+ readMode(true)
+ {
}
- return pair(Command::NOP, NULL);
-}
+ std::pair
+ getNextRequest(Bank bank) override;
-gp *Fifo::getPendingRequest(Bank /*bank*/)
-{
- return NULL;
-}
+private:
+ Controller *ctrl;
+ bool hazardDetection(Bank bank, std::deque::iterator ext);
+ unsigned int getNumberOfRequest(tlm::tlm_command cmd);
+ void printDebugMessage(std::string message);
+ bool readMode;
+};
+#endif // GROUPER_H