Staggered power-down working, adapt per-bank refresh.

This commit is contained in:
Lukas Steiner
2019-11-22 01:01:08 +01:00
parent 7997648521
commit fa301d2bb4
6 changed files with 63 additions and 61 deletions

View File

@@ -170,6 +170,7 @@ Controller::Controller(sc_module_name name) :
{
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
{
// TODO: remove bankMachines in constructor
RefreshManagerIF *manager = new RefreshManagerBankwise
(bankMachinesOnRank[rankID], powerDownManagers[rankID], Rank(rankID), checker);
refreshManagers.push_back(manager);
@@ -357,7 +358,10 @@ tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &trans,
Rank rank = DramExtension::getRank(trans);
ranksNumberOfPayloads[rank.ID()]--;
if (ranksNumberOfPayloads[rank.ID()] == 0)
{
refreshManagers[rank.ID()]->messageIdle();
powerDownManagers[rank.ID()]->triggerEntry(TriggerSource::Controller);
}
}
return TLM_ACCEPTED;
@@ -396,7 +400,10 @@ void Controller::acquirePayload()
totalNumberOfPayloads++;
if(ranksNumberOfPayloads[rank.ID()] == 0)
{
refreshManagers[rank.ID()]->messageActive();
powerDownManagers[rank.ID()]->triggerExit(TriggerSource::Controller);
}
ranksNumberOfPayloads[rank.ID()]++;
scheduler->storeRequest(payloadToAcquire);

View File

@@ -52,6 +52,16 @@ RefreshManager::RefreshManager(std::vector<BankMachine *> &bankMachines,
maxPulledin = -config.ControllerCoreRefMaxPulledIn;
}
void RefreshManager::messageActive()
{
controllerIdle = false;
}
void RefreshManager::messageIdle()
{
controllerIdle = true;
}
std::pair<Command, tlm_generic_payload *> RefreshManager::getNextCommand()
{
if (sc_time_stamp() == timeToSchedule && !blocked)
@@ -80,65 +90,38 @@ sc_time RefreshManager::start()
if (state == RmState::Regular)
{
bool forcedRefresh = (flexibilityCounter == maxPostponed);
if (!forcedRefresh)
if (!forcedRefresh && !controllerIdle)
{
for (auto it : bankMachines)
{
if (!it->isIdle())
{
flexibilityCounter++;
timeForNextTrigger += memSpec->getRefreshIntervalAB();
return timeForNextTrigger - sc_time_stamp();
}
}
flexibilityCounter++;
timeForNextTrigger += memSpec->getRefreshIntervalAB();
return timeForNextTrigger - sc_time_stamp();
}
else // regular refresh that cannot be postponed -> force precharge
else
{
for (auto it : bankMachines)
it->block();
}
for (auto it : bankMachines)
{
if (it->getState() == BmState::Activated) // at least one bank is active -> do PREA
{
if (activatedBanks > 0)
nextCommand = Command::PREA;
delay = checker->delayToSatisfyConstraints(Command::PREA, rank, BankGroup(0), Bank(0));
timeToSchedule = sc_time_stamp() + delay;
return delay;
}
else
nextCommand = Command::REFA;
delay = checker->delayToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
timeToSchedule = sc_time_stamp() + delay;
return delay;
}
if (forcedRefresh) // if refresh is forced all banks will remain in precharged state
state = RmState::Precharged;
nextCommand = Command::REFA;
delay = checker->delayToSatisfyConstraints(Command::REFA, rank, BankGroup(0), Bank(0));
timeToSchedule = sc_time_stamp() + delay;
return delay;
}
else if (state == RmState::Pulledin)
else // if (state == RmState::Pulledin)
{
for (auto it : bankMachines)
if (!controllerIdle)
{
if (!it->isIdle()) // at least one bank has a payload -> abort pulling in
{
state = RmState::Regular;
timeForNextTrigger += memSpec->getRefreshIntervalAB();
return timeForNextTrigger - sc_time_stamp();
}
state = RmState::Regular;
timeForNextTrigger += memSpec->getRefreshIntervalAB();
return timeForNextTrigger - sc_time_stamp();
}
else
{
// nextCommand stays Command::REFA
delay = checker->delayToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
timeToSchedule = sc_time_stamp() + delay;
return delay;
}
delay = checker->delayToSatisfyConstraints(Command::REFA, rank, BankGroup(0), Bank(0));
timeToSchedule = sc_time_stamp() + delay;
return delay;
}
else // if (state == RmState::Precharged)
{
nextCommand = Command::REFA;
delay = checker->delayToSatisfyConstraints(Command::REFA, rank, BankGroup(0), Bank(0));
timeToSchedule = sc_time_stamp() + delay;
return delay;
}
}
else
@@ -147,8 +130,13 @@ sc_time RefreshManager::start()
void RefreshManager::updateState(Command command, tlm_generic_payload *)
{
// TODO: first ask if RAS command, otherwise ignore it
if (command == Command::REFA)
if (command == Command::ACT)
activatedBanks++;
else if (command == Command::PRE)
activatedBanks--;
else if (command == Command::PREA)
activatedBanks = 0;
else if (command == Command::REFA)
{
if (blocked)
{
@@ -172,14 +160,6 @@ void RefreshManager::updateState(Command command, tlm_generic_payload *)
}
}
}
else if (command == Command::PREA)
{
// if PREA was successful we will do the refresh in any case
for (auto it : bankMachines)
it->block();
// TODO: remove for and insert blocking directly into BM
state = RmState::Precharged;
}
else if (command == Command::PDEA || command == Command::PDEP)
blocked = true;
else if (command == Command::SREFEN)

View File

@@ -52,8 +52,11 @@ public:
virtual sc_time start() override;
virtual void updateState(Command, tlm_generic_payload *) override;
virtual void messageActive() override;
virtual void messageIdle() override;
private:
enum class RmState {Regular, Precharged, Pulledin} state = RmState::Regular;
enum class RmState {Regular, Pulledin} state = RmState::Regular;
const MemSpec *memSpec;
std::vector<BankMachine *> &bankMachines;
PowerDownManagerIF *powerDownManager;
@@ -64,6 +67,9 @@ private:
CheckerIF *checker;
Command nextCommand;
bool controllerIdle = true;
unsigned activatedBanks = 0;
int flexibilityCounter = 0;
int maxPostponed = 0;
int maxPulledin = 0;

View File

@@ -54,6 +54,9 @@ public:
virtual sc_time start() override;
virtual void updateState(Command, tlm_generic_payload *) override;
virtual void messageActive() override {}
virtual void messageIdle() override {}
private:
enum class RmState {Regular, Precharged, Pulledin} state = RmState::Regular;
const MemSpec *memSpec;

View File

@@ -49,6 +49,9 @@ public:
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() override;
virtual sc_time start() override;
virtual void updateState(Command, tlm_generic_payload *) override {}
virtual void messageActive() override {}
virtual void messageIdle() override {}
};
#endif // REFRESHMANAGERDUMMY_H

View File

@@ -50,6 +50,9 @@ public:
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() = 0;
virtual sc_time start() = 0;
virtual void updateState(Command, tlm_generic_payload *) = 0;
virtual void messageIdle() = 0;
virtual void messageActive() = 0;
};
#endif // REFRESHMANAGERIF_H