Improved and simplified version of PDM.

This commit is contained in:
Lukas Steiner
2020-04-02 22:31:08 +02:00
parent a5343a9da2
commit a57d91acd3
7 changed files with 72 additions and 59 deletions

View File

@@ -380,7 +380,7 @@ void Controller::finishBeginReq()
Rank rank = DramExtension::getRank(payloadToAcquire);
if (ranksNumberOfPayloads[rank.ID()] == 0)
powerDownManagers[rank.ID()]->triggerExit(TriggerSource::Controller);
powerDownManagers[rank.ID()]->triggerExit();
ranksNumberOfPayloads[rank.ID()]++;

View File

@@ -45,7 +45,8 @@ public:
PowerDownManagerDummy() {}
virtual void triggerEntry() override {}
virtual void triggerExit(TriggerSource) override {}
virtual void triggerExit() override {}
virtual void triggerInterruption() override {}
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
virtual void updateState(Command) override {}

View File

@@ -42,15 +42,14 @@
using namespace tlm;
enum class TriggerSource {Controller, RefreshManager};
class PowerDownManagerIF
{
public:
virtual ~PowerDownManagerIF() {}
virtual void triggerEntry() = 0;
virtual void triggerExit(TriggerSource) = 0;
virtual void triggerExit() = 0;
virtual void triggerInterruption() = 0;
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() = 0;
virtual void updateState(Command) = 0;

View File

@@ -43,34 +43,28 @@ PowerDownManagerStaggered::PowerDownManagerStaggered(Rank rank, CheckerIF *check
void PowerDownManagerStaggered::triggerEntry()
{
controllerIdle = true;
if (state == PdmState::Idle)
triggered = true;
entryTriggered = true;
}
void PowerDownManagerStaggered::triggerExit(TriggerSource source)
void PowerDownManagerStaggered::triggerExit()
{
if (source == TriggerSource::Controller)
{
controllerIdle = false;
enterSelfRefresh = false;
controllerIdle = false;
enterSelfRefresh = false;
entryTriggered = false;
if (state == PdmState::Idle)
triggered = false;
else
triggered = true;
}
else // if (source == TriggerSource::RefreshManager)
{
if (state == PdmState::Idle && !enterSelfRefresh)
triggered = false;
else if (state == PdmState::PrechargePd && !triggered)
{
triggered = true;
enterSelfRefresh = true;
}
else if (state == PdmState::ActivePd) // TODO: check if normal else is also ok here
triggered = true;
}
if (state != PdmState::Idle)
exitTriggered = true;
}
void PowerDownManagerStaggered::triggerInterruption()
{
entryTriggered = false;
if (state != PdmState::Idle)
exitTriggered = true;
}
std::pair<Command, tlm_generic_payload *> PowerDownManagerStaggered::getNextCommand()
@@ -85,28 +79,33 @@ sc_time PowerDownManagerStaggered::start()
{
timeToSchedule = sc_max_time();
if (triggered)
if (exitTriggered)
{
if (state == PdmState::Idle)
{
if (enterSelfRefresh)
nextCommand = Command::SREFEN;
else if (activatedBanks == 0)
nextCommand = Command::PDEP;
else
nextCommand = Command::PDEA;
}
else if (state == PdmState::ActivePd)
if (state == PdmState::ActivePdn)
nextCommand = Command::PDXA;
else if (state == PdmState::PrechargePd)
else if (state == PdmState::PrechargePdn)
nextCommand = Command::PDXP;
else if (state == PdmState::SelfRefresh)
nextCommand = Command::SREFEX;
else // if (state == PdmState::Refresh)
else if (state == PdmState::ExtraRefresh)
nextCommand = Command::REFA;
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
}
else if (entryTriggered)
{
if (activatedBanks != 0)
nextCommand = Command::PDEA;
else
nextCommand = Command::PDEP;
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
}
else if (enterSelfRefresh)
{
nextCommand = Command::SREFEN;
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
}
return timeToSchedule;
}
@@ -121,36 +120,48 @@ void PowerDownManagerStaggered::updateState(Command command)
activatedBanks = 0;
else if (command == Command::PDEA)
{
state = PdmState::ActivePd;
triggered = false;
state = PdmState::ActivePdn;
entryTriggered = false;
}
else if (command == Command::PDEP)
{
state = PdmState::PrechargePd;
triggered = false;
state = PdmState::PrechargePdn;
entryTriggered = false;
}
else if (command == Command::SREFEN)
{
state = PdmState::SelfRefresh;
triggered = false;
entryTriggered = false;
enterSelfRefresh = false;
}
else if (command == Command::PDXA)
{
state = PdmState::Idle;
triggered = false;
exitTriggered = false;
}
else if (command == Command::PDXP)
{
state = PdmState::Idle;
if (!enterSelfRefresh)
triggered = false;
exitTriggered = false;
if (controllerIdle)
enterSelfRefresh = true;
}
else if (command == Command::SREFEX)
state = PdmState::Refresh;
else if (command == Command::REFA && state == PdmState::Refresh)
state = PdmState::ExtraRefresh;
else if (command == Command::REFA)
{
state = PdmState::Idle;
triggered = false;
if (state == PdmState::ExtraRefresh)
{
state = PdmState::Idle;
exitTriggered = false;
}
else if (controllerIdle)
entryTriggered = true;
}
else if (command == Command::REFB)
{
if (controllerIdle)
entryTriggered = true;
}
}

View File

@@ -47,14 +47,15 @@ public:
PowerDownManagerStaggered(Rank, CheckerIF *);
virtual void triggerEntry() override;
virtual void triggerExit(TriggerSource) override;
virtual void triggerExit() override;
virtual void triggerInterruption() override;
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
virtual void updateState(Command) override;
virtual sc_time start() override;
private:
enum class PdmState {Idle, ActivePd, PrechargePd, SelfRefresh, Refresh} state = PdmState::Idle;
enum class PdmState {Idle, ActivePdn, PrechargePdn, SelfRefresh, ExtraRefresh} state = PdmState::Idle;
tlm_generic_payload powerDownPayload;
Rank rank;
CheckerIF *checker;
@@ -62,9 +63,10 @@ private:
sc_time timeToSchedule;
Command nextCommand;
bool triggered = true;
bool enterSelfRefresh = false;
bool controllerIdle = true;
bool entryTriggered = true;
bool exitTriggered = false;
bool enterSelfRefresh = false;
unsigned activatedBanks = 0;
};

View File

@@ -72,7 +72,7 @@ sc_time RefreshManagerBankwise::start()
if (sc_time_stamp() >= timeForNextTrigger)
{
powerDownManager->triggerExit(TriggerSource::RefreshManager);
powerDownManager->triggerInterruption();
if (sleeping)
return timeToSchedule;

View File

@@ -64,7 +64,7 @@ sc_time RefreshManagerRankwise::start()
if (sc_time_stamp() >= timeForNextTrigger)
{
powerDownManager->triggerExit(TriggerSource::RefreshManager);
powerDownManager->triggerInterruption();
if (sleeping)
return timeToSchedule;