diff --git a/DRAMSys/analyzer/scripts/tests.py b/DRAMSys/analyzer/scripts/tests.py index 531c5c8a..8185d44f 100755 --- a/DRAMSys/analyzer/scripts/tests.py +++ b/DRAMSys/analyzer/scripts/tests.py @@ -245,7 +245,7 @@ def phase_transitions_are_valid(connection): # validTransitions tells you which phases are allowed to follow the last transaction. if (dramconfig.bankwiseLogic == "1"): - validTransitions['PRE'] = set(['ACT', 'REFB']) + validTransitions['PRE'] = set(['ACT', 'REFB', 'SREFB']) validTransitions['ACT'] = set(['RD', 'RDA', 'WR', 'WRA', 'PRE', 'PRE_ALL']) validTransitions['RD'] = set(['PRE', 'RD', 'RDA', 'WR', 'WRA', 'PDNAB']) @@ -253,14 +253,14 @@ def phase_transitions_are_valid(connection): validTransitions['RDA'] = set(['ACT', 'REFB', 'PDNPB']) validTransitions['WRA'] = set(['ACT', 'REFB', 'PDNPB']) - validTransitions['REFB'] = set(['ACT', 'PDNPB', 'SREFB']) + validTransitions['REFB'] = set(['ACT', 'REFB', 'PDNPB', 'SREFB']) validTransitions['PDNAB'] = set(['PRE', 'RD', 'RDA', 'WR', 'WRA', 'REFB']) validTransitions['PDNPB'] = set(['ACT', 'REFB']) validTransitions['SREFB'] = set(['ACT']) else: validTransitions['PRE'] = set(['ACT', 'PRE_ALL']) - validTransitions['PRE_ALL'] = set(['REFA']) + validTransitions['PRE_ALL'] = set(['REFA', 'SREF']) validTransitions['ACT'] = set(['RD', 'RDA', 'WR', 'WRA', 'PRE_ALL']) validTransitions['RD'] = set(['PRE', 'PRE_ALL', 'RD', 'RDA', 'WR', 'WRA', 'PDNA']) @@ -276,13 +276,13 @@ def phase_transitions_are_valid(connection): # This was the original query: # query = """SELECT PhaseName, phases.ID FROM phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE TBank=:bank AND PhaseName NOT IN ('REQ','RESP') ORDER BY PhaseBegin""" - # However, refreshes and pre_all are attributed to Bank 0 therefore this must be added to the order evaluation: + # However, refreshes, pre_all and self-refreshes are attributed to Bank 0 therefore this must be added to the order evaluation: query = """SELECT PhaseName, phases.ID FROM phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE - ((TBank=:bank) OR (PhaseNAME = "REFA" AND TBank=0) OR (PhaseNAME = "PRE_ALL" AND TBank=0)) + ((TBank=:bank) OR (PhaseNAME = "REFA" AND TBank=0) OR (PhaseNAME = "PRE_ALL" AND TBank=0) OR (PhaseNAME = "SREF" AND TBank=0)) AND PhaseName NOT IN ('REQ','RESP') ORDER BY PhaseBegin""" for bankNumber in range(dramconfig.numberOfBanks): @@ -424,6 +424,31 @@ def row_buffer_is_used_correctly(connection): return TestSuceeded() +@test +def no_commands_during_refresh(connection): + """Checks that no command was scheduled during refresh period""" + cursor = connection.cursor() + if (dramconfig.bankwiseLogic == "1"): + query = """SELECT PhaseBegin, PhaseEnd, TBank FROM phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE PhaseName = 'REFB' """ + test_query = """SELECT PhaseName FROM phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE ((PhaseBegin >= ? and PhaseEnd <= ?) or (PhaseBegin <= ? and PhaseEnd > ?) or (PhaseBegin < ? and PhaseEnd >= ?)) and PhaseName NOT IN ('REQ','RESP','REFB') and TBank = ?""" + else: + query = """SELECT PhaseBegin, PhaseEnd FROM phases WHERE PhaseName = 'REFA' """ + test_query = """SELECT PhaseName FROM phases WHERE ((PhaseBegin >= ? and PhaseEnd <= ?) or (PhaseBegin <= ? and PhaseEnd > ?) or (PhaseBegin < ? and PhaseEnd >= ?)) and PhaseName NOT IN ('REQ','RESP', 'REFA')""" + + cursor.execute(query); + result = cursor.fetchall(); + for row in result: + if(dramconfig.bankwiseLogic == "1"): + cursor.execute(test_query, (row[0], row[1], row[0], row[0], row[1], row[1], row[2])) + else: + cursor.execute(test_query, (row[0], row[1], row[0], row[0], row[1], row[1])) + test = cursor.fetchone(); + if(test is not None): + return TestFailed("A Command {0} was scheduled during a refresh period".format(test[0])) + + return TestSuceeded() + + # ----------- activate checks --------------------------------------- @test def activate_to_activate_holds(connection): diff --git a/DRAMSys/simulator/resources/configs/memconfigs/fifoStrict.xml b/DRAMSys/simulator/resources/configs/memconfigs/fifoStrict.xml index 270d9037..179defd4 100644 --- a/DRAMSys/simulator/resources/configs/memconfigs/fifoStrict.xml +++ b/DRAMSys/simulator/resources/configs/memconfigs/fifoStrict.xml @@ -4,7 +4,7 @@ - + diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index 4d9fd6cd..593718da 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -106,7 +106,8 @@ SOURCES += \ src/error/errormodel.cpp \ src/controller/Controller.cpp \ src/simulation/TracePlayer.cpp \ - src/simulation/StlPlayer.cpp + src/simulation/StlPlayer.cpp \ + src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ @@ -167,7 +168,8 @@ HEADERS += \ src/controller/IController.h \ src/controller/core/configuration/ConfigurationLoader.h \ src/error/errormodel.h \ - src/simulation/ExampleInitiator.h + src/simulation/ExampleInitiator.h \ + src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/src/controller/Controller.cpp b/DRAMSys/simulator/src/controller/Controller.cpp index 52b416d6..bcd52ca6 100644 --- a/DRAMSys/simulator/src/controller/Controller.cpp +++ b/DRAMSys/simulator/src/controller/Controller.cpp @@ -32,6 +32,7 @@ * Authors: * Robert Gernhardt * Matthias Jung + * Felipe S. Prado */ #include "Controller.h" @@ -52,11 +53,11 @@ void Controller::buildScheduler() { scheduler = new FR_FCFS(*controllerCore); } - // else if (selectedScheduler == "PAR_BS") - // { - // scheduler = new PAR_BS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, - // Configuration::getInstance().Capsize); - // } + //else if (selectedScheduler == "PAR_BS") + //{ + // scheduler = new PAR_BS(*controllerCore,Configuration::getInstance().RefreshAwareScheduling, + // Configuration::getInstance().Capsize); + //} // else if (selectedScheduler == "Grouper") // { // scheduler = new ReadWriteGrouper(*controllerCore); @@ -65,6 +66,7 @@ void Controller::buildScheduler() reportFatal(name(), "unsupported scheduler: " + selectedScheduler); } +//Send the next scheduled command to the DRAM void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payload) { sc_assert(command.getStart() >= sc_time_stamp()); @@ -96,7 +98,6 @@ void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payl case Command::AutoRefresh: if(!Configuration::getInstance().BankwiseLogic) { - if(command.getBank() == Bank(0)) controllerCorePEQ.notify(payload, BEGIN_REFA, command.getStart() - sc_time_stamp()); } else @@ -109,13 +110,11 @@ void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payl controllerCorePEQ.notify(payload, BEGIN_PRE, command.getStart() - sc_time_stamp()); break; case Command::PrechargeAll: - if(command.getBank() == Bank(0)) controllerCorePEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp()); break; case Command::PDNA: if(!Configuration::getInstance().BankwiseLogic) { - if(command.getBank() == Bank(0)) controllerCorePEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp()); } else @@ -124,7 +123,6 @@ void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payl case Command::PDNAX: if(!Configuration::getInstance().BankwiseLogic) { - if(command.getBank() == Bank(0)) controllerCorePEQ.notify(payload, END_PDNA, command.getStart() - sc_time_stamp()); } else @@ -133,7 +131,6 @@ void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payl case Command::PDNP: if(!Configuration::getInstance().BankwiseLogic) { - if(command.getBank() == Bank(0)) controllerCorePEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp()); } else @@ -142,7 +139,6 @@ void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payl case Command::PDNPX: if(!Configuration::getInstance().BankwiseLogic) { - if(command.getBank() == Bank(0)) controllerCorePEQ.notify(payload, END_PDNP, command.getStart() - sc_time_stamp()); } else @@ -151,7 +147,6 @@ void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payl case Command::SREF: if(!Configuration::getInstance().BankwiseLogic) { - if(command.getBank() == Bank(0)) controllerCorePEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp()); } else @@ -160,7 +155,6 @@ void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payl case Command::SREFX: if(!Configuration::getInstance().BankwiseLogic) { - if(command.getBank() == Bank(0)) controllerCorePEQ.notify(payload, END_SREF, command.getStart() - sc_time_stamp()); } else @@ -172,6 +166,7 @@ void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payl } } +//Trigger the next planned refresh or the power down mode on the DRAM void Controller::send(Trigger trigger, sc_time time, tlm_generic_payload &payload) { sc_assert(time >= sc_time_stamp()); @@ -251,6 +246,7 @@ tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &payload, tlm_phas } else if (phase == END_RESP) { + recTime = fwDelay + sc_time_stamp() + Configuration::getInstance().memSpec.clk; notDelay = clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay); @@ -263,6 +259,7 @@ tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &payload, tlm_phas tlmRecorder->recordPhase(payload, phase, recTime); frontendPEQ.notify(payload, phase, notDelay); + } return TLM_ACCEPTED; } @@ -375,7 +372,6 @@ void Controller::scheduleNextFromScheduler(Bank bank) printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString(nextRequest.first) + "] (unblocked)"); } } - } void Controller::sendToFrontend(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) diff --git a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp index a892ab43..57233afd 100644 --- a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp +++ b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp @@ -32,6 +32,7 @@ * Authors: * Janik Schlemminger * Matthias Jung + * Felipe S. Prado */ #include @@ -52,6 +53,7 @@ #include "powerdown/PowerDownManager.h" #include "powerdown/PowerDownManagerTimeout.h" #include "powerdown/PowerDownManagerBankwise.h" +#include "powerdown/PowerDownManagerTimeoutBankwise.h" #include "powerdown/NoPowerDown.h" #include "../../common/DebugManager.h" @@ -78,11 +80,11 @@ ControllerCore::ControllerCore(sc_module_name /*name*/, IController& wrapperConn if (config.BankwiseLogic) { - refreshManager = new RefreshManagerBankwise("refManagerBw", *this); + refreshManager = new RefreshManagerBankwise("refManagerBw", *this); } else { - refreshManager = new RefreshManager("refManager", *this); + refreshManager = new RefreshManager("refManager", *this); } if(config.PowerDownMode == EPowerDownMode::Staggered) @@ -94,7 +96,10 @@ ControllerCore::ControllerCore(sc_module_name /*name*/, IController& wrapperConn } else if(config.PowerDownMode == EPowerDownMode::TimeoutPDN || config.PowerDownMode == EPowerDownMode::TimeoutSREF) { - powerDownManager = new PowerDownManagerTimeout("pdnManagerTout", *this); + if (config.BankwiseLogic) + powerDownManager = new PowerDownManagerTimeoutBankwise("pdnManagerBw", *this); + else + powerDownManager = new PowerDownManagerTimeout("pdnManager", *this); } else if(config.PowerDownMode == EPowerDownMode::NoPowerDown) { @@ -144,7 +149,7 @@ void ControllerCore::scheduleRequest(Command command, tlm::tlm_generic_payload & state->cleanUp(start); ScheduledCommand scheduledCommand = schedule(command, start, payload); if(!(command == Command::Precharge && refreshManager->hasCollision(scheduledCommand))) - { + { state->change(scheduledCommand); controller.send(scheduledCommand, payload); } diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.cpp b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.cpp index 80493bb4..7c1f59e6 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.cpp +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.cpp @@ -32,6 +32,7 @@ * Authors: * Janik Schlemminger * Matthias Jung + * Felipe S. Prado */ #include @@ -55,6 +56,7 @@ PowerDownManager::PowerDownManager(sc_module_name /*name*/, ControllerCore& cont { setUpDummy(powerDownPayloads[bank], bank); } + //controllerCore.controller.send(PDNTrigger, sc_time_stamp(), powerDownPayloads[Bank(0)]); } PowerDownManager::~PowerDownManager() @@ -62,7 +64,7 @@ PowerDownManager::~PowerDownManager() } -void PowerDownManager::sleep(Bank bank, sc_time time) +void PowerDownManager::sleep(Bank /*bank*/, sc_time time) { if (!canSleep() || isInPowerDown()) return; @@ -88,7 +90,7 @@ void PowerDownManager::sleep(Bank bank, sc_time time) Command cmd = IPowerDownManager::getSleepCommand(state); ScheduledCommand pdn(cmd, time, getMinExecutionTimeForPowerDownCmd(cmd), - DramExtension::getExtension(powerDownPayloads[bank])); + DramExtension::getExtension(powerDownPayloads[Bank(0)])); controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); @@ -99,13 +101,13 @@ void PowerDownManager::sleep(Bank bank, sc_time time) else { setPowerDownState(state); - sendPowerDownPayloads(pdn); + sendPowerDownPayload(pdn); } } void PowerDownManager::wakeUp(Bank bank, sc_time time) { - printDebugMessage("Waking up at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); + printDebugMessage("Waking up at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); if (isAwakeForRefresh()) //Request enters system during Refresh { @@ -114,56 +116,59 @@ void PowerDownManager::wakeUp(Bank bank, sc_time time) else if (isInPowerDown()) //Request wakes up power down { Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); - ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), - DramExtension::getExtension(powerDownPayloads[bank])); + ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[Bank(0)]), + DramExtension::getExtension(powerDownPayloads[Bank(0)])); controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); if (cmd == Command::SREFX) { - // Leaving Self Refresh. Plan the next refresh. + // Leaving Self Refresh. Plan the next refresh. controllerCore.refreshManager->reInitialize(bank, pdn.getEnd()); - printDebugMessage("Waking up. Leaving Self Refresh at " + time.to_string() + " next refresh planned to " + pdn.getEnd().to_string()); + printDebugMessage("Waking up. Leaving Self Refresh at " + time.to_string() + " next refresh planned to " + pdn.getEnd().to_string()); } setPowerDownState(PowerDownState::Awake); - printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks"); - sendPowerDownPayloads(pdn); + printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks"); + sendPowerDownPayload(pdn); } - printDebugMessage("Awaken at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); + printDebugMessage("Awaken at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); } -void PowerDownManager::wakeUpForRefresh(Bank bank, sc_time time) +void PowerDownManager::wakeUpForRefresh(Bank /*bank*/, sc_time time) { - printDebugMessage("Waking up for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); + printDebugMessage("Waking up for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); if (isInPowerDown()) { Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); - ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), - DramExtension::getExtension(powerDownPayloads[bank])); + ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[Bank(0)]), + DramExtension::getExtension(powerDownPayloads[Bank(0)])); setPowerDownState(PowerDownState::AwakeForRefresh); - printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks"); - sendPowerDownPayloads(pdn); + printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks"); + sendPowerDownPayload(pdn); } - + printDebugMessage("Awaken for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); } -void PowerDownManager::sendPowerDownPayloads(ScheduledCommand& cmd) +void PowerDownManager::sendPowerDownPayload(ScheduledCommand& pdnToSend) { - controllerCore.state->bus.moveCommandToNextFreeSlot(cmd); - for (Bank bank : controllerCore.getBanks()) + controllerCore.state->bus.moveCommandToNextFreeSlot(pdnToSend); + for (size_t bank = 1; bank < controllerCore.getBanks().size(); bank++) { tlm_generic_payload& payloadToSend = powerDownPayloads[bank]; - ScheduledCommand pdnToSend(cmd.getCommand(), cmd.getStart(), cmd.getExecutionTime(), DramExtension::getExtension(payloadToSend)); - controllerCore.state->change(pdnToSend); - printDebugMessage("Sending power down command " + commandToString(pdnToSend.getCommand()) + " on bank " + to_string(pdnToSend.getBank().ID()) + " start time " + pdnToSend.getStart().to_string() + " end time " + pdnToSend.getEnd().to_string()); - controllerCore.controller.send(pdnToSend, payloadToSend); + ScheduledCommand pdn(pdnToSend.getCommand(), pdnToSend.getStart(), pdnToSend.getExecutionTime(), DramExtension::getExtension(payloadToSend)); + controllerCore.state->change(pdn); + } + controllerCore.state->change(pdnToSend); + controllerCore.controller.send(pdnToSend, powerDownPayloads[Bank(0)]); + printDebugMessage("Sending power down command " + commandToString(pdnToSend.getCommand()) + " on bank " + to_string(pdnToSend.getBank().ID()) + " start time " + pdnToSend.getStart().to_string() + " end time " + pdnToSend.getEnd().to_string()); + } void PowerDownManager::setPowerDownState(PowerDownState state) @@ -205,6 +210,6 @@ void PowerDownManager::triggerSleep(Bank bank, sc_time time) void PowerDownManager::printDebugMessage(std::string message) { - DebugManager::getInstance().printDebugMessage(this->name(), message); + DebugManager::getInstance().printDebugMessage(this->name(), message); } diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.h b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.h index 2eabdadc..9a4a2484 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.h +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.h @@ -49,13 +49,13 @@ public: virtual ~PowerDownManager(); virtual void triggerSleep(Bank bank, sc_time time) override; - virtual void sleep(Bank bank, sc_time time) override; + virtual void sleep(Bank /*bank*/, sc_time time) override; virtual void wakeUp(Bank bank, sc_time time) override; virtual void wakeUpForRefresh(Bank bank, sc_time time) override; virtual bool isInSelfRefresh(Bank bank) override; -private: - void sendPowerDownPayloads(ScheduledCommand& cmd); +protected: + void sendPowerDownPayload(ScheduledCommand& pdnToSend); bool isInPowerDown(); void setPowerDownState(PowerDownState state); bool canSleep(); diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.cpp b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.cpp index 266c4f26..cf2d02a5 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.cpp +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.cpp @@ -42,12 +42,13 @@ using namespace tlm; -PowerDownManagerBankwise::PowerDownManagerBankwise(sc_module_name /*name*/, ControllerCore& controller) : controllerCore(controller) +PowerDownManagerBankwise::PowerDownManagerBankwise(sc_module_name /*name*/, ControllerCore& controllerCore) : controllerCore(controllerCore) { - for (Bank bank : controller.getBanks()) + for (Bank bank : controllerCore.getBanks()) { setUpDummy(powerDownPayloads[bank], bank); powerDownStates[bank] = PowerDownState::Awake; + //controllerCore.controller.send(PDNTrigger, sc_time_stamp(), powerDownPayloads[bank]); } } @@ -86,65 +87,65 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time) } else { - setState(state, bank); + setPowerDownState(state, bank); sendPowerDownPayload(pdn); } } void PowerDownManagerBankwise::wakeUp(Bank bank, sc_time time) { - printDebugMessage("Waking up on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank])); + printDebugMessage("Waking up on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank])); - if (isAwakeForRefresh(bank)) { - printDebugMessage("It was already awake for refresh on bank " + to_string(bank.ID()) + " at " + time.to_string()); - setState(PowerDownState::Awake, bank); - } else if (isInPowerDown(bank)) { - // Request wake up from power down. A Power Down Exit request will be generated (PDNAX, PDNPX, SREFX). - Command pdnExitCmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); - // Mount the command to be scheduled - ScheduledCommand pdnExit(pdnExitCmd, time, getExecutionTime(pdnExitCmd, powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank])); - // Ensure that time constraints are respected - controllerCore.getCommandChecker(pdnExitCmd).delayToSatisfyConstraints(pdnExit); + if (isAwakeForRefresh(bank)) { + printDebugMessage("It was already awake for refresh on bank " + to_string(bank.ID()) + " at " + time.to_string()); + setPowerDownState(PowerDownState::Awake, bank); + } else if (isInPowerDown(bank)) { + // Request wake up from power down. A Power Down Exit request will be generated (PDNAX, PDNPX, SREFX). + Command pdnExitCmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); + // Mount the command to be scheduled + ScheduledCommand pdnExit(pdnExitCmd, time, getExecutionTime(pdnExitCmd, powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank])); + // Ensure that time constraints are respected + controllerCore.getCommandChecker(pdnExitCmd).delayToSatisfyConstraints(pdnExit); - if (pdnExitCmd == Command::SREFX) { - // Leaving Self Refresh. Plan the next refresh. - controllerCore.refreshManager->reInitialize(bank, pdnExit.getEnd()); - printDebugMessage("Waking up. Leaving Self Refresh on Bank " + to_string(bank.ID()) + " at " + time.to_string() + " next refresh planned to " + pdnExit.getEnd().to_string()); - } + if (pdnExitCmd == Command::SREFX) { + // Leaving Self Refresh. Plan the next refresh. + controllerCore.refreshManager->reInitialize(bank, pdnExit.getEnd()); + printDebugMessage("Waking up. Leaving Self Refresh on Bank " + to_string(bank.ID()) + " at " + time.to_string() + " next refresh planned to " + pdnExit.getEnd().to_string()); + } - setState(PowerDownState::Awake, bank); + setPowerDownState(PowerDownState::Awake, bank); - printDebugMessage("Sending power down exit command " + commandToString(pdnExitCmd) + " on bank " + to_string(bank.ID()) + " at " + time.to_string() + " start time " + pdnExit.getStart().to_string() + " end time " + pdnExit.getEnd().to_string()); - sendPowerDownPayload(pdnExit); - } + printDebugMessage("Sending power down exit command " + commandToString(pdnExitCmd) + " on bank " + to_string(bank.ID()) + " at " + time.to_string() + " start time " + pdnExit.getStart().to_string() + " end time " + pdnExit.getEnd().to_string()); + sendPowerDownPayload(pdnExit); + } - printDebugMessage("Awaken on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank])); + printDebugMessage("Awaken on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank])); } void PowerDownManagerBankwise::wakeUpForRefresh(Bank bank, sc_time time) { - printDebugMessage("Waking up for refresh on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank])); + printDebugMessage("Waking up for refresh on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank])); - if (isInPowerDown(bank)) { - // A Power Down Exit request will be generated (PDNAX, PDNPX, SREFX). - Command pdnExitCmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); - // Get the execution time for this request - sc_time executionTime = getExecutionTime(pdnExitCmd, powerDownPayloads[bank]); - // Mount the command to be scheduled - ScheduledCommand pdnExit(pdnExitCmd, time, executionTime, DramExtension::getExtension(powerDownPayloads[bank])); + if (isInPowerDown(bank)) { + // A Power Down Exit request will be generated (PDNAX, PDNPX, SREFX). + Command pdnExitCmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); + // Get the execution time for this request + sc_time executionTime = getExecutionTime(pdnExitCmd, powerDownPayloads[bank]); + // Mount the command to be scheduled + ScheduledCommand pdnExit(pdnExitCmd, time, executionTime, DramExtension::getExtension(powerDownPayloads[bank])); - setState(PowerDownState::AwakeForRefresh, bank); + setPowerDownState(PowerDownState::AwakeForRefresh, bank); - printDebugMessage("Sending power down exit command " + commandToString(pdnExitCmd) + " on bank " + to_string(bank.ID()) + " at " + time.to_string() + " start time " + pdnExit.getStart().to_string() + " end time " + pdnExit.getEnd().to_string()); - sendPowerDownPayload(pdnExit); - } + printDebugMessage("Sending power down exit command " + commandToString(pdnExitCmd) + " on bank " + to_string(bank.ID()) + " at " + time.to_string() + " start time " + pdnExit.getStart().to_string() + " end time " + pdnExit.getEnd().to_string()); + sendPowerDownPayload(pdnExit); + } - printDebugMessage("Awaken for refresh on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank])); + printDebugMessage("Awaken for refresh on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank])); } bool PowerDownManagerBankwise::isInPowerDown(Bank bank) { - return isIn(powerDownStates[bank], { PowerDownState::PDNActive, PowerDownState::PDNPrecharge, PowerDownState::PDNSelfRefresh }); + return isIn(powerDownStates[bank], { PowerDownState::PDNActive, PowerDownState::PDNPrecharge, PowerDownState::PDNSelfRefresh }); } bool PowerDownManagerBankwise::isInSelfRefresh(Bank bank) @@ -162,19 +163,19 @@ bool PowerDownManagerBankwise::isAwake(Bank bank) return powerDownStates[bank] == PowerDownState::Awake; } -void PowerDownManagerBankwise::setState(PowerDownState state, Bank bank) +void PowerDownManagerBankwise::setPowerDownState(PowerDownState state, Bank bank) { - PowerDownState& bankstate = powerDownStates[bank]; - bankstate = state; - printDebugMessage("Is now in state " + powerDownStateToString(state) + " on Bank " + to_string(bank.ID())); + PowerDownState& bankstate = powerDownStates[bank]; + bankstate = state; + printDebugMessage("Is now in state " + powerDownStateToString(state) + " on Bank " + to_string(bank.ID())); } void PowerDownManagerBankwise::sendPowerDownPayload(ScheduledCommand &pdn) { - controllerCore.state->bus.moveCommandToNextFreeSlot(pdn); - controllerCore.state->change(pdn); - printDebugMessage("Sending power down command " + commandToString(pdn.getCommand()) + " on bank " + to_string(pdn.getBank().ID()) + " start time " + pdn.getStart().to_string() + " end time " + pdn.getEnd().to_string()); - controllerCore.controller.send(pdn, powerDownPayloads[pdn.getBank()]); + controllerCore.state->bus.moveCommandToNextFreeSlot(pdn); + controllerCore.state->change(pdn); + printDebugMessage("Sending power down command " + commandToString(pdn.getCommand()) + " on bank " + to_string(pdn.getBank().ID()) + " start time " + pdn.getStart().to_string() + " end time " + pdn.getEnd().to_string()); + controllerCore.controller.send(pdn, powerDownPayloads[pdn.getBank()]); } bool PowerDownManagerBankwise::canSleep(Bank bank) @@ -189,6 +190,6 @@ void PowerDownManagerBankwise::triggerSleep(Bank bank, sc_time time) void PowerDownManagerBankwise::printDebugMessage(std::string message) { - DebugManager::getInstance().printDebugMessage(this->name(), message); + DebugManager::getInstance().printDebugMessage(this->name(), message); } diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.h b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.h index c15ab4fd..bbe8b1f3 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.h +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.h @@ -52,33 +52,33 @@ class ControllerCore; class PowerDownManagerBankwise : public sc_module, public IPowerDownManager { public: - PowerDownManagerBankwise(sc_module_name /*name*/, ControllerCore& controllerCore); - virtual ~PowerDownManagerBankwise(){} - virtual void triggerSleep(Bank bank, sc_time time) override; - virtual void sleep(Bank bank, sc_time time) override; - virtual void wakeUp(Bank bank, sc_time time) override; - virtual void wakeUpForRefresh(Bank bank, sc_time time) override; - virtual bool isInSelfRefresh(Bank bank) override; + PowerDownManagerBankwise(sc_module_name /*name*/, ControllerCore& controllerCore); + virtual ~PowerDownManagerBankwise(){} + virtual void triggerSleep(Bank bank, sc_time time) override; + virtual void sleep(Bank bank, sc_time time) override; + virtual void wakeUp(Bank bank, sc_time time) override; + virtual void wakeUpForRefresh(Bank bank, sc_time time) override; + virtual bool isInSelfRefresh(Bank bank) override; -private: - virtual bool isInPowerDown(Bank bank); - virtual bool isAwake(Bank bank); - virtual bool isAwakeForRefresh(Bank bank); +protected: + virtual bool isInPowerDown(Bank bank); + virtual bool isAwake(Bank bank); + virtual bool isAwakeForRefresh(Bank bank); - ControllerCore &controllerCore; - std::map powerDownPayloads; - std::map powerDownStates; + ControllerCore &controllerCore; + std::map powerDownPayloads; + std::map powerDownStates; - virtual bool canSleep(Bank bank); + virtual bool canSleep(Bank bank); - void setState(PowerDownState state, Bank bank); + void setPowerDownState(PowerDownState state, Bank bank); - Command getWakeUpCommand(PowerDownState state); - Command getSleepCommand(PowerDownState state); + Command getWakeUpCommand(PowerDownState state); + Command getSleepCommand(PowerDownState state); - void sendPowerDownPayload(ScheduledCommand &pdn); + void sendPowerDownPayload(ScheduledCommand &pdn); - void printDebugMessage(std::string message); + void printDebugMessage(std::string message); }; #endif /* POWERDOWNMANAGERBANKWISE_H_ */ diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.cpp b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.cpp index a1763d18..3b68008e 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.cpp +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.cpp @@ -33,6 +33,7 @@ * Janik Schlemminger * Robert Gernhardt * Matthias Jung + * Felipe S. Prado */ #include "PowerDownManagerTimeout.h" @@ -43,14 +44,10 @@ using namespace tlm; - -PowerDownManagerTimeout::PowerDownManagerTimeout(sc_module_name /*name*/, ControllerCore& controller): controllerCore(controller) +PowerDownManagerTimeout::PowerDownManagerTimeout(sc_module_name name, ControllerCore& controllerCore): + PowerDownManager(name, controllerCore) { - powerDownState = PowerDownState::Awake; - for (Bank bank : controller.getBanks()) - { - setUpDummy(powerDownPayloads[bank], bank); - } + //controllerCore.controller.send(PDNTrigger, Configuration::getInstance().getPowerDownTimeout(), powerDownPayloads[Bank(0)]); } PowerDownManagerTimeout::~PowerDownManagerTimeout() @@ -58,19 +55,36 @@ PowerDownManagerTimeout::~PowerDownManagerTimeout() // TODO Auto-generated destructor stub } -void PowerDownManagerTimeout::sleep(Bank bank, sc_time time) +void PowerDownManagerTimeout::sleep(Bank /*bank*/, sc_time time) { - bool test_canSleep = canSleep(); - bool test_isInPowerDown = isInPowerDown(); - sc_time last_scheduled_command = controllerCore.state->getLastScheduledCommand().getEnd(); - sc_time power_down_timeout = Configuration::getInstance().getPowerDownTimeout(); - bool test_timeCondition = (time - last_scheduled_command) >= power_down_timeout; - bool test_awakeForRefresh = (powerDownState == PowerDownState::AwakeForRefresh); + bool timeoutTest; + if(!isAwakeForRefresh()) + { + sc_time lastReadScheduled; + sc_time lastWriteScheduled; + if(Configuration::getInstance().OpenPagePolicy) + { + lastReadScheduled= controllerCore.state->getLastCommand(Command::Read).getEnd(); + lastWriteScheduled = controllerCore.state->getLastCommand(Command::Write).getEnd(); + } + else + { + lastReadScheduled = controllerCore.state->getLastCommand(Command::ReadA).getEnd(); + lastWriteScheduled = controllerCore.state->getLastCommand(Command::WriteA).getEnd(); + } + sc_time lastScheduledCommand = max(lastReadScheduled,lastWriteScheduled); + timeoutTest = (time - lastScheduledCommand) >= Configuration::getInstance().getPowerDownTimeout(); + } + else + { + timeoutTest = true; + } //test_awakeForRefresh = false; - if( test_canSleep && !test_isInPowerDown && (test_timeCondition || test_awakeForRefresh )) + if( canSleep() && !isInPowerDown() && timeoutTest) { + PowerDownState newState; if(Configuration::getInstance().PowerDownMode == EPowerDownMode::TimeoutPDN) { @@ -78,12 +92,36 @@ void PowerDownManagerTimeout::sleep(Bank bank, sc_time time) } else // PowerDownMode == TimeoutSREF { + if(!controllerCore.state->rowBufferStates->allRowBuffersAreClosed()) + { + ScheduledCommand prechargeAllMaster(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, powerDownPayloads[Bank(0)]), DramExtension::getExtension(powerDownPayloads[Bank(0)])); + + controllerCore.getCommandChecker(Command::PrechargeAll).delayToSatisfyConstraints(prechargeAllMaster); + + if (controllerCore.refreshManager->hasCollision(prechargeAllMaster)) + { + return; + } + else + { + for (size_t i = 1; i < controllerCore.getBanks().size(); i++) + { + ScheduledCommand prechargeAll(Command::PrechargeAll, prechargeAllMaster.getStart(), prechargeAllMaster.getExecutionTime(), + powerDownPayloads[Bank(i)]); + controllerCore.state->change(prechargeAll); + } + controllerCore.state->change(prechargeAllMaster); + controllerCore.controller.send(prechargeAllMaster, powerDownPayloads[Bank(0)]); + } + + } + newState = PowerDownState::PDNSelfRefresh; } Command cmd = IPowerDownManager::getSleepCommand(newState); ScheduledCommand pdn(cmd, time, getMinExecutionTimeForPowerDownCmd(cmd), - DramExtension::getExtension(powerDownPayloads[bank])); + DramExtension::getExtension(powerDownPayloads[Bank(0)])); controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); @@ -94,71 +132,11 @@ void PowerDownManagerTimeout::sleep(Bank bank, sc_time time) else { setPowerDownState(newState); - sendPowerDownPayloads(pdn); + sendPowerDownPayload(pdn); } } } -bool PowerDownManagerTimeout::isInPowerDown() -{ - return ( powerDownState == PowerDownState::PDNActive - || powerDownState == PowerDownState::PDNPrecharge - || powerDownState == PowerDownState::PDNSelfRefresh); -} - -void PowerDownManagerTimeout::setPowerDownState(PowerDownState state) -{ - powerDownState = state; - printDebugMessage("Is now in state " + powerDownStateToString(powerDownState) + " on all banks"); -} - -void PowerDownManagerTimeout::wakeUp(Bank bank, sc_time time) -{ - printDebugMessage("Waking up at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); - - if (isInPowerDown()) //Request wakes up power down - { - Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); - ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), - DramExtension::getExtension(powerDownPayloads[bank])); - controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); - - if (cmd == Command::SREFX) { - // Leaving Self Refresh. Plan the next refresh. - controllerCore.refreshManager->reInitialize(bank, pdn.getEnd()); - printDebugMessage("Waking up. Leaving Self Refresh at " + time.to_string() + " next refresh planned to " + pdn.getEnd().to_string()); - } - - setPowerDownState(PowerDownState::Awake); - - printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks"); - sendPowerDownPayloads(pdn); - } - - printDebugMessage("Awaken at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); -} - -void PowerDownManagerTimeout::wakeUpForRefresh(Bank bank, sc_time time) -{ - printDebugMessage("Waking up for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); - - if (isInPowerDown()) - { - Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); - ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), - DramExtension::getExtension(powerDownPayloads[bank])); - - setPowerDownState(PowerDownState::AwakeForRefresh); - - printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks"); - sendPowerDownPayloads(pdn); - - // Schedule Next Powerdown after Refresh: - } - - printDebugMessage("Awaken for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); -} - void PowerDownManagerTimeout::triggerSleep(Bank /*bank*/, sc_time time) { if(canSleep() && !isInPowerDown()) @@ -167,36 +145,3 @@ void PowerDownManagerTimeout::triggerSleep(Bank /*bank*/, sc_time time) } } -bool PowerDownManagerTimeout::isInSelfRefresh(Bank /*bank*/) -{ - return powerDownState == PowerDownState::PDNSelfRefresh; -} - -bool PowerDownManagerTimeout::canSleep() -{ - for (Bank bank : controllerCore.getBanks()) - { - if (controllerCore.numberOfPayloads[bank] != 0) - return false; - } - return true; -} - -void PowerDownManagerTimeout::sendPowerDownPayloads(ScheduledCommand& cmd) -{ - controllerCore.state->bus.moveCommandToNextFreeSlot(cmd); - for (Bank bank : controllerCore.getBanks()) - { - tlm_generic_payload& payloadToSend = powerDownPayloads[bank]; - ScheduledCommand pdnToSend(cmd.getCommand(), cmd.getStart(), cmd.getExecutionTime(), - DramExtension::getExtension(payloadToSend)); - controllerCore.state->change(pdnToSend); - controllerCore.controller.send(pdnToSend, payloadToSend); - } -} - -void PowerDownManagerTimeout::printDebugMessage(std::string message) -{ - DebugManager::getInstance().printDebugMessage(this->name(), message); -} - diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.h b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.h index 46dfb866..39c206ca 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.h +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.h @@ -33,6 +33,7 @@ * Janik Schlemminger * Robert Gernhardt * Matthias Jung + * Felipe S. Prado */ #ifndef POWERDOWNMANAGERTIMEOUT_H_ @@ -46,30 +47,14 @@ class ControllerCore; -class PowerDownManagerTimeout: public IPowerDownManager, public sc_module +class PowerDownManagerTimeout: public PowerDownManager { public: PowerDownManagerTimeout(sc_module_name /*name*/, ControllerCore& controllerCore); virtual ~PowerDownManagerTimeout(); - virtual void triggerSleep(Bank bank, sc_time time); - virtual void sleep(Bank bank, sc_time time); - - virtual void wakeUp(Bank bank, sc_time time); - virtual void wakeUpForRefresh(Bank bank, sc_time time); - - virtual bool isInSelfRefresh(Bank bank); -private: - bool canSleep(); - ControllerCore& controllerCore; - - std::map powerDownPayloads; - void sendPowerDownPayloads(ScheduledCommand& cmd); - - PowerDownState powerDownState; - void setPowerDownState(PowerDownState state); - bool isInPowerDown(); - void printDebugMessage(std::string message); + virtual void triggerSleep(Bank /*bank*/, sc_time time); + virtual void sleep(Bank /*bank*/, sc_time time); }; diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp new file mode 100644 index 00000000..e520243a --- /dev/null +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2015, 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: + * Janik Schlemminger + * Robert Gernhardt + * Matthias Jung + * Felipe S. Prado + */ + +#include "PowerDownManagerTimeoutBankwise.h" +#include "../ControllerCore.h" +#include "../../../common/Utils.h" +#include "../../../common/DebugManager.h" +#include "../TimingCalculation.h" + +using namespace tlm; + +PowerDownManagerTimeoutBankwise::PowerDownManagerTimeoutBankwise(sc_module_name name, ControllerCore& controllerCore): + PowerDownManagerBankwise(name, controllerCore) +{ + /*for (Bank bank : controllerCore.getBanks()) + { + controllerCore.controller.send(PDNTrigger, controllerCore.config.getPowerDownTimeout(), powerDownPayloads[bank]); + }*/ +} + +PowerDownManagerTimeoutBankwise::~PowerDownManagerTimeoutBankwise() +{ + // TODO Auto-generated destructor stub +} + +void PowerDownManagerTimeoutBankwise::sleep(Bank bank, sc_time time) +{ + bool timeoutTest; + if(!isAwakeForRefresh(bank)) + { + sc_time lastReadScheduled; + sc_time lastWriteScheduled; + if(Configuration::getInstance().OpenPagePolicy) + { + lastReadScheduled= controllerCore.state->getLastCommand(Command::Read, bank).getEnd(); + lastWriteScheduled = controllerCore.state->getLastCommand(Command::Write, bank).getEnd(); + } + else + { + lastReadScheduled = controllerCore.state->getLastCommand(Command::ReadA, bank).getEnd(); + lastWriteScheduled = controllerCore.state->getLastCommand(Command::WriteA, bank).getEnd(); + } + sc_time lastScheduledCommand = max(lastReadScheduled,lastWriteScheduled); + timeoutTest = (time - lastScheduledCommand) >= Configuration::getInstance().getPowerDownTimeout(); + } + else + { + timeoutTest = true; + } + + if( canSleep(bank) && !isInPowerDown(bank) && timeoutTest) + { + PowerDownState newState; + if(Configuration::getInstance().PowerDownMode == EPowerDownMode::TimeoutPDN) + { + newState = controllerCore.state->rowBufferStates->rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge; + } + else // PowerDownMode == TimeoutSREF + { + if(controllerCore.state->rowBufferStates->rowBufferIsOpen(bank)) + { + ScheduledCommand precharge(Command::Precharge, time, getExecutionTime(Command::Precharge, powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank])); + + controllerCore.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(precharge); + + if (controllerCore.refreshManager->hasCollision(precharge)) + { + return; + } + else + { + controllerCore.state->change(precharge); + controllerCore.controller.send(precharge, powerDownPayloads[bank]); + } + + } + + newState = PowerDownState::PDNSelfRefresh; + } + + + Command cmd = IPowerDownManager::getSleepCommand(newState); + ScheduledCommand pdn(cmd, time, getMinExecutionTimeForPowerDownCmd(cmd), + DramExtension::getExtension(powerDownPayloads[bank])); + + controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); + + if (controllerCore.refreshManager->hasCollision(pdn)) + { + return; + } + else + { + setPowerDownState(newState, bank); + sendPowerDownPayload(pdn); + } + } +} + +void PowerDownManagerTimeoutBankwise::triggerSleep(Bank bank, sc_time time) +{ + if(canSleep(bank) && !isInPowerDown(bank)) + { + controllerCore.controller.send(PDNTrigger, time + controllerCore.config.getPowerDownTimeout(), powerDownPayloads[bank]); + } +} diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h new file mode 100644 index 00000000..8383a0b8 --- /dev/null +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, 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: + * Janik Schlemminger + * Robert Gernhardt + * Matthias Jung + * Felipe S. Prado + */ + +#ifndef POWERDOWNMANAGERTIMEOUTBANKWISE_H_ +#define POWERDOWNMANAGERTIMEOUTBANKWISE_H_ + +#include "PowerDownManager.h" +#include +#include "../../../common/dramExtension.h" +#include "../scheduling/ScheduledCommand.h" +#include + +class ControllerCore; + +class PowerDownManagerTimeoutBankwise: public PowerDownManagerBankwise +{ +public: + PowerDownManagerTimeoutBankwise(sc_module_name /*name*/, ControllerCore& controllerCore); + virtual ~PowerDownManagerTimeoutBankwise(); + + virtual void triggerSleep(Bank bank, sc_time time); + virtual void sleep(Bank bank, sc_time time); +}; + + + +#endif /* POWERDOWNMANAGERTIMEOUTBANKWISE_H_ */ diff --git a/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp b/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp index d2049f2f..742dfacc 100644 --- a/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp +++ b/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp @@ -32,6 +32,7 @@ * Authors: * Robert Gernhardt * Matthias Jung + * Felipe S. Prado */ #include "RefreshManager.h" @@ -56,41 +57,48 @@ RefreshManager::~RefreshManager() { } +//Check if a command will be scheduled during the next refresh period 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) { sc_assert(!isInvalidated(payload, time)); + //Check if any row on all banks is activated and if so, a PrechargeAll command must be scheduled before the refresh command. if (!controllerCore.state->rowBufferStates->allRowBuffersAreClosed()) { ScheduledCommand prechargeAllMaster(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, refreshPayloads[Bank(0)]), refreshPayloads[Bank(0)]); controllerCore.getCommandChecker(Command::PrechargeAll).delayToSatisfyConstraints(prechargeAllMaster); - for (Bank bank : controllerCore.getBanks()) + for (size_t i = 1;i < controllerCore.getBanks().size(); i++) { ScheduledCommand prechargeAll(Command::PrechargeAll, prechargeAllMaster.getStart(), prechargeAllMaster.getExecutionTime(), - refreshPayloads[bank]); + refreshPayloads[Bank(i)]); controllerCore.state->change(prechargeAll); - controllerCore.controller.send(prechargeAll, refreshPayloads[bank]); } + controllerCore.state->change(prechargeAllMaster); + controllerCore.controller.send(prechargeAllMaster, refreshPayloads[Bank(0)]); } + //Otherwise just the AutoRefresh command is scheduled. ScheduledCommand refreshAllMaster(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayloads[Bank(0)]), DramExtension::getExtension(refreshPayloads[Bank(0)])); controllerCore.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(refreshAllMaster); - for (Bank bank : controllerCore.getBanks()) + for (size_t i = 1;i < controllerCore.getBanks().size(); i++) { - ScheduledCommand refresh(Command::AutoRefresh, refreshAllMaster.getStart(), refreshAllMaster.getExecutionTime(),refreshPayloads[bank]); + ScheduledCommand refresh(Command::AutoRefresh, refreshAllMaster.getStart(), refreshAllMaster.getExecutionTime(),refreshPayloads[Bank(i)]); controllerCore.state->change(refresh); - controllerCore.controller.send(refresh, refreshPayloads[bank]); - DramExtension::getExtension(refreshPayloads[bank]).incrementRow(); + DramExtension::getExtension(refreshPayloads[Bank(i)]).incrementRow(); } + controllerCore.state->change(refreshAllMaster); + DramExtension::getExtension(refreshPayloads[Bank(0)]).incrementRow(); + controllerCore.controller.send(refreshAllMaster, refreshPayloads[Bank(0)]); planNextRefresh(); } @@ -114,6 +122,6 @@ bool RefreshManager::isInvalidated(tlm::tlm_generic_payload& payload __attribute void RefreshManager::printDebugMessage(std::string message) { - DebugManager::getInstance().printDebugMessage(this->name(), message); + DebugManager::getInstance().printDebugMessage(this->name(), message); } diff --git a/DRAMSys/simulator/src/controller/core/scheduling/checker/PowerDownChecker.cpp b/DRAMSys/simulator/src/controller/core/scheduling/checker/PowerDownChecker.cpp index c9a8a988..85f3a867 100644 --- a/DRAMSys/simulator/src/controller/core/scheduling/checker/PowerDownChecker.cpp +++ b/DRAMSys/simulator/src/controller/core/scheduling/checker/PowerDownChecker.cpp @@ -92,19 +92,19 @@ void PowerDownChecker::delayToSatisfyConstraints(ScheduledCommand &command) cons command.establishMinDistanceFromStart(lastSchedCmdOnBankStart, timeConstraint); } - } else if (pdnCmd == Command::PDNAX) { - // Leaving Active Power Down - timeConstraint = config.memSpec.tCKE; - command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNA).getStart(), timeConstraint); - } else if (pdnCmd == Command::PDNPX) { - // Leaving Precharge Power Down - timeConstraint = config.memSpec.tCKE; - command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNP).getStart(), timeConstraint); - } else if (pdnCmd == Command::SREFX) { - // Leaving Self Refresh - timeConstraint = config.memSpec.tCKESR; - command.establishMinDistanceFromStart(state.getLastCommand(Command::SREF).getStart(), timeConstraint); - } + } else if (pdnCmd == Command::PDNAX) { + // Leaving Active Power Down + timeConstraint = config.memSpec.tCKE; + command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNA, bank).getStart(), timeConstraint); + } else if (pdnCmd == Command::PDNPX) { + // Leaving Precharge Power Down + timeConstraint = config.memSpec.tCKE; + command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNP, bank).getStart(), timeConstraint); + } else if (pdnCmd == Command::SREFX) { + // Leaving Self Refresh + timeConstraint = config.memSpec.tCKESR; + command.establishMinDistanceFromStart(state.getLastCommand(Command::SREF, bank).getStart(), timeConstraint); + } state.bus.moveCommandToNextFreeSlot(command); }