PowerDown Manager and Bankwise PowerDown

This commit is contained in:
Janik Schlemminger
2014-04-02 16:10:10 +02:00
parent e930002e5c
commit 9b49ca2d64
27 changed files with 757 additions and 102 deletions

View File

@@ -1,22 +1,212 @@
/*
* PowerDownManager.cpp
*
* Created on: Mar 9, 2014
* Created on: Apr 1, 2014
* Author: jonny
*/
#include <algorithm>
#include "PowerDownManager.h"
#include "../Controller.h"
#include "../utils/Utils.h"
using namespace tlm;
namespace core {
PowerDownManager::PowerDownManager()
PowerDownManager::PowerDownManager(Controller& controller) :
controller(controller), powerDownPayloads(controller.state.bankStates.getNumberOfBanks()), canSleep(
controller.state.bankStates.getNumberOfBanks(), true)
{
// TODO Auto-generated constructor stub
setupPayloads();
init();
}
PowerDownManager::~PowerDownManager()
{
}
} /* namespace controller */
/*
* All Banks are precharged and in Precharge-PowerDown after starting the system
*/
void PowerDownManager::init()
{
for (Bank bank : controller.state.bankStates.getBanks())
{
ScheduledCommand pdn(Command::PDNP, SC_ZERO_TIME, SC_ZERO_TIME,
DramExtension::getExtension(powerDownPayloads.at(bank.ID())));
controller.state.change(pdn);
controller.wrapper.send(pdn, powerDownPayloads.at(bank.ID()));
powerDownState = PowerDownState::PDNPrecharge;
}
}
void PowerDownManager::sleep(Bank bank, sc_time time)
{
canSleep.at(bank.ID()) = true;
if (powerDownState == PowerDownState::NoPowerDown)
{
if (count(canSleep.begin(), canSleep.end(), false) == 0)
{
if (controller.state.bankStates.allRowBuffersAreClosed())
{
powerDownState = PowerDownState::PDNPrecharge;
}
else
{
powerDownState = PowerDownState::PDNActive;
}
sendBegin(time);
}
}
else
{
if (bank == controller.state.getLastCommand(Command::AutoRefresh).getBank())
{
if (powerDownState == PowerDownState::PDNSelfRefresh)
return;
if (powerDownState == PowerDownState::PDNPrecharge)
{
powerDownState = PowerDownState::PDNSelfRefresh;
}
else
{
if (controller.state.bankStates.allRowBuffersAreClosed())
{
powerDownState = PowerDownState::PDNPrecharge;
}
else
{
powerDownState = PowerDownState::PDNActive;
}
}
sendBegin(time);
}
}
}
void PowerDownManager::wakeUp(Bank bank, sc_time time)
{
canSleep.at(bank.ID()) = false;
if (powerDownState != PowerDownState::NoPowerDown)
{
sendEnd(time);
}
powerDownState = PowerDownState::NoPowerDown;
}
void PowerDownManager::wakeUpForRefresh(Bank bank, sc_time time)
{
//canSleep.at(bank.ID()) = false;
if (powerDownState != PowerDownState::NoPowerDown)
{
sendEnd(time);
}
}
bool PowerDownManager::isInSelfRefresh(Bank bank)
{
return powerDownState == PowerDownState::PDNSelfRefresh;
}
bool PowerDownManager::isActive(Bank bank)
{
return powerDownState != PowerDownState::NoPowerDown;
}
void PowerDownManager::sendBegin(sc_time time)
{
Command cmd(Command::NOP);
switch (powerDownState)
{
case PowerDownState::PDNActive:
cmd = Command::PDNA;
break;
case PowerDownState::PDNPrecharge:
cmd = Command::PDNP;
break;
case PowerDownState::PDNSelfRefresh:
cmd = Command::SREF;
break;
}
sc_assert(cmd != Command::NOP);
//time = clkAlign(time, controller.config.Timings.clk);
ScheduledCommand pdn(cmd, time, SC_ZERO_TIME,
DramExtension::getExtension(powerDownPayloads.at(0)));
controller.state.bus.moveCommandToNextFreeSlot(pdn);
for (tlm::tlm_generic_payload& payload : powerDownPayloads)
{
ScheduledCommand pdnToSend(cmd, pdn.getStart(), SC_ZERO_TIME,
DramExtension::getExtension(payload));
controller.state.change(pdnToSend);
controller.wrapper.send(pdnToSend, payload);
}
}
void PowerDownManager::sendEnd(sc_time time)
{
Command cmd(Command::NOP);
switch (powerDownState)
{
case PowerDownState::PDNActive:
cmd = Command::PDNAX;
break;
case PowerDownState::PDNPrecharge:
cmd = Command::PDNPX;
break;
case PowerDownState::PDNSelfRefresh:
time += getDelayToMeetConstraint(
controller.state.getLastCommand(Command::SREF).getStart(), time,
controller.config.Timings.tCKESR);
cmd = Command::SREFX;
break;
}
sc_assert(cmd != Command::NOP);
time = clkAlign(time, controller.config.Timings.clk);
ScheduledCommand pdn(cmd, time, SC_ZERO_TIME,
DramExtension::getExtension(powerDownPayloads.at(0)));
controller.state.bus.moveCommandToNextFreeSlot(pdn);
for (tlm::tlm_generic_payload& payload : powerDownPayloads)
{
ScheduledCommand pdnToSend(cmd, pdn.getStart(), SC_ZERO_TIME,
DramExtension::getExtension(payload));
controller.state.change(pdnToSend);
controller.wrapper.send(pdnToSend, payload);
}
}
void PowerDownManager::setupPayloads()
{
for (Bank bank : controller.state.bankStates.getBanks())
{
tlm_generic_payload& payload = powerDownPayloads.at(bank.ID());
payload.set_address(getStartAddress(bank));
payload.set_command(tlm::TLM_READ_COMMAND);
payload.set_data_length(0);
payload.set_response_status(tlm::TLM_OK_RESPONSE);
payload.set_dmi_allowed(false);
payload.set_byte_enable_length(0);
payload.set_streaming_width(0);
payload.set_extension(new DramExtension(Thread(0), bank, Row(0), Column(0))); //payload takes ownership
}
}
} /* namespace core */