GRP Scheduler introduced.
GRP is a simple read write grouper. However, it is not aware of the row-buffer and therfore it is just optimizing w.r.t to tWTR peanelty. For the functionality of row buffer management we refer to the FR_FCFS_GRP. This scheduler is mainly intersting for ConGen based applications.
This commit is contained in:
@@ -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)
|
||||
|
||||
17
DRAMSys/library/resources/configs/mcconfigs/grp.xml
Normal file
17
DRAMSys/library/resources/configs/mcconfigs/grp.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<mcconfig>
|
||||
<BankwiseLogic value="0"/>
|
||||
<OpenPagePolicy value="1" />
|
||||
<MaxNrOfTransactions value="32" />
|
||||
<Scheduler value="GRP" />
|
||||
<Capsize value="5" />
|
||||
<!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Error Modelling -->
|
||||
<ControllerCoreDisableRefresh value="0"/>
|
||||
<ControllerCoreForceMaxRefBurst value="0"/>
|
||||
<ControllerCoreEnableRefPostpone value="0"/>
|
||||
<ControllerCoreEnableRefPullIn value="0"/>
|
||||
<ControllerCoreMaxPostponedARCmd value="8"/>
|
||||
<ControllerCoreMaxPulledInARCmd value="8"/>
|
||||
</mcconfig>
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
|
||||
180
DRAMSys/library/src/controller/scheduler/grp.cpp
Normal file
180
DRAMSys/library/src/controller/scheduler/grp.cpp
Normal file
@@ -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<Command, gp *> GRP::getNextRequest(Bank bank)
|
||||
{
|
||||
// If the bank is empty we do nothing:
|
||||
if (buffer[bank].empty()) {
|
||||
return pair<Command, tlm::tlm_generic_payload *>(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<Command, gp *>(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<Command, gp *>(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<Command, gp *>(getReadWriteCommand(*write),
|
||||
write);
|
||||
} else {
|
||||
printDebugMessage("Write miss found");
|
||||
return pair<Command, gp *>(getNextCommand(write), write);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If nothing was found we check the other banks before we switch the mode:
|
||||
pair<Command, gp *> 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<gp *>::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);
|
||||
}
|
||||
@@ -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<Command, tlm::tlm_generic_payload *> 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, tlm::tlm_generic_payload *>(command, payload);
|
||||
public:
|
||||
GRP(ControllerCore &controllerCore, Controller *c) :
|
||||
FR_FCFS(controllerCore),
|
||||
ctrl(c),
|
||||
readMode(true)
|
||||
{
|
||||
}
|
||||
|
||||
return pair<Command, tlm::tlm_generic_payload *>(Command::NOP, NULL);
|
||||
}
|
||||
std::pair<Command, tlm::tlm_generic_payload *>
|
||||
getNextRequest(Bank bank) override;
|
||||
|
||||
gp *Fifo::getPendingRequest(Bank /*bank*/)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
private:
|
||||
|
||||
Controller *ctrl;
|
||||
bool hazardDetection(Bank bank, std::deque<gp *>::iterator ext);
|
||||
unsigned int getNumberOfRequest(tlm::tlm_command cmd);
|
||||
void printDebugMessage(std::string message);
|
||||
bool readMode;
|
||||
};
|
||||
|
||||
#endif // GROUPER_H
|
||||
Reference in New Issue
Block a user