Merge pull request #55 from fzeder/master
Issue#50 fixed and some improvements
This commit is contained in:
@@ -48,7 +48,7 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
TlmRecorder::TlmRecorder(string uri, string dbname, bool recenable) : sqlScriptURI(uri), dbName(dbname), senderName("TlmRecorder"), recordingEnabled(recenable), totalNumTransactions(1), simulationTimeCoveredByRecording(SC_ZERO_TIME)
|
||||
TlmRecorder::TlmRecorder(sc_module_name /*name*/, string uri, string dbname, bool recenable) : sqlScriptURI(uri), dbName(dbname), recordingEnabled(recenable), totalNumTransactions(1), simulationTimeCoveredByRecording(SC_ZERO_TIME)
|
||||
{
|
||||
if (TlmRecorder::recordingEnabled == true) {
|
||||
recordedData.reserve(transactionCommitRate);
|
||||
@@ -141,6 +141,8 @@ void TlmRecorder::introduceTransactionSystem(tlm::tlm_generic_payload& trans)
|
||||
else
|
||||
currentTransactionsInSystem[&trans].timeOfGeneration = GenerationExtension::getExtension(&trans).TimeOfGeneration();
|
||||
|
||||
printDebugMessage("New transaction #" + to_string(id) + " generation time " + currentTransactionsInSystem[&trans].timeOfGeneration.to_string());
|
||||
|
||||
if (id % transactionCommitRate == 0)
|
||||
{
|
||||
printDebugMessage(
|
||||
@@ -154,6 +156,8 @@ void TlmRecorder::removeTransactionFromSystem(tlm::tlm_generic_payload& trans)
|
||||
{
|
||||
assert(currentTransactionsInSystem.count(&trans) != 0);
|
||||
|
||||
printDebugMessage("Removing transaction #" + to_string(currentTransactionsInSystem[&trans].id));
|
||||
|
||||
Transaction& recordingData = currentTransactionsInSystem[&trans];
|
||||
recordedData.push_back(recordingData);
|
||||
currentTransactionsInSystem.erase(&trans);
|
||||
@@ -226,13 +230,21 @@ void TlmRecorder::createTables(string pathToURI)
|
||||
void TlmRecorder::setUpTransactionTerminatingPhases()
|
||||
{
|
||||
transactionTerminatingPhases.push_back(tlm::END_RESP);
|
||||
|
||||
// Refresh All
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm::tlm_phase>(END_REFA));
|
||||
|
||||
// Refresh Bank
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm::tlm_phase>(END_REFB));
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm::tlm_phase>(END_PDNP));
|
||||
|
||||
// Phases for Power Down
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm::tlm_phase>(END_PDNA));
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm::tlm_phase>(END_PDNP));
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm::tlm_phase>(END_SREF));
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm::tlm_phase>(END_PDNPB));
|
||||
|
||||
// Phases for Power Down Bankwise
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm::tlm_phase>(END_PDNAB));
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm::tlm_phase>(END_PDNPB));
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm::tlm_phase>(END_SREFB));
|
||||
}
|
||||
|
||||
@@ -348,7 +360,7 @@ void TlmRecorder::executeSqlCommand(string command)
|
||||
|
||||
void TlmRecorder::printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(TlmRecorder::senderName, message);
|
||||
DebugManager::getInstance().printDebugMessage(this->name(), message);
|
||||
}
|
||||
|
||||
void TlmRecorder::closeConnection()
|
||||
|
||||
@@ -55,14 +55,13 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
class TlmRecorder {
|
||||
class TlmRecorder : public sc_module {
|
||||
public:
|
||||
std::string sqlScriptURI;
|
||||
std::string dbName;
|
||||
std::string senderName;
|
||||
bool recordingEnabled;
|
||||
|
||||
TlmRecorder(string uri, string dbname, bool recenable);
|
||||
TlmRecorder(sc_module_name /*name*/, string uri, string dbname, bool recenable);
|
||||
~TlmRecorder();
|
||||
|
||||
void recordMemconfig(string memconfig){this->memconfig = memconfig;}
|
||||
|
||||
Submodule DRAMSys/simulator/src/common/third_party/icewrapper updated: 37cde24d8f...f252aff3b1
@@ -87,6 +87,10 @@ std::string commandToString(Command command)
|
||||
return "SREFX";
|
||||
break;
|
||||
|
||||
case Command::NOP:
|
||||
return "NOP";
|
||||
break;
|
||||
|
||||
default:
|
||||
SC_REPORT_FATAL("command", "commandToString was called with unknown command");
|
||||
break;
|
||||
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
Controller(sc_module_name /*name*/, TlmRecorder *rec) :
|
||||
frontendPEQ(this, &Controller<BUSWIDTH>::frontendPEQCallback), dramPEQ(this, &Controller<BUSWIDTH>::dramPEQCallback), controllerCorePEQ(this, &Controller<BUSWIDTH>::controllerCorePEQCallback), debugManager(DebugManager::getInstance()), tlmRecorder(rec)
|
||||
{
|
||||
controllerCore = new ControllerCore(*this, numberOfPayloadsInSystem);
|
||||
controllerCore = new ControllerCore("core", *this, numberOfPayloadsInSystem);
|
||||
buildScheduler();
|
||||
iSocket.register_nb_transport_bw(this, &Controller<BUSWIDTH>::nb_transport_bw);
|
||||
tSocket.register_nb_transport_fw(this, &Controller<BUSWIDTH>::nb_transport_fw);
|
||||
@@ -342,17 +342,27 @@ void Controller<BUSWIDTH>::controllerCorePEQCallback(tlm_generic_payload &payloa
|
||||
template<unsigned int BUSWIDTH>
|
||||
tlm_sync_enum Controller<BUSWIDTH>::nb_transport_fw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &fwDelay)
|
||||
{
|
||||
sc_time recTime;
|
||||
sc_time notDelay;
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
tlmRecorder->recordPhase(payload, phase, fwDelay + sc_time_stamp());
|
||||
frontendPEQ.notify(payload, phase,
|
||||
clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay) + Configuration::getInstance().memSpec.clk);
|
||||
recTime = fwDelay + sc_time_stamp();
|
||||
notDelay = clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay) + Configuration::getInstance().memSpec.clk;
|
||||
|
||||
printDebugMessage("[fw] Recording " + phaseNameToString(phase) + " at " + recTime.to_string() + " notification in " + notDelay.to_string());
|
||||
|
||||
tlmRecorder->recordPhase(payload, phase, recTime);
|
||||
frontendPEQ.notify(payload, phase, notDelay);
|
||||
}
|
||||
else if (phase == END_RESP)
|
||||
{
|
||||
tlmRecorder->recordPhase(payload, phase,
|
||||
fwDelay + sc_time_stamp() + Configuration::getInstance().memSpec.clk);
|
||||
frontendPEQ.notify(payload, phase, clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay));
|
||||
recTime = fwDelay + sc_time_stamp() + Configuration::getInstance().memSpec.clk;
|
||||
notDelay = clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay);
|
||||
|
||||
printDebugMessage("[fw] Recording " + phaseNameToString(phase) + " at " + recTime.to_string() + " notification in " + notDelay.to_string());
|
||||
|
||||
tlmRecorder->recordPhase(payload, phase, recTime);
|
||||
frontendPEQ.notify(payload, phase, notDelay);
|
||||
}
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
@@ -450,7 +460,7 @@ void Controller<BUSWIDTH>::scheduleNextFromScheduler(Bank bank)
|
||||
{
|
||||
controllerCore->powerDownManager->wakeUp(DramExtension::getExtension(nextRequest.second).getBank(), sc_time_stamp());
|
||||
controllerCore->scheduleRequest(nextRequest.first, *nextRequest.second);
|
||||
printDebugMessage("\t-> Next payload was scheduled by core");
|
||||
printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString(nextRequest.first) + "]");
|
||||
}
|
||||
|
||||
while (!blockedRequests.empty()) {
|
||||
@@ -461,7 +471,7 @@ void Controller<BUSWIDTH>::scheduleNextFromScheduler(Bank bank)
|
||||
if (nextRequest.second != NULL) {
|
||||
controllerCore->powerDownManager->wakeUp(DramExtension::getExtension(nextRequest.second).getBank(), sc_time_stamp());
|
||||
controllerCore->scheduleRequest(nextRequest.first, *nextRequest.second);
|
||||
printDebugMessage("\t-> Next payload was scheduled by core");
|
||||
printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString(nextRequest.first) + "] (unblocked)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,8 +488,14 @@ void Controller<BUSWIDTH>::sendToFrontend(tlm_generic_payload &payload, const tl
|
||||
template<unsigned int BUSWIDTH>
|
||||
tlm_sync_enum Controller<BUSWIDTH>::nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay)
|
||||
{
|
||||
dramPEQ.notify(payload, phase, bwDelay);
|
||||
tlmRecorder->recordPhase(payload, phase, bwDelay + sc_time_stamp());
|
||||
sc_time recTime = bwDelay + sc_time_stamp();
|
||||
sc_time notDelay = bwDelay;
|
||||
|
||||
printDebugMessage("[bw] Recording " + phaseNameToString(phase) + " at " + recTime.to_string() + " notification in " + notDelay.to_string());
|
||||
|
||||
dramPEQ.notify(payload, phase, notDelay);
|
||||
tlmRecorder->recordPhase(payload, phase, recTime);
|
||||
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,8 @@ const ScheduledCommand ControllerState::getLastScheduledCommand()
|
||||
}
|
||||
}
|
||||
|
||||
printDebugMessage("Last scheduled command was " + commandToString(lastCommand.getCommand()));
|
||||
|
||||
return lastCommand;
|
||||
}
|
||||
|
||||
@@ -87,6 +89,8 @@ const ScheduledCommand ControllerState::getLastScheduledCommand(Bank bank)
|
||||
lastCommand = current;
|
||||
}
|
||||
|
||||
printDebugMessage("Last scheduled command on bank " + to_string(bank.ID()) + " was " + commandToString(lastCommand.getCommand()));
|
||||
|
||||
return lastCommand;
|
||||
}
|
||||
|
||||
@@ -94,6 +98,7 @@ void ControllerState::change(const ScheduledCommand& scheduledCommand)
|
||||
{
|
||||
bus.blockSlot(scheduledCommand.getStart());
|
||||
|
||||
printDebugMessage("Changing state on bank " + to_string(scheduledCommand.getBank().ID()) + " command is " + commandToString(scheduledCommand.getCommand()));
|
||||
lastScheduledByCommandAndBank[scheduledCommand.getCommand()][scheduledCommand.getBank()] = scheduledCommand;
|
||||
|
||||
switch (scheduledCommand.getCommand())
|
||||
@@ -102,30 +107,30 @@ void ControllerState::change(const ScheduledCommand& scheduledCommand)
|
||||
lastDataStrobeCommands.emplace_back(scheduledCommand);
|
||||
break;
|
||||
case Command::ReadA:
|
||||
rowBufferStates.closeRowBuffer(scheduledCommand.getBank());
|
||||
rowBufferStates->closeRowBuffer(scheduledCommand.getBank());
|
||||
lastDataStrobeCommands.emplace_back(scheduledCommand);
|
||||
break;
|
||||
case Command::Write:
|
||||
lastDataStrobeCommands.emplace_back(scheduledCommand);
|
||||
break;
|
||||
case Command::WriteA:
|
||||
rowBufferStates.closeRowBuffer(scheduledCommand.getBank());
|
||||
rowBufferStates->closeRowBuffer(scheduledCommand.getBank());
|
||||
lastDataStrobeCommands.emplace_back(scheduledCommand);
|
||||
break;
|
||||
case Command::AutoRefresh:
|
||||
break;
|
||||
case Command::Activate:
|
||||
rowBufferStates.openRowInRowBuffer(scheduledCommand.getBank(), scheduledCommand.getRow());
|
||||
rowBufferStates->openRowInRowBuffer(scheduledCommand.getBank(), scheduledCommand.getRow());
|
||||
lastActivates.emplace(scheduledCommand.getStart(), scheduledCommand);
|
||||
break;
|
||||
case Command::Precharge:
|
||||
rowBufferStates.closeRowBuffer(scheduledCommand.getBank());
|
||||
rowBufferStates->closeRowBuffer(scheduledCommand.getBank());
|
||||
break;
|
||||
case Command::PrechargeAll:
|
||||
rowBufferStates.closeAllRowBuffers();
|
||||
rowBufferStates->closeAllRowBuffers();
|
||||
break;
|
||||
case Command::SREF:
|
||||
rowBufferStates.closeRowBuffer(scheduledCommand.getBank());
|
||||
rowBufferStates->closeRowBuffer(scheduledCommand.getBank());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -145,3 +150,9 @@ void ControllerState::cleanUp(sc_time time)
|
||||
if(time >= config->memSpec.tActHistory())
|
||||
lastActivates.erase(lastActivates.begin(), lastActivates.lower_bound(time - config->memSpec.tActHistory()));
|
||||
}
|
||||
|
||||
void ControllerState::printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(ownerName, message);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,13 +48,11 @@
|
||||
class ControllerState
|
||||
{
|
||||
public:
|
||||
ControllerState(Configuration* config) :
|
||||
rowBufferStates(), bus(config->memSpec.clk), config(config)
|
||||
{
|
||||
}
|
||||
virtual ~ControllerState()
|
||||
ControllerState(std::string ownerName, Configuration *config) : bus(config->memSpec.clk), ownerName(ownerName), config(config)
|
||||
{
|
||||
rowBufferStates = new RowBufferState(ownerName);
|
||||
}
|
||||
virtual ~ControllerState(){}
|
||||
|
||||
const ScheduledCommand getLastCommand(Command command, Bank bank);
|
||||
const ScheduledCommand getLastCommand(Command command);
|
||||
@@ -64,7 +62,7 @@ public:
|
||||
void change(const ScheduledCommand& scheduledCommand);
|
||||
void cleanUp(sc_time time);
|
||||
|
||||
RowBufferState rowBufferStates;
|
||||
RowBufferState *rowBufferStates;
|
||||
|
||||
//used by the various checkers
|
||||
std::map<Command, std::map<Bank, ScheduledCommand> > lastScheduledByCommandAndBank;
|
||||
@@ -77,8 +75,10 @@ public:
|
||||
std::map<sc_time, ScheduledCommand> lastActivates;
|
||||
|
||||
private:
|
||||
std::string ownerName;
|
||||
Configuration* config;
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
|
||||
#endif /* CONTROLLER_STATE_H_ */
|
||||
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
RowBufferState::RowBufferState()
|
||||
RowBufferState::RowBufferState(std::string ownerName) : ownerName(ownerName)
|
||||
{
|
||||
closeAllRowBuffers();
|
||||
closeAllRowBuffers();
|
||||
}
|
||||
|
||||
RowBufferState::~RowBufferState()
|
||||
@@ -62,13 +62,13 @@ Row RowBufferState::getRowInRowBuffer(Bank bank) const
|
||||
|
||||
void RowBufferState::openRowInRowBuffer(Bank bank,Row row)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, "Row buffer for bank " + to_string(bank.ID()) + " is now open");
|
||||
printDebugMessage("Row buffer for bank " + to_string(bank.ID()) + " is now open");
|
||||
rowsInRowBuffers[bank] = row;
|
||||
}
|
||||
|
||||
void RowBufferState::closeRowBuffer(Bank bank)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, "Row buffer for bank " + to_string(bank.ID()) + " is now closed");
|
||||
printDebugMessage("Row buffer for bank " + to_string(bank.ID()) + " is now closed");
|
||||
rowsInRowBuffers[bank] = Row::NO_ROW;
|
||||
}
|
||||
|
||||
@@ -90,4 +90,8 @@ void RowBufferState::closeAllRowBuffers()
|
||||
}
|
||||
}
|
||||
|
||||
void RowBufferState::printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(ownerName, message);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,12 +36,13 @@
|
||||
|
||||
#ifndef ROWBUFFERSTATES_H_
|
||||
#define ROWBUFFERSTATES_H_
|
||||
|
||||
#include <map>
|
||||
#include "../common/dramExtension.h"
|
||||
|
||||
class RowBufferState {
|
||||
public:
|
||||
RowBufferState();
|
||||
RowBufferState(std::string ownerName);
|
||||
virtual ~RowBufferState();
|
||||
|
||||
bool rowBufferIsOpen(Bank bank) const;
|
||||
@@ -53,7 +54,10 @@ public:
|
||||
void closeAllRowBuffers();
|
||||
|
||||
private:
|
||||
std::string ownerName;
|
||||
std::map<Bank,Row> rowsInRowBuffers;
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
#endif /* BANKSTATES_H_ */
|
||||
|
||||
|
||||
@@ -55,25 +55,21 @@
|
||||
#include "powerdown/NoPowerDown.h"
|
||||
#include "../../common/DebugManager.h"
|
||||
|
||||
|
||||
|
||||
std::string ControllerCore::senderName = "Controller Core";
|
||||
|
||||
ControllerCore::ControllerCore(IController& wrapperConnector, std::map<Bank, int>& numberOfPayloads) :
|
||||
config(Configuration::getInstance()), state(&config), controller(wrapperConnector), numberOfPayloads(
|
||||
numberOfPayloads), commandChecker()
|
||||
|
||||
ControllerCore::ControllerCore(sc_module_name /*name*/, IController& wrapperConnector, std::map<Bank, int>& numberOfPayloads) :
|
||||
config(Configuration::getInstance()), controller(wrapperConnector), numberOfPayloads(numberOfPayloads), commandChecker()
|
||||
{
|
||||
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);
|
||||
state = new ControllerState(name(), &config);
|
||||
|
||||
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::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::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];
|
||||
@@ -82,20 +78,20 @@ ControllerCore::ControllerCore(IController& wrapperConnector, std::map<Bank, int
|
||||
|
||||
if (config.BankwiseLogic)
|
||||
{
|
||||
refreshManager = new RefreshManagerBankwise(*this);
|
||||
powerDownManager = new PowerDownManagerBankwise(*this);
|
||||
refreshManager = new RefreshManagerBankwise("refManagerBw", *this);
|
||||
powerDownManager = new PowerDownManagerBankwise("pdnManagerBw", *this);
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshManager = new RefreshManager(*this);
|
||||
refreshManager = new RefreshManager("refManager", *this);
|
||||
|
||||
if(config.PowerDownMode == EPowerDownMode::Staggered)
|
||||
{
|
||||
powerDownManager = new PowerDownManager(*this);
|
||||
powerDownManager = new PowerDownManager("pdnManager", *this);
|
||||
}
|
||||
else if(config.PowerDownMode == EPowerDownMode::TimeoutPDN || config.PowerDownMode == EPowerDownMode::TimeoutSREF)
|
||||
{
|
||||
powerDownManager = new PowerDownManagerTimeout(*this);
|
||||
powerDownManager = new PowerDownManagerTimeout("pdnManagerTout", *this);
|
||||
}
|
||||
else if(config.PowerDownMode == EPowerDownMode::NoPowerDown)
|
||||
{
|
||||
@@ -119,6 +115,7 @@ ControllerCore::~ControllerCore()
|
||||
delete commandChecker[Command::PDNA];
|
||||
delete refreshManager;
|
||||
delete powerDownManager;
|
||||
delete state;
|
||||
}
|
||||
|
||||
void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload)
|
||||
@@ -128,7 +125,7 @@ void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload)
|
||||
sc_time time = sc_time_stamp();
|
||||
Bank bank = DramExtension::getExtension(payload).getBank();
|
||||
|
||||
state.cleanUp(time);
|
||||
state->cleanUp(time);
|
||||
|
||||
if (!refreshManager->isInvalidated(payload, time) && !powerDownManager->isInSelfRefresh(bank))
|
||||
{
|
||||
@@ -142,10 +139,10 @@ void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload)
|
||||
void ControllerCore::scheduleRequest(Command command, tlm::tlm_generic_payload &payload)
|
||||
{
|
||||
sc_time start = clkAlign(sc_time_stamp());
|
||||
state.cleanUp(start);
|
||||
state->cleanUp(start);
|
||||
|
||||
ScheduledCommand scheduledCommand = schedule(command, start, payload);
|
||||
state.change(scheduledCommand);
|
||||
state->change(scheduledCommand);
|
||||
controller.send(scheduledCommand, payload);
|
||||
}
|
||||
|
||||
@@ -164,7 +161,7 @@ ScheduledCommand ControllerCore::schedule(Command command, sc_time start,
|
||||
bool ControllerCore::bankIsBusy(Bank bank)
|
||||
{
|
||||
sc_time time = sc_time_stamp();
|
||||
ScheduledCommand lastScheduledCommand = state.getLastScheduledCommand(bank);
|
||||
ScheduledCommand lastScheduledCommand = state->getLastScheduledCommand(bank);
|
||||
|
||||
if (lastScheduledCommand.isNoCommand())
|
||||
return false;
|
||||
@@ -227,6 +224,6 @@ ICommandChecker& ControllerCore::getCommandChecker(Command command)
|
||||
|
||||
void ControllerCore::printDebugMessage(string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, message);
|
||||
DebugManager::getInstance().printDebugMessage(this->name(), message);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,10 +51,10 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
class ControllerCore
|
||||
class ControllerCore : public sc_module
|
||||
{
|
||||
public:
|
||||
ControllerCore(IController& controller, std::map<Bank, int>& numberOfPayloads);
|
||||
ControllerCore(sc_module_name /*name*/, IController& controller, std::map<Bank, int>& numberOfPayloads);
|
||||
virtual ~ControllerCore() ;
|
||||
|
||||
void scheduleRequest(Command command, tlm::tlm_generic_payload& payload);
|
||||
@@ -62,23 +62,23 @@ public:
|
||||
|
||||
const std::vector<Bank>& getBanks();
|
||||
std::vector<Bank> getFreeBanks();
|
||||
const RowBufferState& getRowBufferStates(){return state.rowBufferStates;}
|
||||
const RowBufferState& getRowBufferStates(){return *(state->rowBufferStates);}
|
||||
bool bankIsBusy(Bank bank);
|
||||
|
||||
ICommandChecker& getCommandChecker(Command command); static void printDebugMessage(string message);
|
||||
ICommandChecker& getCommandChecker(Command command);
|
||||
|
||||
Configuration config;
|
||||
ControllerState state;
|
||||
ControllerState *state;
|
||||
IController& controller;
|
||||
IPowerDownManager* powerDownManager;
|
||||
IRefreshManager* refreshManager;
|
||||
std::map<Bank,int>& numberOfPayloads;
|
||||
static std::string senderName;
|
||||
|
||||
private:
|
||||
|
||||
ScheduledCommand schedule(Command command, sc_time start, tlm::tlm_generic_payload &payload);
|
||||
std::map<Command, ICommandChecker*> commandChecker;
|
||||
void printDebugMessage(string message);
|
||||
};
|
||||
|
||||
#endif /* CONTROLLER_H_ */
|
||||
|
||||
@@ -81,10 +81,8 @@ void Slots::blockSlots(sc_time begin, sc_time end, bool excludeBorders)
|
||||
end -= clk;
|
||||
}
|
||||
|
||||
for (sc_time time = begin; time <= end; time += clk)
|
||||
{
|
||||
slotSet.insert(time);
|
||||
for (sc_time time = begin; time <= end; time += clk) {
|
||||
blockSlot(time);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -46,15 +46,16 @@ class Slots
|
||||
public:
|
||||
Slots(sc_time clk);
|
||||
virtual ~Slots();
|
||||
|
||||
void moveCommandToNextFreeSlot(ScheduledCommand& command);
|
||||
void cleanUpSlots(sc_time time);
|
||||
void blockSlots(sc_time begin, sc_time end, bool excludeBorders);
|
||||
void blockSlot(sc_time time);
|
||||
bool isFree(sc_time);
|
||||
std::set<sc_time> slotSet;
|
||||
|
||||
private:
|
||||
sc_time clk;
|
||||
std::set<sc_time> slotSet;
|
||||
void blockSlots(sc_time begin, sc_time end, bool excludeBorders);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ const sc_time clkAlign(sc_time time, Alignment alignment)
|
||||
return floor(time / clk) * clk;
|
||||
}
|
||||
|
||||
// Returns the execution time for commands that have a fixed execution time
|
||||
sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload)
|
||||
{
|
||||
MemSpec& config = Configuration::getInstance().memSpec;
|
||||
@@ -101,7 +102,6 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload)
|
||||
{
|
||||
return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC;
|
||||
}
|
||||
|
||||
else if (command == Command::PDNAX || command == Command::PDNPX || command == Command::SREFX)
|
||||
{
|
||||
return config.clk;
|
||||
@@ -113,6 +113,7 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the minimum execution time for commands that have a variable execution time
|
||||
sc_time getMinExecutionTimeForPowerDownCmd(Command command)
|
||||
{
|
||||
MemSpec& config = Configuration::getInstance().memSpec;
|
||||
|
||||
@@ -82,6 +82,7 @@ inline Command IPowerDownManager::getSleepCommand(PowerDownState state)
|
||||
break;
|
||||
default:
|
||||
SC_REPORT_FATAL("In PowerDownManager sendPowerdownBegin", "invalid powerDownState");
|
||||
break;
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ using namespace tlm;
|
||||
using namespace std;
|
||||
|
||||
|
||||
PowerDownManager::PowerDownManager(ControllerCore& controller) :
|
||||
PowerDownManager::PowerDownManager(sc_module_name /*name*/, ControllerCore& controller) :
|
||||
controllerCore(controller)
|
||||
{
|
||||
powerDownState = PowerDownState::Awake;
|
||||
@@ -71,14 +71,14 @@ void PowerDownManager::sleep(Bank bank, sc_time time)
|
||||
|
||||
if (state == PowerDownState::Awake) //coming from active
|
||||
{
|
||||
state = controllerCore.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive;
|
||||
state = controllerCore.state->rowBufferStates->allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive;
|
||||
}
|
||||
else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down
|
||||
{
|
||||
sc_assert(controllerCore.state.rowBufferStates.allRowBuffersAreClosed());
|
||||
sc_assert(controllerCore.state->rowBufferStates->allRowBuffersAreClosed());
|
||||
|
||||
if (controllerCore.state.getLastCommand(Command::PDNA).getStart()
|
||||
>= controllerCore.state.getLastCommand(Command::PDNP).getStart())
|
||||
if (controllerCore.state->getLastCommand(Command::PDNA).getStart()
|
||||
>= controllerCore.state->getLastCommand(Command::PDNP).getStart())
|
||||
state = PowerDownState::PDNPrecharge;
|
||||
else
|
||||
{
|
||||
@@ -105,6 +105,8 @@ void PowerDownManager::sleep(Bank bank, sc_time time)
|
||||
|
||||
void PowerDownManager::wakeUp(Bank bank, sc_time time)
|
||||
{
|
||||
printDebugMessage("Waking up at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState));
|
||||
|
||||
if (isAwakeForRefresh()) //Request enters system during Refresh
|
||||
{
|
||||
setPowerDownState(PowerDownState::Awake);
|
||||
@@ -116,16 +118,25 @@ void PowerDownManager::wakeUp(Bank bank, sc_time time)
|
||||
DramExtension::getExtension(powerDownPayloads[bank]));
|
||||
controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn);
|
||||
|
||||
if (cmd == Command::SREFX)
|
||||
if (cmd == Command::SREFX) {
|
||||
// Leaving Self Refresh. Plan the next refresh.
|
||||
controllerCore.refreshManager->reInitialize(bank, pdn.getEnd());
|
||||
printDebugMessage("Waking up. Leaving Self Refresh at " + time.to_string() + " next refresh planned to " + pdn.getEnd().to_string());
|
||||
}
|
||||
|
||||
setPowerDownState(PowerDownState::Awake);
|
||||
|
||||
printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks");
|
||||
sendPowerDownPayloads(pdn);
|
||||
}
|
||||
|
||||
printDebugMessage("Awaken at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState));
|
||||
}
|
||||
|
||||
void PowerDownManager::wakeUpForRefresh(Bank bank, sc_time time)
|
||||
{
|
||||
printDebugMessage("Waking up for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState));
|
||||
|
||||
if (isInPowerDown())
|
||||
{
|
||||
Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState);
|
||||
@@ -133,20 +144,24 @@ void PowerDownManager::wakeUpForRefresh(Bank bank, sc_time time)
|
||||
DramExtension::getExtension(powerDownPayloads[bank]));
|
||||
|
||||
setPowerDownState(PowerDownState::AwakeForRefresh);
|
||||
|
||||
printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks");
|
||||
sendPowerDownPayloads(pdn);
|
||||
}
|
||||
|
||||
printDebugMessage("Awaken for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState));
|
||||
}
|
||||
|
||||
void PowerDownManager::sendPowerDownPayloads(ScheduledCommand& cmd)
|
||||
{
|
||||
controllerCore.state.bus.moveCommandToNextFreeSlot(cmd);
|
||||
controllerCore.state->bus.moveCommandToNextFreeSlot(cmd);
|
||||
for (Bank bank : controllerCore.getBanks())
|
||||
{
|
||||
tlm_generic_payload& payloadToSend = powerDownPayloads[bank];
|
||||
|
||||
ScheduledCommand pdnToSend(cmd.getCommand(), cmd.getStart(), cmd.getExecutionTime(),
|
||||
DramExtension::getExtension(payloadToSend));
|
||||
controllerCore.state.change(pdnToSend);
|
||||
ScheduledCommand pdnToSend(cmd.getCommand(), cmd.getStart(), cmd.getExecutionTime(), DramExtension::getExtension(payloadToSend));
|
||||
controllerCore.state->change(pdnToSend);
|
||||
printDebugMessage("Sending power down command " + commandToString(pdnToSend.getCommand()) + " on bank " + to_string(pdnToSend.getBank().ID()) + " start time " + pdnToSend.getStart().to_string() + " end time " + pdnToSend.getEnd().to_string());
|
||||
controllerCore.controller.send(pdnToSend, payloadToSend);
|
||||
}
|
||||
}
|
||||
@@ -154,8 +169,7 @@ void PowerDownManager::sendPowerDownPayloads(ScheduledCommand& cmd)
|
||||
void PowerDownManager::setPowerDownState(PowerDownState state)
|
||||
{
|
||||
powerDownState = state;
|
||||
DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName,
|
||||
"Is now in state " + powerDownStateToString(powerDownState) + " on all banks");
|
||||
printDebugMessage("Is now in state " + powerDownStateToString(powerDownState) + " on all banks");
|
||||
}
|
||||
|
||||
bool PowerDownManager::isInPowerDown()
|
||||
@@ -189,5 +203,8 @@ void PowerDownManager::triggerSleep(Bank bank, sc_time time)
|
||||
sleep(bank, time);
|
||||
}
|
||||
|
||||
|
||||
void PowerDownManager::printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(this->name(), message);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@
|
||||
|
||||
class ControllerCore;
|
||||
|
||||
class PowerDownManager: public IPowerDownManager
|
||||
class PowerDownManager: public IPowerDownManager, public sc_module
|
||||
{
|
||||
public:
|
||||
PowerDownManager(ControllerCore& controllerCore);
|
||||
PowerDownManager(sc_module_name /*name*/, ControllerCore& controllerCore);
|
||||
virtual ~PowerDownManager();
|
||||
|
||||
virtual void triggerSleep(Bank bank, sc_time time) override;
|
||||
@@ -64,6 +64,7 @@ private:
|
||||
PowerDownState powerDownState;
|
||||
std::map<Bank, tlm::tlm_generic_payload> powerDownPayloads;
|
||||
ControllerCore& controllerCore;
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -42,11 +42,7 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
|
||||
std::string PowerDownManagerBankwise::senderName = "pdn manager";
|
||||
|
||||
PowerDownManagerBankwise::PowerDownManagerBankwise(ControllerCore& controller) :
|
||||
controllerCore(controller)
|
||||
PowerDownManagerBankwise::PowerDownManagerBankwise(sc_module_name /*name*/, ControllerCore& controller) : controllerCore(controller)
|
||||
{
|
||||
for (Bank bank : controller.getBanks())
|
||||
{
|
||||
@@ -65,14 +61,14 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time)
|
||||
PowerDownState state = powerDownStates[bank];
|
||||
if (state == PowerDownState::Awake) //coming from active
|
||||
{
|
||||
state = controllerCore.state.rowBufferStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge;
|
||||
state = controllerCore.state->rowBufferStates->rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge;
|
||||
}
|
||||
else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down
|
||||
{
|
||||
sc_assert(!controllerCore.state.rowBufferStates.rowBufferIsOpen(bank));
|
||||
sc_assert(!controllerCore.state->rowBufferStates->rowBufferIsOpen(bank));
|
||||
|
||||
if (controllerCore.state.getLastCommand(Command::PDNA, bank).getStart()
|
||||
>= controllerCore.state.getLastCommand(Command::PDNP, bank).getStart())
|
||||
if (controllerCore.state->getLastCommand(Command::PDNA, bank).getStart()
|
||||
>= controllerCore.state->getLastCommand(Command::PDNP, bank).getStart())
|
||||
state = PowerDownState::PDNPrecharge;
|
||||
else
|
||||
{
|
||||
@@ -97,43 +93,58 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time)
|
||||
|
||||
void PowerDownManagerBankwise::wakeUp(Bank bank, sc_time time)
|
||||
{
|
||||
if (isAwakeForRefresh(bank))
|
||||
{
|
||||
setState(PowerDownState::Awake, bank);
|
||||
}
|
||||
else if (isInPowerDown(bank))
|
||||
{
|
||||
//Request wakes up power down
|
||||
Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]);
|
||||
ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]),
|
||||
DramExtension::getExtension(powerDownPayloads[bank]));
|
||||
controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn);
|
||||
printDebugMessage("Waking up on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank]));
|
||||
|
||||
if (cmd == Command::SREFX)
|
||||
controllerCore.refreshManager->reInitialize(bank, pdn.getEnd());
|
||||
if (isAwakeForRefresh(bank)) {
|
||||
printDebugMessage("It was already awake for refresh on bank " + to_string(bank.ID()) + " at " + time.to_string());
|
||||
setState(PowerDownState::Awake, bank);
|
||||
} else if (isInPowerDown(bank)) {
|
||||
// Request wake up from power down. A Power Down Exit request will be generated (PDNAX, PDNPX, SREFX).
|
||||
Command pdnExitCmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]);
|
||||
// Mount the command to be scheduled
|
||||
ScheduledCommand pdnExit(pdnExitCmd, time, getExecutionTime(pdnExitCmd, powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank]));
|
||||
// Ensure that time constraints are respected
|
||||
controllerCore.getCommandChecker(pdnExitCmd).delayToSatisfyConstraints(pdnExit);
|
||||
|
||||
setState(PowerDownState::Awake, bank);
|
||||
sendPowerDownPayload(pdn);
|
||||
}
|
||||
if (pdnExitCmd == Command::SREFX) {
|
||||
// Leaving Self Refresh. Plan the next refresh.
|
||||
controllerCore.refreshManager->reInitialize(bank, pdnExit.getEnd());
|
||||
printDebugMessage("Waking up. Leaving Self Refresh on Bank " + to_string(bank.ID()) + " at " + time.to_string() + " next refresh planned to " + pdnExit.getEnd().to_string());
|
||||
}
|
||||
|
||||
setState(PowerDownState::Awake, bank);
|
||||
|
||||
printDebugMessage("Sending power down exit command " + commandToString(pdnExitCmd) + " on bank " + to_string(bank.ID()) + " at " + time.to_string() + " start time " + pdnExit.getStart().to_string() + " end time " + pdnExit.getEnd().to_string());
|
||||
sendPowerDownPayload(pdnExit);
|
||||
}
|
||||
|
||||
printDebugMessage("Awaken on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank]));
|
||||
}
|
||||
|
||||
void PowerDownManagerBankwise::wakeUpForRefresh(Bank bank, sc_time time)
|
||||
{
|
||||
if (isInPowerDown(bank))
|
||||
{
|
||||
Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]);
|
||||
ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]),
|
||||
DramExtension::getExtension(powerDownPayloads[bank]));
|
||||
printDebugMessage("Waking up for refresh on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank]));
|
||||
|
||||
setState(PowerDownState::AwakeForRefresh, bank);
|
||||
sendPowerDownPayload(pdn);
|
||||
}
|
||||
if (isInPowerDown(bank)) {
|
||||
// A Power Down Exit request will be generated (PDNAX, PDNPX, SREFX).
|
||||
Command pdnExitCmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]);
|
||||
// Get the execution time for this request
|
||||
sc_time executionTime = getExecutionTime(pdnExitCmd, powerDownPayloads[bank]);
|
||||
// Mount the command to be scheduled
|
||||
ScheduledCommand pdnExit(pdnExitCmd, time, executionTime, DramExtension::getExtension(powerDownPayloads[bank]));
|
||||
|
||||
setState(PowerDownState::AwakeForRefresh, bank);
|
||||
|
||||
printDebugMessage("Sending power down exit command " + commandToString(pdnExitCmd) + " on bank " + to_string(bank.ID()) + " at " + time.to_string() + " start time " + pdnExit.getStart().to_string() + " end time " + pdnExit.getEnd().to_string());
|
||||
sendPowerDownPayload(pdnExit);
|
||||
}
|
||||
|
||||
printDebugMessage("Awaken for refresh on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank]));
|
||||
}
|
||||
|
||||
bool PowerDownManagerBankwise::isInPowerDown(Bank bank)
|
||||
{
|
||||
return isIn(powerDownStates[bank],
|
||||
{ PowerDownState::PDNActive, PowerDownState::PDNPrecharge, PowerDownState::PDNSelfRefresh });
|
||||
return isIn(powerDownStates[bank], { PowerDownState::PDNActive, PowerDownState::PDNPrecharge, PowerDownState::PDNSelfRefresh });
|
||||
}
|
||||
|
||||
bool PowerDownManagerBankwise::isInSelfRefresh(Bank bank)
|
||||
@@ -153,18 +164,17 @@ bool PowerDownManagerBankwise::isAwake(Bank bank)
|
||||
|
||||
void PowerDownManagerBankwise::setState(PowerDownState state, Bank bank)
|
||||
{
|
||||
PowerDownState& bankstate = powerDownStates[bank];
|
||||
bankstate = state;
|
||||
|
||||
DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName,
|
||||
"Is now in state " + powerDownStateToString(state) + " on Bank " + to_string(bank.ID()));
|
||||
PowerDownState& bankstate = powerDownStates[bank];
|
||||
bankstate = state;
|
||||
printDebugMessage("Is now in state " + powerDownStateToString(state) + " on Bank " + to_string(bank.ID()));
|
||||
}
|
||||
|
||||
void PowerDownManagerBankwise::sendPowerDownPayload(ScheduledCommand& pdn)
|
||||
void PowerDownManagerBankwise::sendPowerDownPayload(ScheduledCommand &pdn)
|
||||
{
|
||||
controllerCore.state.bus.moveCommandToNextFreeSlot(pdn);
|
||||
controllerCore.state.change(pdn);
|
||||
controllerCore.controller.send(pdn, powerDownPayloads[pdn.getBank()]);
|
||||
controllerCore.state->bus.moveCommandToNextFreeSlot(pdn);
|
||||
controllerCore.state->change(pdn);
|
||||
printDebugMessage("Sending power down command " + commandToString(pdn.getCommand()) + " on bank " + to_string(pdn.getBank().ID()) + " start time " + pdn.getStart().to_string() + " end time " + pdn.getEnd().to_string());
|
||||
controllerCore.controller.send(pdn, powerDownPayloads[pdn.getBank()]);
|
||||
}
|
||||
|
||||
bool PowerDownManagerBankwise::canSleep(Bank bank)
|
||||
@@ -177,5 +187,8 @@ void PowerDownManagerBankwise::triggerSleep(Bank bank, sc_time time)
|
||||
sleep(bank, time);
|
||||
}
|
||||
|
||||
|
||||
void PowerDownManagerBankwise::printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(this->name(), message);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,27 +49,23 @@
|
||||
|
||||
class ControllerCore;
|
||||
|
||||
class PowerDownManagerBankwise: public IPowerDownManager
|
||||
class PowerDownManagerBankwise : public sc_module, public IPowerDownManager
|
||||
{
|
||||
public:
|
||||
PowerDownManagerBankwise(ControllerCore& controllerCore);
|
||||
virtual ~PowerDownManagerBankwise()
|
||||
{
|
||||
}
|
||||
PowerDownManagerBankwise(sc_module_name /*name*/, ControllerCore& controllerCore);
|
||||
virtual ~PowerDownManagerBankwise(){}
|
||||
virtual void triggerSleep(Bank bank, sc_time time) override;
|
||||
virtual void sleep(Bank bank, sc_time time) override;
|
||||
virtual void wakeUp(Bank bank, sc_time time) override;
|
||||
virtual void wakeUpForRefresh(Bank bank, sc_time time) override;
|
||||
virtual bool isInSelfRefresh(Bank bank) override;
|
||||
|
||||
static std::string senderName;
|
||||
|
||||
private:
|
||||
virtual bool isInPowerDown(Bank bank);
|
||||
virtual bool isAwake(Bank bank);
|
||||
virtual bool isAwakeForRefresh(Bank bank);
|
||||
|
||||
ControllerCore& controllerCore;
|
||||
ControllerCore &controllerCore;
|
||||
std::map<Bank, tlm::tlm_generic_payload> powerDownPayloads;
|
||||
std::map<Bank, PowerDownState> powerDownStates;
|
||||
|
||||
@@ -80,8 +76,10 @@ private:
|
||||
Command getWakeUpCommand(PowerDownState state);
|
||||
Command getSleepCommand(PowerDownState state);
|
||||
|
||||
void sendPowerDownPayload(ScheduledCommand& pdn);
|
||||
void sendPowerDownPayload(ScheduledCommand &pdn);
|
||||
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
|
||||
#endif /* POWERDOWNMANAGERBANKWISE_H_ */
|
||||
|
||||
|
||||
@@ -44,8 +44,9 @@
|
||||
using namespace tlm;
|
||||
|
||||
|
||||
PowerDownManagerTimeout::PowerDownManagerTimeout(ControllerCore& controller): controllerCore(controller)
|
||||
PowerDownManagerTimeout::PowerDownManagerTimeout(sc_module_name /*name*/, ControllerCore& controller): controllerCore(controller)
|
||||
{
|
||||
powerDownState = PowerDownState::Awake;
|
||||
for (Bank bank : controller.getBanks())
|
||||
{
|
||||
setUpDummy(powerDownPayloads[bank], bank);
|
||||
@@ -61,7 +62,7 @@ void PowerDownManagerTimeout::sleep(Bank bank, sc_time time)
|
||||
{
|
||||
bool test_canSleep = canSleep();
|
||||
bool test_isInPowerDown = isInPowerDown();
|
||||
sc_time last_scheduled_command = controllerCore.state.getLastScheduledCommand().getEnd();
|
||||
sc_time last_scheduled_command = controllerCore.state->getLastScheduledCommand().getEnd();
|
||||
sc_time power_down_timeout = Configuration::getInstance().getPowerDownTimeout();
|
||||
bool test_timeCondition = (time - last_scheduled_command) >= power_down_timeout;
|
||||
bool test_awakeForRefresh = (powerDownState == PowerDownState::AwakeForRefresh);
|
||||
@@ -73,7 +74,7 @@ void PowerDownManagerTimeout::sleep(Bank bank, sc_time time)
|
||||
PowerDownState newState;
|
||||
if(Configuration::getInstance().PowerDownMode == EPowerDownMode::TimeoutPDN)
|
||||
{
|
||||
newState = controllerCore.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive;
|
||||
newState = controllerCore.state->rowBufferStates->allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive;
|
||||
}
|
||||
else // PowerDownMode == TimeoutSREF
|
||||
{
|
||||
@@ -108,12 +109,13 @@ bool PowerDownManagerTimeout::isInPowerDown()
|
||||
void PowerDownManagerTimeout::setPowerDownState(PowerDownState state)
|
||||
{
|
||||
powerDownState = state;
|
||||
DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName,
|
||||
"Is now in state " + powerDownStateToString(powerDownState) + " on all banks");
|
||||
printDebugMessage("Is now in state " + powerDownStateToString(powerDownState) + " on all banks");
|
||||
}
|
||||
|
||||
void PowerDownManagerTimeout::wakeUp(Bank bank, sc_time time)
|
||||
{
|
||||
printDebugMessage("Waking up at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState));
|
||||
|
||||
if (isInPowerDown()) //Request wakes up power down
|
||||
{
|
||||
Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState);
|
||||
@@ -121,16 +123,25 @@ void PowerDownManagerTimeout::wakeUp(Bank bank, sc_time time)
|
||||
DramExtension::getExtension(powerDownPayloads[bank]));
|
||||
controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn);
|
||||
|
||||
if (cmd == Command::SREFX)
|
||||
if (cmd == Command::SREFX) {
|
||||
// Leaving Self Refresh. Plan the next refresh.
|
||||
controllerCore.refreshManager->reInitialize(bank, pdn.getEnd());
|
||||
printDebugMessage("Waking up. Leaving Self Refresh at " + time.to_string() + " next refresh planned to " + pdn.getEnd().to_string());
|
||||
}
|
||||
|
||||
setPowerDownState(PowerDownState::Awake);
|
||||
|
||||
printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks");
|
||||
sendPowerDownPayloads(pdn);
|
||||
}
|
||||
|
||||
printDebugMessage("Awaken at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState));
|
||||
}
|
||||
|
||||
void PowerDownManagerTimeout::wakeUpForRefresh(Bank bank, sc_time time)
|
||||
{
|
||||
printDebugMessage("Waking up for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState));
|
||||
|
||||
if (isInPowerDown())
|
||||
{
|
||||
Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState);
|
||||
@@ -138,10 +149,14 @@ void PowerDownManagerTimeout::wakeUpForRefresh(Bank bank, sc_time time)
|
||||
DramExtension::getExtension(powerDownPayloads[bank]));
|
||||
|
||||
setPowerDownState(PowerDownState::AwakeForRefresh);
|
||||
|
||||
printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks");
|
||||
sendPowerDownPayloads(pdn);
|
||||
|
||||
// Schedule Next Powerdown after Refresh:
|
||||
}
|
||||
|
||||
printDebugMessage("Awaken for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState));
|
||||
}
|
||||
|
||||
void PowerDownManagerTimeout::triggerSleep(Bank /*bank*/, sc_time time)
|
||||
@@ -169,14 +184,19 @@ bool PowerDownManagerTimeout::canSleep()
|
||||
|
||||
void PowerDownManagerTimeout::sendPowerDownPayloads(ScheduledCommand& cmd)
|
||||
{
|
||||
controllerCore.state.bus.moveCommandToNextFreeSlot(cmd);
|
||||
controllerCore.state->bus.moveCommandToNextFreeSlot(cmd);
|
||||
for (Bank bank : controllerCore.getBanks())
|
||||
{
|
||||
tlm_generic_payload& payloadToSend = powerDownPayloads[bank];
|
||||
ScheduledCommand pdnToSend(cmd.getCommand(), cmd.getStart(), cmd.getExecutionTime(),
|
||||
DramExtension::getExtension(payloadToSend));
|
||||
controllerCore.state.change(pdnToSend);
|
||||
controllerCore.state->change(pdnToSend);
|
||||
controllerCore.controller.send(pdnToSend, payloadToSend);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerDownManagerTimeout::printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(this->name(), message);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,10 +46,10 @@
|
||||
|
||||
class ControllerCore;
|
||||
|
||||
class PowerDownManagerTimeout: public IPowerDownManager
|
||||
class PowerDownManagerTimeout: public IPowerDownManager, public sc_module
|
||||
{
|
||||
public:
|
||||
PowerDownManagerTimeout(ControllerCore& controllerCore);
|
||||
PowerDownManagerTimeout(sc_module_name /*name*/, ControllerCore& controllerCore);
|
||||
virtual ~PowerDownManagerTimeout();
|
||||
|
||||
virtual void triggerSleep(Bank bank, sc_time time);
|
||||
@@ -66,9 +66,10 @@ private:
|
||||
std::map<Bank, tlm::tlm_generic_payload> powerDownPayloads;
|
||||
void sendPowerDownPayloads(ScheduledCommand& cmd);
|
||||
|
||||
PowerDownState powerDownState = PowerDownState::Awake;
|
||||
PowerDownState powerDownState;
|
||||
void setPowerDownState(PowerDownState state);
|
||||
bool isInPowerDown();
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManager::RefreshManager(ControllerCore& controller) :
|
||||
RefreshManager::RefreshManager(sc_module_name /*name*/, ControllerCore& controller) :
|
||||
controllerCore(controller), timing(controller.config.memSpec.refreshTimings[Bank(0)]), nextPlannedRefresh(SC_ZERO_TIME)
|
||||
{
|
||||
for (Bank bank : controller.getBanks())
|
||||
@@ -58,14 +58,14 @@ RefreshManager::~RefreshManager()
|
||||
|
||||
bool RefreshManager::hasCollision(const ScheduledCommand& command)
|
||||
{
|
||||
return command.getStart() < controllerCore.state.getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() > nextPlannedRefresh;
|
||||
return command.getStart() < controllerCore.state->getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() > nextPlannedRefresh;
|
||||
}
|
||||
|
||||
void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribute__((unused)), sc_time time)
|
||||
{
|
||||
sc_assert(!isInvalidated(payload, time));
|
||||
|
||||
if (!controllerCore.state.rowBufferStates.allRowBuffersAreClosed())
|
||||
if (!controllerCore.state->rowBufferStates->allRowBuffersAreClosed())
|
||||
{
|
||||
ScheduledCommand prechargeAllMaster(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, refreshPayloads[Bank(0)]),
|
||||
refreshPayloads[Bank(0)]);
|
||||
@@ -75,7 +75,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribu
|
||||
{
|
||||
ScheduledCommand prechargeAll(Command::PrechargeAll, prechargeAllMaster.getStart(), prechargeAllMaster.getExecutionTime(),
|
||||
refreshPayloads[bank]);
|
||||
controllerCore.state.change(prechargeAll);
|
||||
controllerCore.state->change(prechargeAll);
|
||||
controllerCore.controller.send(prechargeAll, refreshPayloads[bank]);
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribu
|
||||
for (Bank bank : controllerCore.getBanks())
|
||||
{
|
||||
ScheduledCommand refresh(Command::AutoRefresh, refreshAllMaster.getStart(), refreshAllMaster.getExecutionTime(),refreshPayloads[bank]);
|
||||
controllerCore.state.change(refresh);
|
||||
controllerCore.state->change(refresh);
|
||||
controllerCore.controller.send(refresh, refreshPayloads[bank]);
|
||||
DramExtension::getExtension(refreshPayloads[bank]).incrementRow();
|
||||
}
|
||||
@@ -112,3 +112,8 @@ bool RefreshManager::isInvalidated(tlm::tlm_generic_payload& payload __attribute
|
||||
return nextPlannedRefresh > time;
|
||||
}
|
||||
|
||||
void RefreshManager::printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(this->name(), message);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,16 +43,16 @@
|
||||
|
||||
class ControllerCore;
|
||||
|
||||
class RefreshManager : public IRefreshManager
|
||||
class RefreshManager : public IRefreshManager, public sc_module
|
||||
{
|
||||
public:
|
||||
RefreshManager(ControllerCore& controllerCore);
|
||||
RefreshManager(sc_module_name /*name*/, ControllerCore& controllerCore);
|
||||
virtual ~RefreshManager();
|
||||
|
||||
virtual bool hasCollision(const ScheduledCommand& command) override;
|
||||
virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) override;
|
||||
void reInitialize(Bank bank, sc_time time) override;
|
||||
virtual bool isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) override;
|
||||
virtual bool isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) override;
|
||||
|
||||
private:
|
||||
ControllerCore& controllerCore;
|
||||
@@ -61,7 +61,8 @@ private:
|
||||
std::map<Bank, tlm::tlm_generic_payload> refreshPayloads;
|
||||
|
||||
void planNextRefresh();
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
|
||||
#endif /* REFRESHMANAGER_H_ */
|
||||
|
||||
|
||||
@@ -42,8 +42,7 @@
|
||||
using namespace std;
|
||||
|
||||
|
||||
RefreshManagerBankwise::RefreshManagerBankwise(ControllerCore& controller) :
|
||||
controllerCore(controller)
|
||||
RefreshManagerBankwise::RefreshManagerBankwise(sc_module_name /*name*/, ControllerCore& controller) : controllerCore(controller)
|
||||
{
|
||||
for (Bank bank : controller.getBanks())
|
||||
{
|
||||
@@ -58,8 +57,17 @@ RefreshManagerBankwise::~RefreshManagerBankwise()
|
||||
|
||||
bool RefreshManagerBankwise::hasCollision(const ScheduledCommand& command)
|
||||
{
|
||||
return command.getStart() < controllerCore.state.getLastCommand(Command::AutoRefresh, command.getBank()).getEnd()
|
||||
|| command.getEnd() > nextPlannedRefreshs[command.getBank()];}
|
||||
Bank bank = command.getBank();
|
||||
// Get the last AutoRefresh command for this bank and the time of its end
|
||||
ScheduledCommand lastAutoRefreshCmd = controllerCore.state->getLastCommand(Command::AutoRefresh, bank);
|
||||
sc_time endTimeLastAutoRefreshCmd = lastAutoRefreshCmd.getEnd();
|
||||
// Get the time of the next planned refresh for this bank
|
||||
sc_time timeNextPlannedRefresh = nextPlannedRefreshs[command.getBank()];
|
||||
// Collision:
|
||||
// - the start time of the command is before the end time of the last auto refresh command for this bank
|
||||
// - the end time of the command is after the next planned refresh for this bank
|
||||
return command.getStart() < endTimeLastAutoRefreshCmd || command.getEnd() > timeNextPlannedRefresh;
|
||||
}
|
||||
|
||||
void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time)
|
||||
{
|
||||
@@ -69,18 +77,18 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload,
|
||||
|
||||
DramExtension& extension = DramExtension::getExtension(refreshPayload);
|
||||
|
||||
if (controllerCore.state.rowBufferStates.rowBufferIsOpen(extension.getBank()))
|
||||
if (controllerCore.state->rowBufferStates->rowBufferIsOpen(extension.getBank()))
|
||||
{
|
||||
ScheduledCommand precharge(Command::Precharge, time, getExecutionTime(Command::Precharge, refreshPayload), extension);
|
||||
|
||||
controllerCore.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(precharge);
|
||||
controllerCore.state.change(precharge);
|
||||
controllerCore.state->change(precharge);
|
||||
controllerCore.controller.send(precharge, refreshPayload);
|
||||
}
|
||||
|
||||
ScheduledCommand refresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayload), extension);
|
||||
controllerCore.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(refresh);
|
||||
controllerCore.state.change(refresh);
|
||||
controllerCore.state->change(refresh);
|
||||
controllerCore.controller.send(refresh, refreshPayload);
|
||||
|
||||
extension.incrementRow();
|
||||
@@ -104,4 +112,8 @@ bool RefreshManagerBankwise::isInvalidated(tlm::tlm_generic_payload& payload, sc
|
||||
return nextPlannedRefreshs[DramExtension::getExtension(payload).getBank()] > time;
|
||||
}
|
||||
|
||||
void RefreshManagerBankwise::printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(this->name(), message);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,13 +44,13 @@
|
||||
|
||||
class ControllerCore;
|
||||
|
||||
class RefreshManagerBankwise : public IRefreshManager
|
||||
class RefreshManagerBankwise : public IRefreshManager, public sc_module
|
||||
{
|
||||
public:
|
||||
RefreshManagerBankwise(ControllerCore& controllerCore);
|
||||
RefreshManagerBankwise(sc_module_name /*name*/, ControllerCore& controllerCore);
|
||||
virtual ~RefreshManagerBankwise();
|
||||
|
||||
virtual bool hasCollision(const ScheduledCommand& command) override;
|
||||
virtual bool hasCollision(const ScheduledCommand& command) override;
|
||||
virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) override;
|
||||
|
||||
void reInitialize(Bank bank, sc_time time) override;
|
||||
@@ -58,14 +58,15 @@ public:
|
||||
bool isInvalidated(tlm::tlm_generic_payload& payload,sc_time time) override;
|
||||
|
||||
private:
|
||||
|
||||
ControllerCore& controllerCore;
|
||||
ControllerCore &controllerCore;
|
||||
|
||||
std::map<Bank, tlm::tlm_generic_payload> refreshPayloads;
|
||||
std::map<Bank, sc_time> nextPlannedRefreshs;
|
||||
|
||||
void planNextRefresh(Bank bank);
|
||||
|
||||
void printDebugMessage(std::string message);
|
||||
};
|
||||
|
||||
|
||||
#endif /* BANKWISEREFRESHMANAGER_H_ */
|
||||
|
||||
|
||||
@@ -37,67 +37,75 @@
|
||||
#include "PowerDownChecker.h"
|
||||
#include "../../TimingCalculation.h"
|
||||
|
||||
void PowerDownChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
|
||||
sc_time PowerDownChecker::getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const
|
||||
{
|
||||
sc_assert(
|
||||
command.commandIsIn(
|
||||
{ Command::SREF, Command::PDNA, Command::PDNP, Command::PDNAX, Command::PDNPX, Command::SREFX }));
|
||||
sc_assert(pdnCmd == Command::SREF || pdnCmd == Command::PDNA || pdnCmd == Command::PDNP);
|
||||
|
||||
if (command.commandIsIn( { Command::SREF, Command::PDNA, Command::PDNP }))
|
||||
{
|
||||
ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(command.getBank());
|
||||
sc_time constraint;
|
||||
|
||||
if (lastCommandOnBank.isValidCommand())
|
||||
{
|
||||
if (lastCommandOnBank.getCommand() == Command::Read || lastCommandOnBank.getCommand() == Command::ReadA)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tRL + getReadAccessTime() + config.memSpec.clk);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::Write)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::WriteA)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(),
|
||||
config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.clk);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::AutoRefresh)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRFC);
|
||||
}
|
||||
else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXP);
|
||||
}
|
||||
if (lastCmd == Command::Read || lastCmd == Command::ReadA) {
|
||||
constraint = config.memSpec.tRL + getReadAccessTime() + config.memSpec.clk;
|
||||
} else if (lastCmd == Command::Write) {
|
||||
constraint = config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR;
|
||||
} else if (lastCmd == Command::WriteA) {
|
||||
constraint = config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.clk;
|
||||
} else if (lastCmd == Command::AutoRefresh) {
|
||||
constraint = config.memSpec.tRFC;
|
||||
} else if (lastCmd == Command::PDNPX || lastCmd == Command::PDNAX) {
|
||||
constraint = config.memSpec.tXP;
|
||||
} else if (lastCmd == Command::SREFX) {
|
||||
constraint = config.memSpec.tXSR;
|
||||
} else {
|
||||
reportFatal("Powerdown checker", commandToString(pdnCmd) + " can not follow " + commandToString(lastCmd));
|
||||
}
|
||||
|
||||
else if (lastCommandOnBank.getCommand() == Command::SREFX)
|
||||
{
|
||||
command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXSR);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
reportFatal("Powerdown checker", commandToString(command.getCommand()) + " can not follow " + commandToString(lastCommandOnBank.getCommand()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (command.getCommand() == Command::PDNAX)
|
||||
{
|
||||
command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNA).getStart(), config.memSpec.tCKE);
|
||||
}
|
||||
else if (command.getCommand() == Command::PDNPX)
|
||||
{
|
||||
command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNP).getStart(), config.memSpec.tCKE);
|
||||
}
|
||||
else if (command.getCommand() == Command::SREFX)
|
||||
{
|
||||
command.establishMinDistanceFromStart(state.getLastCommand(Command::SREF).getStart(), config.memSpec.tCKESR);
|
||||
}
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
return constraint;
|
||||
}
|
||||
|
||||
void PowerDownChecker::delayToSatisfyConstraints(ScheduledCommand &command) const
|
||||
{
|
||||
sc_assert(command.commandIsIn({Command::PDNA, Command::PDNP, Command::SREF, Command::PDNAX, Command::PDNPX, Command::SREFX}));
|
||||
|
||||
// Power Down commmand (one of the listed above)
|
||||
Command pdnCmd = command.getCommand();
|
||||
Bank bank = command.getBank();
|
||||
|
||||
sc_time timeConstraint;
|
||||
|
||||
if (pdnCmd == Command::PDNA || pdnCmd == Command::PDNP || pdnCmd == Command::SREF) {
|
||||
// Entering in one of the Power Down modes:
|
||||
// PDNA - Active Power Down
|
||||
// PDNP - Precharge Power Down
|
||||
// SREF - Self Refresh
|
||||
|
||||
// Get the last scheduled command on this bank
|
||||
ScheduledCommand lastSchedCmdOnBank = state.getLastScheduledCommand(bank);
|
||||
|
||||
if (lastSchedCmdOnBank.isValidCommand()) {
|
||||
// Get the start time for the last scheduled command on this bank
|
||||
sc_time lastSchedCmdOnBankStart = lastSchedCmdOnBank.getStart();
|
||||
// Get the last command on this bank itself
|
||||
Command lastCmdBank = lastSchedCmdOnBank.getCommand();
|
||||
|
||||
timeConstraint = getTimeConstraintToEnterPowerDown(lastCmdBank, pdnCmd);
|
||||
|
||||
command.establishMinDistanceFromStart(lastSchedCmdOnBankStart, timeConstraint);
|
||||
}
|
||||
|
||||
} else if (pdnCmd == Command::PDNAX) {
|
||||
// Leaving Active Power Down
|
||||
timeConstraint = config.memSpec.tCKE;
|
||||
command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNA).getStart(), timeConstraint);
|
||||
} else if (pdnCmd == Command::PDNPX) {
|
||||
// Leaving Precharge Power Down
|
||||
timeConstraint = config.memSpec.tCKE;
|
||||
command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNP).getStart(), timeConstraint);
|
||||
} else if (pdnCmd == Command::SREFX) {
|
||||
// Leaving Self Refresh
|
||||
timeConstraint = config.memSpec.tCKESR;
|
||||
command.establishMinDistanceFromStart(state.getLastCommand(Command::SREF).getStart(), timeConstraint);
|
||||
}
|
||||
|
||||
state.bus.moveCommandToNextFreeSlot(command);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,29 +37,25 @@
|
||||
#ifndef POWERDOWNCHECKER_H_
|
||||
#define POWERDOWNCHECKER_H_
|
||||
|
||||
#include <systemc>
|
||||
|
||||
#include "../../../ControllerState.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "ICommandChecker.h"
|
||||
#include <systemc>
|
||||
|
||||
|
||||
class PowerDownChecker : public ICommandChecker
|
||||
{
|
||||
public:
|
||||
PowerDownChecker(const Configuration& config, ControllerState& state) :
|
||||
config(config), state(state)
|
||||
{
|
||||
}
|
||||
virtual ~PowerDownChecker()
|
||||
{
|
||||
}
|
||||
PowerDownChecker(const Configuration &config, ControllerState &state) : config(config), state(state) {}
|
||||
virtual ~PowerDownChecker() {}
|
||||
|
||||
virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override;
|
||||
|
||||
private:
|
||||
const Configuration& config;
|
||||
ControllerState& state;
|
||||
const Configuration &config;
|
||||
ControllerState &state;
|
||||
sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
|
||||
};
|
||||
|
||||
|
||||
#endif /* POWERDOWNCHECKER_H_ */
|
||||
|
||||
|
||||
@@ -104,8 +104,13 @@ private:
|
||||
// This function is called when an arbiter's initiator socket receives a transaction from a memory controller
|
||||
tlm_sync_enum nb_transport_bw(int channelId, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay)
|
||||
{
|
||||
tlmRecorders[channelId]->recordPhase(payload, phase, bwDelay + sc_time_stamp());
|
||||
payloadEventQueue.notify(payload, phase, bwDelay);
|
||||
sc_time recTime = bwDelay + sc_time_stamp();
|
||||
sc_time notDelay = bwDelay;
|
||||
|
||||
printDebugMessage("[bw] Recording " + phaseNameToString(phase) + " at " + recTime.to_string() + " notification in " + notDelay.to_string());
|
||||
|
||||
tlmRecorders[channelId]->recordPhase(payload, phase, recTime);
|
||||
payloadEventQueue.notify(payload, phase, notDelay);
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
@@ -210,6 +215,11 @@ private:
|
||||
DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(decodedAddress.channel), Bank(decodedAddress.bank), BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength);
|
||||
payload.set_auto_extension(extension);
|
||||
}
|
||||
|
||||
void printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(this->name(), message);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* ARBITER_H_ */
|
||||
|
||||
@@ -200,7 +200,21 @@ struct Dram : sc_module
|
||||
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& payload, tlm::tlm_phase& phase, sc_time& delay)
|
||||
{
|
||||
tlmRecorder->recordPhase(payload, phase, sc_time_stamp() + delay);
|
||||
// Recording time used by the traceAnalyzer
|
||||
sc_time recTime = sc_time_stamp() + delay;
|
||||
|
||||
// These are terminating phases recorded by the DRAM. The execution
|
||||
// time of the related command must be taken into consideration.
|
||||
if (phase == END_PDNA || phase == END_PDNAB) {
|
||||
recTime += getExecutionTime(Command::PDNAX, payload);
|
||||
} else if (phase == END_PDNP || phase == END_PDNPB) {
|
||||
recTime += getExecutionTime(Command::PDNPX, payload);
|
||||
} else if (phase == END_SREF || phase == END_SREFB) {
|
||||
recTime += getExecutionTime(Command::SREFX, payload);
|
||||
}
|
||||
|
||||
printDebugMessage("[fw] Recording " + phaseNameToString(phase) + " at " + recTime.to_string());
|
||||
tlmRecorder->recordPhase(payload, phase, recTime);
|
||||
|
||||
// This is only needed for power simulation:
|
||||
unsigned long long cycle = 0;
|
||||
@@ -386,6 +400,7 @@ struct Dram : sc_module
|
||||
{
|
||||
if(powerAnalysis == true){SC_REPORT_FATAL("DRAM", "DRAM PEQ was called with unknown phase");}
|
||||
}
|
||||
|
||||
return tlm::TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,8 @@ void Simulation::setupTlmRecorders(const string &traceName, const string &pathTo
|
||||
for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) {
|
||||
std::string sqlScriptURI = pathToResources + string("scripts/createTraceDB.sql");
|
||||
std::string dbName = traceName + string("_channel") + std::to_string(i) + ".tdb";
|
||||
TlmRecorder *tlmRecorder = new TlmRecorder(sqlScriptURI.c_str(), dbName.c_str(), Configuration::getInstance().DatabaseRecording);
|
||||
std::string recorderName = "tlmRecorder" + std::to_string(i);
|
||||
TlmRecorder *tlmRecorder = new TlmRecorder(recorderName.c_str(), sqlScriptURI.c_str(), dbName.c_str(), Configuration::getInstance().DatabaseRecording);
|
||||
|
||||
tlmRecorder->recordMemconfig(Configuration::getInstance().memconfigUri);
|
||||
tlmRecorder->recordMemspec(Configuration::getInstance().memspecUri);
|
||||
@@ -113,7 +114,7 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT
|
||||
TemperatureController::getInstance();
|
||||
|
||||
for (size_t i = 0; i < Configuration::getInstance().NumberOfTracePlayers; i++) {
|
||||
std::string playerStr = "player" + std::to_string(i);
|
||||
std::string playerStr = "tracePlayer" + std::to_string(i);
|
||||
TracePlayer<> *player;
|
||||
// When data should be stored during the simulation the StlDataPlayer is needed.
|
||||
// Else: no data should be stored, for instance to get a faster simulation
|
||||
|
||||
@@ -136,8 +136,7 @@ void TracePlayer<BUSWIDTH>::peqCallback(tlm_generic_payload &payload, const tlm_
|
||||
sendToTarget(payload, phase, SC_ZERO_TIME);
|
||||
|
||||
transactionsSent++;
|
||||
DebugManager::getInstance().printDebugMessage(name(),
|
||||
"Sending transaction number: " + std::to_string(transactionsSent));
|
||||
DebugManager::getInstance().printDebugMessage(name(), "Performing request #" + std::to_string(transactionsSent));
|
||||
}
|
||||
else if (phase == END_REQ)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user