Merge pull request #98 from sprado/master
Restructuring of the Power Down Managers and some improvements
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<MaxNrOfTransactions value="8" />
|
||||
<Scheduler value="FIFO_STRICT" />
|
||||
<Capsize value="5" />
|
||||
<PowerDownMode value="NoPowerDown" />
|
||||
<PowerDownMode value="NoPowerDown" /> <!-- 4 Modes: NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF -->
|
||||
<PowerDownTimeout value="100" />
|
||||
<!-- Error Modelling -->
|
||||
<ErrorChipSeed value="42" />
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Matthias Jung
|
||||
* Felipe S. Prado
|
||||
*/
|
||||
|
||||
#include <systemc.h>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Matthias Jung
|
||||
* Felipe S. Prado
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Bank, tlm::tlm_generic_payload> powerDownPayloads;
|
||||
std::map<Bank, PowerDownState> powerDownStates;
|
||||
ControllerCore &controllerCore;
|
||||
std::map<Bank, tlm::tlm_generic_payload> powerDownPayloads;
|
||||
std::map<Bank, PowerDownState> 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_ */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Bank, tlm::tlm_generic_payload> 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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
@@ -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 <systemc.h>
|
||||
#include "../../../common/dramExtension.h"
|
||||
#include "../scheduling/ScheduledCommand.h"
|
||||
#include <map>
|
||||
|
||||
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_ */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user