From e547991e4ed3a9835de459994fc6011b93dce953 Mon Sep 17 00:00:00 2001 From: robert Date: Sat, 12 Apr 2014 12:05:04 +0200 Subject: [PATCH] reeintegrated dram module --- dram/.settings/language.settings.xml | 2 +- dram/src/common/TlmRecorder.cpp | 6 - dram/src/common/TlmRecorder.h | 7 +- dram/src/common/protocol.h | 1 - dram/src/common/xmlAddressdecoder.cpp | 6 - dram/src/common/xmlAddressdecoder.h | 83 ++--- dram/src/core/TimingCalculation.cpp | 68 ++-- dram/src/core/TimingCalculation.h | 2 + dram/src/core/configuration/Configuration.cpp | 6 - dram/src/core/configuration/Configuration.h | 6 +- dram/src/core/powerdown/PowerDownManager.cpp | 8 +- .../powerdown/PowerDownManagerBankwise.cpp | 4 +- dram/src/simulation/Controller.h | 303 ++++++++---------- dram/src/simulation/Dram.h | 125 ++------ dram/src/simulation/main.cpp | 4 +- 15 files changed, 256 insertions(+), 375 deletions(-) diff --git a/dram/.settings/language.settings.xml b/dram/.settings/language.settings.xml index 127cd8ac..b20c7d94 100644 --- a/dram/.settings/language.settings.xml +++ b/dram/.settings/language.settings.xml @@ -4,7 +4,7 @@ - + diff --git a/dram/src/common/TlmRecorder.cpp b/dram/src/common/TlmRecorder.cpp index d77184ff..84fb4f2c 100644 --- a/dram/src/common/TlmRecorder.cpp +++ b/dram/src/common/TlmRecorder.cpp @@ -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) diff --git a/dram/src/common/TlmRecorder.h b/dram/src/common/TlmRecorder.h index 19293037..fba69078 100755 --- a/dram/src/common/TlmRecorder.h +++ b/dram/src/common/TlmRecorder.h @@ -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 recordPhase(tlm::tlm_generic_payload &trans, std::string name, sc_time begin, sc_time end); diff --git a/dram/src/common/protocol.h b/dram/src/common/protocol.h index 6740fbd5..08b16358 100755 --- a/dram/src/common/protocol.h +++ b/dram/src/common/protocol.h @@ -43,7 +43,6 @@ DECLARE_EXTENDED_PHASE(END_SREF); //Triggers DECLARE_EXTENDED_PHASE(REFRESH_TRIGGER); -DECLARE_EXTENDED_PHASE(WAKEUP_TRIGGER); #endif diff --git a/dram/src/common/xmlAddressdecoder.cpp b/dram/src/common/xmlAddressdecoder.cpp index 7271b39c..f81d5f47 100644 --- a/dram/src/common/xmlAddressdecoder.cpp +++ b/dram/src/common/xmlAddressdecoder.cpp @@ -73,12 +73,6 @@ xmlAddressDecoder::xmlAddressDecoder(string addressConfigURI) } } -xmlAddressDecoder& xmlAddressDecoder::getInstance() -{ - static xmlAddressDecoder decoder(xmlAddressDecoder::addressConfigURI); - return decoder; -} - xmlAddressDecoder::~xmlAddressDecoder() { delete doc; diff --git a/dram/src/common/xmlAddressdecoder.h b/dram/src/common/xmlAddressdecoder.h index 0ff5ffeb..61546dde 100755 --- a/dram/src/common/xmlAddressdecoder.h +++ b/dram/src/common/xmlAddressdecoder.h @@ -13,7 +13,6 @@ /// \date 02.07.2012 // - #include #include #include @@ -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 - T getAttribute(TiXmlElement * element, const std::string s) - { - T d; - element->QueryValueAttribute(s, &d); - return d; - } + TiXmlDocument * doc; + TiXmlElement * dramconfig; + TiXmlElement * addressmap; + + template + T getAttribute(TiXmlElement * element, const std::string s) + { + T d; + element->QueryValueAttribute(s, &d); + return d; + } }; - #endif diff --git a/dram/src/core/TimingCalculation.cpp b/dram/src/core/TimingCalculation.cpp index 643b02a7..9472c8c0 100644 --- a/dram/src/core/TimingCalculation.cpp +++ b/dram/src/core/TimingCalculation.cpp @@ -14,7 +14,6 @@ namespace core { - sc_time getDistance(sc_time a, sc_time b) { if (a > b) @@ -40,31 +39,30 @@ 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 lengthOnDataStrobe = getBurstLengthOnDataStrobe(payload.get_streaming_width()); - if(Configuration::getInstance().DataRate == 1) + if (Configuration::getInstance().DataRate == 1) lengthOnDataStrobe -= Configuration::getInstance().Timings.clk; if (command == Command::Write) @@ -76,55 +74,67 @@ sc_time getExecutionTime(Command command,tlm::tlm_generic_payload& payload) return config.tWL + lengthOnDataStrobe + config.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) - { - assert(config.tCKE == config.clk * 3); - 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); } } + diff --git a/dram/src/core/TimingCalculation.h b/dram/src/core/TimingCalculation.h index a6f5bbb3..b579240c 100644 --- a/dram/src/core/TimingCalculation.h +++ b/dram/src/core/TimingCalculation.h @@ -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); diff --git a/dram/src/core/configuration/Configuration.cpp b/dram/src/core/configuration/Configuration.cpp index 48e766c5..9ba25e5a 100644 --- a/dram/src/core/configuration/Configuration.cpp +++ b/dram/src/core/configuration/Configuration.cpp @@ -21,11 +21,5 @@ Configuration::Configuration() loader.loadConfiguration(*this, Configuration::memspecUri, Configuration::memconfigUri); } -Configuration& Configuration::getInstance() -{ - static Configuration configuration; - return configuration; -} - } /* namespace core */ diff --git a/dram/src/core/configuration/Configuration.h b/dram/src/core/configuration/Configuration.h index 24a1c12f..f72b9077 100644 --- a/dram/src/core/configuration/Configuration.h +++ b/dram/src/core/configuration/Configuration.h @@ -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; diff --git a/dram/src/core/powerdown/PowerDownManager.cpp b/dram/src/core/powerdown/PowerDownManager.cpp index 431e8501..660c78df 100644 --- a/dram/src/core/powerdown/PowerDownManager.cpp +++ b/dram/src/core/powerdown/PowerDownManager.cpp @@ -60,7 +60,7 @@ void PowerDownManager::sleep(Bank bank, sc_time time) } ScheduledCommand pdn(IPowerDownManager::getSleepCommand(state), time, - getExecutionTime(IPowerDownManager::getSleepCommand(state), powerDownPayloads[bank]), + getMinimalExecutionTime(IPowerDownManager::getSleepCommand(state), powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank])); controller.state.bus.moveCommandToNextFreeSlot(pdn); @@ -96,14 +96,14 @@ void PowerDownManager::wakeUp(Bank bank, sc_time time) case PowerDownState::PDNSelfRefresh: startOfExitCommand = max(time, controller.state.getLastCommand(Command::SREF).getEnd()); controller.refreshManager->reInitialize(bank, - startOfExitCommand + getExecutionTime(Command::SREFX, powerDownPayloads[bank])); + startOfExitCommand + getMinimalExecutionTime(Command::SREFX, powerDownPayloads[bank])); break; default: break; } Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); - ScheduledCommand pdn(cmd, startOfExitCommand, getExecutionTime(cmd, powerDownPayloads[bank]), + ScheduledCommand pdn(cmd, startOfExitCommand, getMinimalExecutionTime(cmd, powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank])); setState(PowerDownState::Awake); @@ -116,7 +116,7 @@ void PowerDownManager::wakeUpForRefresh(Bank bank, sc_time time) if (isInPowerDown()) { Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); - ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), + ScheduledCommand pdn(cmd, time, getMinimalExecutionTime(cmd, powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank])); setState(PowerDownState::AwakeForRefresh); diff --git a/dram/src/core/powerdown/PowerDownManagerBankwise.cpp b/dram/src/core/powerdown/PowerDownManagerBankwise.cpp index 0b7ea60a..1a41a685 100644 --- a/dram/src/core/powerdown/PowerDownManagerBankwise.cpp +++ b/dram/src/core/powerdown/PowerDownManagerBankwise.cpp @@ -32,7 +32,7 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time) return; tlm_generic_payload& payload = powerDownPayloads[bank]; - sc_time minTime = getExecutionTime(Command::PDNA, payload); + sc_time minTime = getMinimalExecutionTime(Command::PDNA, payload); PowerDownState state = powerDownStates[bank]; if (state == PowerDownState::Awake) //coming from active @@ -49,7 +49,7 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time) else { state = PowerDownState::PDNSelfRefresh; - minTime = getExecutionTime(Command::SREF, payload); + minTime = getMinimalExecutionTime(Command::SREF, payload); } } diff --git a/dram/src/simulation/Controller.h b/dram/src/simulation/Controller.h index 58aee120..f578db2e 100644 --- a/dram/src/simulation/Controller.h +++ b/dram/src/simulation/Controller.h @@ -43,21 +43,14 @@ public: Controller(sc_module_name name) : frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerPEQ(this, - &Controller::controllerPEQCallback), debugManager(DebugManager::getInstance()) + &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,71 @@ public: } } + // ------- Interaction with controller core --------- virtual void send(const ScheduledCommand& command, tlm_generic_payload& payload) override { 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()); + controllerPEQ.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()); + controllerPEQ.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()); + controllerPEQ.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()); + controllerPEQ.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()); + controllerPEQ.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()); + controllerPEQ.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()); + controllerPEQ.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()); + controllerPEQ.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()); + controllerPEQ.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()); + controllerPEQ.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()); + controllerPEQ.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()); + controllerPEQ.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()); + controllerPEQ.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()); + dramPEQ.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 @@ -206,6 +168,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()); + sendToDram(payload, phase, SC_ZERO_TIME); + + if (phase == BEGIN_RD || phase == BEGIN_WR) + scheduleNextPayload(bank); + else if (isIn(phase, { BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA })) + { + } + 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 if (phase == BEGIN_AUTO_REFRESH) + printDebugMessage("Entering auto refresh 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; @@ -217,72 +207,10 @@ private: tlm_utils::peq_with_cb_and_phase dramPEQ; tlm_utils::peq_with_cb_and_phase controllerPEQ; - sc_time inputBufferDelay; DebugManager& debugManager; - unsigned int getNumberOfPayloadsInSystem() - { - unsigned int sum = 0; - for (Bank bank : controller->getBanks()) - { - sum += numberOfPayloadsInSystem[bank]; - } - return sum; - } + // --- FRONTEND INTERACTION ------ - 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)) - { - - if (controller->isBusy(sc_time_stamp(), bank)) - { - printDebugMessage("\t-> break: controller is busy"); - return; - } - - controller->powerDownManager->wakeUp(bank, sc_time_stamp()); - - 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 tlm_sync_enum nb_transport_fw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay) { DramExtension::getExtension(payload); @@ -336,44 +264,88 @@ private: } } - void dramPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase) + void payloadEntersSystem(tlm_generic_payload& payload) { Bank bank = DramExtension::getExtension(payload).getBank(); - if (phase == BEGIN_RD || phase == BEGIN_WR) + 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()); + } + + unsigned int getNumberOfPayloadsInSystem() + { + unsigned int sum = 0; + for (Bank bank : controller->getBanks()) { - scheduleNextPayload(bank); - sendToDram(payload, phase, SC_ZERO_TIME); + sum += numberOfPayloadsInSystem[bank]; } - else if (phase == END_RD || phase == END_WR) + return sum; + } + + void scheduleNextPayload(Bank bank) + { + printDebugMessage("Triggering schedule next payload on bank " + to_string(bank.ID())); + if (scheduler->hasTransactionForBank(bank)) { - TlmRecorder::getInstance().recordPhase(payload, BEGIN_RESP, sc_time_stamp()); - sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); + + if (controller->isBusy(sc_time_stamp(), bank)) + { + printDebugMessage("\t-> break: controller is busy"); + return; + } + + controller->powerDownManager->wakeUp(bank, sc_time_stamp()); + + 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 if (phase == END_RDA || phase == END_WRA) + 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(); + + if (phase == END_RD || phase == END_WR || phase == END_RDA || phase == END_WRA) { TlmRecorder::getInstance().recordPhase(payload, BEGIN_RESP, sc_time_stamp()); 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())); @@ -385,25 +357,12 @@ 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); @@ -412,13 +371,7 @@ private: 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); diff --git a/dram/src/simulation/Dram.h b/dram/src/simulation/Dram.h index b5dbbc58..bd84ef3b 100644 --- a/dram/src/simulation/Dram.h +++ b/dram/src/simulation/Dram.h @@ -9,22 +9,16 @@ #define DRAM_H_ -#include -#include #include #include #include -#include #include - +#include "../core/TimingCalculation.h" #include "../common/protocol.h" -#include "../common/xmlConfig.h" -using namespace sc_core; -using namespace sc_dt; using namespace std; using namespace tlm; - +using namespace core; template struct Dram: sc_module @@ -32,7 +26,6 @@ struct Dram: sc_module tlm_utils::simple_target_socket tSocket; sc_event target_done_event; tlm_utils::peq_with_cb_and_phase m_peq; - xmlConfig xc; SC_CTOR(Dram) : tSocket("socket") ,m_peq(this, &Dram::peq_cb) { @@ -44,48 +37,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); return tlm::TLM_ACCEPTED; } - void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase) + void peq_cb(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,phase, getExecutionTime(Command::Precharge, payload)); + } + else if (phase == BEGIN_PRE_ALL) + { + sendToController(payload,phase, getExecutionTime(Command::PrechargeAll, payload)); } else if(phase == BEGIN_ACT) { - send_end_act(trans); + sendToController(payload,phase, getExecutionTime(Command::Activate, payload)); } else if(phase == BEGIN_WR) { - send_end_wr(trans,true); + sendToController(payload,phase, getExecutionTime(Command::Write, payload)); } else if(phase == BEGIN_RD) { - send_end_rd(trans,true); + sendToController(payload,phase, getExecutionTime(Command::Read, payload)); } else if(phase == BEGIN_WRA) { - send_end_wr(trans,false); + sendToController(payload,phase, getExecutionTime(Command::WriteA, payload)); } else if(phase == BEGIN_RDA) { - send_end_rd(trans,false); + sendToController(payload,phase, getExecutionTime(Command::ReadA, payload)); } else if(phase == BEGIN_AUTO_REFRESH) { - send_end_auto_refresh(trans); + sendToController(payload,phase, 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,90 +102,20 @@ 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 ); - } - - void send_end_pre(tlm::tlm_generic_payload& trans) - { - tlm::tlm_phase bw_phase; - sc_time delay; - - bw_phase = END_PRE; - delay = xc.tRP; - - tSocket->nb_transport_bw( trans, bw_phase, delay ); - } - 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 ); + DramExtension::getExtension(payload); + tlm_phase TPhase = phase; + sc_time TDelay = delay; + tSocket->nb_transport_bw(payload, TPhase, TDelay); } }; diff --git a/dram/src/simulation/main.cpp b/dram/src/simulation/main.cpp index 8c67fa28..b48cc665 100644 --- a/dram/src/simulation/main.cpp +++ b/dram/src/simulation/main.cpp @@ -77,7 +77,7 @@ int sc_main(int argc, char **argv) sc_set_time_resolution(1, SC_PS); - resources = pathOfFile(argv[0]) + string("/../resources/"); + resources = pathOfFile(argv[0]) + string("/../resources/"); DramSetup setup; setup.memconfig = "memconfig.xml"; @@ -98,7 +98,7 @@ int sc_main(int argc, char **argv) string traceName("tpr.tdb"); string trace2 = "empty.stl"; - string trace1 = "chstone-jpeg_32.stl"; + string trace1 = "mediabench-g721encode_32.stl"; //trace1 = "trace.stl";