Staggered power-down working, adapt per-bank refresh.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user