This commit is contained in:
Janik Schlemminger
2014-04-12 21:22:59 +02:00
16 changed files with 279 additions and 382 deletions

View File

@@ -4,7 +4,7 @@
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-2055719358" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} -E -P -v -dD &quot;${INPUTS}&quot; -std=c++11">
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-60060699001507781" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} -E -P -v -dD &quot;${INPUTS}&quot; -std=c++11">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@@ -14,7 +14,7 @@
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-2055719358" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} -E -P -v -dD &quot;${INPUTS}&quot; -std=c++11">
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-60060699001507781" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} -E -P -v -dD &quot;${INPUTS}&quot; -std=c++11">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>

View File

@@ -30,12 +30,6 @@ TlmRecorder::~TlmRecorder()
closeConnection();
}
TlmRecorder& TlmRecorder::getInstance()
{
static TlmRecorder decoder;
return decoder;
}
void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, tlm::tlm_phase phase, sc_time time)
{
if (currentTransactionsInSystem.count(&trans) == 0)

View File

@@ -23,7 +23,12 @@ public:
static std::string sqlScriptURI;
static std::string dbName;
static std::string senderName;
static TlmRecorder& getInstance();
static inline TlmRecorder& getInstance()
{
static TlmRecorder decoder;
return decoder;
}
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time time);
void recordDebugMessage(std::string message, sc_time time);
@@ -32,6 +37,7 @@ public:
void recordMemconfig(string memconfig){this->memconfig = memconfig;}
void recordMemspec(string memspec){this->memspec = memspec;}
void recordTracenames(string traces){this->traces = traces;}
private:
std::string memconfig,memspec,traces;
TlmRecorder();

View File

@@ -43,7 +43,6 @@ DECLARE_EXTENDED_PHASE(END_SREF);
//Triggers
DECLARE_EXTENDED_PHASE(REFRESH_TRIGGER);
DECLARE_EXTENDED_PHASE(WAKEUP_TRIGGER);
#endif

View File

