From 9646c0e93b98b9db40de3b898b26eddbc60a2a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Tue, 28 Jun 2016 11:18:06 +0200 Subject: [PATCH 1/6] Issue#12 - removal of template parameters from sockets It is possible to remove the "BUSWIDTH" and "TYPES" parameters from the sockets. What happens is that the default values are used. The default BUSWIDTH is 32, then by removing it we are using 32 instead of the old value 128. It seems that this change does not affect functionality. The default TYPES is tlm::tlm_base_protocol_types, so by removing we do not change anything. --- DRAMSys/simulator/src/controller/Controller.h | 4 ++-- DRAMSys/simulator/src/simulation/Arbiter.h | 4 ++-- DRAMSys/simulator/src/simulation/Dram.h | 2 +- DRAMSys/simulator/src/simulation/ReorderBuffer.h | 4 ++-- DRAMSys/simulator/src/simulation/TracePlayer.h | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DRAMSys/simulator/src/controller/Controller.h b/DRAMSys/simulator/src/controller/Controller.h index 7fc07d8a..577e3964 100644 --- a/DRAMSys/simulator/src/controller/Controller.h +++ b/DRAMSys/simulator/src/controller/Controller.h @@ -102,8 +102,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: diff --git a/DRAMSys/simulator/src/simulation/Arbiter.h b/DRAMSys/simulator/src/simulation/Arbiter.h index 5e190451..86016cc9 100644 --- a/DRAMSys/simulator/src/simulation/Arbiter.h +++ b/DRAMSys/simulator/src/simulation/Arbiter.h @@ -57,8 +57,8 @@ 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 0d7f95a6..7258e090 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -65,7 +65,7 @@ template struct Dram : sc_module { // TLM Related: - tlm_utils::simple_target_socket tSocket; + tlm_utils::simple_target_socket tSocket; // Power Model related bool powerAnalysis = Configuration::getInstance().PowerAnalysis; diff --git a/DRAMSys/simulator/src/simulation/ReorderBuffer.h b/DRAMSys/simulator/src/simulation/ReorderBuffer.h index 744a4517..7f20577d 100644 --- a/DRAMSys/simulator/src/simulation/ReorderBuffer.h +++ b/DRAMSys/simulator/src/simulation/ReorderBuffer.h @@ -49,8 +49,8 @@ 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/TracePlayer.h b/DRAMSys/simulator/src/simulation/TracePlayer.h index 070b8127..515373a2 100644 --- a/DRAMSys/simulator/src/simulation/TracePlayer.h +++ b/DRAMSys/simulator/src/simulation/TracePlayer.h @@ -59,7 +59,7 @@ template struct TracePlayer: public sc_module { public: - tlm_utils::simple_initiator_socket iSocket; + tlm_utils::simple_initiator_socket iSocket; TracePlayer(TracePlayerListener* listener); virtual void nextPayload() = 0; From d30062db6859b769722cf5ced2296797f3d15636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Wed, 29 Jun 2016 14:47:56 +0200 Subject: [PATCH 2/6] Issue#12 - removal of BUSWIDTH from some modules Other changes: Empty file Controller.cpp removed. --- DRAMSys/simulator/simulator.pro | 1 - .../simulator/src/controller/Controller.cpp | 40 ------------------- DRAMSys/simulator/src/simulation/Arbiter.h | 1 - DRAMSys/simulator/src/simulation/Dram.h | 4 +- .../simulator/src/simulation/ReorderBuffer.h | 1 - .../simulator/src/simulation/Simulation.cpp | 4 +- DRAMSys/simulator/src/simulation/Simulation.h | 8 ++-- 7 files changed, 9 insertions(+), 50 deletions(-) delete mode 100644 DRAMSys/simulator/src/controller/Controller.cpp diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index bc65a145..7eed4ce4 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -99,7 +99,6 @@ 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 \ diff --git a/DRAMSys/simulator/src/controller/Controller.cpp b/DRAMSys/simulator/src/controller/Controller.cpp deleted file mode 100644 index a6422469..00000000 --- a/DRAMSys/simulator/src/controller/Controller.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 "Controller.h" - - diff --git a/DRAMSys/simulator/src/simulation/Arbiter.h b/DRAMSys/simulator/src/simulation/Arbiter.h index 86016cc9..eea6a3cc 100644 --- a/DRAMSys/simulator/src/simulation/Arbiter.h +++ b/DRAMSys/simulator/src/simulation/Arbiter.h @@ -54,7 +54,6 @@ using namespace std; using namespace tlm; -template struct Arbiter: public sc_module { public: tlm_utils::multi_passthrough_initiator_socket iSocket; diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index 7258e090..59ac2513 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -61,9 +61,11 @@ 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; diff --git a/DRAMSys/simulator/src/simulation/ReorderBuffer.h b/DRAMSys/simulator/src/simulation/ReorderBuffer.h index 7f20577d..bbc1bc14 100644 --- a/DRAMSys/simulator/src/simulation/ReorderBuffer.h +++ b/DRAMSys/simulator/src/simulation/ReorderBuffer.h @@ -45,7 +45,6 @@ using namespace std; using namespace tlm; -template struct ReorderBuffer: public sc_module { public: diff --git a/DRAMSys/simulator/src/simulation/Simulation.cpp b/DRAMSys/simulator/src/simulation/Simulation.cpp index 5105c29c..dae8d5dc 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.cpp +++ b/DRAMSys/simulator/src/simulation/Simulation.cpp @@ -143,7 +143,7 @@ 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); for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) { @@ -152,7 +152,7 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT 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 3b5d24fb..29d4ae09 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.h +++ b/DRAMSys/simulator/src/simulation/Simulation.h @@ -98,13 +98,13 @@ private: // and initiate transactions targeting the memory) std::vector*> players; // All transactions pass through the same arbiter - 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; From f8763fa3f2213d59deac32b6d97ceda0efdd463f Mon Sep 17 00:00:00 2001 From: sprado Date: Wed, 29 Jun 2016 14:55:03 +0200 Subject: [PATCH 3/6] Fix indentation and Power Down Manager problem fixed --- .../src/controller/core/ControllerCore.cpp | 38 ++++++++++--------- .../scheduling/checker/RefreshChecker.cpp | 9 ++--- 2 files changed, 24 insertions(+), 23 deletions(-) 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) { } From f00c5ddf959c22a58b69d9ffdb23f174074e73e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Wed, 29 Jun 2016 23:47:35 +0200 Subject: [PATCH 4/6] Issue#12 - removal of BUSWIDTH from some modules Controller.cpp is back, but now it is not empty anymore. --- DRAMSys/simulator/simulator.pro | 3 +- .../simulator/src/controller/Controller.cpp | 526 ++++++++++++++++++ DRAMSys/simulator/src/controller/Controller.h | 515 +---------------- DRAMSys/simulator/src/simulation/Dram.h | 4 +- .../simulator/src/simulation/Simulation.cpp | 2 +- DRAMSys/simulator/src/simulation/Simulation.h | 2 +- 6 files changed, 536 insertions(+), 516 deletions(-) create mode 100644 DRAMSys/simulator/src/controller/Controller.cpp diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index 7eed4ce4..a3ce17e7 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -103,7 +103,8 @@ SOURCES += \ 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 HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ diff --git a/DRAMSys/simulator/src/controller/Controller.cpp b/DRAMSys/simulator/src/controller/Controller.cpp new file mode 100644 index 00000000..52b416d6 --- /dev/null +++ b/DRAMSys/simulator/src/controller/Controller.cpp @@ -0,0 +1,526 @@ +/* + * 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 "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 577e3964..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() @@ -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/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index 59ac2513..f02b7ea4 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -88,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") { @@ -583,7 +583,7 @@ struct Dram : sc_module { tlmRecorder = rec; } - void setDramController(Controller<> *contr) + void setDramController(Controller *contr) { dramController = contr; } diff --git a/DRAMSys/simulator/src/simulation/Simulation.cpp b/DRAMSys/simulator/src/simulation/Simulation.cpp index dae8d5dc..19e863ed 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.cpp +++ b/DRAMSys/simulator/src/simulation/Simulation.cpp @@ -148,7 +148,7 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT 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); diff --git a/DRAMSys/simulator/src/simulation/Simulation.h b/DRAMSys/simulator/src/simulation/Simulation.h index 29d4ae09..96a8abe1 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.h +++ b/DRAMSys/simulator/src/simulation/Simulation.h @@ -100,7 +100,7 @@ private: // All transactions pass through the same 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; // DRAM units From 17bfb3ec8532265f4f5d399ad3d78d6d0c9bb758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Thu, 30 Jun 2016 11:48:02 +0200 Subject: [PATCH 5/6] Issue#12 - removal of BUSWIDTH from modules --- DRAMSys/simulator/simulator.pro | 4 +- .../simulator/src/simulation/Simulation.cpp | 6 +- DRAMSys/simulator/src/simulation/Simulation.h | 8 +- .../simulator/src/simulation/StlDataPlayer.h | 8 +- .../simulator/src/simulation/StlPlayer.cpp | 55 +++++++++ DRAMSys/simulator/src/simulation/StlPlayer.h | 22 +--- .../simulator/src/simulation/TraceGenerator.h | 31 ++--- .../simulator/src/simulation/TracePlayer.cpp | 108 +++++++++++++++++ .../simulator/src/simulation/TracePlayer.h | 112 ++---------------- 9 files changed, 196 insertions(+), 158 deletions(-) create mode 100644 DRAMSys/simulator/src/simulation/StlPlayer.cpp create mode 100644 DRAMSys/simulator/src/simulation/TracePlayer.cpp diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index a3ce17e7..66248108 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -104,7 +104,9 @@ SOURCES += \ src/controller/scheduler/IScheduler.cpp \ src/controller/scheduler/FifoStrict.cpp \ src/error/errormodel.cpp \ - src/controller/Controller.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/simulation/Simulation.cpp b/DRAMSys/simulator/src/simulation/Simulation.cpp index 19e863ed..04582c68 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.cpp +++ b/DRAMSys/simulator/src/simulation/Simulation.cpp @@ -116,20 +116,20 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT 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); diff --git a/DRAMSys/simulator/src/simulation/Simulation.h b/DRAMSys/simulator/src/simulation/Simulation.h index 96a8abe1..2f4c6bd0 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.h +++ b/DRAMSys/simulator/src/simulation/Simulation.h @@ -96,15 +96,15 @@ 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 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; // DRAM units - std::vector drams; + std::vector drams; // Transaction Recorders (one per channel). They generate the output databases. std::vector tlmRecorders; @@ -116,7 +116,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 515373a2..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); + 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_ */ - From 242ce4b4f857c125b0c7103d9ff708b5da1917d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Thu, 30 Jun 2016 17:08:04 +0200 Subject: [PATCH 6/6] Issue#63 - added DDR3 to tests.py Other changes: Added a link to the SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit.xml memory specs from DRAMPower. --- DRAMSys/analyzer/scripts/tests.py | 29 +++++++++++++++++-- ...SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit.xml | 1 + 2 files changed, 28 insertions(+), 2 deletions(-) create mode 120000 DRAMSys/simulator/resources/configs/memspecs/SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit.xml 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