Merge pull request #55 from fzeder/master

Issue#50 fixed and some improvements
This commit is contained in:
Matthias Jung
2016-02-23 23:13:31 +01:00
31 changed files with 401 additions and 255 deletions

View File

@@ -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()

View File

@@ -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;}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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_ */

View File

@@ -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);
}

View File

@@ -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_ */

View File

@@ -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);
}

View File

@@ -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_ */

View File

@@ -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);
}
}

View File

@@ -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);
};

View File

@@ -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;

View File

@@ -82,6 +82,7 @@ inline Command IPowerDownManager::getSleepCommand(PowerDownState state)
break;
default:
SC_REPORT_FATAL("In PowerDownManager sendPowerdownBegin", "invalid powerDownState");
break;
}
return cmd;
}

View File

@@ -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);
}

View File

@@ -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);
};

View File

@@ -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);
}

View File

@@ -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_ */

View File

@@ -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);
}

View File

@@ -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);
};

View File

@@ -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);
}

View File

@@ -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_ */

View File

@@ -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);
}

View File

@@ -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_ */

View File

@@ -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);
}

View File

@@ -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_ */

View File

@@ -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_ */

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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)
{