@@ -73,12 +73,6 @@ xmlAddressDecoder::xmlAddressDecoder(string addressConfigURI)
}
}
xmlAddressDecoder& xmlAddressDecoder::getInstance()
{
static xmlAddressDecoder decoder(xmlAddressDecoder::addressConfigURI);
return decoder;
}
xmlAddressDecoder::~xmlAddressDecoder()
{
delete doc;

View File

@@ -13,7 +13,6 @@
/// \date 02.07.2012
//
#include <tlm.h>
#include <iostream>
#include <sstream>
@@ -36,52 +35,56 @@ class xmlAddressDecoder
{
public:
static std::string addressConfigURI;
static xmlAddressDecoder& getInstance();
static std::string addressConfigURI;
void getNode(unsigned int addr, node * n);
void getBRC(unsigned int addr, unsigned int &bank, unsigned int &row, unsigned int &colum);
void getCBRC(unsigned int addr, unsigned int &channel, unsigned int &bank, unsigned int &row, unsigned int &colum);
void getC(unsigned int addr, unsigned int &channel);
unsigned int getNumberOfBanks();
unsigned int getNumberOfRowsPerBank();
unsigned int getNumberOfColumsPerRow();
unsigned int getNumberOfBytesPerColumn();
static inline xmlAddressDecoder& getInstance()
{
static xmlAddressDecoder decoder(xmlAddressDecoder::addressConfigURI);
return decoder;
}
private:
xmlAddressDecoder(std::string URI);
~xmlAddressDecoder();
void getNode(unsigned int addr, node * n);
void getBRC(unsigned int addr, unsigned int &bank, unsigned int &row, unsigned int &colum);
void getCBRC(unsigned int addr, unsigned int &channel, unsigned int &bank, unsigned int &row, unsigned int &colum);
void getC(unsigned int addr, unsigned int &channel);
unsigned int getNumberOfBanks();
unsigned int getNumberOfRowsPerBank();
unsigned int getNumberOfColumsPerRow();
unsigned int getNumberOfBytesPerColumn();
unsigned int channelMask;
unsigned int rowMask;
unsigned int bankMask;
unsigned int columMask;
unsigned int bytesMask;
private:
xmlAddressDecoder(std::string URI);
~xmlAddressDecoder();
unsigned int channelShift;
unsigned int rowShift;
unsigned int bankShift;
unsigned int columShift;
unsigned int bytesShift;
unsigned int channelMask;
unsigned int rowMask;
unsigned int bankMask;
unsigned int columMask;
unsigned int bytesMask;
unsigned int channelSize;
unsigned int bankSize;
unsigned int rowSize;
unsigned int columSize;
unsigned int bytesSize;
unsigned int channelShift;
unsigned int rowShift;
unsigned int bankShift;
unsigned int columShift;
unsigned int bytesShift;
TiXmlDocument * doc;
TiXmlElement * dramconfig;
TiXmlElement * addressmap;
unsigned int channelSize;
unsigned int bankSize;
unsigned int rowSize;
unsigned int columSize;
unsigned int bytesSize;
template <class T>
T getAttribute(TiXmlElement * element, const std::string s)
{
T d;
element->QueryValueAttribute<T>(s, &d);
return d;
}
TiXmlDocument * doc;
TiXmlElement * dramconfig;
TiXmlElement * addressmap;
template<class T>
T getAttribute(TiXmlElement * element, const std::string s)
{
T d;
element->QueryValueAttribute<T>(s, &d);
return d;
}
};
#endif

View File

@@ -84,13 +84,12 @@ void ControllerCore::resetState()
void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time)
{
Bank bank = DramExtension::getExtension(payload).getBank();
printDebugMessage("Scheduling refresh on bank " + to_string(bank.ID()));
printDebugMessage("Triggering refresh on bank " + to_string(bank.ID()));
state.cleanUp(time);
if (!refreshManager->isInvalidated(payload, time) && !powerDownManager->isInSelfRefresh(bank))
{
printDebugMessage("Waking up bank " + to_string(bank.ID()) + " for refresh");
powerDownManager->wakeUpForRefresh(bank, time); //expects PDNA and PDNP to exit without delay
refreshManager->scheduleRefresh(payload, time);
}

View File

@@ -14,7 +14,6 @@
namespace core {
sc_time getDistance(sc_time a, sc_time b)
{
if (a > b)
@@ -40,30 +39,29 @@ const sc_time clkAlign(sc_time time, Alignment alignment)
return floor(time / clk) * clk;
}
sc_time getExecutionTime(Command command,tlm::tlm_generic_payload& payload)
sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload)
{
TimingConfiguration& config = Configuration::getInstance().Timings;
if(command == Command::Precharge || command == Command::PrechargeAll)
if (command == Command::Precharge || command == Command::PrechargeAll)
{
return config.tRP;
}
else if(command == Command::Activate)
else if (command == Command::Activate)
{
return config.tRCD;
}
else if(command == Command::Read)
else if (command == Command::Read)
{
return config.tRL + getBurstLengthOnDataStrobe(payload.get_streaming_width());
}
else if(command == Command::ReadA)
else if (command == Command::ReadA)
{
return getBurstLengthOnDataStrobe(payload.get_streaming_width())
+ max(config.tRP, config.tRL);
return getBurstLengthOnDataStrobe(payload.get_streaming_width()) + max(config.tRP, config.tRL);
}
else if(command == Command::Write || command == Command::WriteA)
else if (command == Command::Write || command == Command::WriteA)
{
sc_time lockTime;;
sc_time lockTime;
Configuration& config = Configuration::getInstance();
if(config.DataRate == 1)
lockTime = getBurstLengthOnDataStrobe(payload.get_streaming_width()) - config.Timings.clk;
@@ -81,54 +79,67 @@ sc_time getExecutionTime(Command command,tlm::tlm_generic_payload& payload)
return config.Timings.tWL + lockTime + config.Timings.tWR;
}
}
else if(command == Command::PrechargeAll)
else if (command == Command::PrechargeAll)
{
return config.tRP;
}
else if(command == Command::AutoRefresh)
else if (command == Command::AutoRefresh)
{
return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC;
}
else if(command == Command::PDNA || command == Command::PDNP)
{
return config.tCKE;
}
else if(command == Command::SREF)
{
return config.tCKESR;
}
else if(command == Command::PDNAX || command == Command::PDNPX || command == Command::SREFX)
else if (command == Command::PDNAX || command == Command::PDNPX || command == Command::SREFX)
{
return config.clk;
}
else
{
SC_REPORT_FATAL("getExecutionTime", "unkown command");
SC_REPORT_FATAL("getExecutionTime", "command not known or command doesn't have a fixed execution time");
return SC_ZERO_TIME;
}
}
sc_time getMinimalExecutionTime(Command command, tlm::tlm_generic_payload& payload)
{
TimingConfiguration& config = Configuration::getInstance().Timings;
if (command == Command::PDNA || command == Command::PDNP)
{
return config.tCKE;
}
else if (command == Command::SREF)
{
return config.tCKESR;
}
else
{
SC_REPORT_FATAL("getMinimalExecutionTime", "command is not know or command has a fixed execution time");
return SC_ZERO_TIME;
}
}
bool isClkAligned(sc_time time, sc_time clk)
{
return !((time / clk) - ceil(time / clk));
return !((time / clk) - ceil(time / clk));
}
bool TimeInterval::timeIsInInterval(sc_time time)
{
return (start < time && time < end);
return (start < time && time < end);
}
bool TimeInterval::intersects(TimeInterval other)
{
return other.timeIsInInterval(this->start) || this->timeIsInInterval(other.start);
return other.timeIsInInterval(this->start) || this->timeIsInInterval(other.start);
}
sc_time getBurstLengthOnDataStrobe(unsigned int burstlength)
{
Configuration& config = Configuration::getInstance();
sc_assert((burstlength / config.DataRate) > 0);
Configuration& config = Configuration::getInstance();
sc_assert((burstlength / config.DataRate) > 0);
return config.Timings.clk * (burstlength / config.DataRate);
return config.Timings.clk * (burstlength / config.DataRate);
}
}

