diff --git a/DRAMSys/analyzer/scripts/tests.py b/DRAMSys/analyzer/scripts/tests.py index ee844236..531c5c8a 100755 --- a/DRAMSys/analyzer/scripts/tests.py +++ b/DRAMSys/analyzer/scripts/tests.py @@ -109,11 +109,36 @@ class DramConfig(object): self.tXSRDLL = self.clk * memspec.getIntValue("XSDLL") self.tAL = self.clk * memspec.getIntValue("AL") self.tRFC = self.clk * memspec.getIntValue("RFC") + + elif (self. memoryType == "DDR3"): + self.nActivateWindow = 4 + self.tRP = self.clk * memspec.getIntValue("RP"); + self.tRAS = self.clk * memspec.getIntValue("RAS"); + self.tRC = self.clk * memspec.getIntValue("RC"); + self.tRTP = self.clk * memspec.getIntValue("RTP"); + self.tRRD_S = self.clk * memspec.getIntValue("RRD"); + self.tRRD_L = self.clk * memspec.getIntValue("RRD"); + self.tCCD_S = self.clk * memspec.getIntValue("CCD"); + self.tCCD_L = self.clk * memspec.getIntValue("CCD"); + self.tRCD = self.clk * memspec.getIntValue("RCD"); + self.tNAW = self.clk * memspec.getIntValue("FAW"); + self.tRL = self.clk * memspec.getIntValue("RL"); + self.tWL = self.clk * memspec.getIntValue("WL"); + self.tWR = self.clk * memspec.getIntValue("WR"); + self.tWTR_S = self.clk * memspec.getIntValue("WTR"); + self.tWTR_L = self.clk * memspec.getIntValue("WTR"); + self.tCKESR = self.clk * memspec.getIntValue("CKESR"); + self.tCKE = self.clk * memspec.getIntValue("CKE"); + self.tXP = self.clk * memspec.getIntValue("XP"); + self.tXPDLL = self.clk * memspec.getIntValue("XPDLL"); + self.tXSR = self.clk * memspec.getIntValue("XS"); + self.tXSRDLL = self.clk * memspec.getIntValue("XSDLL"); + self.tAL = self.clk * memspec.getIntValue("AL"); + self.tRFC = self.clk * memspec.getIntValue("RFC"); + else: raise Exception("MemoryType not supported yet. Insert a coin into the coin machine and try again") - # TODO ADD DDR3 - def clkAlign(self, value): return math.ceil(1.0*value/self.clk)*self.clk diff --git a/DRAMSys/simulator/resources/configs/memspecs/SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit.xml b/DRAMSys/simulator/resources/configs/memspecs/SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit.xml new file mode 120000 index 00000000..23f3dba5 --- /dev/null +++ b/DRAMSys/simulator/resources/configs/memspecs/SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit.xml @@ -0,0 +1 @@ +../../../src/common/third_party/DRAMPower/memspecs/SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit.xml \ No newline at end of file diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index 40038097..457f50a5 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -99,12 +99,14 @@ SOURCES += \ src/controller/core/configuration/ConfigurationLoader.cpp \ src/controller/core/powerdown/NoPowerDown.cpp \ src/controller/Command.cpp \ - src/controller/Controller.cpp \ src/controller/ControllerState.cpp \ src/controller/RowBufferStates.cpp \ src/controller/scheduler/IScheduler.cpp \ src/controller/scheduler/FifoStrict.cpp \ - src/error/errormodel.cpp + src/error/errormodel.cpp \ + src/controller/Controller.cpp \ + src/simulation/TracePlayer.cpp \ + src/simulation/StlPlayer.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ diff --git a/DRAMSys/simulator/src/controller/Controller.cpp b/DRAMSys/simulator/src/controller/Controller.cpp index a6422469..52b416d6 100644 --- a/DRAMSys/simulator/src/controller/Controller.cpp +++ b/DRAMSys/simulator/src/controller/Controller.cpp @@ -30,11 +30,497 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: - * Janik Schlemminger * Robert Gernhardt * Matthias Jung */ #include "Controller.h" +void Controller::buildScheduler() +{ + string selectedScheduler = Configuration::getInstance().Scheduler; + if (selectedScheduler == "FIFO") + { + scheduler = new Fifo(*controllerCore); + } + else if (selectedScheduler == "FIFO_STRICT") + { + scheduler = new FifoStrict(*this, *controllerCore); + } + else if (selectedScheduler == "FR_FCFS") + { + scheduler = new FR_FCFS(*controllerCore); + } + // else if (selectedScheduler == "PAR_BS") + // { + // scheduler = new PAR_BS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, + // Configuration::getInstance().Capsize); + // } + // else if (selectedScheduler == "Grouper") + // { + // scheduler = new ReadWriteGrouper(*controllerCore); + // } + else + reportFatal(name(), "unsupported scheduler: " + selectedScheduler); +} + +void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payload) +{ + sc_assert(command.getStart() >= sc_time_stamp()); + TimeInterval dataStrobe; + + switch (command.getCommand()) + { + //TODO: refactor tlm recorder + case Command::Read: + dataStrobe = command.getIntervalOnDataStrobe(); + tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); + controllerCorePEQ.notify(payload, BEGIN_RD, command.getStart() - sc_time_stamp()); + break; + case Command::ReadA: + dataStrobe = command.getIntervalOnDataStrobe(); + tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); + controllerCorePEQ.notify(payload, BEGIN_RDA, command.getStart() - sc_time_stamp()); + break; + case Command::Write: + dataStrobe = command.getIntervalOnDataStrobe(); + tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); + controllerCorePEQ.notify(payload, BEGIN_WR, command.getStart() - sc_time_stamp()); + break; + case Command::WriteA: + dataStrobe = command.getIntervalOnDataStrobe(); + tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); + controllerCorePEQ.notify(payload, BEGIN_WRA, command.getStart() - sc_time_stamp()); + break; + case Command::AutoRefresh: + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, BEGIN_REFA, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, BEGIN_REFB, command.getStart() - sc_time_stamp()); + break; + case Command::Activate: + controllerCorePEQ.notify(payload, BEGIN_ACT, command.getStart() - sc_time_stamp()); + break; + case Command::Precharge: + controllerCorePEQ.notify(payload, BEGIN_PRE, command.getStart() - sc_time_stamp()); + break; + case Command::PrechargeAll: + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp()); + break; + case Command::PDNA: + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, BEGIN_PDNAB, command.getStart() - sc_time_stamp()); + break; + case Command::PDNAX: + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, END_PDNA, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, END_PDNAB, command.getStart() - sc_time_stamp()); + break; + case Command::PDNP: + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, BEGIN_PDNPB, command.getStart() - sc_time_stamp()); + break; + case Command::PDNPX: + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, END_PDNP, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, END_PDNPB, command.getStart() - sc_time_stamp()); + break; + case Command::SREF: + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, BEGIN_SREFB, command.getStart() - sc_time_stamp()); + break; + case Command::SREFX: + if(!Configuration::getInstance().BankwiseLogic) + { + if(command.getBank() == Bank(0)) + controllerCorePEQ.notify(payload, END_SREF, command.getStart() - sc_time_stamp()); + } + else + controllerCorePEQ.notify(payload, END_SREFB, command.getStart() - sc_time_stamp()); + break; + default: + SC_REPORT_FATAL(0, "unsupported command was sent by controller"); + break; + } +} + +void Controller::send(Trigger trigger, sc_time time, tlm_generic_payload &payload) +{ + sc_assert(time >= sc_time_stamp()); + + sc_time delay = time - sc_time_stamp(); + if (trigger == Trigger::REFTrigger) + { + controllerCorePEQ.notify(payload, REF_TRIGGER, delay); + } + else if (trigger == Trigger::PDNTrigger) + { + controllerCorePEQ.notify(payload, PDN_TRIGGER, delay); + } + else + { + SC_REPORT_FATAL("controller wrapper", "unknown trigger"); + } +} + +void Controller::controllerCorePEQCallback(tlm_generic_payload &payload, const tlm_phase &phase) +{ + if (phase == REF_TRIGGER) + { + controllerCore->triggerRefresh(payload); + } + else if (phase == PDN_TRIGGER) + { + controllerCore->powerDownManager->sleep(DramExtension::getExtension(payload).getBank(),sc_time_stamp()); + } + else + { + Bank bank = DramExtension::getBank(payload); + sendToDram(payload, phase, SC_ZERO_TIME); + + if (phase == BEGIN_RD || phase == BEGIN_WR) + { + scheduleNextFromScheduler(DramExtension::getBank(payload)); + } + else if (phase == BEGIN_REFB) + printDebugMessage("Entering REFB on bank " + to_string(bank.ID())); + else if (phase == BEGIN_REFA) + printDebugMessage("Entering REFA"); + else if (containsPhase(phase, { BEGIN_PDNAB, BEGIN_PDNPB, BEGIN_SREFB })) + printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); + else if (containsPhase(phase, { END_PDNAB, END_PDNPB, END_SREFB })) + printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); + else if (containsPhase(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF })) + printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on all banks"); + else if (containsPhase(phase, { END_PDNA, END_PDNP, END_SREF })) + printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on all banks" ); + else if (containsPhase(phase, { BEGIN_RD, BEGIN_WR, BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA })) + { + } + else + SC_REPORT_FATAL(0, "refreshTriggerPEQCallback queue in controller wrapper was triggered with unsupported phase"); + } +} + +tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &fwDelay) +{ + sc_time recTime; + sc_time notDelay; + if (phase == BEGIN_REQ) + { + 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); + + //Bandwidth IDLE + if ((getTotalNumberOfPayloadsInSystem()== 0)&& idleState){ + endBandwidthIdleCollector(); + } + } + else if (phase == END_RESP) + { + 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()); + + // Badnwith IDLE + if (getTotalNumberOfPayloadsInSystem()==1){ + startBandwidthIdleCollector(); + } + + tlmRecorder->recordPhase(payload, phase, recTime); + frontendPEQ.notify(payload, phase, notDelay); + } + return TLM_ACCEPTED; +} + +unsigned int Controller::transport_dbg(tlm::tlm_generic_payload& trans) +{ + return iSocket->transport_dbg(trans); +} + +void Controller::frontendPEQCallback(tlm_generic_payload &payload, const tlm_phase &phase) +{ + if (phase == BEGIN_REQ) + { + printDebugMessage(string("Payload in system: ") + to_string(getTotalNumberOfPayloadsInSystem())); + payload.acquire(); + payloadEntersSystem(payload); + if (getTotalNumberOfPayloadsInSystem() > controllerCore->config.MaxNrOfTransactions) + { + printDebugMessage("##Backpressure: Max number of transactions in system reached"); + backpressure = &payload; + return; + } + payload.set_response_status(tlm::TLM_OK_RESPONSE); + sendToFrontend(payload, END_REQ, SC_ZERO_TIME); + + scheduler->schedule(&payload); + scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank()); + } + else if (phase == END_RESP) + { + if (backpressure != NULL) + { + printDebugMessage("##Backpressure released"); + backpressure->set_response_status(tlm::TLM_OK_RESPONSE); + sendToFrontend(*backpressure, END_REQ, SC_ZERO_TIME); + + scheduler->schedule(backpressure); + scheduleNextFromScheduler(DramExtension::getExtension(backpressure).getBank()); + backpressure = NULL; + } + + payloadLeavesSystem(payload); + payload.release(); + } + else + { + SC_REPORT_FATAL(0, "Frontend PEQ event queue in controller wrapper was triggered with unknown phase"); + } +} + +void Controller::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]++; + // Set Start Time for Simulation + if (startTimeSet == false){ + printDebugMessage("Simulation Timer Start"); + startTime = sc_time_stamp()-Configuration::getInstance().memSpec.clk; + startTimeSet = true; + } +} + +void Controller::payloadLeavesSystem(tlm_generic_payload &payload) +{ + Bank bank = DramExtension::getExtension(payload).getBank(); + numberOfPayloadsInSystem[bank]--; + printDebugMessage( + "Payload left system on bank " + to_string(bank.ID()) + ". Total number of payloads in Controller: " + + to_string(getTotalNumberOfPayloadsInSystem())); + controllerCore->powerDownManager->triggerSleep(bank, sc_time_stamp()); +} + +unsigned int Controller::getTotalNumberOfPayloadsInSystem() +{ + unsigned int sum = 0; + for (Bank bank : controllerCore->getBanks()) + { + sum += numberOfPayloadsInSystem[bank]; + } + return sum; +} + +void Controller::scheduleNextFromScheduler(Bank bank) +{ + + if(controllerCore->bankIsBusy(bank)) + { + return; + } + + pair nextRequest = scheduler->getNextRequest(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 [" + commandToString(nextRequest.first) + "]"); + } + + while (!blockedRequests.empty()) { + bank = blockedRequests.front(); + blockedRequests.pop(); + + pair nextRequest = scheduler->getNextRequest(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 [" + commandToString(nextRequest.first) + "] (unblocked)"); + } + } + +} + +void Controller::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); +} + +tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &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()); + + dramPEQ.notify(payload, phase, notDelay); + tlmRecorder->recordPhase(payload, phase, recTime); + + return TLM_ACCEPTED; +} + +void Controller::dramPEQCallback(tlm_generic_payload &payload, const tlm_phase &phase) +{ + Bank bank = DramExtension::getExtension(payload).getBank(); + printDebugMessage("Received " + phaseNameToString(phase) + " on bank " + to_string(bank.ID()) + " from DRAM"); + + if (phase == END_RD || phase == END_WR) + { + sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); + } + else if (phase == END_RDA || phase == END_WRA) + { + sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); + scheduleNextFromScheduler(bank); + } + else if (phase == END_REFA) + { + printDebugMessage("Finished auto refresh on all banks "); + + bool sleepy = true; + for(Bank bank : controllerCore->getBanks()) + { + if(numberOfPayloadsInSystem[bank] != 0) + { + sleepy = false; + scheduleNextFromScheduler(bank); + } + } + + if(sleepy == true) + { + controllerCore->powerDownManager->sleep(0,sc_time_stamp()); + } + } + else if(phase == END_REFB) + { + printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID())); + + if(numberOfPayloadsInSystem[bank] == 0) + { + controllerCore->powerDownManager->sleep(bank,sc_time_stamp()); + } + else + { + scheduleNextFromScheduler(bank); + } + scheduleNextFromScheduler(bank); + } + else if (containsPhase(phase, { END_PRE, END_ACT })) + { + scheduleNextFromScheduler(bank); + } + else if(phase == END_PRE_ALL) + { + // No need to trigger anything for a END_PRE_ALL. It is followed by a AUTO_REFRESH anyway (in our current + // scheduler implementation) + } + else + { + string str = string("dramPEQCallback queue in controller wrapper was triggered with unsupported phase ") + + phaseNameToString(phase); + SC_REPORT_FATAL(0, str.c_str()); + } +} + +void Controller::sendToDram(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) +{ + tlm_phase TPhase = phase; + sc_time TDelay = delay; + iSocket->nb_transport_fw(payload, TPhase, TDelay); +} + +void Controller::printDebugMessage(string message) +{ + debugManager.printDebugMessage(name(), message); +} + +bool Controller::containsPhase(tlm_phase phase, std::vector phases) +{ + for (tlm_phase p : phases) + { + if (p == phase) + return true; + } + return false; +} + +void Controller::terminateSimulation() +{ + for (Bank bank : controllerCore->getBanks()) + { + controllerCore->powerDownManager->wakeUp(bank, clkAlign(sc_time_stamp())); + } +} + +void Controller::startBandwidthIdleCollector() +{ + printDebugMessage("IDLE Start"); + idleStart = sc_time_stamp(); + endTime = sc_time_stamp(); + idleState = true; +} + +void Controller::endBandwidthIdleCollector() +{ + printDebugMessage("IDLE End"); + idleTime += sc_time_stamp()-idleStart+ Configuration::getInstance().memSpec.clk; + idleState = false; +} + +sc_time Controller::getIdleTime() +{ + printDebugMessage("IDLE Time: "+idleTime.to_string()); + return idleTime; +} + +sc_time Controller::getEndTime() +{ + printDebugMessage("End Time: "+endTime.to_string()); + return endTime; +} + +sc_time Controller::getStartTime() +{ + printDebugMessage("Start Time: "+startTime.to_string()); + return startTime; +} diff --git a/DRAMSys/simulator/src/controller/Controller.h b/DRAMSys/simulator/src/controller/Controller.h index 7fc07d8a..a07a8b74 100644 --- a/DRAMSys/simulator/src/controller/Controller.h +++ b/DRAMSys/simulator/src/controller/Controller.h @@ -72,18 +72,17 @@ using namespace std; using namespace tlm; -template struct Controller: public sc_module, public IController { public: Controller(sc_module_name /*name*/, TlmRecorder *rec) : - frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerCorePEQ(this, &Controller::controllerCorePEQCallback), debugManager(DebugManager::getInstance()), tlmRecorder(rec) + frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerCorePEQ(this, &Controller::controllerCorePEQCallback), debugManager(DebugManager::getInstance()), tlmRecorder(rec) { controllerCore = new ControllerCore("core", *this, numberOfPayloadsInSystem); buildScheduler(); - iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw); - tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw); - tSocket.register_transport_dbg(this, &Controller::transport_dbg); + iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw); + tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw); + tSocket.register_transport_dbg(this, &Controller::transport_dbg); } ~Controller() @@ -102,8 +101,8 @@ public: virtual void send(const ScheduledCommand& command, tlm_generic_payload& payload) override; virtual void send(Trigger trigger, sc_time time, tlm_generic_payload& payload) override; - tlm_utils::simple_initiator_socket iSocket; - tlm_utils::simple_target_socket tSocket; + tlm_utils::simple_initiator_socket iSocket; + tlm_utils::simple_target_socket tSocket; unsigned int getTotalNumberOfPayloadsInSystem(); private: @@ -156,511 +155,5 @@ private: }; -// --- IMPLEMENTATION ----- -template -void Controller::buildScheduler() -{ - string selectedScheduler = Configuration::getInstance().Scheduler; - - if (selectedScheduler == "FIFO") - { - scheduler = new Fifo(*controllerCore); - } - else if (selectedScheduler == "FIFO_STRICT") - { - scheduler = new FifoStrict(*this, *controllerCore); - } - else if (selectedScheduler == "FR_FCFS") - { - scheduler = new FR_FCFS(*controllerCore); - } -// else if (selectedScheduler == "PAR_BS") -// { -// scheduler = new PAR_BS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, -// Configuration::getInstance().Capsize); -// } -// else if (selectedScheduler == "Grouper") -// { -// scheduler = new ReadWriteGrouper(*controllerCore); -// } - else - reportFatal(name(), "unsupported scheduler: " + selectedScheduler); -} - -template -void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payload) -{ - sc_assert(command.getStart() >= sc_time_stamp()); - TimeInterval dataStrobe; - - switch (command.getCommand()) - { - //TODO: refactor tlm recorder - case Command::Read: - dataStrobe = command.getIntervalOnDataStrobe(); - tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); - controllerCorePEQ.notify(payload, BEGIN_RD, command.getStart() - sc_time_stamp()); - break; - case Command::ReadA: - dataStrobe = command.getIntervalOnDataStrobe(); - tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); - controllerCorePEQ.notify(payload, BEGIN_RDA, command.getStart() - sc_time_stamp()); - break; - case Command::Write: - dataStrobe = command.getIntervalOnDataStrobe(); - tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); - controllerCorePEQ.notify(payload, BEGIN_WR, command.getStart() - sc_time_stamp()); - break; - case Command::WriteA: - dataStrobe = command.getIntervalOnDataStrobe(); - tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); - controllerCorePEQ.notify(payload, BEGIN_WRA, command.getStart() - sc_time_stamp()); - break; - case Command::AutoRefresh: - if(!Configuration::getInstance().BankwiseLogic) - { - if(command.getBank() == Bank(0)) - controllerCorePEQ.notify(payload, BEGIN_REFA, command.getStart() - sc_time_stamp()); - } - else - controllerCorePEQ.notify(payload, BEGIN_REFB, command.getStart() - sc_time_stamp()); - break; - case Command::Activate: - controllerCorePEQ.notify(payload, BEGIN_ACT, command.getStart() - sc_time_stamp()); - break; - case Command::Precharge: - controllerCorePEQ.notify(payload, BEGIN_PRE, command.getStart() - sc_time_stamp()); - break; - case Command::PrechargeAll: - if(command.getBank() == Bank(0)) - controllerCorePEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp()); - break; - case Command::PDNA: - if(!Configuration::getInstance().BankwiseLogic) - { - if(command.getBank() == Bank(0)) - controllerCorePEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp()); - } - else - controllerCorePEQ.notify(payload, BEGIN_PDNAB, command.getStart() - sc_time_stamp()); - break; - case Command::PDNAX: - if(!Configuration::getInstance().BankwiseLogic) - { - if(command.getBank() == Bank(0)) - controllerCorePEQ.notify(payload, END_PDNA, command.getStart() - sc_time_stamp()); - } - else - controllerCorePEQ.notify(payload, END_PDNAB, command.getStart() - sc_time_stamp()); - break; - case Command::PDNP: - if(!Configuration::getInstance().BankwiseLogic) - { - if(command.getBank() == Bank(0)) - controllerCorePEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp()); - } - else - controllerCorePEQ.notify(payload, BEGIN_PDNPB, command.getStart() - sc_time_stamp()); - break; - case Command::PDNPX: - if(!Configuration::getInstance().BankwiseLogic) - { - if(command.getBank() == Bank(0)) - controllerCorePEQ.notify(payload, END_PDNP, command.getStart() - sc_time_stamp()); - } - else - controllerCorePEQ.notify(payload, END_PDNPB, command.getStart() - sc_time_stamp()); - break; - case Command::SREF: - if(!Configuration::getInstance().BankwiseLogic) - { - if(command.getBank() == Bank(0)) - controllerCorePEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp()); - } - else - controllerCorePEQ.notify(payload, BEGIN_SREFB, command.getStart() - sc_time_stamp()); - break; - case Command::SREFX: - if(!Configuration::getInstance().BankwiseLogic) - { - if(command.getBank() == Bank(0)) - controllerCorePEQ.notify(payload, END_SREF, command.getStart() - sc_time_stamp()); - } - else - controllerCorePEQ.notify(payload, END_SREFB, command.getStart() - sc_time_stamp()); - break; - default: - SC_REPORT_FATAL(0, "unsupported command was sent by controller"); - break; - } -} - -template -void Controller::send(Trigger trigger, sc_time time, tlm_generic_payload &payload) -{ - sc_assert(time >= sc_time_stamp()); - - sc_time delay = time - sc_time_stamp(); - if (trigger == Trigger::REFTrigger) - { - controllerCorePEQ.notify(payload, REF_TRIGGER, delay); - } - else if (trigger == Trigger::PDNTrigger) - { - controllerCorePEQ.notify(payload, PDN_TRIGGER, delay); - } - else - { - SC_REPORT_FATAL("controller wrapper", "unknown trigger"); - } -} - -template -void Controller::controllerCorePEQCallback(tlm_generic_payload &payload, const tlm_phase &phase) -{ - if (phase == REF_TRIGGER) - { - controllerCore->triggerRefresh(payload); - } - else if (phase == PDN_TRIGGER) - { - controllerCore->powerDownManager->sleep(DramExtension::getExtension(payload).getBank(),sc_time_stamp()); - } - else - { - Bank bank = DramExtension::getBank(payload); - sendToDram(payload, phase, SC_ZERO_TIME); - - if (phase == BEGIN_RD || phase == BEGIN_WR) - { - scheduleNextFromScheduler(DramExtension::getBank(payload)); - } - else if (phase == BEGIN_REFB) - printDebugMessage("Entering REFB on bank " + to_string(bank.ID())); - else if (phase == BEGIN_REFA) - printDebugMessage("Entering REFA"); - else if (containsPhase(phase, { BEGIN_PDNAB, BEGIN_PDNPB, BEGIN_SREFB })) - printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); - else if (containsPhase(phase, { END_PDNAB, END_PDNPB, END_SREFB })) - printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); - else if (containsPhase(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF })) - printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on all banks"); - else if (containsPhase(phase, { END_PDNA, END_PDNP, END_SREF })) - printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on all banks" ); - else if (containsPhase(phase, { BEGIN_RD, BEGIN_WR, BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA })) - { - } - else - SC_REPORT_FATAL(0, "refreshTriggerPEQCallback queue in controller wrapper was triggered with unsupported phase"); - } -} - -template -tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &fwDelay) -{ - sc_time recTime; - sc_time notDelay; - if (phase == BEGIN_REQ) - { - 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); - - //Bandwidth IDLE - if ((getTotalNumberOfPayloadsInSystem()== 0)&& idleState){ - endBandwidthIdleCollector(); - } - } - else if (phase == END_RESP) - { - 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()); - - // Badnwith IDLE - if (getTotalNumberOfPayloadsInSystem()==1){ - startBandwidthIdleCollector(); - } - - tlmRecorder->recordPhase(payload, phase, recTime); - frontendPEQ.notify(payload, phase, notDelay); - } - return TLM_ACCEPTED; -} - -template -unsigned int Controller::transport_dbg(tlm::tlm_generic_payload& trans) -{ - return iSocket->transport_dbg(trans); -} - -template -void Controller::frontendPEQCallback(tlm_generic_payload &payload, const tlm_phase &phase) -{ - if (phase == BEGIN_REQ) - { - printDebugMessage(string("Payload in system: ") + to_string(getTotalNumberOfPayloadsInSystem())); - payload.acquire(); - payloadEntersSystem(payload); - if (getTotalNumberOfPayloadsInSystem() > controllerCore->config.MaxNrOfTransactions) - { - printDebugMessage("##Backpressure: Max number of transactions in system reached"); - backpressure = &payload; - return; - } - payload.set_response_status(tlm::TLM_OK_RESPONSE); - sendToFrontend(payload, END_REQ, SC_ZERO_TIME); - - scheduler->schedule(&payload); - scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank()); - } - else if (phase == END_RESP) - { - if (backpressure != NULL) - { - printDebugMessage("##Backpressure released"); - backpressure->set_response_status(tlm::TLM_OK_RESPONSE); - sendToFrontend(*backpressure, END_REQ, SC_ZERO_TIME); - - scheduler->schedule(backpressure); - scheduleNextFromScheduler(DramExtension::getExtension(backpressure).getBank()); - backpressure = NULL; - } - - payloadLeavesSystem(payload); - payload.release(); - } - else - { - SC_REPORT_FATAL(0, "Frontend PEQ event queue in controller wrapper was triggered with unknown phase"); - } -} - -template -void Controller::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]++; - // Set Start Time for Simulation - if (startTimeSet == false){ - printDebugMessage("Simulation Timer Start"); - startTime = sc_time_stamp()-Configuration::getInstance().memSpec.clk; - startTimeSet = true; - } -} - -template -void Controller::payloadLeavesSystem(tlm_generic_payload &payload) -{ - Bank bank = DramExtension::getExtension(payload).getBank(); - numberOfPayloadsInSystem[bank]--; - printDebugMessage( - "Payload left system on bank " + to_string(bank.ID()) + ". Total number of payloads in Controller: " - + to_string(getTotalNumberOfPayloadsInSystem())); - controllerCore->powerDownManager->triggerSleep(bank, sc_time_stamp()); -} - -template -unsigned int Controller::getTotalNumberOfPayloadsInSystem() -{ - unsigned int sum = 0; - for (Bank bank : controllerCore->getBanks()) - { - sum += numberOfPayloadsInSystem[bank]; - } - return sum; -} - -template -void Controller::scheduleNextFromScheduler(Bank bank) -{ - - if(controllerCore->bankIsBusy(bank)) - { - return; - } - - pair nextRequest = scheduler->getNextRequest(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 [" + commandToString(nextRequest.first) + "]"); - } - - while (!blockedRequests.empty()) { - bank = blockedRequests.front(); - blockedRequests.pop(); - - pair nextRequest = scheduler->getNextRequest(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 [" + commandToString(nextRequest.first) + "] (unblocked)"); - } - } - -} - -template -void Controller::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); -} - -template -tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &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()); - - dramPEQ.notify(payload, phase, notDelay); - tlmRecorder->recordPhase(payload, phase, recTime); - - return TLM_ACCEPTED; -} - -template -void Controller::dramPEQCallback(tlm_generic_payload &payload, const tlm_phase &phase) -{ - Bank bank = DramExtension::getExtension(payload).getBank(); - printDebugMessage("Received " + phaseNameToString(phase) + " on bank " + to_string(bank.ID()) + " from DRAM"); - - if (phase == END_RD || phase == END_WR) - { - sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); - } - else if (phase == END_RDA || phase == END_WRA) - { - sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); - scheduleNextFromScheduler(bank); - } - else if (phase == END_REFA) - { - printDebugMessage("Finished auto refresh on all banks "); - - bool sleepy = true; - for(Bank bank : controllerCore->getBanks()) - { - if(numberOfPayloadsInSystem[bank] != 0) - { - sleepy = false; - scheduleNextFromScheduler(bank); - } - } - - if(sleepy == true) - { - controllerCore->powerDownManager->sleep(0,sc_time_stamp()); - } - } - else if(phase == END_REFB) - { - printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID())); - - if(numberOfPayloadsInSystem[bank] == 0) - { - controllerCore->powerDownManager->sleep(bank,sc_time_stamp()); - } - else - { - scheduleNextFromScheduler(bank); - } - scheduleNextFromScheduler(bank); - } - else if (containsPhase(phase, { END_PRE, END_ACT })) - { - scheduleNextFromScheduler(bank); - } - else if(phase == END_PRE_ALL) - { - // No need to trigger anything for a END_PRE_ALL. It is followed by a AUTO_REFRESH anyway (in our current - // scheduler implementation) - } - else - { - string str = string("dramPEQCallback queue in controller wrapper was triggered with unsupported phase ") - + phaseNameToString(phase); - SC_REPORT_FATAL(0, str.c_str()); - } -} - -template -void Controller::sendToDram(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) -{ - tlm_phase TPhase = phase; - sc_time TDelay = delay; - iSocket->nb_transport_fw(payload, TPhase, TDelay); -} - -template -void Controller::printDebugMessage(string message) -{ - debugManager.printDebugMessage(name(), message); -} - -template -bool Controller::containsPhase(tlm_phase phase, std::vector phases) -{ - for (tlm_phase p : phases) - { - if (p == phase) - return true; - } - return false; -} - -template -void Controller::terminateSimulation() -{ - for (Bank bank : controllerCore->getBanks()) - { - controllerCore->powerDownManager->wakeUp(bank, clkAlign(sc_time_stamp())); - } -} - -template -void Controller::startBandwidthIdleCollector(){ - printDebugMessage("IDLE Start"); - idleStart = sc_time_stamp(); - endTime = sc_time_stamp(); - idleState = true; -} - -template -void Controller::endBandwidthIdleCollector(){ - printDebugMessage("IDLE End"); - idleTime += sc_time_stamp()-idleStart+ Configuration::getInstance().memSpec.clk; - idleState = false; -} -template -sc_time Controller::getIdleTime(){ - printDebugMessage("IDLE Time: "+idleTime.to_string()); - return idleTime; -} -template -sc_time Controller::getEndTime(){ - printDebugMessage("End Time: "+endTime.to_string()); - return endTime; -} -template -sc_time Controller::getStartTime(){ - printDebugMessage("Start Time: "+startTime.to_string()); - return startTime; -} - - #endif /* CONTROLLERWRAPPER_H_ */ diff --git a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp index e8c079f5..a892ab43 100644 --- a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp +++ b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp @@ -78,29 +78,31 @@ ControllerCore::ControllerCore(sc_module_name /*name*/, IController& wrapperConn if (config.BankwiseLogic) { - refreshManager = new RefreshManagerBankwise("refManagerBw", *this); - powerDownManager = new PowerDownManagerBankwise("pdnManagerBw", *this); + refreshManager = new RefreshManagerBankwise("refManagerBw", *this); } else { - refreshManager = new RefreshManager("refManager", *this); + refreshManager = new RefreshManager("refManager", *this); + } - if(config.PowerDownMode == EPowerDownMode::Staggered) - { - powerDownManager = new PowerDownManager("pdnManager", *this); - } - else if(config.PowerDownMode == EPowerDownMode::TimeoutPDN || config.PowerDownMode == EPowerDownMode::TimeoutSREF) - { - powerDownManager = new PowerDownManagerTimeout("pdnManagerTout", *this); - } - else if(config.PowerDownMode == EPowerDownMode::NoPowerDown) - { - powerDownManager = new NoPowerDown(); - } + if(config.PowerDownMode == EPowerDownMode::Staggered) + { + if (config.BankwiseLogic) + powerDownManager = new PowerDownManagerBankwise("pdnManagerBw", *this); else - { - SC_REPORT_FATAL(0, "Unsupported powerdown mode in constructor of controller core"); - } + powerDownManager = new PowerDownManager("pdnManager", *this); + } + else if(config.PowerDownMode == EPowerDownMode::TimeoutPDN || config.PowerDownMode == EPowerDownMode::TimeoutSREF) + { + powerDownManager = new PowerDownManagerTimeout("pdnManagerTout", *this); + } + else if(config.PowerDownMode == EPowerDownMode::NoPowerDown) + { + powerDownManager = new NoPowerDown(); + } + else + { + SC_REPORT_FATAL(0, "Unsupported powerdown mode in constructor of controller core"); } } diff --git a/DRAMSys/simulator/src/controller/core/scheduling/checker/RefreshChecker.cpp b/DRAMSys/simulator/src/controller/core/scheduling/checker/RefreshChecker.cpp index 3978253e..0fec86e2 100644 --- a/DRAMSys/simulator/src/controller/core/scheduling/checker/RefreshChecker.cpp +++ b/DRAMSys/simulator/src/controller/core/scheduling/checker/RefreshChecker.cpp @@ -57,17 +57,16 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const } else if (lastCommandOnBank.getCommand() == Command::WriteA) { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); } else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXP); } else if (lastCommandOnBank.getCommand() == Command::SREFX) - { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXSR); - } + { + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXSR); + } else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) { } diff --git a/DRAMSys/simulator/src/simulation/Arbiter.h b/DRAMSys/simulator/src/simulation/Arbiter.h index 6d1bee1f..db8c46af 100644 --- a/DRAMSys/simulator/src/simulation/Arbiter.h +++ b/DRAMSys/simulator/src/simulation/Arbiter.h @@ -54,11 +54,10 @@ using namespace std; using namespace tlm; -template struct Arbiter: public sc_module { public: - tlm_utils::multi_passthrough_initiator_socket iSocket; - tlm_utils::multi_passthrough_target_socket tSocket; + tlm_utils::multi_passthrough_initiator_socket iSocket; + tlm_utils::multi_passthrough_target_socket tSocket; SC_CTOR(Arbiter) : payloadEventQueue(this, &Arbiter::peqCallback) { // The arbiter communicates with one or more memory unity through one or more sockets (one or more memory channels). diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index 89e08283..90293eea 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -61,11 +61,13 @@ using namespace std; using namespace tlm; using namespace Data; -template struct Dram : sc_module { + // FIXME: remove this define and use the value from config + const static unsigned int BUSWIDTH = 128; + // TLM Related: - tlm_utils::simple_target_socket tSocket; + tlm_utils::simple_target_socket tSocket; // Power Model related bool powerAnalysis = Configuration::getInstance().PowerAnalysis; @@ -86,7 +88,7 @@ struct Dram : sc_module map< unsigned long int, std::array > memory; TlmRecorder *tlmRecorder; - Controller<>* dramController; + Controller *dramController; SC_CTOR(Dram) : tSocket("socket") { @@ -582,7 +584,7 @@ struct Dram : sc_module { tlmRecorder = rec; } - void setDramController(Controller<> *contr) + void setDramController(Controller *contr) { dramController = contr; } diff --git a/DRAMSys/simulator/src/simulation/ReorderBuffer.h b/DRAMSys/simulator/src/simulation/ReorderBuffer.h index 744a4517..bbc1bc14 100644 --- a/DRAMSys/simulator/src/simulation/ReorderBuffer.h +++ b/DRAMSys/simulator/src/simulation/ReorderBuffer.h @@ -45,12 +45,11 @@ using namespace std; using namespace tlm; -template struct ReorderBuffer: public sc_module { public: - tlm_utils::simple_initiator_socket iSocket; - tlm_utils::simple_target_socket tSocket; + tlm_utils::simple_initiator_socket iSocket; + tlm_utils::simple_target_socket tSocket; SC_CTOR(ReorderBuffer) : payloadEventQueue(this, &ReorderBuffer::peqCallback), responseIsPendingInInitator(false) diff --git a/DRAMSys/simulator/src/simulation/Simulation.cpp b/DRAMSys/simulator/src/simulation/Simulation.cpp index 186d4b81..7dec81dc 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.cpp +++ b/DRAMSys/simulator/src/simulation/Simulation.cpp @@ -117,20 +117,20 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT #if 0 for (size_t i = 0; i < Configuration::getInstance().NumberOfTracePlayers; i++) { std::string playerStr = "tracePlayer" + std::to_string(i); - TracePlayer<> *player; + 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 // or if you simply dont care about the data the normal StlPlayer is used. if(Configuration::getInstance().ErrorStoreMode == ErrorStorageMode::NoStorage) { - StlPlayer<> *newPlayer = new StlPlayer<>(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this); + StlPlayer *newPlayer = new StlPlayer(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this); player = newPlayer; newPlayer->getTraceLength(pathToResources + string("traces/") + devices[i].trace); totalTransactions += newPlayer->getNumberOfLines(pathToResources + string("traces/") + devices[i].trace); } else { - StlDataPlayer<> *newPlayer = new StlDataPlayer<>(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this); + StlDataPlayer *newPlayer = new StlDataPlayer(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this); player = newPlayer; newPlayer->getTraceLength(pathToResources + string("traces/") + devices[i].trace); totalTransactions += newPlayer->getNumberOfLines(pathToResources + string("traces/") + devices[i].trace); @@ -145,18 +145,18 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT // Create and properly initialize TLM recorders. They need to be ready before creating some modules. setupTlmRecorders(traceName, pathToResources, devices); - arbiter = new Arbiter<128>("arbiter"); + arbiter = new Arbiter("arbiter"); arbiter->setTlmRecorders(tlmRecorders); init = new ExampleInitiator<>("init"); for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) { std::string str = "controller" + std::to_string(i); - Controller<> *controller = new Controller<>(str.c_str(), tlmRecorders[i]); + Controller *controller = new Controller(str.c_str(), tlmRecorders[i]); controllers.push_back(controller); str = "dram" + std::to_string(i); - Dram<> *dram = new Dram<>(str.c_str()); + Dram *dram = new Dram(str.c_str()); dram->setTlmRecorder(tlmRecorders[i]); dram->setDramController(controllers[i]); drams.push_back(dram); diff --git a/DRAMSys/simulator/src/simulation/Simulation.h b/DRAMSys/simulator/src/simulation/Simulation.h index b38e31af..df26e78c 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.h +++ b/DRAMSys/simulator/src/simulation/Simulation.h @@ -97,16 +97,16 @@ private: // A vector of pointers to all trace player (devices which acquire the bus // and initiate transactions targeting the memory) - std::vector*> players; + std::vector players; // All transactions pass through the same arbiter ExampleInitiator<> *init; - Arbiter<> *arbiter; + Arbiter *arbiter; // Each DRAM unit has a controller - std::vector*> controllers; + std::vector controllers; // TODO: Each DRAM has a reorder buffer (check this!) - ReorderBuffer<> *reorder; + ReorderBuffer *reorder; // DRAM units - std::vector*> drams; + std::vector drams; // Transaction Recorders (one per channel). They generate the output databases. std::vector tlmRecorders; @@ -118,7 +118,7 @@ private: void setupTlmRecorders(const string &traceName, const string &pathToResources, const std::vector &devices); void instantiateModules(const string &traceName, const string &pathToResources, const std::vector &devices); void bindSockets(); - void setupDebugManager(const string& traceName); + void setupDebugManager(const string &traceName); }; #endif /* SIMULATIONMANAGER_H_ */ diff --git a/DRAMSys/simulator/src/simulation/StlDataPlayer.h b/DRAMSys/simulator/src/simulation/StlDataPlayer.h index 8c29b30b..9c520b4b 100644 --- a/DRAMSys/simulator/src/simulation/StlDataPlayer.h +++ b/DRAMSys/simulator/src/simulation/StlDataPlayer.h @@ -45,8 +45,7 @@ using namespace std; using namespace tlm; -template -struct StlDataPlayer: public TracePlayer +struct StlDataPlayer: public TracePlayer { public: StlDataPlayer(sc_module_name /*name*/, string pathToTrace, unsigned int clkMhz, TracePlayerListener* listener); @@ -199,10 +198,9 @@ private: }; -template -StlDataPlayer::StlDataPlayer(sc_module_name /*name*/, string pathToTrace, unsigned int clkMhz, +StlDataPlayer::StlDataPlayer(sc_module_name /*name*/, string pathToTrace, unsigned int clkMhz, TracePlayerListener* listener) : - TracePlayer(listener),file(pathToTrace) + TracePlayer(listener),file(pathToTrace) { if (!file.is_open()) SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); diff --git a/DRAMSys/simulator/src/simulation/StlPlayer.cpp b/DRAMSys/simulator/src/simulation/StlPlayer.cpp new file mode 100644 index 00000000..b0bb4a00 --- /dev/null +++ b/DRAMSys/simulator/src/simulation/StlPlayer.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2015, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Janik Schlemminger + * Robert Gernhardt + * Matthias Jung + */ + +#include "StlPlayer.h" + + +StlPlayer::StlPlayer(sc_module_name /*name*/, string pathToTrace, unsigned int clkMhz, + TracePlayerListener* listener) : + TracePlayer(listener),file(pathToTrace) +{ + if (!file.is_open()) + SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); + + if(clkMhz == 0) + clk = Configuration::getInstance().memSpec.clk; + else + clk = FrequencyToClk(clkMhz); + + this->burstlength = Configuration::getInstance().memSpec.BurstLength; + this->bytesPerColumn = xmlAddressDecoder::getInstance().amount["bytes"]; +} diff --git a/DRAMSys/simulator/src/simulation/StlPlayer.h b/DRAMSys/simulator/src/simulation/StlPlayer.h index 809a4da7..cb56a556 100644 --- a/DRAMSys/simulator/src/simulation/StlPlayer.h +++ b/DRAMSys/simulator/src/simulation/StlPlayer.h @@ -45,8 +45,7 @@ using namespace std; using namespace tlm; -template -struct StlPlayer: public TracePlayer +struct StlPlayer: public TracePlayer { public: StlPlayer(sc_module_name /*name*/, string pathToTrace, unsigned int clkMhz, TracePlayerListener *listener); @@ -185,23 +184,4 @@ private: sc_time clk; }; - -template -StlPlayer::StlPlayer(sc_module_name /*name*/, string pathToTrace, unsigned int clkMhz, - TracePlayerListener* listener) : - TracePlayer(listener),file(pathToTrace) -{ - if (!file.is_open()) - SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); - - if(clkMhz == 0) - clk = Configuration::getInstance().memSpec.clk; - else - clk = FrequencyToClk(clkMhz); - - this->burstlength = Configuration::getInstance().memSpec.BurstLength; - this->bytesPerColumn = xmlAddressDecoder::getInstance().amount["bytes"]; -} - #endif // STLPLAYER_H - diff --git a/DRAMSys/simulator/src/simulation/TraceGenerator.h b/DRAMSys/simulator/src/simulation/TraceGenerator.h index 2f9ade1d..1cb3ccfb 100644 --- a/DRAMSys/simulator/src/simulation/TraceGenerator.h +++ b/DRAMSys/simulator/src/simulation/TraceGenerator.h @@ -44,12 +44,19 @@ using namespace std; using namespace tlm; -template -struct TraceGenerator: public TracePlayer +struct TraceGenerator: public TracePlayer { public: TraceGenerator(sc_module_name /*name*/, unsigned int clkMhz, - TracePlayerListener* listener); + TracePlayerListener* listener) : TracePlayer(listener), transCounter(0) + { + if(clkMhz == 0) + clk = Configuration::getInstance().memSpec.clk; + else + clk = FrequencyToClk(clkMhz); + + this->burstlenght = Configuration::getInstance().memSpec.BurstLength; + } virtual void nextPayload() override { @@ -67,32 +74,18 @@ public: payload->set_dmi_allowed(false); payload->set_byte_enable_length(0); payload->set_streaming_width(this->burstlenght); - this->setDataPointer(payload, dataElement); + this->setDataPointer(payload, dataElement, 16); payload->set_command(TLM_READ_COMMAND); transCounter++; this->payloadEventQueue.notify(*payload, BEGIN_REQ, SC_ZERO_TIME); } - private: unsigned int burstlenght; sc_time clk; unsigned int transCounter; }; - -template -TraceGenerator::TraceGenerator(sc_module_name /*name*/, unsigned int clkMhz, - TracePlayerListener* listener) : - TracePlayer(listener), transCounter(0) -{ - if(clkMhz == 0) - clk = Configuration::getInstance().memSpec.clk; - else - clk = FrequencyToClk(clkMhz); - - this->burstlenght = Configuration::getInstance().memSpec.BurstLength; -} - #endif + diff --git a/DRAMSys/simulator/src/simulation/TracePlayer.cpp b/DRAMSys/simulator/src/simulation/TracePlayer.cpp new file mode 100644 index 00000000..42a726cc --- /dev/null +++ b/DRAMSys/simulator/src/simulation/TracePlayer.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Robert Gernhardt + * Matthias Jung + */ + +#include "TracePlayer.h" + +TracePlayer::TracePlayer(TracePlayerListener* listener) : + payloadEventQueue(this, &TracePlayer::peqCallback), transactionsSent(0), listener(listener) +{ + iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw); +} + +gp *TracePlayer::allocatePayload() +{ + return memoryManager.allocate(); +} + +void TracePlayer::terminate() +{ + cout << sc_time_stamp() << " " << this->name() << " terminated " << std::endl; + listener->tracePlayerTerminates(); +} + +void TracePlayer::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage(this->name(), message); +} + +//TODO: this doesn't depend on the tracePlayer, move it somewhere +void TracePlayer::setDataPointer(gp* payload, unsigned char * dataElement, unsigned int size) +{ + //check if payload takes ownership + payload->set_data_length(size); + payload->set_data_ptr(dataElement); + for(unsigned i = 0; i < size; i++) + dataElement[i] = 0; +} + +tlm_sync_enum TracePlayer::nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) +{ + payloadEventQueue.notify(payload, phase, bwDelay); + return TLM_ACCEPTED; +} + +void TracePlayer::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) +{ + + if (phase == BEGIN_REQ) + { + payload.acquire(); + GenerationExtension* genExtension = new GenerationExtension(sc_time_stamp()); + payload.set_auto_extension(genExtension); + sendToTarget(payload, phase, SC_ZERO_TIME); + + transactionsSent++; + DebugManager::getInstance().printDebugMessage(name(), "Performing request #" + std::to_string(transactionsSent)); + } + else if (phase == END_REQ) + { + nextPayload(); + } + else if (phase == BEGIN_RESP) + { + sendToTarget(payload, END_RESP, SC_ZERO_TIME); + payload.release(); + if(Configuration::getInstance().SimulationProgressBar) + listener->transactionFinished(); + } + else if (phase == END_RESP) + { + } + else + { + SC_REPORT_FATAL(0, "TracePlayer PEQ was triggered with unknown phase"); + } +} diff --git a/DRAMSys/simulator/src/simulation/TracePlayer.h b/DRAMSys/simulator/src/simulation/TracePlayer.h index 070b8127..7182fc67 100644 --- a/DRAMSys/simulator/src/simulation/TracePlayer.h +++ b/DRAMSys/simulator/src/simulation/TracePlayer.h @@ -55,12 +55,11 @@ using namespace std; using namespace tlm; -template struct TracePlayer: public sc_module { public: - tlm_utils::simple_initiator_socket iSocket; - TracePlayer(TracePlayerListener* listener); + tlm_utils::simple_initiator_socket iSocket; + TracePlayer(TracePlayerListener *listener); virtual void nextPayload() = 0; protected: @@ -73,112 +72,15 @@ protected: private: tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay); void peqCallback(tlm_generic_payload& payload, const tlm_phase& phase); - void sendToTarget(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay); - + void sendToTarget(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) + { + tlm_phase TPhase = phase; + sc_time TDelay = delay; + iSocket->nb_transport_fw(payload, TPhase, TDelay); + } MemoryManager memoryManager; unsigned int transactionsSent; TracePlayerListener* listener; }; -template -TracePlayer::TracePlayer(TracePlayerListener* listener) : - payloadEventQueue(this, &TracePlayer::peqCallback), transactionsSent(0), listener(listener) -{ - iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw); -} - -template -gp *TracePlayer::allocatePayload() -{ - return memoryManager.allocate(); -} - -template -void TracePlayer::terminate() -{ - cout << sc_time_stamp() << " " << this->name() << " terminated " << std::endl; - listener->tracePlayerTerminates(); -} - -template -void TracePlayer::printDebugMessage(std::string message) -{ - DebugManager::getInstance().printDebugMessage(this->name(), message); -} - -template -//TODO: this doesn't depend on the tracePlayer, move it somewhere -void TracePlayer::setDataPointer(gp* payload, unsigned char * dataElement, unsigned int size) -{ - //check if payload takes ownership - payload->set_data_length(size); - payload->set_data_ptr(dataElement); - for(unsigned i = 0; i < size; i++) - dataElement[i] = 0; -} - -template -tlm_sync_enum TracePlayer::nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) -{ - payloadEventQueue.notify(payload, phase, bwDelay); - return TLM_ACCEPTED; -} - -template -void TracePlayer::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) -{ - - if (phase == BEGIN_REQ) - { - payload.acquire(); - GenerationExtension* genExtension = new GenerationExtension(sc_time_stamp()); - payload.set_auto_extension(genExtension); - sendToTarget(payload, phase, SC_ZERO_TIME); - - transactionsSent++; - DebugManager::getInstance().printDebugMessage(name(), "Performing request #" + std::to_string(transactionsSent)); - } - else if (phase == END_REQ) - { - nextPayload(); - } - else if (phase == BEGIN_RESP) - { -//TODO: cleanup: -// unsigned char * dataElement = payload.get_data_ptr(); -// -// if(payload.get_command() == TLM_READ_COMMAND) -// { -// cout << "0x"; -// for(int i=0; i < 16*2; i++) -// { -// cout << hex << int(dataElement[i]); -// } -// cout << endl; -// } - - sendToTarget(payload, END_RESP, SC_ZERO_TIME); - payload.release(); - if(Configuration::getInstance().SimulationProgressBar) - listener->transactionFinished(); - - } - else if (phase == END_RESP) - { - } - else - { - SC_REPORT_FATAL(0, "TracePlayer PEQ was triggered with unknown phase"); - } -} - -template -void TracePlayer::sendToTarget(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) -{ - tlm_phase TPhase = phase; - sc_time TDelay = delay; - iSocket->nb_transport_fw(payload, TPhase, TDelay); -} - #endif /* TRACEPLAYER_H_ */ -