From c699ad9e5383bf44fe0cbec182a143272a2d0280 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 2 Jun 2020 19:08:07 +0200 Subject: [PATCH] Created DRAMSysRecordable for easy removing of recording. --- DRAMSys/library/CMakeLists.txt | 1 + DRAMSys/library/src/common/utils.cpp | 13 ++ DRAMSys/library/src/common/utils.h | 1 + DRAMSys/library/src/simulation/DRAMSys.cpp | 208 ++++++----------- DRAMSys/library/src/simulation/DRAMSys.h | 44 ++-- .../src/simulation/DRAMSysRecordable.cpp | 217 ++++++++++++++++++ .../src/simulation/DRAMSysRecordable.h | 66 ++++++ DRAMSys/library/src/simulation/dram/Dram.cpp | 23 +- DRAMSys/library/src/simulation/dram/Dram.h | 1 + .../src/simulation/dram/DramRecordable.cpp | 14 +- .../src/simulation/dram/DramRecordable.h | 3 +- DRAMSys/simulator/main.cpp | 19 +- 12 files changed, 423 insertions(+), 187 deletions(-) create mode 100644 DRAMSys/library/src/simulation/DRAMSysRecordable.cpp create mode 100644 DRAMSys/library/src/simulation/DRAMSysRecordable.h diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index 816577f4..e897240b 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -153,6 +153,7 @@ add_library(DRAMSysLibrary src/simulation/Arbiter.cpp src/simulation/DRAMSys.cpp + src/simulation/DRAMSysRecordable.cpp src/simulation/ReorderBuffer.h src/simulation/TemperatureController.cpp diff --git a/DRAMSys/library/src/common/utils.cpp b/DRAMSys/library/src/common/utils.cpp index 41839997..65999dc0 100644 --- a/DRAMSys/library/src/common/utils.cpp +++ b/DRAMSys/library/src/common/utils.cpp @@ -81,6 +81,19 @@ json parseJSON(std::string path) } } +bool parseBool(json &obj, std::string name) +{ + if (!obj.empty()) + { + if (obj.is_boolean()) + return obj; + else + throw std::invalid_argument("Expected type for '" + name + "': bool"); + } + else + SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str()); +} + unsigned int parseUint(json &obj, std::string name) { if (!obj.empty()) diff --git a/DRAMSys/library/src/common/utils.h b/DRAMSys/library/src/common/utils.h index 5684f5ed..0e52b291 100644 --- a/DRAMSys/library/src/common/utils.h +++ b/DRAMSys/library/src/common/utils.h @@ -103,6 +103,7 @@ static inline void loadbar(unsigned int x, } nlohmann::json parseJSON(std::string path); +bool parseBool(nlohmann::json &obj, std::string name); unsigned int parseUint(nlohmann::json &obj, std::string name); double parseUdouble(nlohmann::json &obj, std::string name); std::string parseString(nlohmann::json &obj, std::string name); diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 479f3521..fa119ed2 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -34,6 +34,7 @@ * Matthias Jung * Eder F. Zulian * Felipe S. Prado + * Lukas Steiner */ #include @@ -44,12 +45,10 @@ #include "DRAMSys.h" #include "../common/third_party/nlohmann/single_include/nlohmann/json.hpp" -#include "../common/TlmRecorder.h" #include "../common/DebugManager.h" #include "../common/utils.h" #include "../simulation/TemperatureController.h" #include "../error/ecchamming.h" -#include "dram/DramRecordable.h" #include "dram/DramDDR3.h" #include "dram/DramDDR4.h" #include "dram/DramWideIO.h" @@ -60,11 +59,12 @@ #include "dram/DramGDDR5X.h" #include "dram/DramGDDR6.h" #include "../controller/Controller.h" -#include "../controller/ControllerRecordable.h" DRAMSys::DRAMSys(sc_module_name name, std::string simulationToRun, - std::string pathToResources) : sc_module(name), tSocket("DRAMSys_tSocket") + std::string pathToResources, + bool initAndBind) + : sc_module(name), tSocket("DRAMSys_tSocket") { // Initialize ecc pointer ecc = nullptr; @@ -78,56 +78,61 @@ DRAMSys::DRAMSys(sc_module_name name, SC_REPORT_FATAL("SimulationManager", "Cannot load simulation: simulation node expected"); - // Load all sub-configuration JSON files - std::string memspec = simulationdoc["simulation"]["memspec"]; - std::string mcconfig = simulationdoc["simulation"]["mcconfig"]; - std::string amconfig = simulationdoc["simulation"]["addressmapping"]; - std::string simconfig = simulationdoc["simulation"]["simconfig"]; - std::string thermalconfig = simulationdoc["simulation"]["thermalconfig"]; - Configuration::getInstance().setPathToResources(pathToResources); // Load config and initialize modules Configuration::getInstance().loadMCConfig(Configuration::getInstance(), - pathToResources - + "configs/mcconfigs/" - + mcconfig); + pathToResources + + "configs/mcconfigs/" + + std::string(simulationdoc["simulation"]["mcconfig"])); Configuration::getInstance().loadMemSpec(Configuration::getInstance(), - pathToResources - + "configs/memspecs/" - + memspec); + pathToResources + + "configs/memspecs/" + + std::string(simulationdoc["simulation"]["memspec"])); Configuration::getInstance().loadSimConfig(Configuration::getInstance(), - pathToResources - + "configs/simulator/" - + simconfig); + pathToResources + + "configs/simulator/" + + std::string(simulationdoc["simulation"]["simconfig"])); Configuration::getInstance().loadTemperatureSimConfig(Configuration::getInstance(), - pathToResources - + "configs/thermalsim/" - + thermalconfig); + pathToResources + + "configs/thermalsim/" + + std::string(simulationdoc["simulation"]["thermalconfig"])); // Setup the debug manager: setupDebugManager(Configuration::getInstance().simulationName); - // If a simulation file is passed as argument to DRAMSys the simulation ID - // is prepended to the simulation name if found. - std::string simName; - simName = Configuration::getInstance().simulationName; - - if (!simulationdoc["simulation"]["simulationid"].empty()) + if (initAndBind) { - std::string sid = simulationdoc["simulation"]["simulationid"]; - simName = sid + '_' + Configuration::getInstance().simulationName; + // Instantiate all internal DRAMSys modules: + std::string amconfig = simulationdoc["simulation"]["addressmapping"]; + instantiateModules(pathToResources, amconfig); + // Connect all internal DRAMSys modules: + bindSockets(); + report(headline); } +} - // Instantiate all internal DRAMSys modules: - instantiateModules(simName, pathToResources, amconfig); - // Connect all internal DRAMSys modules: - bindSockets(); +DRAMSys::~DRAMSys() +{ + if (ecc) + delete ecc; - report(headline); + delete arbiter; + + for (auto dram : drams) + delete dram; + + for (auto controller : controllers) + delete controller; + + for (auto tlmChecker : playersTlmCheckers) + delete tlmChecker; + + for (auto tlmChecker : controllersTlmCheckers) + delete tlmChecker; } void DRAMSys::logo() @@ -158,44 +163,13 @@ void DRAMSys::setupDebugManager(const std::string &traceName __attribute__((unus #endif } -void DRAMSys::setupTlmRecorders(const std::string &traceName, - const std::string &pathToResources) -{ - // Create TLM Recorders, one per channel. - for (size_t i = 0; i < Configuration::getInstance().numberOfMemChannels; i++) - { - std::string sqlScriptURI = pathToResources - + std::string("scripts/createTraceDB.sql"); - - std::string dbName = traceName + std::string("_ch") + std::to_string(i) + ".tdb"; - - std::string recorderName = "tlmRecorder" + std::to_string(i); - - TlmRecorder *tlmRecorder = - new TlmRecorder(recorderName, sqlScriptURI.c_str(), dbName.c_str()); - tlmRecorder->recordMCconfig(Configuration::getInstance().mcconfigUri); - tlmRecorder->recordMemspec(Configuration::getInstance().memspecUri); - - std::string traceNames = Configuration::getInstance().simulationName; - tlmRecorder->recordTracenames(traceNames); - - tlmRecorders.push_back(tlmRecorder); - } -} - -void DRAMSys::instantiateModules(const std::string &traceName, - const std::string &pathToResources, +void DRAMSys::instantiateModules(const std::string &pathToResources, const std::string &amconfig) { // The first call to getInstance() creates the Temperature Controller. // The same instance will be accessed by all other modules. TemperatureController::getInstance(); - // Create and properly initialize TLM recorders. - // They need to be ready before creating some modules. - if (Configuration::getInstance().databaseRecording) - setupTlmRecorders(traceName, pathToResources); - // Create new ECC Controller if (Configuration::getInstance().ECCMode == "Hamming") ecc = new ECCHamming("ECCHamming"); @@ -210,72 +184,43 @@ void DRAMSys::instantiateModules(const std::string &traceName, // Create arbiter arbiter = new Arbiter("arbiter", pathToResources + "configs/amconfigs/" + amconfig); - // Create DRAM + // Create controllers and DRAMs std::string memoryType = Configuration::getInstance().memSpec->memoryType; for (size_t i = 0; i < Configuration::getInstance().numberOfMemChannels; i++) { std::string str = "controller" + std::to_string(i); - ControllerIF *controller; - if (Configuration::getInstance().databaseRecording) - controller = new ControllerRecordable(str.c_str(), tlmRecorders[i]); - else - controller = new Controller(str.c_str()); + ControllerIF *controller = new Controller(str.c_str()); controllers.push_back(controller); str = "dram" + std::to_string(i); Dram *dram; - if (Configuration::getInstance().databaseRecording) - { - if (memoryType == "DDR3") - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "WIDEIO_SDR") - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "DDR4") - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "LPDDR4") - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "WIDEIO2") - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "HBM2") - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "GDDR5") - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "GDDR5X") - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "GDDR6") - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else - SC_REPORT_FATAL("DRAMSys", "Unsupported DRAM type"); - } + if (memoryType == "DDR3") + dram = new DramDDR3(str.c_str()); + else if (memoryType == "WIDEIO_SDR") + dram = new DramWideIO(str.c_str()); + else if (memoryType == "DDR4") + dram = new DramDDR4(str.c_str()); + else if (memoryType == "LPDDR4") + dram = new DramLPDDR4(str.c_str()); + else if (memoryType == "WIDEIO2") + dram = new DramWideIO2(str.c_str()); + else if (memoryType == "HBM2") + dram = new DramHBM2(str.c_str()); + else if (memoryType == "GDDR5") + dram = new DramGDDR5(str.c_str()); + else if (memoryType == "GDDR5X") + dram = new DramGDDR5X(str.c_str()); + else if (memoryType == "GDDR6") + dram = new DramGDDR6(str.c_str()); else - { - if (memoryType == "DDR3") - dram = new DramDDR3(str.c_str()); - else if (memoryType == "WIDEIO_SDR") - dram = new DramWideIO(str.c_str()); - else if (memoryType == "DDR4") - dram = new DramDDR4(str.c_str()); - else if (memoryType == "LPDDR4") - dram = new DramLPDDR4(str.c_str()); - else if (memoryType == "WIDEIO2") - dram = new DramWideIO2(str.c_str()); - else if (memoryType == "HBM2") - dram = new DramHBM2(str.c_str()); - else if (memoryType == "GDDR5") - dram = new DramGDDR5(str.c_str()); - else if (memoryType == "GDDR5X") - dram = new DramGDDR5X(str.c_str()); - else if (memoryType == "GDDR6") - dram = new DramGDDR6(str.c_str()); - else - SC_REPORT_FATAL("DRAMSys", "Unsupported DRAM type"); - } + SC_REPORT_FATAL("DRAMSys", "Unsupported DRAM type"); drams.push_back(dram); - if (Configuration::getInstance().checkTLM2Protocol) { + if (Configuration::getInstance().checkTLM2Protocol) + { str = "TLMCheckerController" + std::to_string(i); tlm_utils::tlm2_base_protocol_checker<> *controllerTlmChecker = new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); @@ -317,29 +262,6 @@ void DRAMSys::bindSockets() } } -DRAMSys::~DRAMSys() -{ - if (ecc) - delete ecc; - - delete arbiter; - - for (auto dram : drams) - delete dram; - - for (auto rec : tlmRecorders) - delete rec; - - for (auto tlmChecker : playersTlmCheckers) - delete tlmChecker; - - for (auto tlmChecker : controllersTlmCheckers) - delete tlmChecker; - - for (auto controller : controllers) - delete controller; -} - void DRAMSys::report(std::string message) { PRINTDEBUGMESSAGE(name(), message); diff --git a/DRAMSys/library/src/simulation/DRAMSys.h b/DRAMSys/library/src/simulation/DRAMSys.h index b6d113f1..34f47091 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.h +++ b/DRAMSys/library/src/simulation/DRAMSys.h @@ -34,6 +34,7 @@ * Matthias Jung * Eder F. Zulian * Felipe S. Prado + * Lukas Steiner */ #ifndef DRAMSYS_H @@ -50,7 +51,6 @@ #include "../common/tlm2_base_protocol_checker.h" #include "../error/eccbaseclass.h" #include "../controller/ControllerIF.h" -#include "../common/TlmRecorder.h" class DRAMSys : public sc_module { @@ -60,21 +60,19 @@ public: std::vector*> playersTlmCheckers; - sc_event terminateSimulation; - SC_HAS_PROCESS(DRAMSys); DRAMSys(sc_module_name name, std::string simulationToRun, - std::string pathToResources); + std::string pathToResources) + : DRAMSys(name, simulationToRun, pathToResources, true) {} - ~DRAMSys(); + virtual ~DRAMSys(); - void logo(); - -private: - - std::string traceName; - //DramSetup setup; +protected: + DRAMSys(sc_module_name name, + std::string simulationToRun, + std::string pathToResources, + bool initAndBind); //TLM 2.0 Protocol Checkers std::vector*> @@ -82,28 +80,28 @@ private: // All transactions pass first through the ECC Controller ECCBaseClass *ecc; - // All transactions pass through the same arbiter - Arbiter *arbiter; - // Each DRAM unit has a controller - std::vector controllers; // TODO: Each DRAM has a reorder buffer (check this!) ReorderBuffer *reorder; + // All transactions pass through the same arbiter + Arbiter *arbiter; + + // Each DRAM unit has a controller + std::vector controllers; + // DRAM units std::vector drams; - // Transaction Recorders (one per channel). - // They generate the output databases. - std::vector tlmRecorders; - void report(std::string message); - void setupTlmRecorders(const std::string &traceName, - const std::string &pathToResources); - void instantiateModules(const std::string &traceName, - const std::string &pathToResources, + +private: + void logo(); + + void instantiateModules(const std::string &pathToResources, const std::string &amconfig); void bindSockets(); + void setupDebugManager(const std::string &traceName); }; diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp new file mode 100644 index 00000000..60e4dbd9 --- /dev/null +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2020, 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 "DRAMSysRecordable.h" +#include "../controller/ControllerRecordable.h" +#include "dram/DramRecordable.h" +#include "dram/DramDDR3.h" +#include "dram/DramDDR4.h" +#include "dram/DramWideIO.h" +#include "dram/DramLPDDR4.h" +#include "dram/DramWideIO2.h" +#include "dram/DramHBM2.h" +#include "dram/DramGDDR5.h" +#include "dram/DramGDDR5X.h" +#include "dram/DramGDDR6.h" +#include "../common/TlmRecorder.h" +#include "../simulation/TemperatureController.h" +#include "../error/ecchamming.h" + +DRAMSysRecordable::DRAMSysRecordable(sc_module_name name, + std::string simulationToRun, + std::string pathToResources) + : DRAMSys(name, simulationToRun, pathToResources, false) +{ + // Read Configuration Setup: + nlohmann::json simulationdoc = parseJSON(simulationToRun); + + // If a simulation file is passed as argument to DRAMSys the simulation ID + // is prepended to the simulation name if found. + std::string traceName; + + if (!simulationdoc["simulation"]["simulationid"].empty()) + { + std::string sid = simulationdoc["simulation"]["simulationid"]; + traceName = sid + '_' + Configuration::getInstance().simulationName; + } + else + traceName = Configuration::getInstance().simulationName; + + std::string amconfig = simulationdoc["simulation"]["addressmapping"]; + instantiateModules(traceName, pathToResources, amconfig); + bindSockets(); + report(headline); +} + +DRAMSysRecordable::~DRAMSysRecordable() +{ + if (Configuration::getInstance().powerAnalysis) + { + for (auto dram : drams) + dram->reportPower(); + } + + for (auto rec : tlmRecorders) + delete rec; +} + +void DRAMSysRecordable::setupTlmRecorders(const std::string &traceName, + const std::string &pathToResources) +{ + // Create TLM Recorders, one per channel. + for (size_t i = 0; i < Configuration::getInstance().numberOfMemChannels; i++) + { + std::string sqlScriptURI = pathToResources + + std::string("scripts/createTraceDB.sql"); + + std::string dbName = traceName + std::string("_ch") + std::to_string(i) + ".tdb"; + + std::string recorderName = "tlmRecorder" + std::to_string(i); + + TlmRecorder *tlmRecorder = + new TlmRecorder(recorderName, sqlScriptURI.c_str(), dbName.c_str()); + tlmRecorder->recordMCconfig(Configuration::getInstance().mcconfigUri); + tlmRecorder->recordMemspec(Configuration::getInstance().memspecUri); + + std::string traceNames = Configuration::getInstance().simulationName; + tlmRecorder->recordTracenames(traceNames); + + tlmRecorders.push_back(tlmRecorder); + } +} + +void DRAMSysRecordable::instantiateModules(const std::string &traceName, + const std::string &pathToResources, + const std::string &amconfig) +{ + // The first call to getInstance() creates the Temperature Controller. + // The same instance will be accessed by all other modules. + TemperatureController::getInstance(); + + // Create and properly initialize TLM recorders. + // They need to be ready before creating some modules. + setupTlmRecorders(traceName, pathToResources); + + // Create new ECC Controller + if (Configuration::getInstance().ECCMode == "Hamming") + ecc = new ECCHamming("ECCHamming"); + else if (Configuration::getInstance().ECCMode == "Disabled") + ecc = nullptr; + else + SC_REPORT_FATAL("DRAMSys", "Unsupported ECC mode"); + + // Save ECC Controller into the configuration struct to adjust it dynamically + Configuration::getInstance().pECC = ecc; + + // Create arbiter + arbiter = new Arbiter("arbiter", pathToResources + "configs/amconfigs/" + amconfig); + + // Create controllers and DRAMs + std::string memoryType = Configuration::getInstance().memSpec->memoryType; + for (size_t i = 0; i < Configuration::getInstance().numberOfMemChannels; i++) + { + std::string str = "controller" + std::to_string(i); + + ControllerIF *controller = new ControllerRecordable(str.c_str(), tlmRecorders[i]); + controllers.push_back(controller); + + str = "dram" + std::to_string(i); + Dram *dram; + + if (memoryType == "DDR3") + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == "WIDEIO_SDR") + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == "DDR4") + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == "LPDDR4") + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == "WIDEIO2") + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == "HBM2") + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == "GDDR5") + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == "GDDR5X") + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == "GDDR6") + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else + SC_REPORT_FATAL("DRAMSys", "Unsupported DRAM type"); + + drams.push_back(dram); + + if (Configuration::getInstance().checkTLM2Protocol) + { + str = "TLMCheckerController" + std::to_string(i); + tlm_utils::tlm2_base_protocol_checker<> *controllerTlmChecker = + new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); + controllersTlmCheckers.push_back(controllerTlmChecker); + } + } +} + +void DRAMSysRecordable::bindSockets() +{ + // If ECC Controller enabled, put it between Trace and arbiter + if (Configuration::getInstance().ECCMode == "Hamming") + { + assert(ecc != nullptr); + tSocket.bind(ecc->t_socket); + ecc->i_socket.bind(arbiter->tSocket); + } + else if (Configuration::getInstance().ECCMode == "Disabled") + tSocket.bind(arbiter->tSocket); + else + SC_REPORT_FATAL("DRAMSys", "Unsupported ECC mode"); + + if (Configuration::getInstance().checkTLM2Protocol) + { + for (size_t i = 0; i < Configuration::getInstance().numberOfMemChannels; i++) + { + arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); + controllersTlmCheckers[i]->initiator_socket.bind(controllers[i]->tSocket); + controllers[i]->iSocket.bind(drams[i]->tSocket); + } + } + else + { + for (size_t i = 0; i < Configuration::getInstance().numberOfMemChannels; i++) + { + arbiter->iSocket.bind(controllers[i]->tSocket); + controllers[i]->iSocket.bind(drams[i]->tSocket); + } + } +} diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.h b/DRAMSys/library/src/simulation/DRAMSysRecordable.h new file mode 100644 index 00000000..318d9307 --- /dev/null +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020, 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 DRAMSYSRECORDABLE_H +#define DRAMSYSRECORDABLE_H + +#include "DRAMSys.h" +#include "../common/TlmRecorder.h" + +class DRAMSysRecordable : public DRAMSys +{ +public: + DRAMSysRecordable(sc_module_name name, + std::string simulationToRun, + std::string pathToResources); + + virtual ~DRAMSysRecordable(); + +private: + // Transaction Recorders (one per channel). + // They generate the output databases. + std::vector tlmRecorders; + + void setupTlmRecorders(const std::string &traceName, + const std::string &pathToResources); + + void instantiateModules(const std::string &traceName, + const std::string &pathToResources, + const std::string &amconfig); + + void bindSockets(); +}; + +#endif // DRAMSYSRECORDABLE_H diff --git a/DRAMSys/library/src/simulation/dram/Dram.cpp b/DRAMSys/library/src/simulation/dram/Dram.cpp index feaea294..16a76f98 100644 --- a/DRAMSys/library/src/simulation/dram/Dram.cpp +++ b/DRAMSys/library/src/simulation/dram/Dram.cpp @@ -107,8 +107,22 @@ Dram::~Dram() { if (Configuration::getInstance().powerAnalysis) { - if (!Configuration::getInstance().databaseRecording) - DRAMPower->calcEnergy(); + reportPower(); + delete DRAMPower; + } + + if (Configuration::getInstance().useMalloc) + free(memory); +} + +void Dram::reportPower() +{ + static bool alreadyCalled = false; + + if (!alreadyCalled) + { + alreadyCalled = true; + DRAMPower->calcEnergy(); // Print the final total energy and the average power for // the simulation: @@ -124,12 +138,7 @@ Dram::~Dram() << DRAMPower->getPower().average_power * Configuration::getInstance().numberOfDevicesOnDIMM << std::string(" mW") << std::endl; - - delete DRAMPower; } - - if (Configuration::getInstance().useMalloc) - free(memory); } tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload &payload, diff --git a/DRAMSys/library/src/simulation/dram/Dram.h b/DRAMSys/library/src/simulation/dram/Dram.h index 04a286f9..5a068c67 100644 --- a/DRAMSys/library/src/simulation/dram/Dram.h +++ b/DRAMSys/library/src/simulation/dram/Dram.h @@ -73,6 +73,7 @@ protected: public: tlm_utils::simple_target_socket tSocket; + virtual void reportPower(); virtual ~Dram(); }; diff --git a/DRAMSys/library/src/simulation/dram/DramRecordable.cpp b/DRAMSys/library/src/simulation/dram/DramRecordable.cpp index bd15f0e1..67830919 100644 --- a/DRAMSys/library/src/simulation/dram/DramRecordable.cpp +++ b/DRAMSys/library/src/simulation/dram/DramRecordable.cpp @@ -62,16 +62,12 @@ DramRecordable::DramRecordable(sc_module_name name, TlmRecorder *tlmRe } template -DramRecordable::~DramRecordable() +void DramRecordable::reportPower() { - if (Configuration::getInstance().powerAnalysis) - { - this->DRAMPower->calcEnergy(); - tlmRecorder->recordPower(sc_time_stamp().to_seconds(), - this->DRAMPower->getPower().window_average_power - * Configuration::getInstance().numberOfDevicesOnDIMM); - } - tlmRecorder->closeConnection(); + BaseDram::reportPower(); + tlmRecorder->recordPower(sc_time_stamp().to_seconds(), + this->DRAMPower->getPower().window_average_power + * Configuration::getInstance().numberOfDevicesOnDIMM); } template diff --git a/DRAMSys/library/src/simulation/dram/DramRecordable.h b/DRAMSys/library/src/simulation/dram/DramRecordable.h index fe835bf1..db668652 100644 --- a/DRAMSys/library/src/simulation/dram/DramRecordable.h +++ b/DRAMSys/library/src/simulation/dram/DramRecordable.h @@ -48,7 +48,8 @@ class DramRecordable final : public BaseDram public: DramRecordable(sc_module_name, TlmRecorder *); SC_HAS_PROCESS(DramRecordable); - ~DramRecordable(); + + virtual void reportPower(); private: virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &payload, diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index 15c25f94..ed57df4f 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -33,6 +33,7 @@ * Robert Gernhardt * Matthias Jung * Luiza Correa + * Lukas Steiner */ #include @@ -43,9 +44,11 @@ #include #include "simulation/DRAMSys.h" +#include "simulation/DRAMSysRecordable.h" #include "TraceSetup.h" +#include "common/third_party/nlohmann/single_include/nlohmann/json.hpp" -std::string resources; +using json = nlohmann::json; std::string pathOfFile(std::string file) { @@ -61,7 +64,7 @@ int sc_main(int argc, char **argv) { sc_set_time_resolution(1, SC_PS); - + std::string resources; std::string simulationJSON; // Run only with default config (ddr3-example.json): if (argc == 1) { @@ -86,7 +89,15 @@ int sc_main(int argc, char **argv) std::vector players; // Instantiate DRAMSys: - DRAMSys *dramSys = new DRAMSys("DRAMSys", simulationJSON, resources); + DRAMSys *dramSys; + json simulationdoc = parseJSON(simulationJSON); + json simulatordoc = parseJSON(resources + "configs/simulator/" + + std::string(simulationdoc["simulation"]["simconfig"])); + + if (simulatordoc["simconfig"]["DatabaseRecording"]) + dramSys = new DRAMSysRecordable("DRAMSys", simulationJSON, resources); + else + dramSys = new DRAMSys("DRAMSys", simulationJSON, resources); // Instantiate STL Players: TraceSetup *ts = new TraceSetup(simulationJSON, resources, &players); @@ -94,7 +105,7 @@ int sc_main(int argc, char **argv) // Bind STL Players with DRAMSys: for (size_t i = 0; i < players.size(); i++) { - if(Configuration::getInstance().checkTLM2Protocol) + if (Configuration::getInstance().checkTLM2Protocol) { std::string str = "TLMCheckerPlayer" + std::to_string(i); tlm_utils::tlm2_base_protocol_checker<> *playerTlmChecker =