View File

@@ -28,7 +28,9 @@ struct TimeInterval
bool intersects(TimeInterval other);
};
sc_time getMinimalExecutionTime(Command command, tlm::tlm_generic_payload& payload);
sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload);
sc_time getBurstLengthOnDataStrobe(unsigned int burstlength);
sc_time getDelayToMeetConstraint(sc_time previous, sc_time start, sc_time constraint);

View File

@@ -21,11 +21,5 @@ Configuration::Configuration()
loader.loadConfiguration(*this, Configuration::memspecUri, Configuration::memconfigUri);
}
Configuration& Configuration::getInstance()
{
static Configuration configuration;
return configuration;
}
} /* namespace core */

View File

@@ -20,7 +20,11 @@ struct Configuration
static std::string memspecUri;
static std::string memconfigUri;
static Configuration& getInstance();
static inline Configuration& getInstance()
{
static Configuration configuration;
return configuration;
}
std::string MemoryId;
std::string MemoryType;

View File

@@ -60,7 +60,7 @@ void PowerDownManager::sleep(Bank bank, sc_time time)
}
Command cmd = IPowerDownManager::getSleepCommand(state);
ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]),
ScheduledCommand pdn(cmd, time, getMinimalExecutionTime(cmd, powerDownPayloads[bank]),
DramExtension::getExtension(powerDownPayloads[bank]));
controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn);

View File

@@ -32,7 +32,6 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time)
return;
tlm_generic_payload& payload = powerDownPayloads[bank];
sc_time minTime = getExecutionTime(Command::PDNA, payload);
PowerDownState state = powerDownStates[bank];
if (state == PowerDownState::Awake) //coming from active
@@ -49,12 +48,11 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time)
else
{
state = PowerDownState::PDNSelfRefresh;
minTime = getExecutionTime(Command::SREF, payload);
}
}
Command cmd = IPowerDownManager::getSleepCommand(state);
ScheduledCommand pdn(cmd, time, minTime, DramExtension::getExtension(payload));
ScheduledCommand pdn(cmd, time, getMinimalExecutionTime(cmd, payload), DramExtension::getExtension(payload));
controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn);
if (state != PowerDownState::PDNSelfRefresh && controller.refreshManager->hasCollision(pdn))

View File

