Updated structure of RefreshManager for bankwise refresh implementation.

This commit is contained in:
Lukas Steiner (2)
2019-08-13 11:39:15 +02:00
parent 38a099b8e8
commit 3b26997ea4
6 changed files with 45 additions and 68 deletions

View File

@@ -61,8 +61,8 @@ ControllerNew::ControllerNew(sc_module_name name) :
refreshManager = new RefreshManagerDummy();
else
{
refreshManager = new RefreshManager();
refreshEvent.notify(refreshManager->getInitialDelay());
refreshManager = new RefreshManager(bankMachines);
refreshEvent.notify(refreshManager->getTriggerDelay());
}
if (config.Scheduler == "FifoStrict")
{
@@ -128,22 +128,9 @@ void ControllerNew::controllerMethod()
std::pair<Command, tlm_generic_payload *> result;
// (5.1) Check for refresh command (PREA or REFA)
result = refreshManager->getNextCommand();
refreshEvent.notify(refreshManager->getTriggerDelay());
if (result.second != nullptr)
{
sc_time delay = refreshManager->updateState();
refreshEvent.notify(delay);
if (result.first == Command::PREA)
{
bool forcedPrecharges = false;
for (auto it : bankMachines)
forcedPrecharges |= it.second->forcePrecharge();
// Send the PREA only if at least one bank was precharged
if (forcedPrecharges)
sendToDram(result.first, result.second);
}
else
sendToDram(result.first, result.second);
}
sendToDram(result.first, result.second);
// (5.2) Check for other commands (PRE, ACT, RD or WR)
else
{
@@ -170,7 +157,7 @@ void ControllerNew::controllerMethod()
for (auto it : bankMachines)
{
sc_time delay = it.second->startBankMachine();
if (delay != SC_ZERO_TIME) // must be checked to avoid
if (delay != SC_ZERO_TIME) // must be checked to avoid livelock
bankMachineEvent.notify(delay);
}
}

View File

@@ -37,44 +37,44 @@
#include "../core/configuration/Configuration.h"
#include "../../common/utils.h"
RefreshManager::RefreshManager()
RefreshManager::RefreshManager(std::map<Bank, BankMachine *> &bankMachines) : bankMachines(bankMachines)
{
setUpDummy(refreshPayload);
memSpec = dynamic_cast<MemSpecDDR3 *>(Configuration::getInstance().memSpec);
if (memSpec == nullptr)
SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen");
timeForNextREFA = memSpec->tREFI;
timeForNextPREA = timeForNextREFA - memSpec->tRP;
timeForNextTrigger = memSpec->tREFI - memSpec->tRP;
}
std::pair<Command, tlm_generic_payload *> RefreshManager::getNextCommand()
{
if (sc_time_stamp() == timeForNextPREA)
return std::pair<Command, tlm_generic_payload *>(Command::PREA, &refreshPayload);
else if (sc_time_stamp() == timeForNextREFA)
return std::pair<Command, tlm_generic_payload *>(Command::REFA, &refreshPayload);
if (sc_time_stamp() == timeForNextTrigger)
{
if (state == RmState::IDLE)
{
state = RmState::REFRESHING;
timeForNextTrigger += memSpec->tRP;
bool forcedPrecharges = false;
for (auto it : bankMachines)
forcedPrecharges |= it.second->forcePrecharge();
if (forcedPrecharges)
return std::pair<Command, tlm_generic_payload *>(Command::PREA, &refreshPayload);
else
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
}
else
{
state = RmState::IDLE;
timeForNextTrigger += (memSpec->tREFI - memSpec->tRP);
return std::pair<Command, tlm_generic_payload *>(Command::REFA, &refreshPayload);
}
}
else
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
}
sc_time RefreshManager::updateState()
sc_time RefreshManager::getTriggerDelay()
{
if (state == RmState::IDLE)
{
state = RmState::REFRESHING;
timeForNextPREA += memSpec->tREFI;
return memSpec->tRP;
}
else
{
state = RmState::IDLE;
timeForNextREFA += memSpec->tREFI;
return (memSpec->tREFI - memSpec->tRP);
}
}
sc_time RefreshManager::getInitialDelay()
{
return timeForNextPREA;
return timeForNextTrigger - sc_time_stamp();
}

View File

@@ -41,33 +41,30 @@
#include "RefreshManagerIF.h"
#include "../Command.h"
#include "../core/configuration/MemSpec.h"
#include "../BankMachine.h"
using namespace tlm;
enum class RmState
{
IDLE,
REFRESHING
};
class RefreshManager final : public RefreshManagerIF
{
public:
RefreshManager();
RefreshManager(std::map<Bank, BankMachine *> &);
std::pair<Command, tlm_generic_payload *> getNextCommand();
sc_time updateState();
sc_time getInitialDelay();
sc_time getTriggerDelay();
private:
enum class RmState
{
IDLE,
REFRESHING
};
RmState state = RmState::IDLE;
const MemSpecDDR3 *memSpec;
std::map<Bank, BankMachine *> &bankMachines;
tlm_generic_payload refreshPayload;
sc_time timeForNextREFA;
sc_time timeForNextPREA;
sc_time timeForNextTrigger;
};
#endif // REFRESHMANAGER_H

View File

@@ -39,12 +39,7 @@ std::pair<Command, tlm_generic_payload *> RefreshManagerDummy::getNextCommand()
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
}
sc_time RefreshManagerDummy::updateState()
sc_time RefreshManagerDummy::getTriggerDelay()
{
return SC_ZERO_TIME;
}
sc_time RefreshManagerDummy::getInitialDelay()
{
return SC_ZERO_TIME;
return sc_max_time() - sc_time_stamp();
}

View File

@@ -47,8 +47,7 @@ class RefreshManagerDummy final : public RefreshManagerIF
{
public:
std::pair<Command, tlm_generic_payload *> getNextCommand();
sc_time updateState();
sc_time getInitialDelay();
sc_time getTriggerDelay();
};
#endif // REFRESHMANAGERDUMMY_H

View File

@@ -48,8 +48,7 @@ public:
virtual ~RefreshManagerIF() {}
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() = 0;
virtual sc_time updateState() = 0;
virtual sc_time getInitialDelay() = 0;
virtual sc_time getTriggerDelay() = 0;
};
#endif // REFRESHMANAGERIF_H