From a2d2bcb7ca4a4dd43128c643718b983e3fd36e2a Mon Sep 17 00:00:00 2001 From: Ana Mativi Date: Fri, 28 Jul 2017 17:30:56 +0200 Subject: [PATCH] Postpone Refresh Implementation --- .../configs/mcconfigs/fifoStrict.xml | 3 + DRAMSys/simulator/resources/resources.pri | 2 + .../simulations/ddr3_postpone_test.xml | 19 ++++ .../core/configuration/Configuration.cpp | 6 ++ .../core/configuration/Configuration.h | 3 + .../core/refresh/RefreshManager.cpp | 95 +++++++++++++++++-- .../controller/core/refresh/RefreshManager.h | 13 ++- .../scheduling/checker/RefreshChecker.cpp | 2 + README.md | 9 ++ 9 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 DRAMSys/simulator/resources/simulations/ddr3_postpone_test.xml diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifoStrict.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifoStrict.xml index 7ca1a824..79dfe5d5 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fifoStrict.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifoStrict.xml @@ -9,4 +9,7 @@ + + + diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index e2e85724..71cc54aa 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -8,6 +8,7 @@ OTHER_FILES += resources/simulations/wideio-example.xml OTHER_FILES += resources/simulations/wideio-ecc.xml OTHER_FILES += resources/simulations/ddr3-ecc.xml OTHER_FILES += resources/simulations/sms-example.xml +OTHER_FILES += resources/simulations/ddr3_postpone_test.xml # Simulator Files OTHER_FILES += resources/configs/simulator/wideio.xml @@ -69,6 +70,7 @@ OTHER_FILES += resources/traces/sms_t1.stl OTHER_FILES += resources/traces/sms_t2.stl OTHER_FILES += resources/traces/sms_t3.stl OTHER_FILES += resources/traces/sms_t4.stl +OTHER_FILES += resources/traces/ddr3_postpone_test.stl # Memory Controller Configs OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml diff --git a/DRAMSys/simulator/resources/simulations/ddr3_postpone_test.xml b/DRAMSys/simulator/resources/simulations/ddr3_postpone_test.xml new file mode 100644 index 00000000..bcaee4bf --- /dev/null +++ b/DRAMSys/simulator/resources/simulations/ddr3_postpone_test.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + ddr3_postpone_test.stl + + diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp index 6cb0ffb9..0d970ba4 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp @@ -202,6 +202,12 @@ void Configuration::setParameter(std::string name, std::string value) } else if (name == "ControllerCoreDisableRefresh") ControllerCoreDisableRefresh = string2bool(value); + else if (name == "ControllerCoreForceMaxRefPostpone") + ControllerCoreForceMaxRefPostpone = string2bool(value); + else if (name == "ControllerCoreEnableRefPostpone") + ControllerCoreEnableRefPostpone = string2bool(value); + else if (name == "ControllerCoreMaxPostponedARCmd") + ControllerCoreMaxPostponedARCmd = string2int(value); else if (name == "ThermalSimulation") ThermalSimulation = string2bool(value); else if(name == "SimulationProgressBar") diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h index 082d7530..5de19ff8 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h @@ -83,6 +83,9 @@ struct Configuration bool Debug = false; unsigned int NumberOfMemChannels = 1; bool ControllerCoreDisableRefresh = false; + bool ControllerCoreForceMaxRefPostpone = false; + bool ControllerCoreEnableRefPostpone = false; + unsigned int ControllerCoreMaxPostponedARCmd = 8; bool ThermalSimulation = false; bool SimulationProgressBar = false; unsigned int NumberOfDevicesOnDIMM = 1; diff --git a/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp b/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp index 742dfacc..bb5a7a4e 100644 --- a/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp +++ b/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp @@ -46,11 +46,15 @@ using namespace tlm; RefreshManager::RefreshManager(sc_module_name /*name*/, ControllerCore& controller) : controllerCore(controller), timing(controller.config.memSpec.refreshTimings[Bank(0)]), nextPlannedRefresh(SC_ZERO_TIME) { + if (controllerCore.config.ControllerCoreEnableRefPostpone) + { + maxpostpone = controllerCore.config.ControllerCoreMaxPostponedARCmd; + } for (Bank bank : controller.getBanks()) { setUpDummy(refreshPayloads[bank], bank); } - planNextRefresh(); + planNextRefresh(timing.tREFI); } RefreshManager::~RefreshManager() @@ -63,8 +67,7 @@ bool RefreshManager::hasCollision(const ScheduledCommand& command) return command.getStart() < controllerCore.state->getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() >= nextPlannedRefresh; } -//Schedule and trigger the refresh and plan the next one. AutoRefresh and PrechargeAll are scheduled just once per refresh period. -void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribute__((unused)), sc_time time) +void RefreshManager::doRefresh(tlm::tlm_generic_payload& payload __attribute__((unused)), sc_time time) { sc_assert(!isInvalidated(payload, time)); @@ -99,20 +102,96 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribu controllerCore.state->change(refreshAllMaster); DramExtension::getExtension(refreshPayloads[Bank(0)]).incrementRow(); controllerCore.controller.send(refreshAllMaster, refreshPayloads[Bank(0)]); - - planNextRefresh(); } -void RefreshManager::planNextRefresh() +bool RefreshManager::pendingRequests() { - nextPlannedRefresh += timing.tREFI; + for (Bank bank : controllerCore.getBanks()) + { + if (controllerCore.numberOfPayloads[bank] != 0) + return true; + } + return false; +} + +//This function is sensitive to state transitions only. For multiple calls of this function we ensure that burst is only updated on a state change +void RefreshManager::evaluateBurstState() +{ + bool pendingReq = pendingRequests(); + + if ((arCmdCounter == maxpostpone) || ((!pendingReq&&!burst) && !controllerCore.config.ControllerCoreForceMaxRefPostpone)) + { + burst = true; + if (arCmdCounter>1) //A single refresh is considered a special case of a burst. It's only necessary to align if the burst consists of more than 1 AR command + { + alignToTrefiNeeded=true; + alignToTrefiValue=arCmdCounter-1; //For a burst consisting of multiple AR the gaps between the start of the burst and the last AR must be subtracted in order to align the next burst to tREFI + } + } + if (arCmdCounter == 0) //Burst is done. All AR commands are issued already + { + burst = false; + } +} + +sc_time RefreshManager::alignToTrefi() +{ + if (alignToTrefiNeeded) //Alignment is only needed when the previous burst consisted of more than 1 AR command + { + alignToTrefiNeeded = false; //This happens only for the first AR of the burst that follows + return alignToTrefiValue*timing.tRFC; + } + else + { + return SC_ZERO_TIME; + } +} + +sc_time RefreshManager::getNextRefTiming() +{ + if (burst) + { + return timing.tRFC; + } + else + { + return timing.tREFI-alignToTrefi(); + } +} + +//Depending on burst state, either schedule a refresh or postpone it. Check burst state before and after triggering a refresh to check if state changes are needed +void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribute__((unused)), sc_time time) +{ + sc_time nextRefTiming; + + if (!burst) + { + arCmdCounter++; + } + + evaluateBurstState(); + + if (burst) + { + doRefresh(payload, time); + arCmdCounter--; + evaluateBurstState(); + } + + nextRefTiming = getNextRefTiming(); + planNextRefresh(nextRefTiming); +} + +void RefreshManager::planNextRefresh(sc_time nextRefTiming) +{ + nextPlannedRefresh += nextRefTiming; controllerCore.controller.send(REFTrigger, nextPlannedRefresh, refreshPayloads[Bank(0)]); } void RefreshManager::reInitialize(Bank /*bank*/, sc_time time) { nextPlannedRefresh = clkAlign(time, Alignment::DOWN); - planNextRefresh(); + planNextRefresh(timing.tREFI); } bool RefreshManager::isInvalidated(tlm::tlm_generic_payload& payload __attribute__((unused)), sc_time time) diff --git a/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.h b/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.h index 0b24236e..ce89474f 100644 --- a/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.h +++ b/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.h @@ -59,9 +59,20 @@ private: RefreshTiming& timing; sc_time nextPlannedRefresh; std::map refreshPayloads; + unsigned int maxpostpone = 1; + unsigned int alignToTrefiValue = 0; + unsigned int arCmdCounter = 0; + bool burst = false; + bool alignToTrefiNeeded = false; - void planNextRefresh(); + void doRefresh(tlm::tlm_generic_payload& payload, sc_time time); + void planNextRefresh(sc_time time); void printDebugMessage(std::string message); + bool pendingRequests(); + void burstRefresh(); + void evaluateBurstState(); + sc_time getNextRefTiming(); + sc_time alignToTrefi(); }; #endif /* REFRESHMANAGER_H_ */ diff --git a/DRAMSys/simulator/src/controller/core/scheduling/checker/RefreshChecker.cpp b/DRAMSys/simulator/src/controller/core/scheduling/checker/RefreshChecker.cpp index 111e3d31..dd6d3869 100644 --- a/DRAMSys/simulator/src/controller/core/scheduling/checker/RefreshChecker.cpp +++ b/DRAMSys/simulator/src/controller/core/scheduling/checker/RefreshChecker.cpp @@ -70,6 +70,7 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const } else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) { + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRFC); } else reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommandOnBank.getCommand())); @@ -108,6 +109,7 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const } else if (lastCommand.getCommand() == Command::AutoRefresh) { + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRFC); } else reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommand.getCommand())); diff --git a/README.md b/README.md index 75ce2bc9..6025bcc0 100644 --- a/README.md +++ b/README.md @@ -741,6 +741,15 @@ Below, the sub-configurations are listed and explained. - *ControllerCoreDisableRefresh* (boolean) - "1": disables refreshes - "0": normal operation (refreshes enabled) + - *ControllerCoreForceMaxRefPostpone* (boolean) + - "1": force the value on ControllerCoreMaxPostponedARCmd always. Requires ControllerCoreEnableRefPostpone to be enabled + - "0": normal operation + - *ControllerCoreEnableRefPostpone* (boolean) + - "1": enables the postpone refresh feature + - "0": normal operation + - *ControllerCoreMaxPostponedARCmd* (unsigned int) + - Max AR commands to be postponed. + - **Trace Setups** - *clkMhz* (unsigned int)