@@ -42,22 +42,15 @@ public:
tlm_utils::simple_target_socket<Controller, BUSWIDTH, tlm::tlm_base_protocol_types> tSocket;
Controller(sc_module_name name) :
frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerPEQ(this,
&Controller::controllerPEQCallback), debugManager(DebugManager::getInstance())
frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerCorePEQ(
this, &Controller::controllerCorePEQCallback), debugManager(DebugManager::getInstance())
{
controller = new ControllerCore(*this, numberOfPayloadsInSystem);
buildScheduler();
inputBufferDelay = controller->config.Timings.clk;
iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw);
tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw);
}
~Controller()
{
delete controller;
delete scheduler;
}
void buildScheduler()
{
string selectedScheduler = Configuration::getInstance().Scheduler;
@@ -79,6 +72,12 @@ public:
reportFatal(name(), "unsupported scheduler: " + selectedScheduler);
}
~Controller()
{
delete controller;
delete scheduler;
}
void terminateSimulation()
{
for (Bank bank : controller->getBanks())
@@ -87,108 +86,69 @@ public:
}
}
// ------- Interaction with controller core ---------
virtual void send(const ScheduledCommand& command, tlm_generic_payload& payload) override
{
sc_assert(command.getStart() >= sc_time_stamp());
TimeInterval dataStrobe;
TlmRecorder& rec = TlmRecorder::getInstance();
switch (command.getCommand())
{
case Command::Read:
rec.recordPhase(payload, BEGIN_RD, command.getStart());
dataStrobe = command.getIntervalOnDataStrobe();
rec.updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
rec.recordPhase(payload, END_RD, command.getEnd());
dramPEQ.notify(payload, BEGIN_RD, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_RD, command.getEnd() - sc_time_stamp());
TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
controllerCorePEQ.notify(payload, BEGIN_RD, command.getStart() - sc_time_stamp());
break;
case Command::ReadA:
rec.recordPhase(payload, BEGIN_RDA, command.getStart());
dataStrobe = command.getIntervalOnDataStrobe();
rec.updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
rec.recordPhase(payload, END_RDA, command.getEnd());
dramPEQ.notify(payload, BEGIN_RDA, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_RDA, command.getEnd() - sc_time_stamp());
TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
controllerCorePEQ.notify(payload, BEGIN_RDA, command.getStart() - sc_time_stamp());
break;
case Command::Write:
rec.recordPhase(payload, BEGIN_WR, command.getStart());
dataStrobe = command.getIntervalOnDataStrobe();
rec.updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
rec.recordPhase(payload, END_WR, command.getEnd());
dramPEQ.notify(payload, BEGIN_WR, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_WR, command.getEnd() - sc_time_stamp());
TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
controllerCorePEQ.notify(payload, BEGIN_WR, command.getStart() - sc_time_stamp());
break;
case Command::WriteA:
rec.recordPhase(payload, BEGIN_WRA, command.getStart());
dataStrobe = command.getIntervalOnDataStrobe();
rec.updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
rec.recordPhase(payload, END_WRA, command.getEnd());
dramPEQ.notify(payload, BEGIN_WRA, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_WRA, command.getEnd() - sc_time_stamp());
TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
controllerCorePEQ.notify(payload, BEGIN_WRA, command.getStart() - sc_time_stamp());
break;
case Command::AutoRefresh:
rec.recordPhase(payload, BEGIN_AUTO_REFRESH, command.getStart());
rec.recordPhase(payload, END_AUTO_REFRESH, command.getEnd());
dramPEQ.notify(payload, BEGIN_AUTO_REFRESH, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_AUTO_REFRESH, command.getEnd() - sc_time_stamp());
controllerCorePEQ.notify(payload, BEGIN_AUTO_REFRESH, command.getStart() - sc_time_stamp());
break;
case Command::Activate:
rec.recordPhase(payload, BEGIN_ACT, command.getStart());
rec.recordPhase(payload, END_ACT, command.getEnd());
dramPEQ.notify(payload, BEGIN_ACT, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_ACT, command.getEnd() - sc_time_stamp());
controllerCorePEQ.notify(payload, BEGIN_ACT, command.getStart() - sc_time_stamp());
break;
case Command::Precharge:
rec.recordPhase(payload, BEGIN_PRE, command.getStart());
rec.recordPhase(payload, END_PRE, command.getEnd());
dramPEQ.notify(payload, BEGIN_PRE, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_PRE, command.getEnd() - sc_time_stamp());
controllerCorePEQ.notify(payload, BEGIN_PRE, command.getStart() - sc_time_stamp());
break;
case Command::PrechargeAll:
rec.recordPhase(payload, BEGIN_PRE_ALL, command.getStart());
rec.recordPhase(payload, END_PRE_ALL, command.getEnd());
dramPEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp());
dramPEQ.notify(payload, END_PRE_ALL, command.getEnd() - sc_time_stamp());
controllerCorePEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp());
break;
case Command::PDNA:
dramPEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, BEGIN_PDNA, command.getStart());
controllerCorePEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp());
break;
case Command::PDNP:
dramPEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, BEGIN_PDNP, command.getStart());
controllerCorePEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp());
break;
case Command::SREF:
dramPEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, BEGIN_SREF, command.getStart());
controllerCorePEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp());
break;
case Command::PDNAX:
dramPEQ.notify(payload, END_PDNA, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, END_PDNA, command.getEnd());
controllerCorePEQ.notify(payload, END_PDNA, command.getEnd() - sc_time_stamp());
break;
case Command::PDNPX:
dramPEQ.notify(payload, END_PDNP, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, END_PDNP, command.getEnd());
controllerCorePEQ.notify(payload, END_PDNP, command.getEnd() - sc_time_stamp());
break;
case Command::SREFX:
dramPEQ.notify(payload, END_SREF, command.getStart() - sc_time_stamp());
rec.recordPhase(payload, END_SREF, command.getEnd());
controllerCorePEQ.notify(payload, END_SREF, command.getEnd() - sc_time_stamp());
break;
default:
SC_REPORT_FATAL(0, "unsupported command in controller");
SC_REPORT_FATAL(0, "unsupported command was sent by controller");
break;
}
}
virtual void send(Trigger trigger, sc_time time, tlm_generic_payload& payload) override
@@ -198,7 +158,7 @@ public:
sc_time delay = time - sc_time_stamp();
if (trigger == Trigger::RefreshTrigger)
{
controllerPEQ.notify(payload, REFRESH_TRIGGER, delay);
controllerCorePEQ.notify(payload, REFRESH_TRIGGER, delay);
}
else
{
@@ -206,6 +166,34 @@ public:
}
}
void controllerCorePEQCallback(tlm_generic_payload& payload, const tlm_phase& phase)
{
if (phase == REFRESH_TRIGGER)
{
controller->triggerRefresh(payload, sc_time_stamp());
}
else
{
Bank bank = DramExtension::getExtension(payload).getBank();
TlmRecorder::getInstance().recordPhase(payload, phase, sc_time_stamp());
if (isIn(phase, { BEGIN_RD, BEGIN_WR, BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA, BEGIN_AUTO_REFRESH }))
{
sendToDram(payload, phase, SC_ZERO_TIME);
if (phase == BEGIN_RD || phase == BEGIN_WR)
scheduleNextPayload(bank);
else if (phase == BEGIN_AUTO_REFRESH)
printDebugMessage("Entering auto refresh on bank " + to_string(bank.ID()));
}
else if (isIn(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF }))
printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID()));
else if (isIn(phase, { END_PDNA, END_PDNP, END_SREF }))
printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID()));
else
SC_REPORT_FATAL(0, "refreshTriggerPEQCallback queue in controller wrapper was triggered with unsupported phase");
}
}
private:
ControllerCore* controller;
Scheduler* scheduler;
@@ -215,85 +203,21 @@ private:
tlm_utils::peq_with_cb_and_phase<Controller> frontendPEQ;
tlm_utils::peq_with_cb_and_phase<Controller> dramPEQ;
tlm_utils::peq_with_cb_and_phase<Controller> controllerPEQ;
tlm_utils::peq_with_cb_and_phase<Controller> controllerCorePEQ;
sc_time inputBufferDelay;
DebugManager& debugManager;
unsigned int getNumberOfPayloadsInSystem()
{
unsigned int sum = 0;
for (Bank bank : controller->getBanks())
{
sum += numberOfPayloadsInSystem[bank];
}
return sum;
}
void payloadEntersSystem(tlm_generic_payload& payload)
{
Bank bank = DramExtension::getExtension(payload).getBank();
printDebugMessage("Transaction enters system on bank " + to_string(bank.ID()));
numberOfPayloadsInSystem[bank]++;
}
void payloadLeavesSystem(tlm_generic_payload& payload)
{
Bank bank = DramExtension::getExtension(payload).getBank();
numberOfPayloadsInSystem[bank]--;
controller->powerDownManager->sleep(bank, sc_time_stamp());
}
void scheduleNextPayload(Bank bank)
{
printDebugMessage("Triggering schedule next payload on bank " + to_string(bank.ID()));
if (scheduler->hasTransactionForBank(bank))
{
controller->powerDownManager->wakeUp(bank, sc_time_stamp());
if (controller->isBusy(sc_time_stamp(), bank))
{
printDebugMessage("\t-> break: controller is busy");
return;
}
tlm_generic_payload* nextTransaction = scheduler->getTransactionForBank(bank);
if (controller->scheduleRequest(sc_time_stamp(), *nextTransaction))
{
scheduler->popTransactionForBank(bank, nextTransaction);
printDebugMessage("\t-> payload was scheduled by core");
}
else
{
printDebugMessage("\t-> break: payload was not scheduled by core (collision with refresh)");
}
}
else
{
printDebugMessage("\t-> break: no transaction for bank");
controller->powerDownManager->sleep(bank, sc_time_stamp());
}
}
tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay)
{
return TLM_ACCEPTED;
}
// Initiated by dram frontend
// --- FRONTEND INTERACTION ------
tlm_sync_enum nb_transport_fw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay)
{
DramExtension::getExtension(payload);
TlmRecorder::getInstance().recordPhase(payload, phase, sc_time_stamp());
if (phase == BEGIN_REQ)
{
payload.acquire();
TlmRecorder::getInstance().recordPhase(payload, phase, sc_time_stamp());
payloadEntersSystem(payload);
if (getNumberOfPayloadsInSystem() > controller->config.MaxNrOfTransactions)
if (getTotalNumberOfPayloadsInSystem() > controller->config.MaxNrOfTransactions)
{
printDebugMessage("##Backpressure: Max number of transactions in system reached");
backpressure = &payload;
@@ -336,9 +260,88 @@ private:
}
}
void dramPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase)
void payloadEntersSystem(tlm_generic_payload& payload)
{
Bank bank = DramExtension::getExtension(payload).getBank();
printDebugMessage(
"Payload enters system on bank " + to_string(bank.ID()) + ". Total number of payloads in Controller: "
+ to_string(getTotalNumberOfPayloadsInSystem()));
numberOfPayloadsInSystem[bank]++;
}
void payloadLeavesSystem(tlm_generic_payload& payload)
{
Bank bank = DramExtension::getExtension(payload).getBank();
numberOfPayloadsInSystem[bank]--;
controller->powerDownManager->sleep(bank, sc_time_stamp());
printDebugMessage(
"Payload left system on bank " + to_string(bank.ID()) + ". Total number of payloads in Controller: "
+ to_string(getTotalNumberOfPayloadsInSystem()));
}
unsigned int getTotalNumberOfPayloadsInSystem()
{
unsigned int sum = 0;
for (Bank bank : controller->getBanks())
{
sum += numberOfPayloadsInSystem[bank];
}
return sum;
}
void scheduleNextPayload(Bank bank)
{
printDebugMessage("Triggering schedule next payload on bank " + to_string(bank.ID()));
if (scheduler->hasTransactionForBank(bank))
{
controller->powerDownManager->wakeUp(bank, sc_time_stamp());
if (controller->isBusy(sc_time_stamp(), bank))
{
printDebugMessage("\t-> break: controller is busy");
return;
}
tlm_generic_payload* nextTransaction = scheduler->getTransactionForBank(bank);
if (controller->scheduleRequest(sc_time_stamp(), *nextTransaction))
{
scheduler->popTransactionForBank(bank, nextTransaction);
printDebugMessage("\t-> payload was scheduled by core");
}
else
{
printDebugMessage("\t-> break: payload was not scheduled by core (collision with refresh)");
}
}
else
{
printDebugMessage("\t-> break: no transaction for bank");
controller->powerDownManager->sleep(bank, sc_time_stamp());
}
}
void sendToFrontend(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay)
{
tlm_phase TPhase = phase;
sc_time TDelay = delay;
tSocket->nb_transport_bw(payload, TPhase, TDelay);
}
// --- DRAM INTERACTION ------
tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay)
{
dramPEQ.notify(payload, phase, bwDelay);
return TLM_ACCEPTED;
}
void dramPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase)
{
TlmRecorder::getInstance().recordPhase(payload, phase, sc_time_stamp());
Bank bank = DramExtension::getExtension(payload).getBank();
printDebugMessage("Received " + phaseNameToString(phase) + " from DRAM");
if (phase == BEGIN_RD || phase == BEGIN_WR)
{
scheduleNextPayload(bank);
@@ -357,25 +360,6 @@ private:
sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME);
scheduleNextPayload(bank);
}
else if (isIn(phase, { BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA }))
{
sendToDram(payload, phase, SC_ZERO_TIME);
}
else if (isIn(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF }))
{
printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID()));
sendToDram(payload, phase, SC_ZERO_TIME);
}
else if (isIn(phase, { END_PDNA, END_PDNP, END_SREF }))
{
printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID()));
sendToDram(payload, phase, SC_ZERO_TIME);
}
else if (phase == BEGIN_AUTO_REFRESH)
{
printDebugMessage("Entering auto refresh on bank " + to_string(bank.ID()));
sendToDram(payload, phase, SC_ZERO_TIME);
}
else if (phase == END_AUTO_REFRESH)
{
printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID()));
@@ -387,40 +371,20 @@ private:
}
else
{
ostringstream oss;
oss << phase;
string str = string("dramPEQCallback queue in controller wrapper was triggered with unknown phase ") + oss.str();
string str = string("dramPEQCallback queue in controller wrapper was triggered with unsupported phase ")
+ phaseNameToString(phase);
SC_REPORT_FATAL(0, str.c_str());
}
}
void controllerPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase)
{
if (phase == REFRESH_TRIGGER)
{
controller->triggerRefresh(payload, sc_time_stamp());
}
else
{
SC_REPORT_FATAL(0, "controllerPEQCallback queue in controller wrapper was triggered with unknown phase");
}
}
void sendToDram(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay)
{
DramExtension::getExtension(payload);
tlm_phase TPhase = phase;
sc_time TDelay = delay;
iSocket->nb_transport_fw(payload, TPhase, TDelay);
}
void sendToFrontend(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay)
{
tlm_phase TPhase = phase;
sc_time TDelay = delay;
tSocket->nb_transport_bw(payload, TPhase, TDelay);
}
//Helpers
void printDebugMessage(string message)
{
debugManager.printDebugMessage(name(), message);

View File

@@ -9,34 +9,28 @@
#define DRAM_H_
#include <iomanip>
#include <fstream>
#include <tlm.h>
#include <systemc.h>
#include <tlm_utils/peq_with_cb_and_phase.h>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
#include "../common/DebugManager.h"
#include "../core/TimingCalculation.h"
#include "../common/protocol.h"
#include "../common/xmlConfig.h"
#include "../common/Utils.h"
using namespace sc_core;
using namespace sc_dt;
using namespace std;
using namespace tlm;
using namespace core;
template <unsigned int BUSWIDTH = 128, unsigned int WORDS = 4096, bool STORE = true, bool FIXED_BL = false, unsigned int FIXED_BL_VALUE = 0>
struct Dram: sc_module
{
tlm_utils::simple_target_socket<Dram, BUSWIDTH, tlm::tlm_base_protocol_types> tSocket;
sc_event target_done_event;
tlm_utils::peq_with_cb_and_phase<Dram> m_peq;
xmlConfig xc;
tlm_utils::peq_with_cb_and_phase<Dram> controllePEQ;
SC_CTOR(Dram) : tSocket("socket") ,m_peq(this, &Dram::peq_cb)
SC_CTOR(Dram) : tSocket("socket") ,controllePEQ(this, &Dram::controllerPEQCallback)
{
tSocket.register_nb_transport_fw(this, &Dram::nb_transport_fw);
tSocket.register_nb_transport_fw(this, &Dram::nb_transport_fw);
}
~Dram()
@@ -44,48 +38,48 @@ struct Dram: sc_module
}
// TLM-2 non-blocking transport method
virtual tlm::tlm_sync_enum nb_transport_fw( tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay )
{
// Queue the transaction until the annotated time has elapsed
m_peq.notify( trans, phase, delay);
controllePEQ.notify(trans, phase, delay);
return tlm::TLM_ACCEPTED;
}
void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase)
void controllerPEQCallback(tlm::tlm_generic_payload& payload, const tlm::tlm_phase& phase)
{
if(phase == BEGIN_PRE || phase == BEGIN_PRE_ALL)
if(phase == BEGIN_PRE)
{
if(phase == BEGIN_PRE)
{
send_end_pre(trans);
}
sendToController(payload, END_PRE, getExecutionTime(Command::Precharge, payload));
}
else if (phase == BEGIN_PRE_ALL)
{
sendToController(payload, END_PRE_ALL, getExecutionTime(Command::PrechargeAll, payload));
}
else if(phase == BEGIN_ACT)
{
send_end_act(trans);
sendToController(payload, END_ACT, getExecutionTime(Command::Activate, payload));
}
else if(phase == BEGIN_WR)
{
send_end_wr(trans,true);
sendToController(payload, END_WR, getExecutionTime(Command::Write, payload));
}
else if(phase == BEGIN_RD)
{
send_end_rd(trans,true);
sendToController(payload, END_RD, getExecutionTime(Command::Read, payload));
}
else if(phase == BEGIN_WRA)
{
send_end_wr(trans,false);
sendToController(payload, END_WRA, getExecutionTime(Command::WriteA, payload));
}
else if(phase == BEGIN_RDA)
{
send_end_rd(trans,false);
sendToController(payload, END_RDA, getExecutionTime(Command::ReadA, payload));
}
else if(phase == BEGIN_AUTO_REFRESH)
{
send_end_auto_refresh(trans);
sendToController(payload, END_AUTO_REFRESH, getExecutionTime(Command::AutoRefresh, payload));
}
//Powerdown phases have to be started and ended by the controller, because they do not have a fixed length
else if(phase == BEGIN_PDNP)
{
@@ -109,91 +103,26 @@ struct Dram: sc_module
else if(phase == END_SREF)
{
}
else // case tlm::BEGIN_REQ,END_REQ...
{
SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by target (2)");
}
}
void send_end_auto_refresh(tlm::tlm_generic_payload& trans)
{
tlm::tlm_phase bw_phase;
sc_time delay;
bw_phase = END_AUTO_REFRESH;
delay = xc.tREFB;
tSocket->nb_transport_bw( trans, bw_phase, delay );
}
void send_end_rd(tlm::tlm_generic_payload& trans, bool open_page_policy_f)
{
tlm::tlm_phase bw_phase;
sc_time delay = SC_ZERO_TIME;
unsigned int BL = 2;
if(open_page_policy_f == true)
{
bw_phase = END_RD;
delay = xc.tRL + xc.clk * BL;
}
else
{
bw_phase = END_RDA;
delay = xc.tRL + xc.clk * BL;
SC_REPORT_FATAL("DRAM", "DRAM PEQ was called with unknown phase");
}
tSocket->nb_transport_bw( trans, bw_phase, delay );
}
void send_end_wr(tlm::tlm_generic_payload& trans, bool open_page_policy_f)
void sendToController(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay)
{
tlm::tlm_phase bw_phase;
sc_time delay = SC_ZERO_TIME;
unsigned int BL = 2;
if(open_page_policy_f == true)
{
bw_phase = END_WR;
delay = xc.tWL + xc.clk * (BL -1);
}
else
{
bw_phase = END_WRA;
delay = xc.tWL + xc.clk * (BL -1) + xc.tWR;
}
// Send end of WR
tSocket->nb_transport_bw( trans, bw_phase, delay );
tlm_phase TPhase = phase;
sc_time TDelay = delay;
tSocket->nb_transport_bw(payload, TPhase, TDelay);
}
void send_end_pre(tlm::tlm_generic_payload& trans)
void printDebugMessage(string message)
{
tlm::tlm_phase bw_phase;
sc_time delay;
bw_phase = END_PRE;
delay = xc.tRP;
tSocket->nb_transport_bw( trans, bw_phase, delay );
DebugManager::getInstance().printDebugMessage(name(), message);
}
void send_end_act(tlm::tlm_generic_payload& trans)
{
tlm::tlm_phase bw_phase;
sc_time delay;
bw_phase = END_ACT;
delay = xc.tRCD;
tSocket->nb_transport_bw( trans, bw_phase, delay );
}
};

View File

@@ -35,11 +35,11 @@ int sc_main(int argc, char **argv)
{
sc_set_time_resolution(1, SC_PS);
resources = pathOfFile(argv[0]) + string("/../resources/");
string simulationToRun = "first.xml";
SimulationManager manager(resources);
manager.loadSimulationFromXML("/home/jonny/git/dram.vp.system/dram/resources/simulations/first.xml");
manager.loadSimulationFromXML(resources + "/simulations/" + simulationToRun);
manager.runSimulations();
manager.startTraceAnalyzer();
return 0;