...
This commit is contained in:
@@ -18,6 +18,8 @@
|
||||
#include "refresh/RefreshManager.h"
|
||||
#include "../../common/dramExtension.h"
|
||||
#include "../../common/Utils.h"
|
||||
#include "TimingCalculation.h"
|
||||
|
||||
#include "powerdown/PowerDownManager.h"
|
||||
#include "powerdown/PowerDownManagerTimeout.h"
|
||||
#include "powerdown/PowerDownManagerBankwise.h"
|
||||
@@ -28,164 +30,164 @@ namespace core {
|
||||
std::string ControllerCore::senderName = "Controller Core";
|
||||
|
||||
ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, std::map<Bank, int>& numberOfPayloads) :
|
||||
config(Configuration::getInstance()), state(&config), wrapper(wrapperConnector), commandChecker(), numberOfPayloads(
|
||||
numberOfPayloads), savedState(&config), commandSequenceGenerator(state), commandSequenceScheduler(*this)
|
||||
config(Configuration::getInstance()), state(&config), wrapper(wrapperConnector), commandChecker(), numberOfPayloads(
|
||||
numberOfPayloads), savedState(&config), commandSequenceGenerator(state), commandSequenceScheduler(*this)
|
||||
|
||||
{
|
||||
commandChecker[Command::Activate] = new ActivateChecker(config, state);
|
||||
commandChecker[Command::Precharge] = new PrechargeChecker(config, state);
|
||||
commandChecker[Command::PrechargeAll] = new PrechargeAllChecker(config, state);
|
||||
commandChecker[Command::Read] = new ReadChecker(config, state);
|
||||
commandChecker[Command::ReadA] = commandChecker[Command::Read];
|
||||
commandChecker[Command::Write] = new WriteChecker(config, state);
|
||||
commandChecker[Command::WriteA] = commandChecker[Command::Write];
|
||||
commandChecker[Command::Activate] = new ActivateChecker(config, state);
|
||||
commandChecker[Command::Precharge] = new PrechargeChecker(config, state);
|
||||
commandChecker[Command::PrechargeAll] = new PrechargeAllChecker(config, state);
|
||||
commandChecker[Command::Read] = new ReadChecker(config, state);
|
||||
commandChecker[Command::ReadA] = commandChecker[Command::Read];
|
||||
commandChecker[Command::Write] = new WriteChecker(config, state);
|
||||
commandChecker[Command::WriteA] = commandChecker[Command::Write];
|
||||
|
||||
commandChecker[Command::AutoRefresh] = new RefreshChecker(config, state);
|
||||
commandChecker[Command::PDNA] = new PowerDownChecker(config, state);
|
||||
commandChecker[Command::PDNP] = commandChecker[Command::PDNA];
|
||||
commandChecker[Command::SREF] = commandChecker[Command::PDNA];
|
||||
commandChecker[Command::PDNAX] = commandChecker[Command::PDNA];
|
||||
commandChecker[Command::PDNPX] = commandChecker[Command::PDNA];
|
||||
commandChecker[Command::SREFX] = commandChecker[Command::PDNA];
|
||||
commandChecker[Command::AutoRefresh] = new RefreshChecker(config, state);
|
||||
commandChecker[Command::PDNA] = new PowerDownChecker(config, state);
|
||||
commandChecker[Command::PDNP] = commandChecker[Command::PDNA];
|
||||
commandChecker[Command::SREF] = commandChecker[Command::PDNA];
|
||||
commandChecker[Command::PDNAX] = commandChecker[Command::PDNA];
|
||||
commandChecker[Command::PDNPX] = commandChecker[Command::PDNA];
|
||||
commandChecker[Command::SREFX] = commandChecker[Command::PDNA];
|
||||
|
||||
if (config.BankwiseLogic)
|
||||
{
|
||||
refreshManager = new RefreshManagerBankwise(*this);
|
||||
powerDownManager = new PowerDownManagerBankwise(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshManager = new RefreshManager(*this);
|
||||
if(config.powerDownMode == PowerDownMode::Staggered)
|
||||
{
|
||||
powerDownManager = new PowerDownManager(*this);
|
||||
}
|
||||
else // TimeoutPDN or TimeoutSREF
|
||||
{
|
||||
powerDownManager = new PowerDownManagerTimeout(*this);
|
||||
}
|
||||
}
|
||||
if (config.BankwiseLogic)
|
||||
{
|
||||
refreshManager = new RefreshManagerBankwise(*this);
|
||||
powerDownManager = new PowerDownManagerBankwise(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshManager = new RefreshManager(*this);
|
||||
if(config.powerDownMode == PowerDownMode::Staggered)
|
||||
{
|
||||
powerDownManager = new PowerDownManager(*this);
|
||||
}
|
||||
else // TimeoutPDN or TimeoutSREF
|
||||
{
|
||||
powerDownManager = new PowerDownManagerTimeout(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ControllerCore::~ControllerCore()
|
||||
{
|
||||
delete commandChecker[Command::Activate];
|
||||
delete commandChecker[Command::Precharge];
|
||||
delete commandChecker[Command::Read];
|
||||
delete commandChecker[Command::Write];
|
||||
delete commandChecker[Command::AutoRefresh];
|
||||
delete commandChecker[Command::PDNA];
|
||||
delete refreshManager;
|
||||
delete powerDownManager;
|
||||
delete commandChecker[Command::Activate];
|
||||
delete commandChecker[Command::Precharge];
|
||||
delete commandChecker[Command::Read];
|
||||
delete commandChecker[Command::Write];
|
||||
delete commandChecker[Command::AutoRefresh];
|
||||
delete commandChecker[Command::PDNA];
|
||||
delete refreshManager;
|
||||
delete powerDownManager;
|
||||
}
|
||||
|
||||
void ControllerCore::saveState()
|
||||
{
|
||||
savedState = state;
|
||||
savedState = state;
|
||||
}
|
||||
|
||||
void ControllerCore::resetState()
|
||||
{
|
||||
state = savedState;
|
||||
state = savedState;
|
||||
}
|
||||
|
||||
void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time)
|
||||
{
|
||||
Bank bank = DramExtension::getExtension(payload).getBank();
|
||||
printDebugMessage("Triggering refresh on bank " + to_string(bank.ID()));
|
||||
Bank bank = DramExtension::getExtension(payload).getBank();
|
||||
printDebugMessage("Triggering refresh on bank " + to_string(bank.ID()));
|
||||
|
||||
state.cleanUp(time);
|
||||
state.cleanUp(time);
|
||||
|
||||
if (!refreshManager->isInvalidated(payload, time) && !powerDownManager->isInSelfRefresh(bank))
|
||||
{
|
||||
powerDownManager->wakeUpForRefresh(bank, time); //expects PDNA and PDNP to exit without delay
|
||||
refreshManager->scheduleRefresh(payload, time);
|
||||
}
|
||||
if (!refreshManager->isInvalidated(payload, time) && !powerDownManager->isInSelfRefresh(bank))
|
||||
{
|
||||
powerDownManager->wakeUpForRefresh(bank, time); //expects PDNA and PDNP to exit without delay
|
||||
refreshManager->scheduleRefresh(payload, time);
|
||||
}
|
||||
}
|
||||
|
||||
bool ControllerCore::scheduleRequest(sc_time start, tlm::tlm_generic_payload& payload)
|
||||
{
|
||||
start = clkAlign(start);
|
||||
state.cleanUp(start);
|
||||
start = clkAlign(start);
|
||||
state.cleanUp(start);
|
||||
|
||||
saveState();
|
||||
saveState();
|
||||
|
||||
CommandSequence sequence = commandSequenceGenerator.generateCommandSequence(payload);
|
||||
CommandSchedule schedule = commandSequenceScheduler.schedule(sequence, start, payload);
|
||||
CommandSequence sequence = commandSequenceGenerator.generateCommandSequence(payload);
|
||||
CommandSchedule schedule = commandSequenceScheduler.schedule(sequence, start, payload);
|
||||
|
||||
if (refreshManager->hasCollision(schedule))
|
||||
{
|
||||
resetState();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
send(schedule, payload);
|
||||
return true;
|
||||
}
|
||||
if (refreshManager->hasCollision(schedule))
|
||||
{
|
||||
resetState();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
send(schedule, payload);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool ControllerCore::isBusy(sc_time time, Bank bank)
|
||||
{
|
||||
ScheduledCommand lastScheduledCommand = state.getLastScheduledCommand(bank);
|
||||
ScheduledCommand lastScheduledCommand = state.getLastScheduledCommand(bank);
|
||||
|
||||
if (lastScheduledCommand.isNoCommand())
|
||||
return false;
|
||||
else if (lastScheduledCommand.commandIsIn( { Command::Write, Command::Read }))
|
||||
{
|
||||
return (time < lastScheduledCommand.getStart());
|
||||
}
|
||||
else if (lastScheduledCommand.commandIsIn( { Command::WriteA, Command::ReadA }))
|
||||
{
|
||||
return (time < lastScheduledCommand.getEnd());
|
||||
}
|
||||
else if (lastScheduledCommand.getCommand() == Command::AutoRefresh)
|
||||
{
|
||||
return (time < lastScheduledCommand.getEnd());
|
||||
}
|
||||
else if (lastScheduledCommand.commandIsIn( { Command::SREFX, Command::PDNPX, Command::PDNAX, Command::SREF, Command::PDNP,
|
||||
Command::PDNA }))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("Core", "Last command in command sequence was activate or precharge. This really doesn't make sense :D.");
|
||||
return false;
|
||||
}
|
||||
if (lastScheduledCommand.isNoCommand())
|
||||
return false;
|
||||
else if (lastScheduledCommand.commandIsIn( { Command::Write, Command::Read }))
|
||||
{
|
||||
return (time < lastScheduledCommand.getStart());
|
||||
}
|
||||
else if (lastScheduledCommand.commandIsIn( { Command::WriteA, Command::ReadA }))
|
||||
{
|
||||
return (time < lastScheduledCommand.getEnd());
|
||||
}
|
||||
else if (lastScheduledCommand.getCommand() == Command::AutoRefresh)
|
||||
{
|
||||
return (time < lastScheduledCommand.getEnd());
|
||||
}
|
||||
else if (lastScheduledCommand.commandIsIn( { Command::SREFX, Command::PDNPX, Command::PDNAX, Command::SREF, Command::PDNP,
|
||||
Command::PDNA }))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("Core", "Last command in command sequence was activate or precharge. This really doesn't make sense :D.");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::vector<Bank>& ControllerCore::getBanks() const
|
||||
{
|
||||
static std::vector<Bank> banks;
|
||||
if (banks.size() == 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < config.NumberOfBanks; i++)
|
||||
{
|
||||
banks.push_back(Bank(i));
|
||||
}
|
||||
}
|
||||
static std::vector<Bank> banks;
|
||||
if (banks.size() == 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < config.NumberOfBanks; i++)
|
||||
{
|
||||
banks.push_back(Bank(i));
|
||||
}
|
||||
}
|
||||
|
||||
return banks;
|
||||
return banks;
|
||||
}
|
||||
|
||||
void ControllerCore::send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const
|
||||
{
|
||||
for (const ScheduledCommand& cmd : schedule.getScheduledCommands())
|
||||
{
|
||||
wrapper.send(cmd, payload);
|
||||
}
|
||||
for (const ScheduledCommand& cmd : schedule.getScheduledCommands())
|
||||
{
|
||||
wrapper.send(cmd, payload);
|
||||
}
|
||||
}
|
||||
|
||||
ICommandChecker& ControllerCore::getCommandChecker(Command command)
|
||||
{
|
||||
return *getElementFromMap(commandChecker, command);
|
||||
return *getElementFromMap(commandChecker, command);
|
||||
}
|
||||
|
||||
void ControllerCore::printDebugMessage(string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, message);
|
||||
DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, message);
|
||||
}
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
Reference in New Issue
Block a user