diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro index 6fbf6467..dabae60c 100644 --- a/DRAMSys/library/library.pro +++ b/DRAMSys/library/library.pro @@ -146,8 +146,7 @@ SOURCES += \ src/common/utils.cpp \ src/simulation/DramDDR3.cpp \ src/simulation/DramDDR4.cpp \ - src/simulation/DramRecordable.cpp \ - src/simulation/DramRecordablePower.cpp + src/simulation/DramRecordable.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ @@ -227,8 +226,7 @@ HEADERS += \ src/controller/core/configuration/TemperatureSimConfig.h \ src/simulation/DramDDR3.h \ src/simulation/DramDDR4.h \ - src/simulation/DramRecordable.h \ - src/simulation/DramRecordablePower.h + src/simulation/DramRecordable.h #src/common/third_party/json/include/nlohmann/json.hpp \ thermalsim = $$(THERMALSIM) diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 563c2a41..61fbfc63 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -55,7 +55,6 @@ #include "../controller/Controller.h" #include "../error/ecchamming.h" #include "DramRecordable.h" -#include "DramRecordablePower.h" #include "DramDDR3.h" #include "RecordableDram.h" @@ -264,7 +263,7 @@ void DRAMSys::instantiateModules(const string &traceName, Dram *dram; if (recordingEnabled) //dram = new RecordableDram(str.c_str(), tlmRecorders[i]); - dram = new DramRecordablePower(str.c_str(), tlmRecorders[i]); + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); else dram = new Dram(str.c_str()); drams.push_back(dram); diff --git a/DRAMSys/library/src/simulation/DramDDR3.h b/DRAMSys/library/src/simulation/DramDDR3.h index c1aa87ca..894809bb 100644 --- a/DRAMSys/library/src/simulation/DramDDR3.h +++ b/DRAMSys/library/src/simulation/DramDDR3.h @@ -43,6 +43,8 @@ class DramDDR3 : public Dram public: DramDDR3(sc_module_name); SC_HAS_PROCESS(DramDDR3); + + ~DramDDR3(); }; #endif // DRAMDDR3_H diff --git a/DRAMSys/library/src/simulation/DramDDR4.h b/DRAMSys/library/src/simulation/DramDDR4.h index 855a3aaf..ed884bc1 100644 --- a/DRAMSys/library/src/simulation/DramDDR4.h +++ b/DRAMSys/library/src/simulation/DramDDR4.h @@ -2,12 +2,18 @@ #define DRAMDDR4_H #include "Dram.h" +#include "systemc" +#include "tlm" + +using namespace tlm; class DramDDR4 : public Dram { public: DramDDR4(sc_module_name); SC_HAS_PROCESS(DramDDR4); + + ~DramDDR4(); }; #endif // DRAMDDR4_H diff --git a/DRAMSys/library/src/simulation/DramRecordable.cpp b/DRAMSys/library/src/simulation/DramRecordable.cpp index 9b1fec3c..d7312d5c 100644 --- a/DRAMSys/library/src/simulation/DramRecordable.cpp +++ b/DRAMSys/library/src/simulation/DramRecordable.cpp @@ -34,14 +34,102 @@ */ #include "DramRecordable.h" -#include "RecordableDram.h" +#include "Dram.h" + +using namespace tlm; template DramRecordable::DramRecordable(sc_module_name name, TlmRecorder *tlmRecorder) - : BaseDram(name, tlmRecorder) + : BaseDram(name), tlmRecorder(tlmRecorder) { - + // Create a thread that is triggered every $powerWindowSize + // to generate a Power over Time plot in the Trace analyzer: + SC_THREAD(powerWindow); } -template class DramRecordable; +template +DramRecordable::~DramRecordable() +{ + BaseDram::DRAMPower->calcEnergy(); + recordPower(); + tlmRecorder->closeConnection(); +} + +template +tlm_sync_enum DramRecordable::nb_transport_fw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &delay) +{ + // Recording time used by the traceAnalyzer + sc_time recTime = sc_time_stamp() + delay; + + // These are terminating phases recorded by the DRAM. The execution + // time of the related command must be taken into consideration. + if (phase == END_PDNA || phase == END_PDNAB) + recTime += getExecutionTime(Command::PDNAX, payload); + else if (phase == END_PDNP || phase == END_PDNPB) + recTime += getExecutionTime(Command::PDNPX, payload); + else if (phase == END_SREF || phase == END_SREFB) + recTime += getExecutionTime(Command::SREFX, payload); + + unsigned int thr = DramExtension::getExtension(payload).getThread().ID(); + unsigned int ch = DramExtension::getExtension(payload).getChannel().ID(); + unsigned int bg = DramExtension::getExtension(payload).getBankGroup().ID(); + unsigned int bank = DramExtension::getExtension(payload).getBank().ID(); + unsigned int row = DramExtension::getExtension(payload).getRow().ID(); + unsigned int col = DramExtension::getExtension(payload).getColumn().ID(); + + // TODO: printDebugMessage not inherited + printDebugMessage("Recording " + phaseNameToString(phase) + " thread " + + to_string(thr) + " channel " + to_string(ch) + " bank group " + to_string( + bg) + " bank " + to_string(bank) + " row " + to_string(row) + " column " + + to_string(col) + " at " + recTime.to_string()); + + tlmRecorder->recordPhase(payload, phase, recTime); + + return BaseDram::nb_transport_fw(payload, phase, delay); +} + +// This Thread is only triggered when Power Simulation is enabled. +// It estimates the current average power which will be stored in the trace database for visualization purposes. +template +void DramRecordable::powerWindow() +{ + unsigned long long clkCycles = 0; + + do { + // At the very beginning (zero clock cycles) the energy is 0, so we wait first + wait(powerWindowSize); + + clkCycles = sc_time_stamp().value() / + Configuration::getInstance().memSpec->clk.value(); + + DRAMPower->calcWindowEnergy(clkCycles); + + // During operation the energy should never be zero since the device is always consuming + assert(!isEqual(DRAMPower->getEnergy().window_energy, 0.0)); + + // Store the time (in seconds) and the current average power (in mW) into the database + recordPower(); + + // Here considering that DRAMPower provides the energy in pJ and the power in mW + printDebugMessage(string("\tWindow Energy: \t") + to_string( + DRAMPower->getEnergy().window_energy * + Configuration::getInstance().NumberOfDevicesOnDIMM) + string("\t[pJ]")); + printDebugMessage(string("\tWindow Average Power: \t") + to_string( + DRAMPower->getPower().window_average_power * + Configuration::getInstance().NumberOfDevicesOnDIMM) + string("\t[mW]")); + + } while (true); +} + +template +void DramRecordable::recordPower() +{ + tlmRecorder->recordPower(sc_time_stamp().to_seconds(), + DRAMPower->getPower().window_average_power + * Configuration::getInstance().NumberOfDevicesOnDIMM); +} + + +template class DramRecordable; diff --git a/DRAMSys/library/src/simulation/DramRecordable.h b/DRAMSys/library/src/simulation/DramRecordable.h index 95139b1f..2e4231ff 100644 --- a/DRAMSys/library/src/simulation/DramRecordable.h +++ b/DRAMSys/library/src/simulation/DramRecordable.h @@ -36,17 +36,46 @@ #ifndef DRAMRECORDABLE_H #define DRAMRECORDABLE_H +#include +#include #include "DramDDR3.h" #include "DramDDR4.h" #include "RecordableDram.h" #include "../common/TlmRecorder.h" +using namespace tlm; + template class DramRecordable : public BaseDram { public: DramRecordable(sc_module_name name, TlmRecorder *tlmRecorder); SC_HAS_PROCESS(DramRecordable); + + ~DramRecordable(); + +protected: + virtual tlm_sync_enum nb_transport_fw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &delay); + +private: + TlmRecorder *tlmRecorder; + sc_time powerWindowSize = Configuration::getInstance().memSpec->clk * + Configuration::getInstance().WindowSize; + + // When working with floats, we have to decide ourselves what is an + // acceptable definition for "equal". Here the number is compared with a + // suitable error margin (0.00001). + bool isEqual(double a, double b, const double epsilon = 1e-05) + { + return std::fabs(a - b) < epsilon; + } + + // This Thread is only triggered when Power Simulation is enabled. + // It estimates the current average power which will be stored in the trace database for visualization purposes. + void powerWindow(); + + void recordPower(); }; #endif // DRAMRECORDABLE_H diff --git a/DRAMSys/library/src/simulation/DramRecordablePower.cpp b/DRAMSys/library/src/simulation/DramRecordablePower.cpp deleted file mode 100644 index bc855e77..00000000 --- a/DRAMSys/library/src/simulation/DramRecordablePower.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2019, 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: - * Lukas Steiner - */ - -#include "DramRecordablePower.h" -#include "RecordableDram.h" - -template -DramRecordablePower::DramRecordablePower - (sc_module_name name, TlmRecorder *tlmRecorder) - : DramRecordable(name, tlmRecorder) -{ - -} - -template class DramRecordablePower; diff --git a/DRAMSys/library/src/simulation/DramRecordablePower.h b/DRAMSys/library/src/simulation/DramRecordablePower.h deleted file mode 100644 index b38dacb2..00000000 --- a/DRAMSys/library/src/simulation/DramRecordablePower.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2019, 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: - * Lukas Steiner - */ - -#ifndef DRAMRECORDABLEPOWER_H -#define DRAMRECORDABLEPOWER_H - -#include "DramRecordable.h" -#include "../common/TlmRecorder.h" - -template -class DramRecordablePower : public DramRecordable -{ -public: - DramRecordablePower(sc_module_name name, TlmRecorder *tlmRecorder); - SC_HAS_PROCESS(DramRecordablePower); -}; - -#endif // DRAMRECORDABLEPOWER_H