Files
DRAMSys/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp
2014-09-03 18:52:32 +02:00

142 lines
4.3 KiB
C++

/*
* PowerDownManagerTimeout.cpp
*
* Created on: May 5, 2014
* Author: jungma
*/
#include "PowerDownManagerTimeout.h"
#include "../ControllerCore.h"
#include "../../../common/Utils.h"
#include "../TimingCalculation.h"
using namespace tlm;
namespace core {
PowerDownManagerTimeout::PowerDownManagerTimeout(ControllerCore& controller): controller(controller)
{
for (Bank bank : controller.getBanks())
{
setUpDummy(powerDownPayloads[bank], bank);
}
}
PowerDownManagerTimeout::~PowerDownManagerTimeout()
{
// TODO Auto-generated destructor stub
}
void PowerDownManagerTimeout::sleep(Bank bank, sc_time time)
{
if(canSleep() && !isInPowerDown() && (time - controller.state.getLastScheduledCommand().getEnd()) >= Configuration::getInstance().getPowerDownTimeout())
{
PowerDownState newState;
if(Configuration::getInstance().PowerDownMode == EPowerDownMode::TimeoutPDN)
{
newState = controller.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive;
}
else
{
newState = PowerDownState::PDNSelfRefresh;
}
Command cmd = IPowerDownManager::getSleepCommand(newState);
ScheduledCommand pdn(cmd, time, getMinExecutionTimeForPowerDownCmd(cmd),
DramExtension::getExtension(powerDownPayloads[bank]));
controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn);
if (controller.refreshManager->hasCollision(pdn))
{
return;
}
else
{
setPowerDownState(newState);
sendPowerDownPayloads(pdn);
}
}
}
bool PowerDownManagerTimeout::isInPowerDown()
{
return (powerDownState == PowerDownState::PDNActive || powerDownState == PowerDownState::PDNPrecharge
|| powerDownState == PowerDownState::PDNSelfRefresh);
}
void PowerDownManagerTimeout::setPowerDownState(PowerDownState state)
{
powerDownState = state;
DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName,
"Is now in state " + powerDownStateToString(powerDownState) + " on all banks");
}
void PowerDownManagerTimeout::wakeUp(Bank bank, sc_time time)
{
if (isInPowerDown()) //Request wakes up power down
{
Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState);
ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]),
DramExtension::getExtension(powerDownPayloads[bank]));
controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn);
if (cmd == Command::SREFX)
controller.refreshManager->reInitialize(bank, pdn.getEnd());
setPowerDownState(PowerDownState::Awake);
sendPowerDownPayloads(pdn);
}
}
void PowerDownManagerTimeout::wakeUpForRefresh(Bank bank, sc_time time)
{
if (isInPowerDown())
{
Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState);
ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]),
DramExtension::getExtension(powerDownPayloads[bank]));
setPowerDownState(PowerDownState::AwakeForRefresh);
sendPowerDownPayloads(pdn);
}
}
void PowerDownManagerTimeout::triggerSleep(Bank /*bank*/, sc_time time)
{
if(canSleep() && !isInPowerDown())
{
controller.wrapper.send(PDNTrigger, time + controller.config.getPowerDownTimeout(), powerDownPayloads[Bank(0)]);
}
}
bool PowerDownManagerTimeout::isInSelfRefresh(Bank /*bank*/)
{
return powerDownState == PowerDownState::PDNSelfRefresh;
}
bool PowerDownManagerTimeout::canSleep()
{
for (Bank bank : controller.getBanks())
{
if (!controller.numberOfPayloads[bank] == 0)
return false;
}
return true;
}
void PowerDownManagerTimeout::sendPowerDownPayloads(ScheduledCommand& cmd)
{
controller.state.bus.moveCommandToNextFreeSlot(cmd);
for (Bank bank : controller.getBanks())
{
tlm_generic_payload& payloadToSend = powerDownPayloads[bank];
ScheduledCommand pdnToSend(cmd.getCommand(), cmd.getStart(), cmd.getExecutionTime(),
DramExtension::getExtension(payloadToSend));
controller.state.change(pdnToSend);
controller.wrapper.send(pdnToSend, payloadToSend);
}
}
}