Matthias Jung, Janik Schlemminger and Robert Gernhardt were used as authors for all files which did not have an author/header.
170 lines
5.9 KiB
C++
170 lines
5.9 KiB
C++
/*
|
|
* 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
|
|
*/
|
|
|
|
#include "PowerDownManagerTimeout.h"
|
|
#include "../ControllerCore.h"
|
|
#include "../../../common/Utils.h"
|
|
#include "../TimingCalculation.h"
|
|
|
|
using namespace tlm;
|
|
|
|
|
|
PowerDownManagerTimeout::PowerDownManagerTimeout(ControllerCore& controller): controllerCore(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 - controllerCore.state.getLastScheduledCommand().getEnd()) >= Configuration::getInstance().getPowerDownTimeout())
|
|
{
|
|
PowerDownState newState;
|
|
if(Configuration::getInstance().PowerDownMode == EPowerDownMode::TimeoutPDN)
|
|
{
|
|
newState = controllerCore.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]));
|
|
|
|
controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn);
|
|
|
|
if (controllerCore.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]));
|
|
controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn);
|
|
|
|
if (cmd == Command::SREFX)
|
|
controllerCore.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())
|
|
{
|
|
controllerCore.controller.send(PDNTrigger, time + controllerCore.config.getPowerDownTimeout(), powerDownPayloads[Bank(0)]);
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|