Files
DRAMSys/dram/src/core/powerdown/PowerDownManager.cpp
2014-05-05 23:24:36 +02:00

167 lines
4.2 KiB
C++

/*
* PowerDownManager.cpp
*
* Created on: Apr 1, 2014
* Author: jonny
*/
#include <algorithm>
#include <string>
#include "PowerDownManager.h"
#include "../ControllerCore.h"
#include "../TimingCalculation.h"
#include "../../common/DebugManager.h"
#include <algorithm>
#include "../../common/Utils.h"
using namespace tlm;
using namespace std;
namespace core {
PowerDownManager::PowerDownManager(ControllerCore& controller) :
controller(controller)
{
powerDownState = PowerDownState::Awake;
for (Bank bank : controller.getBanks())
{
setUpDummy(powerDownPayloads[bank], bank);
}
}
PowerDownManager::~PowerDownManager()
{
}
void PowerDownManager::sleep(Bank bank, sc_time time)
{
if (!canSleep() || isInPowerDown())
return;
PowerDownState state = powerDownState;
if (state == PowerDownState::Awake) //coming from active
{
state = controller.state.bankStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive;
}
else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down
{
sc_assert(controller.state.bankStates.allRowBuffersAreClosed());
if (controller.state.getLastCommand(Command::PDNA).getStart()
>= controller.state.getLastCommand(Command::PDNP).getStart())
state = PowerDownState::PDNPrecharge;
else
{
state = PowerDownState::PDNSelfRefresh;
}
}
Command cmd = IPowerDownManager::getSleepCommand(state);
ScheduledCommand pdn(cmd, time, getMinimalExecutionTime(cmd, powerDownPayloads[bank]),
DramExtension::getExtension(powerDownPayloads[bank]));
controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn);
if (state != PowerDownState::PDNSelfRefresh && controller.refreshManager->hasCollision(pdn))
{
return;
}
else
{
setPowerDownState(state);
sendPowerDownPayloads(pdn);
}
}
void PowerDownManager::wakeUp(Bank bank, sc_time time)
{
if (isAwakeForRefresh()) //Request enters system during Refresh
{
setPowerDownState(PowerDownState::Awake);
}
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]));
controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn);
if (cmd == Command::SREFX)
controller.refreshManager->reInitialize(bank, pdn.getEnd());
setPowerDownState(PowerDownState::Awake);
sendPowerDownPayloads(pdn);
}
}
void PowerDownManager::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 PowerDownManager::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);
}
}
void PowerDownManager::setPowerDownState(PowerDownState state)
{
powerDownState = state;
DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName,
"Is now in state " + powerDownStateToString(powerDownState) + " on all banks");
}
bool PowerDownManager::isInPowerDown()
{
return (powerDownState == PowerDownState::PDNActive || powerDownState == PowerDownState::PDNPrecharge
|| powerDownState == PowerDownState::PDNSelfRefresh);
}
bool PowerDownManager::canSleep()
{
for (Bank bank : controller.getBanks())
{
if (!controller.numberOfPayloads[bank] == 0)
return false;
}
return true;
}
bool PowerDownManager::isInSelfRefresh(Bank bank)
{
return powerDownState == PowerDownState::PDNSelfRefresh;
}
bool PowerDownManager::isAwakeForRefresh()
{
return powerDownState == PowerDownState::AwakeForRefresh;
}
void PowerDownManager::triggerSleep(Bank bank, sc_time time)
{
sleep(bank, time);
}
} /* namespace core */