Updated structure of RefreshManager for bankwise refresh implementation.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user