PowerDown Manager and Bankwise PowerDown
This commit is contained in:
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user