diff --git a/DRAMSys/CMakeLists.txt b/DRAMSys/CMakeLists.txt index 2904122d..e3d7f388 100644 --- a/DRAMSys/CMakeLists.txt +++ b/DRAMSys/CMakeLists.txt @@ -41,7 +41,7 @@ option(DRAMSYS_COVERAGE_CHECK "Coverage check of DRAMSys") option(DRAMSYS_WITH_GEM5 "Build DRAMSys with gem5 coupling") # Configuration: -set(CMAKE_CXX_STANDARD 11 CACHE STRING "C++ Version") +set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ Version") set(DCMAKE_SH "CMAKE_SH-NOTFOUND" CACHE STRING "Ignore sh.exe error on Windows") if(DRAMSYS_COVERAGE_CHECK) diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index 8549b70d..6c69454c 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -31,6 +31,7 @@ # Authors: # Matthias Jung # Lukas Steiner +# Derek Christ cmake_minimum_required(VERSION 3.10) @@ -44,9 +45,8 @@ set(DCMAKE_SH="CMAKE_SH-NOTFOUND") # Add DRAMPower: add_subdirectory(src/common/third_party/DRAMPower) -# Add nlohmann: -set(JSON_BuildTests OFF CACHE INTERNAL "") -add_subdirectory(src/common/third_party/nlohmann) +# Add Configuration +add_subdirectory(src/common/configuration) # Add SystemC: if(DEFINED ENV{SYSTEMC_HOME}) @@ -323,4 +323,5 @@ endif() target_link_libraries(DRAMSysLibrary PUBLIC ${SYSTEMC_LIBRARY} PRIVATE DRAMPower + PUBLIC DRAMSysConfiguration ) diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index b5f9d568..c89b60f9 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -34,6 +34,7 @@ * Robert Gernhardt * Matthias Jung * Eder F. Zulian + * Derek Christ * Lukas Steiner * Derek Christ */ @@ -350,14 +351,8 @@ void TlmRecorder::insertGeneralInfo() sqlite3_bind_int64(insertGeneralInfoStatement, 6, static_cast(Configuration::getInstance().memSpec->tCK.value())); sqlite3_bind_text(insertGeneralInfoStatement, 7, "PS", 2, nullptr); - std::fstream mcconfig_stream, memspec_stream; - mcconfig_stream.open(mcconfig, std::ios::in); - memspec_stream.open(memspec, std::ios::in); - std::string mcconfig_dump((std::istreambuf_iterator(mcconfig_stream)), (std::istreambuf_iterator())); - std::string memspec_dump((std::istreambuf_iterator(memspec_stream)), (std::istreambuf_iterator())); - - sqlite3_bind_text(insertGeneralInfoStatement, 8, mcconfig_dump.c_str(), static_cast(mcconfig_dump.length()), nullptr); - sqlite3_bind_text(insertGeneralInfoStatement, 9, memspec_dump.c_str(), static_cast(memspec_dump.length()), nullptr); + sqlite3_bind_text(insertGeneralInfoStatement, 8, mcconfig.c_str(), static_cast(mcconfig.length()), nullptr); + sqlite3_bind_text(insertGeneralInfoStatement, 9, memspec.c_str(), static_cast(memspec.length()), nullptr); sqlite3_bind_text(insertGeneralInfoStatement, 10, traces.c_str(), static_cast(traces.length()), nullptr); if (Configuration::getInstance().enableWindowing) sqlite3_bind_int64(insertGeneralInfoStatement, 11, static_cast((Configuration::getInstance().memSpec->tCK diff --git a/DRAMSys/library/src/common/configuration/AddressMapping.cpp b/DRAMSys/library/src/common/configuration/AddressMapping.cpp new file mode 100644 index 00000000..1d39e875 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/AddressMapping.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include "AddressMapping.h" + +#include + +namespace DRAMSysConfiguration +{ + +void to_json(json &j, const AddressMapping &m) +{ + json congen = json{}; + + congen = json{{"BYTE_BIT", m.byteBits}, + {"COLUMN_BIT", m.columnBits}, + {"BANK_BIT", m.bankBits}, + {"BANKGROUP_BIT", m.bankGroupBits}, + {"ROW_BIT", m.rowBits}, + {"CHANNEL_BIT", m.channelBits}, + {"RANK_BIT", m.rankBits}, + {"XOR", m.xorBits}}; + + remove_null_values(congen); + + j["CONGEN"] = congen; +} + +void from_json(const json &j, AddressMapping &m) +{ + json j_addressmapping = get_config_json(j, addressMappingPath, "CONGEN"); + + json congen; + if (j_addressmapping["CONGEN"].is_null()) + congen = j_addressmapping; + else + congen = j_addressmapping["CONGEN"]; + + if (congen.contains("COLUMN_BIT")) + congen.at("COLUMN_BIT").get_to(m.columnBits); + + if (congen.contains("BANK_BIT")) + congen.at("BANK_BIT").get_to(m.bankBits); + + if (congen.contains("ROW_BIT")) + congen.at("ROW_BIT").get_to(m.rowBits); + + if (congen.contains("RANK_BIT")) + congen.at("RANK_BIT").get_to(m.rankBits); + + if (congen.contains("CHANNEL_BIT")) + congen.at("CHANNEL_BIT").get_to(m.channelBits); + + if (congen.contains("BYTE_BIT")) + congen.at("BYTE_BIT").get_to(m.byteBits); + + if (congen.contains("BANKGROUP_BIT")) + congen.at("BANKGROUP_BIT").get_to(m.bankGroupBits); + + if (congen.contains("XOR")) + congen.at("XOR").get_to(m.xorBits); +} + +void to_json(json &j, const XorPair &x) +{ + j = json{{"FIRST", x.first}, {"SECOND", x.second}}; +} + +void from_json(const json &j, XorPair &x) +{ + j.at("FIRST").get_to(x.first); + j.at("SECOND").get_to(x.second); +} + +void from_dump(const std::string &dump, AddressMapping &c) +{ + json json_addressmapping = json::parse(dump).at("addressmapping"); + json_addressmapping.get_to(c); +} + +std::string dump(const AddressMapping &c, unsigned int indentation) +{ + json json_addressmapping; + json_addressmapping["addressmapping"] = c; + return json_addressmapping.dump(indentation); +} + +} // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/AddressMapping.h b/DRAMSys/library/src/common/configuration/AddressMapping.h new file mode 100644 index 00000000..45920cf8 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/AddressMapping.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#ifndef DRAMSYSCONFIGURATION_ADDRESSMAPPING_H +#define DRAMSYSCONFIGURATION_ADDRESSMAPPING_H + +#include "util.h" + +#include +#include + +namespace DRAMSysConfiguration +{ +using json = nlohmann::json; + +const std::string addressMappingPath = "configs/amconfigs"; + +struct XorPair +{ + unsigned int first; + unsigned int second; +}; + +void to_json(json &j, const XorPair &x); +void from_json(const json &j, XorPair &x); + +struct AddressMapping +{ + std::optional> byteBits; + std::optional> columnBits; + std::optional> bankBits; + std::optional> bankGroupBits; + std::optional> rowBits; + std::optional> channelBits; + std::optional> rankBits; + std::optional> xorBits; +}; + +void to_json(json &j, const AddressMapping &m); +void from_json(const json &j, AddressMapping &m); + +void from_dump(const std::string &dump, AddressMapping &c); +std::string dump(const AddressMapping &c, unsigned int indentation = -1); + +} // namespace Configuration + +#endif // ADDRESSMAPPING_H diff --git a/DRAMSys/library/src/common/configuration/CMakeLists.txt b/DRAMSys/library/src/common/configuration/CMakeLists.txt new file mode 100644 index 00000000..92a23505 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/CMakeLists.txt @@ -0,0 +1,62 @@ +# Copyright (c) 2021, Technische Universität 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: +# Derek Christ + +set(JSON_BuildTests OFF CACHE INTERNAL "") +set(JSON_ImplicitConversions OFF CACHE INTERNAL "") +add_subdirectory(${CMAKE_SOURCE_DIR}/library/src/common/third_party/nlohmann ${CMAKE_CURRENT_BINARY_DIR}/nlohmann) + +option(DRAMSYS_CONFIGURATION_TESTS "Build the unit tests for configuration." OFF) + +if (DRAMSYS_CONFIGURATION_TESTS) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests) +endif() + +add_library(DRAMSysConfiguration STATIC + Configuration.cpp + AddressMapping.cpp + McConfig.cpp + SimConfig.cpp + ThermalConfig.cpp + TraceSetup.cpp + memspec/MemSpec.cpp + memspec/MemArchitectureSpec.cpp + memspec/MemPowerSpec.cpp + memspec/MemTimingSpec.cpp + util.cpp +) + +target_compile_definitions(DRAMSysConfiguration PUBLIC DRAMSysResourceDirectory="${CMAKE_SOURCE_DIR}/library/resources") + +target_include_directories(DRAMSysConfiguration PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +target_link_libraries(DRAMSysConfiguration PUBLIC nlohmann_json::nlohmann_json) diff --git a/DRAMSys/library/src/common/configuration/Configuration.cpp b/DRAMSys/library/src/common/configuration/Configuration.cpp new file mode 100644 index 00000000..ed331aaf --- /dev/null +++ b/DRAMSys/library/src/common/configuration/Configuration.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include "Configuration.h" + +#include +#include + +namespace DRAMSysConfiguration +{ + +std::string Configuration::resourceDirectory; + +void to_json(json &j, const Configuration &c) +{ + j = json{{"addressmapping", c.addressMapping}, {"mcconfig", c.mcConfig}, {"memspec", c.memSpec}, + {"simulationid", c.simulationId}, {"simconfig", c.simConfig}, {"thermalconfig", c.thermalConfig}, + {"tracesetup", c.traceSetup}}; + + remove_null_values(j); +} + +void from_json(const json &j, Configuration &c) +{ + j.at("addressmapping").get_to(c.addressMapping); + j.at("mcconfig").get_to(c.mcConfig); + j.at("memspec").get_to(c.memSpec); + j.at("simulationid").get_to(c.simulationId); + j.at("simconfig").get_to(c.simConfig); + + if (j.contains("thermalconfig")) + j.at("thermalconfig").get_to(c.thermalConfig); + + if (j.contains("tracesetup")) + j.at("tracesetup").get_to(c.traceSetup); +} + +void from_dump(const std::string &dump, Configuration &c) +{ + json json_simulation = json::parse(dump).at("simulation"); + json_simulation.get_to(c); +} + +std::string dump(const Configuration &c, unsigned int indentation) +{ + json json_simulation; + json_simulation["simulation"] = c; + return json_simulation.dump(indentation); +} + +Configuration from_path(const std::string &path, const std::string &resourceDirectory) +{ + Configuration::resourceDirectory = resourceDirectory; + + std::ifstream file(path); + + if (file.is_open()) + { + json simulation = json::parse(file).at("simulation"); + return simulation.get(); + } + else + { + throw std::runtime_error("Failed to open file " + path); + } +} + +} // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/Configuration.h b/DRAMSys/library/src/common/configuration/Configuration.h new file mode 100644 index 00000000..657f11be --- /dev/null +++ b/DRAMSys/library/src/common/configuration/Configuration.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#ifndef DRAMSYSCONFIGURATION_CONFIGURATION_H +#define DRAMSYSCONFIGURATION_CONFIGURATION_H + +#include "AddressMapping.h" +#include "McConfig.h" +#include "SimConfig.h" +#include "ThermalConfig.h" +#include "TraceSetup.h" +#include "memspec/MemSpec.h" +#include "util.h" + +#include +#include +#include + +/** + * To support polymorphic configurations, a Json "type" tag is used + * to determine the correct type before further parsing. + * + * To support optional values, std::optional is used. The default + * values will be provided by DRAMSys itself. + * + * To achieve static polymorphism, std::variant is used. + */ + +namespace DRAMSysConfiguration +{ +using json = nlohmann::json; + +struct Configuration +{ + AddressMapping addressMapping; + McConfig mcConfig; + MemSpec memSpec; + SimConfig simConfig; + std::string simulationId; + std::optional thermalConfig; + std::optional traceSetup; + + static std::string resourceDirectory; +}; + +void to_json(json &j, const Configuration &p); +void from_json(const json &j, Configuration &p); + +void from_dump(const std::string &dump, Configuration &c); +std::string dump(const Configuration &c, unsigned int indentation = -1); + +Configuration from_path(const std::string &path, const std::string &resourceDirectory = DRAMSysResourceDirectory); + +} // namespace DRAMSysConfiguration + +#endif // DRAMSYSCONFIGURATION_CONFIGURATION_H diff --git a/DRAMSys/library/src/common/configuration/McConfig.cpp b/DRAMSys/library/src/common/configuration/McConfig.cpp new file mode 100644 index 00000000..1abce2f0 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/McConfig.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include "McConfig.h" +#include +namespace DRAMSysConfiguration +{ + +void to_json(json &j, const McConfig &c) +{ + j = json{{"PagePolicy", c.pagePolicy}, + {"Scheduler", c.scheduler}, + {"SchedulerBuffer", c.schedulerBuffer}, + {"RequestBufferSize", c.requestBufferSize}, + {"CmdMux", c.cmdMux}, + {"RespQueue", c.respQueue}, + {"RefreshPolicy", c.refreshPolicy}, + {"RefreshMaxPostponed", c.refreshMaxPostponed}, + {"RefreshMaxPulledin", c.refreshMaxPulledin}, + {"PowerDownPolicy", c.powerDownPolicy}, + {"Arbiter", c.arbiter}, + {"MaxActiveTransactions", c.maxActiveTransactions}, + {"RefreshManagment", c.refreshManagement}, + {"ArbitrationDelayFw", c.arbitrationDelayFw}, + {"ArbitrationDelayBw", c.arbitrationDelayBw}, + {"ThinkDelayFw", c.thinkDelayFw}, + {"ThinkDelayBw", c.thinkDelayBw}, + {"PhyDelayFw", c.phyDelayFw}, + {"PhyDelayBw", c.phyDelayBw}}; + + remove_null_values(j); +} + +void from_json(const json &j, McConfig &c) +{ + json j_mcconfig = get_config_json(j, mcConfigPath, "mcconfig"); + + if (j_mcconfig.contains("PagePolicy")) + j_mcconfig.at("PagePolicy").get_to(c.pagePolicy); + + if (j_mcconfig.contains("Scheduler")) + j_mcconfig.at("Scheduler").get_to(c.scheduler); + + if (j_mcconfig.contains("SchedulerBuffer")) + j_mcconfig.at("SchedulerBuffer").get_to(c.schedulerBuffer); + + if (j_mcconfig.contains("RequestBufferSize")) + j_mcconfig.at("RequestBufferSize").get_to(c.requestBufferSize); + + if (j_mcconfig.contains("CmdMux")) + j_mcconfig.at("CmdMux").get_to(c.cmdMux); + + if (j_mcconfig.contains("RespQueue")) + j_mcconfig.at("RespQueue").get_to(c.respQueue); + + if (j_mcconfig.contains("RefreshPolicy")) + j_mcconfig.at("RefreshPolicy").get_to(c.refreshPolicy); + + if (j_mcconfig.contains("RefreshMaxPostponed")) + j_mcconfig.at("RefreshMaxPostponed").get_to(c.refreshMaxPostponed); + + if (j_mcconfig.contains("RefreshMaxPulledin")) + j_mcconfig.at("RefreshMaxPulledin").get_to(c.refreshMaxPulledin); + + if (j_mcconfig.contains("PowerDownPolicy")) + j_mcconfig.at("PowerDownPolicy").get_to(c.powerDownPolicy); + + if (j_mcconfig.contains("Arbiter")) + j_mcconfig.at("Arbiter").get_to(c.arbiter); + + if (j_mcconfig.contains("MaxActiveTransactions")) + j_mcconfig.at("MaxActiveTransactions").get_to(c.maxActiveTransactions); + + if (j_mcconfig.contains("RefreshManagment")) + j_mcconfig.at("RefreshManagment").get_to(c.refreshManagement); + + if (j_mcconfig.contains("ArbitrationDelayFw")) + j_mcconfig.at("ArbitrationDelayFw").get_to(c.arbitrationDelayFw); + + if (j_mcconfig.contains("ArbitrationDelayBw")) + j_mcconfig.at("ArbitrationDelayBw").get_to(c.arbitrationDelayBw); + + if (j_mcconfig.contains("ThinkDelayFw")) + j_mcconfig.at("ThinkDelayFw").get_to(c.thinkDelayFw); + + if (j_mcconfig.contains("ThinkDelayBw")) + j_mcconfig.at("ThinkDelayBw").get_to(c.thinkDelayBw); + + if (j_mcconfig.contains("PhyDelayFw")) + j_mcconfig.at("PhyDelayFw").get_to(c.phyDelayFw); + + if (j_mcconfig.contains("PhyDelayBw")) + j_mcconfig.at("PhyDelayBw").get_to(c.phyDelayBw); + + invalidateEnum(c.pagePolicy); + invalidateEnum(c.scheduler); + invalidateEnum(c.schedulerBuffer); + invalidateEnum(c.cmdMux); + invalidateEnum(c.respQueue); + invalidateEnum(c.refreshPolicy); + invalidateEnum(c.respQueue); + invalidateEnum(c.powerDownPolicy); + invalidateEnum(c.arbiter); +} + +void to_json(json &j, const RefreshPolicy &r) +{ + if (r == RefreshPolicy::NoRefresh) + j = "NoRefresh"; + else if (r == RefreshPolicy::AllBank) + j = "AllBank"; + else if (r == RefreshPolicy::PerBank) + j = "PerBank"; + else if (r == RefreshPolicy::Per2Bank) + j = "Per2Bank"; + else if (r == RefreshPolicy::SameBank) + j = "SameBank"; + else + j = nullptr; +} + +void from_json(const json &j, RefreshPolicy &r) +{ + if (j == "NoRefresh") + r = RefreshPolicy::NoRefresh; + else if (j == "AllBank" || j == "Rankwise") + r = RefreshPolicy::AllBank; + else if (j == "PerBank" || j == "Bankwise") + r = RefreshPolicy::PerBank; + else if (j == "SameBank" || j == "Groupwise") + r = RefreshPolicy::SameBank; + else if (j == "Per2Bank") + r = RefreshPolicy::Per2Bank; + else + r = RefreshPolicy::Invalid; +} + +void from_dump(const std::string &dump, McConfig &c) +{ + json json_mcconfig = json::parse(dump).at("mcconfig"); + json_mcconfig.get_to(c); +} + +std::string dump(const McConfig &c, unsigned int indentation) +{ + json json_mcconfig; + json_mcconfig["mcconfig"] = c; + return json_mcconfig.dump(indentation); +} + +} // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/McConfig.h b/DRAMSys/library/src/common/configuration/McConfig.h new file mode 100644 index 00000000..051c05e4 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/McConfig.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#ifndef DRAMSYSCONFIGURATION_MCCONFIG_H +#define DRAMSYSCONFIGURATION_MCCONFIG_H + +#include "util.h" + +#include +#include +#include + +namespace DRAMSysConfiguration +{ +using json = nlohmann::json; + +const std::string mcConfigPath = "configs/mcconfigs"; + +enum class PagePolicy +{ + Open, + OpenAdaptive, + Closed, + ClosedAdaptive, + Invalid = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(PagePolicy, { + {PagePolicy::Invalid, nullptr}, + {PagePolicy::Open, "Open"}, + {PagePolicy::OpenAdaptive, "OpenAdaptive"}, + {PagePolicy::Closed, "Closed"}, + {PagePolicy::ClosedAdaptive, "ClosedAdaptive"}, + }) + +enum class Scheduler +{ + Fifo, + FrFcfs, + FrFcfsGrp, + Invalid = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(Scheduler, {{Scheduler::Invalid, nullptr}, + {Scheduler::Fifo, "Fifo"}, + {Scheduler::FrFcfs, "FrFcfs"}, + {Scheduler::FrFcfsGrp, "FrFcfsGrp"}}) + +enum class SchedulerBuffer +{ + Bankwise, + ReadWrite, + Shared, + Invalid = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(SchedulerBuffer, {{SchedulerBuffer::Invalid, nullptr}, + {SchedulerBuffer::Bankwise, "Bankwise"}, + {SchedulerBuffer::ReadWrite, "ReadWrite"}, + {SchedulerBuffer::Shared, "Shared"}}) + +enum class CmdMux +{ + Oldest, + Strict, + Invalid = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(CmdMux, + {{CmdMux::Invalid, nullptr}, {CmdMux::Oldest, "Oldest"}, {CmdMux::Strict, "Strict"}}) + +enum class RespQueue +{ + Fifo, + Reorder, + Invalid = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(RespQueue, {{RespQueue::Invalid, nullptr}, + {RespQueue::Fifo, "Fifo"}, + {RespQueue::Reorder, "Reorder"}}) + +enum class RefreshPolicy +{ + NoRefresh, + AllBank, + PerBank, + Per2Bank, + SameBank, + Invalid = -1 +}; + +enum class PowerDownPolicy +{ + NoPowerDown, + Staggered, + Invalid = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(PowerDownPolicy, {{PowerDownPolicy::Invalid, nullptr}, + {PowerDownPolicy::NoPowerDown, "NoPowerDown"}, + {PowerDownPolicy::Staggered, "Staggered"}}) + +enum class Arbiter +{ + Simple, + Fifo, + Reorder, + Invalid = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(Arbiter, {{Arbiter::Invalid, nullptr}, + {Arbiter::Simple, "Simple"}, + {Arbiter::Fifo, "Fifo"}, + {Arbiter::Reorder, "Reorder"}}) + +struct McConfig +{ + std::optional pagePolicy; + std::optional scheduler; + std::optional schedulerBuffer; + std::optional requestBufferSize; + std::optional cmdMux; + std::optional respQueue; + std::optional refreshPolicy; + std::optional refreshMaxPostponed; + std::optional refreshMaxPulledin; + std::optional powerDownPolicy; + std::optional arbiter; + std::optional maxActiveTransactions; + std::optional refreshManagement; + std::optional arbitrationDelayFw; + std::optional arbitrationDelayBw; + std::optional thinkDelayFw; + std::optional thinkDelayBw; + std::optional phyDelayFw; + std::optional phyDelayBw; +}; + +void to_json(json &j, const McConfig &c); +void from_json(const json &j, McConfig &c); + +void to_json(json &j, const RefreshPolicy &r); +void from_json(const json &j, RefreshPolicy &r); + +void from_dump(const std::string &dump, McConfig &c); +std::string dump(const McConfig &c, unsigned int indentation = -1); + +} // namespace Configuration + +#endif // MCCONFIG_H diff --git a/DRAMSys/library/src/common/configuration/SimConfig.cpp b/DRAMSys/library/src/common/configuration/SimConfig.cpp new file mode 100644 index 00000000..e0894a78 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/SimConfig.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include "SimConfig.h" + +namespace DRAMSysConfiguration +{ + +void to_json(json &j, const SimConfig &c) +{ + j = json{{"AddressOffset", c.addressOffset}, + {"CheckTLM2Protocol", c.checkTLM2Protocol}, + {"DatabaseRecording", c.databaseRecording}, + {"Debug", c.debug}, + {"EnableWindowing", c.enableWindowing}, + {"ErrorCSVFile", c.errorCsvFile}, + {"ErrorChipSeed", c.errorChipSeed}, + {"PowerAnalysis", c.powerAnalysis}, + {"SimulationName", c.simulationName}, + {"SimulationProgressBar", c.simulationProgressBar}, + {"StoreMode", c.storeMode}, + {"ThermalSimulation", c.thermalSimulation}, + {"UseMalloc", c.useMalloc}, + {"WindowSize", c.windowSize}}; +} + +void from_json(const json &j, SimConfig &c) +{ + json j_simconfig = get_config_json(j, simConfigPath, "simconfig"); + + if (j_simconfig.contains("AddressOffset")) + j_simconfig.at("AddressOffset").get_to(c.addressOffset); + + if (j_simconfig.contains("CheckTLM2Protocol")) + j_simconfig.at("CheckTLM2Protocol").get_to(c.checkTLM2Protocol); + + if (j_simconfig.contains("DatabaseRecording")) + j_simconfig.at("DatabaseRecording").get_to(c.databaseRecording); + + if (j_simconfig.contains("Debug")) + j_simconfig.at("Debug").get_to(c.debug); + + if (j_simconfig.contains("EnableWindowing")) + j_simconfig.at("EnableWindowing").get_to(c.enableWindowing); + + if (j_simconfig.contains("ErrorCSVFile")) + j_simconfig.at("ErrorCSVFile").get_to(c.errorCsvFile); + + if (j_simconfig.contains("ErrorChipSeed")) + j_simconfig.at("ErrorChipSeed").get_to(c.errorChipSeed); + + if (j_simconfig.contains("PowerAnalysis")) + j_simconfig.at("PowerAnalysis").get_to(c.powerAnalysis); + + if (j_simconfig.contains("SimulationName")) + j_simconfig.at("SimulationName").get_to(c.simulationName); + + if (j_simconfig.contains("SimulationProgressBar")) + j_simconfig.at("SimulationProgressBar").get_to(c.simulationProgressBar); + + if (j_simconfig.contains("StoreMode")) + j_simconfig.at("StoreMode").get_to(c.storeMode); + + if (j_simconfig.contains("ThermalSimulation")) + j_simconfig.at("ThermalSimulation").get_to(c.thermalSimulation); + + if (j_simconfig.contains("UseMalloc")) + j_simconfig.at("UseMalloc").get_to(c.useMalloc); + + if (j_simconfig.contains("WindowSize")) + j_simconfig.at("WindowSize").get_to(c.windowSize); + + invalidateEnum(c.storeMode); +} + +void from_dump(const std::string &dump, SimConfig &c) +{ + json json_simconfig = json::parse(dump).at("simconfig"); + json_simconfig.get_to(c); +} + +std::string dump(const SimConfig &c, unsigned int indentation) +{ + json json_simconfig; + json_simconfig["simconfig"] = c; + return json_simconfig.dump(indentation); +} + +} // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/SimConfig.h b/DRAMSys/library/src/common/configuration/SimConfig.h new file mode 100644 index 00000000..339495c8 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/SimConfig.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#ifndef DRAMSYSCONFIGURATION_SIMCONFIG_H +#define DRAMSYSCONFIGURATION_SIMCONFIG_H + +#include "util.h" + +#include +#include + +namespace DRAMSysConfiguration +{ +using json = nlohmann::json; + +const std::string simConfigPath = "configs/simulator"; + +enum class StoreMode +{ + NoStorage, + Store, + ErrorModel, + Invalid = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(StoreMode, {{StoreMode::Invalid, nullptr}, + {StoreMode::NoStorage, "NoStorage"}, + {StoreMode::Store, "Store"}, + {StoreMode::ErrorModel, "ErrorModel"}}) + +struct SimConfig +{ + std::optional addressOffset; + std::optional checkTLM2Protocol; + std::optional databaseRecording; + std::optional debug; + std::optional enableWindowing; + std::optional errorCsvFile; + std::optional errorChipSeed; + std::optional powerAnalysis; + std::optional simulationName; + std::optional simulationProgressBar; + std::optional storeMode; + std::optional thermalSimulation; + std::optional useMalloc; + std::optional windowSize; +}; + +void to_json(json &j, const SimConfig &c); +void from_json(const json &j, SimConfig &c); + +void from_dump(const std::string &dump, SimConfig &c); +std::string dump(const SimConfig &c, unsigned int indentation = -1); + +} // namespace Configuration + +#endif diff --git a/DRAMSys/library/src/common/configuration/ThermalConfig.cpp b/DRAMSys/library/src/common/configuration/ThermalConfig.cpp new file mode 100644 index 00000000..f3bed414 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/ThermalConfig.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include "ThermalConfig.h" +#include "util.h" + +namespace DRAMSysConfiguration +{ + +void to_json(json &j, const ThermalConfig &c) +{ + j = json{{"TemperatureScale", c.temperatureScale}, + {"StaticTemperatureDefaultValue", c.staticTemperatureDefaultValue}, + {"ThermalSimPeriod", c.thermalSimPeriod}, + {"ThermalSimUnit", c.thermalSimUnit}, + {"PowerInfoFile", c.powerInfo}, + {"IceServerIp", c.iceServerIp}, + {"IceServerPort", c.iceServerPort}, + {"SimPeriodAdjustFactor", c.simPeriodAdjustFactor}, + {"NPowStableCyclesToIncreasePeriod", c.nPowStableCyclesToIncreasePeriod}, + {"GenerateTemperatureMap", c.generateTemperatureMap}, + {"GeneratePowerMap", c.generatePowerMap}}; +} + +void from_json(const json &j, ThermalConfig &c) +{ + json j_thermalsim = get_config_json(j, thermalConfigPath, "thermalsimconfig"); + + j_thermalsim.at("TemperatureScale").get_to(c.temperatureScale); + j_thermalsim.at("StaticTemperatureDefaultValue").get_to(c.staticTemperatureDefaultValue); + j_thermalsim.at("ThermalSimPeriod").get_to(c.thermalSimPeriod); + j_thermalsim.at("ThermalSimUnit").get_to(c.thermalSimUnit); + j_thermalsim.at("PowerInfoFile").get_to(c.powerInfo); + j_thermalsim.at("IceServerIp").get_to(c.iceServerIp); + j_thermalsim.at("IceServerPort").get_to(c.iceServerPort); + j_thermalsim.at("SimPeriodAdjustFactor").get_to(c.simPeriodAdjustFactor); + j_thermalsim.at("NPowStableCyclesToIncreasePeriod").get_to(c.nPowStableCyclesToIncreasePeriod); + j_thermalsim.at("GenerateTemperatureMap").get_to(c.generateTemperatureMap); + j_thermalsim.at("GeneratePowerMap").get_to(c.generatePowerMap); +} + +void to_json(json &j, const DramDieChannel &c) +{ + j = json{{"init_pow", c.init_pow}, {"threshold", c.threshold}}; +} + +void from_json(const json &j, DramDieChannel &c) +{ + j.at("init_pow").get_to(c.init_pow); + j.at("threshold").get_to(c.threshold); +} + +void to_json(json &j, const PowerInfo &c) +{ + j = json{}; + + for (const auto &channel : c.channels) + { + j.emplace(channel.identifier, channel); + } +} + +void from_json(const json &j, PowerInfo &c) +{ + json j_powerinfo = get_config_json(j, thermalConfigPath, "powerInfo"); + + for (const auto &entry : j_powerinfo.items()) + { + DramDieChannel channel; + j_powerinfo.at(entry.key()).get_to(channel); + channel.identifier = entry.key(); + + c.channels.push_back(channel); + } +} + +void from_dump(const std::string &dump, ThermalConfig &c) +{ + json json_thermalconfig = json::parse(dump).at("thermalconfig"); + json_thermalconfig.get_to(c); +} + +std::string dump(const ThermalConfig &c, unsigned int indentation) +{ + json json_thermalconfig; + json_thermalconfig["thermalconfig"] = c; + return json_thermalconfig.dump(indentation); +} + +} // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/ThermalConfig.h b/DRAMSys/library/src/common/configuration/ThermalConfig.h new file mode 100644 index 00000000..44497346 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/ThermalConfig.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#ifndef DRAMSYSCONFIGURATION_THERMALCONFIG_H +#define DRAMSYSCONFIGURATION_THERMALCONFIG_H + +#include + +namespace DRAMSysConfiguration +{ +using json = nlohmann::json; + +const std::string thermalConfigPath = "configs/thermalsim"; + +enum class TemperatureScale +{ + Celsius, + Fahrenheit, + Kelvin, + Invalid = -1, +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(TemperatureScale, {{TemperatureScale::Invalid, nullptr}, + {TemperatureScale::Celsius, "Celsius"}, + {TemperatureScale::Fahrenheit, "Fahrenheit"}, + {TemperatureScale::Kelvin, "Kelvin"}}) + +enum class ThermalSimUnit +{ + Seconds, + Milliseconds, + Microseconds, + Nanoseconds, + Picoseconds, + Femtoseconds, + Invalid = -1, +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(ThermalSimUnit, {{ThermalSimUnit::Invalid, nullptr}, + {ThermalSimUnit::Seconds, "s"}, + {ThermalSimUnit::Milliseconds, "ms"}, + {ThermalSimUnit::Microseconds, "us"}, + {ThermalSimUnit::Nanoseconds, "ns"}, + {ThermalSimUnit::Picoseconds, "ps"}, + {ThermalSimUnit::Femtoseconds, "fs"}}) + +struct DramDieChannel +{ + std::string identifier; + double init_pow; + double threshold; +}; + +void to_json(json &j, const DramDieChannel &c); +void from_json(const json &j, DramDieChannel &c); + +struct PowerInfo +{ + std::vector channels; +}; + +void to_json(json &j, const PowerInfo &c); +void from_json(const json &j, PowerInfo &c); + +struct ThermalConfig +{ + TemperatureScale temperatureScale; + int staticTemperatureDefaultValue; + double thermalSimPeriod; + ThermalSimUnit thermalSimUnit; + PowerInfo powerInfo; + std::string iceServerIp; + unsigned int iceServerPort; + unsigned int simPeriodAdjustFactor; + unsigned int nPowStableCyclesToIncreasePeriod; + bool generateTemperatureMap; + bool generatePowerMap; +}; + +void to_json(json &j, const ThermalConfig &c); +void from_json(const json &j, ThermalConfig &c); + +void from_dump(const std::string &dump, ThermalConfig &c); +std::string dump(const ThermalConfig &c, unsigned int indentation = -1); + +} // namespace Configuration + +#endif // THERMALCONFIG_H diff --git a/DRAMSys/library/src/common/configuration/TraceSetup.cpp b/DRAMSys/library/src/common/configuration/TraceSetup.cpp new file mode 100644 index 00000000..1e25b4a4 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/TraceSetup.cpp @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include "TraceSetup.h" + +#include + +namespace DRAMSysConfiguration +{ + +TrafficInitiator::~TrafficInitiator() +{ +} + +TraceGeneratorState::~TraceGeneratorState() +{ +} + +void to_json(json &j, const TraceSetup &c) +{ + // Create an empty array + j = json::array(); + + for (const auto &initiator : c.initiators) + { + json initiator_j; + + std::visit( + [&initiator_j](auto &&initiator) + { + initiator_j["name"] = initiator.name; + initiator_j["clkMhz"] = initiator.clkMhz; + initiator_j["maxPendingReadRequests"] = initiator.maxPendingReadRequests; + initiator_j["maxPendingWriteRequests"] = initiator.maxPendingWriteRequests; + initiator_j["addLengthConverter"] = initiator.addLengthConverter; + + using T = std::decay_t; + if constexpr (std::is_same_v) + { + initiator_j["type"] = "generator"; + initiator_j["seed"] = initiator.seed; + initiator_j["maxTransactions"] = initiator.maxTransactions; + initiator_j["idleUntil"] = initiator.idleUntil; + + // When there are less than 2 states, flatten out the json. + if (initiator.states.size() == 1) + { + std::visit( + [&initiator_j](auto &&state) + { + using U = std::decay_t; + + if constexpr (std::is_same_v) + { + initiator_j["numRequests"] = state.numRequests; + initiator_j["rwRatio"] = state.rwRatio; + initiator_j["addressDistribution"] = state.addressDistribution; + initiator_j["addressIncrement"] = state.addressIncrement; + initiator_j["minAddress"] = state.minAddress; + initiator_j["maxAddress"] = state.maxAddress; + initiator_j["clksPerRequest"] = state.clksPerRequest; + initiator_j["notify"] = state.notify; + } + else // if constexpr (std::is_same_v) + { + initiator_j["idleClks"] = state.idleClks; + } + }, + initiator.states.at(0)); + } + else + { + json states_j = json::array(); + + for (const auto &state : initiator.states) + { + json state_j; + state_j["id"] = state.first; + + std::visit( + [&state_j](auto &&state) + { + using U = std::decay_t; + + if constexpr (std::is_same_v) + { + state_j["numRequests"] = state.numRequests; + state_j["rwRatio"] = state.rwRatio; + state_j["addressDistribution"] = state.addressDistribution; + state_j["addressIncrement"] = state.addressIncrement; + state_j["minAddress"] = state.minAddress; + state_j["maxAddress"] = state.maxAddress; + state_j["clksPerRequest"] = state.clksPerRequest; + state_j["notify"] = state.notify; + } + else // if constexpr (std::is_same_v) + { + state_j["idleClks"] = state.idleClks; + } + }, + state.second); + + remove_null_values(state_j); + states_j.insert(states_j.end(), state_j); + } + initiator_j["states"] = states_j; + + json transitions_j = json::array(); + + for (const auto &transition : initiator.transitions) + { + json transition_j; + transition_j["from"] = transition.first; + transition_j["to"] = transition.second.to; + transition_j["propability"] = transition.second.propability; + remove_null_values(transition_j); + transitions_j.insert(transitions_j.end(), transition_j); + } + initiator_j["transitions"] = transitions_j; + } + } + else if constexpr (std::is_same_v) + { + initiator_j["type"] = "hammer"; + initiator_j["numRequests"] = initiator.numRequests; + initiator_j["rowIncrement"] = initiator.rowIncrement; + } + else // if constexpr (std::is_same_v) + { + initiator_j["type"] = "player"; + } + }, + initiator); + + remove_null_values(initiator_j); + j.insert(j.end(), initiator_j); + } +} + +void from_json(const json &j, TraceSetup &c) +{ + for (const auto &initiator_j : j) + { + // Default to Player, when not specified + TrafficInitiatorType type = initiator_j.value("type", TrafficInitiatorType::Player); + + std::variant initiator; + + if (type == TrafficInitiatorType::Player) + { + initiator = TracePlayer{}; + } + else if (type == TrafficInitiatorType::Generator) + { + TraceGenerator generator; + + auto process_state = [](const json &state_j) + -> std::pair> + { + std::variant state; + + if (state_j.contains("idleClks")) + { + // Idle state + TraceGeneratorIdleState idleState; + state_j.at("idleClks").get_to(idleState.idleClks); + + state = std::move(idleState); + } + else + { + // Traffic state + TraceGeneratorTrafficState trafficState; + state_j.at("numRequests").get_to(trafficState.numRequests); + state_j.at("rwRatio").get_to(trafficState.rwRatio); + state_j.at("addressDistribution").get_to(trafficState.addressDistribution); + + if (state_j.contains("addressIncrement")) + state_j.at("addressIncrement").get_to(trafficState.addressIncrement); + + if (state_j.contains("minAddress")) + state_j.at("minAddress").get_to(trafficState.minAddress); + + if (state_j.contains("maxAddress")) + state_j.at("maxAddress").get_to(trafficState.maxAddress); + + if (state_j.contains("clksPerRequest")) + state_j.at("clksPerRequest").get_to(trafficState.clksPerRequest); + + if (state_j.contains("notify")) + state_j.at("notify").get_to(trafficState.notify); + + state = std::move(trafficState); + } + + // Default to 0 + unsigned int id = 0; + + if (state_j.contains("id")) + id = state_j.at("id"); + + return {id, std::move(state)}; + }; + + if (initiator_j.contains("states")) + { + for (const auto &state_j : initiator_j.at("states")) + { + auto state = process_state(state_j); + generator.states[state.first] = std::move(state.second); + } + + for (const auto &transition_j : initiator_j.at("transitions")) + { + TraceGeneratorStateTransition transition; + unsigned int from = transition_j.at("from"); + transition.to = transition_j.at("to"); + transition.propability = transition_j.at("propability"); + generator.transitions.emplace(from, transition); + } + } + else // Only one state will be created + { + auto state = process_state(initiator_j); + generator.states[state.first] = std::move(state.second); + } + + if (initiator_j.contains("seed")) + initiator_j.at("seed").get_to(generator.seed); + + if (initiator_j.contains("maxTransactions")) + initiator_j.at("maxTransactions").get_to(generator.maxTransactions); + + if (initiator_j.contains("idleUntil")) + initiator_j.at("idleUntil").get_to(generator.idleUntil); + + initiator = generator; + } + else if (type == TrafficInitiatorType::Hammer) + { + TraceHammer hammer; + + initiator_j.at("numRequests").get_to(hammer.numRequests); + initiator_j.at("rowIncrement").get_to(hammer.rowIncrement); + + initiator = hammer; + } + + std::visit( + [&initiator_j](auto &&initiator) + { + initiator_j.at("name").get_to(initiator.name); + initiator_j.at("clkMhz").get_to(initiator.clkMhz); + + if (initiator_j.contains("maxPendingReadRequests")) + initiator_j.at("maxPendingReadRequests").get_to(initiator.maxPendingReadRequests); + + if (initiator_j.contains("maxPendingWriteRequests")) + initiator_j.at("maxPendingWriteRequests").get_to(initiator.maxPendingWriteRequests); + + if (initiator_j.contains("addLengthConverter")) + initiator_j.at("addLengthConverter").get_to(initiator.addLengthConverter); + }, + initiator); + + c.initiators.emplace_back(std::move(initiator)); + } +} + +void from_dump(const std::string &dump, TraceSetup &c) +{ + json json_tracesetup = json::parse(dump).at("tracesetup"); + json_tracesetup.get_to(c); +} + +std::string dump(const TraceSetup &c, unsigned int indentation) +{ + json json_tracesetup; + json_tracesetup["tracesetup"] = c; + return json_tracesetup.dump(indentation); +} + +} // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/TraceSetup.h b/DRAMSys/library/src/common/configuration/TraceSetup.h new file mode 100644 index 00000000..d9f0ed9a --- /dev/null +++ b/DRAMSys/library/src/common/configuration/TraceSetup.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#ifndef DRAMSYSCONFIGURATION_TRACESETUP_H +#define DRAMSYSCONFIGURATION_TRACESETUP_H + +#include "util.h" + +#include +#include +#include + +namespace DRAMSysConfiguration +{ +using json = nlohmann::json; + +enum class TrafficInitiatorType +{ + Player, + Generator, + Hammer, + Invalid = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(TrafficInitiatorType, {{TrafficInitiatorType::Invalid, nullptr}, + {TrafficInitiatorType::Player, "player"}, + {TrafficInitiatorType::Hammer, "hammer"}, + {TrafficInitiatorType::Generator, "generator"}}) + +enum class AddressDistribution +{ + Random, + Sequential, + Invalid = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(AddressDistribution, {{AddressDistribution::Invalid, nullptr}, + {AddressDistribution::Random, "random"}, + {AddressDistribution::Sequential, "sequential"}}) + +struct TrafficInitiator +{ + virtual ~TrafficInitiator() = 0; + + uint64_t clkMhz; + std::string name; + std::optional maxPendingReadRequests; + std::optional maxPendingWriteRequests; + std::optional addLengthConverter; +}; + +struct TracePlayer : public TrafficInitiator +{ +}; + +struct TraceGeneratorState +{ + virtual ~TraceGeneratorState() = 0; +}; + +struct TraceGeneratorTrafficState : public TraceGeneratorState +{ + uint64_t numRequests; + double rwRatio; + AddressDistribution addressDistribution; + std::optional addressIncrement; + std::optional minAddress; + std::optional maxAddress; + std::optional clksPerRequest; + std::optional notify; +}; + +struct TraceGeneratorIdleState : public TraceGeneratorState +{ + uint64_t idleClks; +}; + +struct TraceGeneratorStateTransition +{ + unsigned int to; + float propability; +}; + +struct TraceGenerator : public TrafficInitiator +{ + std::optional seed; + std::optional maxTransactions; + std::map> states; + std::multimap transitions; + std::optional idleUntil; +}; + +struct TraceHammer : public TrafficInitiator +{ + uint64_t numRequests; + uint64_t rowIncrement; +}; + +struct TraceSetup +{ + std::vector> initiators; +}; + +void to_json(json &j, const TraceSetup &c); +void from_json(const json &j, TraceSetup &c); + +void from_dump(const std::string &dump, TraceSetup &c); +std::string dump(const TraceSetup &c, unsigned int indentation = -1); + +} // namespace Configuration + +#endif diff --git a/DRAMSys/library/src/common/configuration/memspec/MemArchitectureSpec.cpp b/DRAMSys/library/src/common/configuration/memspec/MemArchitectureSpec.cpp new file mode 100644 index 00000000..ce2b33d2 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/memspec/MemArchitectureSpec.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include "MemArchitectureSpec.h" + +namespace DRAMSysConfiguration +{ + +void to_json(json &j, const MemArchitectureSpec &c) +{ + j = json{}; + + for (const auto &entry : c.entries) + { + j[entry.first] = entry.second; + } +} + +void from_json(const json &j, MemArchitectureSpec &c) +{ + for (const auto &entry : j.items()) + { + c.entries[entry.key()] = entry.value(); + } +} + +} // namespace Configuration diff --git a/DRAMSys/library/src/common/configuration/memspec/MemArchitectureSpec.h b/DRAMSys/library/src/common/configuration/memspec/MemArchitectureSpec.h new file mode 100644 index 00000000..6179e986 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/memspec/MemArchitectureSpec.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#ifndef DRAMSYSCONFIGURATION_MEMARCHITECTURESPEC_H +#define DRAMSYSCONFIGURATION_MEMARCHITECTURESPEC_H + +#include +#include + +namespace DRAMSysConfiguration +{ +using json = nlohmann::json; + +struct MemArchitectureSpec +{ + std::unordered_map entries; +}; + +void to_json(json &j, const MemArchitectureSpec &c); +void from_json(const json &j, MemArchitectureSpec &c); + +} // namespace Configuration + +#endif diff --git a/DRAMSys/library/src/common/configuration/memspec/MemPowerSpec.cpp b/DRAMSys/library/src/common/configuration/memspec/MemPowerSpec.cpp new file mode 100644 index 00000000..0cdb3059 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/memspec/MemPowerSpec.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include "MemPowerSpec.h" + +namespace DRAMSysConfiguration +{ + +void to_json(json &j, const MemPowerSpec &c) +{ + j = json{}; + + for (const auto &entry : c.entries) + { + j[entry.first] = entry.second; + } +} + +void from_json(const json &j, MemPowerSpec &c) +{ + for (const auto &entry : j.items()) + { + c.entries[entry.key()] = entry.value(); + } +} + +} // namespace Configuration diff --git a/DRAMSys/library/src/common/configuration/memspec/MemPowerSpec.h b/DRAMSys/library/src/common/configuration/memspec/MemPowerSpec.h new file mode 100644 index 00000000..513dd750 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/memspec/MemPowerSpec.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#ifndef DRAMSYSCONFIGURATION_MEMPOWERSPEC_H +#define DRAMSYSCONFIGURATION_MEMPOWERSPEC_H + +#include +#include + +namespace DRAMSysConfiguration +{ +using json = nlohmann::json; + +struct MemPowerSpec +{ + std::unordered_map entries; +}; + +void to_json(json &j, const MemPowerSpec &c); +void from_json(const json &j, MemPowerSpec &c); + +} // namespace Configuration + +#endif diff --git a/DRAMSys/library/src/common/configuration/memspec/MemSpec.cpp b/DRAMSys/library/src/common/configuration/memspec/MemSpec.cpp new file mode 100644 index 00000000..cc5dee89 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/memspec/MemSpec.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include "MemSpec.h" + +namespace DRAMSysConfiguration +{ + +void to_json(json &j, const MemSpec &c) +{ + j = json{{"memarchitecturespec", c.memArchitectureSpec}, + {"memoryId", c.memoryId}, + {"memoryType", c.memoryType}, + {"memtimingspec", c.memTimingSpec}, + {"mempowerspec", c.memPowerSpec}}; + + remove_null_values(j); +} + +void from_json(const json &j, MemSpec &c) +{ + json j_memspecs = get_config_json(j, memSpecPath, "memspec"); + + j_memspecs.at("memarchitecturespec").get_to(c.memArchitectureSpec); + j_memspecs.at("memoryId").get_to(c.memoryId); + j_memspecs.at("memoryType").get_to(c.memoryType); + j_memspecs.at("memtimingspec").get_to(c.memTimingSpec); + + if (j_memspecs.contains("mempowerspec")) + j_memspecs.at("mempowerspec").get_to(c.memPowerSpec); +} + +void from_dump(const std::string &dump, MemSpec &c) +{ + json json_memspec = json::parse(dump).at("memspec"); + json_memspec.get_to(c); +} + +std::string dump(const MemSpec &c, unsigned int indentation) +{ + json json_memspec; + json_memspec["memspec"] = c; + return json_memspec.dump(indentation); +} + +} // namespace Configuration diff --git a/DRAMSys/library/src/common/configuration/memspec/MemSpec.h b/DRAMSys/library/src/common/configuration/memspec/MemSpec.h new file mode 100644 index 00000000..0aa2cb7f --- /dev/null +++ b/DRAMSys/library/src/common/configuration/memspec/MemSpec.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#ifndef DRAMSYSCONFIGURATION_MEMSPEC_H +#define DRAMSYSCONFIGURATION_MEMSPEC_H + +#include "MemArchitectureSpec.h" +#include "MemPowerSpec.h" +#include "MemTimingSpec.h" +#include "util.h" + +#include +#include + +namespace DRAMSysConfiguration +{ +using json = nlohmann::json; + +const std::string memSpecPath = "configs/memspecs"; + +struct MemSpec +{ + MemArchitectureSpec memArchitectureSpec; + std::string memoryId; + std::string memoryType; + MemTimingSpec memTimingSpec; + std::optional memPowerSpec; +}; + +void to_json(json &j, const MemSpec &c); +void from_json(const json &j, MemSpec &c); + +void from_dump(const std::string &dump, MemSpec &c); +std::string dump(const MemSpec &c, unsigned int indentation = -1); + +} // namespace Configuration + +#endif // MEMSPEC_H diff --git a/DRAMSys/library/src/common/configuration/memspec/MemTimingSpec.cpp b/DRAMSys/library/src/common/configuration/memspec/MemTimingSpec.cpp new file mode 100644 index 00000000..27414e57 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/memspec/MemTimingSpec.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include "MemTimingSpec.h" + +namespace DRAMSysConfiguration +{ + +void to_json(json &j, const MemTimingSpec &c) +{ + j = json{}; + + for (const auto &entry : c.entries) + { + j[entry.first] = entry.second; + } +} + +void from_json(const json &j, MemTimingSpec &c) +{ + for (const auto &entry : j.items()) + { + c.entries[entry.key()] = entry.value(); + } +} + +} // namespace Configuration diff --git a/DRAMSys/library/src/common/configuration/memspec/MemTimingSpec.h b/DRAMSys/library/src/common/configuration/memspec/MemTimingSpec.h new file mode 100644 index 00000000..d06898be --- /dev/null +++ b/DRAMSys/library/src/common/configuration/memspec/MemTimingSpec.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#ifndef DRAMSYSCONFIGURATION_MEMTIMINGSPEC_H +#define DRAMSYSCONFIGURATION_MEMTIMINGSPEC_H + +#include +#include + +namespace DRAMSysConfiguration +{ +using json = nlohmann::json; + +struct MemTimingSpec +{ + std::unordered_map entries; +}; + +void to_json(json &j, const MemTimingSpec &c); +void from_json(const json &j, MemTimingSpec &c); + +} // namespace Configuration + +#endif diff --git a/DRAMSys/library/src/common/configuration/tests/CMakeLists.txt b/DRAMSys/library/src/common/configuration/tests/CMakeLists.txt new file mode 100644 index 00000000..621a7230 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/tests/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(simpletest simpletest.cpp) +target_link_libraries(simpletest PRIVATE DRAMSysConfiguration nlohmann_json::nlohmann_json) + +add_executable(converter converter.cpp) +target_link_libraries(converter PRIVATE DRAMSysConfiguration nlohmann_json::nlohmann_json) diff --git a/DRAMSys/library/src/common/configuration/tests/converter.cpp b/DRAMSys/library/src/common/configuration/tests/converter.cpp new file mode 100644 index 00000000..08516eb5 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/tests/converter.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + if (argc != 2) + { + std::cerr << "Must specify a simulation json as single argument.\n"; + return -1; + } + + std::string pathToJson = argv[1]; + auto configuration = DRAMSysConfiguration::from_path(pathToJson); + nlohmann::json json; + json["simulation"] = configuration; + + std::ofstream output(pathToJson + "_converted.json"); + output << json.dump(4); + + return 0; +} diff --git a/DRAMSys/library/src/common/configuration/tests/simpletest.cpp b/DRAMSys/library/src/common/configuration/tests/simpletest.cpp new file mode 100644 index 00000000..c0a9ac95 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/tests/simpletest.cpp @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include +#include +#include + +using json = nlohmann::json; + +DRAMSysConfiguration::AddressMapping getAddressMapping() +{ + return DRAMSysConfiguration::AddressMapping{{{0, 1}}, + {{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}, + {{16}}, + {{13, 14, 15}}, + {{17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}}, + {{33}}, + {{}}, + {{}}}; +} + +DRAMSysConfiguration::McConfig getMcConfig() +{ + return DRAMSysConfiguration::McConfig{DRAMSysConfiguration::PagePolicy::Open, + DRAMSysConfiguration::Scheduler::FrFcfs, + DRAMSysConfiguration::SchedulerBuffer::Bankwise, + 8, + DRAMSysConfiguration::CmdMux::Oldest, + DRAMSysConfiguration::RespQueue::Fifo, + DRAMSysConfiguration::RefreshPolicy::AllBank, + 0, + 0, + DRAMSysConfiguration::PowerDownPolicy::NoPowerDown, + DRAMSysConfiguration::Arbiter::Simple, + 128, + {}}; +} + +DRAMSysConfiguration::SimConfig getSimConfig() +{ + return DRAMSysConfiguration::SimConfig{ + 0, false, true, false, false, {"error.csv"}, + 42, false, {"ddr5"}, true, DRAMSysConfiguration::StoreMode::NoStorage, false, false, + 1000}; +} + +DRAMSysConfiguration::ThermalConfig getThermalConfig() +{ + std::vector channels {{"dram_die_channel0", 0.0, 1.0}, {"dram_die_channel1", 0.0, 1.0}, {"dram_die_channel2", 0.0, 1.0}, {"dram_die_channel3", 0.0, 1.0}}; + + return DRAMSysConfiguration::ThermalConfig{ + DRAMSysConfiguration::TemperatureScale::Celsius, + 89, + 100, + DRAMSysConfiguration::ThermalSimUnit::Microseconds, + DRAMSysConfiguration::PowerInfo{channels}, + "127.0.0.1", + 118800, + 10, + 5, + true, + true}; +} + +DRAMSysConfiguration::TracePlayer getTracePlayer() +{ + DRAMSysConfiguration::TracePlayer player; + player.clkMhz = 100; + player.name = "mytrace.stl"; + + return player; +} + +DRAMSysConfiguration::TraceGenerator getTraceGeneratorOneState() +{ + DRAMSysConfiguration::TraceGenerator gen; + gen.clkMhz = 100; + gen.name = "MyTestGen"; + + DRAMSysConfiguration::TraceGeneratorTrafficState state0; + state0.numRequests = 1000; + state0.rwRatio = 0.5; + state0.addressDistribution = DRAMSysConfiguration::AddressDistribution::Random; + state0.addressIncrement = {}; + state0.minAddress = {}; + state0.maxAddress = {}; + state0.clksPerRequest = {}; + + gen.states.emplace(0, state0); + + return gen; +} + +DRAMSysConfiguration::TraceGenerator getTraceGeneratorMultipleStates() +{ + DRAMSysConfiguration::TraceGenerator gen; + + gen.clkMhz = 100; + gen.name = "MyTestGen"; + gen.maxPendingReadRequests = 8; + + DRAMSysConfiguration::TraceGeneratorTrafficState state0; + state0.numRequests = 1000; + state0.rwRatio = 0.5; + state0.addressDistribution = DRAMSysConfiguration::AddressDistribution::Sequential; + state0.addressIncrement = 256; + state0.minAddress = {}; + state0.maxAddress = 1024; + state0.clksPerRequest = {}; + + DRAMSysConfiguration::TraceGeneratorTrafficState state1; + state1.numRequests = 100; + state1.rwRatio = 0.75; + state1.addressDistribution = DRAMSysConfiguration::AddressDistribution::Sequential; + state1.addressIncrement = 512; + state1.minAddress = 1024; + state1.maxAddress = 2048; + state1.clksPerRequest = {}; + + gen.states.emplace(0, state0); + gen.states.emplace(1, state1); + + DRAMSysConfiguration::TraceGeneratorStateTransition transistion0{1, 1.0}; + + gen.transitions.emplace(0, transistion0); + + return gen; +} + +DRAMSysConfiguration::TraceHammer getTraceHammer() +{ + DRAMSysConfiguration::TraceHammer hammer; + + hammer.clkMhz = 100; + hammer.name = "MyTestHammer"; + hammer.numRequests = 4000; + hammer.rowIncrement = 2097152; + + return hammer; +} + +DRAMSysConfiguration::TraceSetup getTraceSetup() +{ + using namespace DRAMSysConfiguration; + + std::vector> initiators; + initiators.emplace_back(getTracePlayer()); + initiators.emplace_back(getTraceGeneratorOneState()); + initiators.emplace_back(getTraceGeneratorMultipleStates()); + initiators.emplace_back(getTraceHammer()); + + return DRAMSysConfiguration::TraceSetup{initiators}; +} + +DRAMSysConfiguration::Configuration getConfig(const DRAMSysConfiguration::MemSpec &memSpec) +{ + return DRAMSysConfiguration::Configuration{ + getAddressMapping(), + getMcConfig(), + memSpec, + getSimConfig(), + "std::string_simulationId", + getThermalConfig(), + // {{}, false}, works too + getTraceSetup(), + }; +} + +int main() +{ + DRAMSysConfiguration::Configuration conf = DRAMSysConfiguration::from_path("ddr5.json"); + std::ofstream fileout("myjson.json"); + json j_my; + j_my["simulation"] = getConfig(conf.memSpec); // just copy memspec over + fileout << j_my.dump(4); + + std::ifstream file2("hbm2.json"); + json hbm2_j = json::parse(file2, nullptr, false); + json hbm2_config = hbm2_j.at("simulation"); + DRAMSysConfiguration::Configuration hbm2conf = hbm2_config.get(); + std::ofstream filehbm2("myhbm2.json"); + json j_myhbm2; + j_myhbm2["simulation"] = hbm2conf; + filehbm2 << j_myhbm2.dump(4); + + std::ifstream file3("myjson.json"); + json ddr5_old = json::parse(file3, nullptr, false); + json ddr5_old_conf = ddr5_old.at("simulation"); + DRAMSysConfiguration::Configuration ddr5_old_config = ddr5_old_conf.get(); + std::ofstream fileoldout("myjson2.json"); + json j_oldconfconv; + j_oldconfconv["simulation"] = ddr5_old_config; + fileoldout << j_oldconfconv.dump(4); +} diff --git a/DRAMSys/library/src/common/configuration/util.cpp b/DRAMSys/library/src/common/configuration/util.cpp new file mode 100644 index 00000000..26ce32e1 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/util.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include "util.h" +#include "Configuration.h" + +#include +#include +namespace DRAMSysConfiguration +{ + +json get_config_json(const json &j, const std::string &configPath, const std::string &objectName) +{ + if (j.is_object()) + { + return j; + } + else // j should be a string path to the real json file + { + std::string jsonFileName; + j.get_to(jsonFileName); + + std::ifstream file(std::string(Configuration::resourceDirectory) + "/" + configPath + "/" + jsonFileName); + json j_object = json::parse(file); + return j_object.at(objectName); + } +} + +} // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/util.h b/DRAMSys/library/src/common/configuration/util.h new file mode 100644 index 00000000..07c12741 --- /dev/null +++ b/DRAMSys/library/src/common/configuration/util.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#ifndef DRAMSYSCONFIGURATION_UTIL_H +#define DRAMSYSCONFIGURATION_UTIL_H + +#include +#include +#include + +namespace DRAMSysConfiguration +{ +using json = nlohmann::json; + +// template +// class Optional : public std::pair +// { +// public: +// Optional() : std::pair{{}, false} +// { +// } +// Optional(const T &v) : std::pair{v, true} +// { +// } + +// bool isValid() const +// { +// return this->second; +// } + +// const T &getValue() const +// { +// assert(this->second == true); +// return this->first; +// } + +// void setValue(const T &v) +// { +// this->first = v; +// this->second = true; +// } + +// void invalidate() +// { +// this->second = false; +// } + +// /** +// * This methods only purpose is to make a optional type +// * valid so that it can be written to by reference. +// */ +// T &setByReference() +// { +// this->second = true; +// return this->first; +// } +// }; + +template +void invalidateEnum(T &value) +{ + if (value.has_value() && value.value() == T::value_type::Invalid) + value.reset(); +} + +json get_config_json(const json &j, const std::string &configPath, const std::string &objectName); + +inline void remove_null_values(json &j) +{ + std::vector keysToRemove; + + for (const auto &element : j.items()) + { + if (element.value() == nullptr) + keysToRemove.emplace_back(element.key()); + } + + std::for_each(keysToRemove.begin(), keysToRemove.end(), [&](const std::string &key) { j.erase(key); }); +} + +} // namespace DRAMSysConfiguration + +/** + * Inspired from + * https://json.nlohmann.me/features/arbitrary_types/#how-can-i-use-get-for-non-default-constructiblenon-copyable-types + */ +namespace nlohmann +{ + +template +void to_json(nlohmann::json &j, const std::optional &v) +{ + if (v.has_value()) + j = v.value(); + else + j = nullptr; +} + +template +void from_json(const nlohmann::json &j, std::optional &v) +{ + if (j.is_null()) + v = std::nullopt; + else + { + v = j.get(); + } +} + +} // namespace nlohmann + +#endif diff --git a/DRAMSys/library/src/common/utils.cpp b/DRAMSys/library/src/common/utils.cpp index edb14a51..08e7fa02 100644 --- a/DRAMSys/library/src/common/utils.cpp +++ b/DRAMSys/library/src/common/utils.cpp @@ -34,6 +34,7 @@ * Robert Gernhardt * Matthias Jung * Luiza Correa + * Derek Christ */ #include @@ -43,7 +44,6 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; bool TimeInterval::timeIsInInterval(const sc_time &time) const { @@ -71,89 +71,6 @@ std::string getPhaseName(const tlm_phase &phase) return oss.str(); } -json parseJSON(const std::string &path) -{ - std::ifstream file(path); - if (file.is_open()) - { - json j = json::parse(file, nullptr, false); - if (!j.is_discarded()) - return j; - else - throw std::invalid_argument("JSON parse error in file '" + path + "'."); - } - else - throw std::invalid_argument("Failed to open file '" + path + "'."); -} - -bool parseBool(json &spec, const std::string &name) -{ - json param = spec[name]; - if (!param.empty()) - { - if (param.is_boolean()) - return param; - else - throw std::invalid_argument("Expected type for parameter '" + name + "': bool"); - } - else - { - SC_REPORT_WARNING("utils", ("Parameter '" + name + "' does not exist, default is false.").c_str()); - return false; - } -} - -unsigned int parseUint(json &spec, const std::string &name) -{ - json param = spec[name]; - if (!param.empty()) - { - if (param.is_number_unsigned()) - return param; - else - throw std::invalid_argument("Expected type for parameter '" + name + "': unsigned int"); - } - else - { - SC_REPORT_WARNING("utils", ("Parameter '" + name + "' does not exist, default is 1.").c_str()); - return 1; - } -} - -double parseUdouble(json &spec, const std::string &name) -{ - json param = spec[name]; - if (!param.empty()) - { - if (param.is_number() && (param > 0)) - return param; - else - throw std::invalid_argument("Expected type for parameter '" + name + "': positive double"); - } - else - { - SC_REPORT_WARNING("utils", ("Parameter '" + name + "' does not exist, default is 1.").c_str()); - return 1; - } -} - -std::string parseString(json &spec, const std::string &name) -{ - json param = spec[name]; - if (!param.empty()) - { - if (param.is_string()) - return param; - else - throw std::invalid_argument("Expected type for parameter '" + name + "': string"); - } - else - { - SC_REPORT_WARNING("utils", ("Parameter '" + name + "' does not exist.").c_str()); - return {}; - } -} - void setUpDummy(tlm_generic_payload &payload, uint64_t channelPayloadID, Rank rank, BankGroup bankGroup, Bank bank) { payload.set_address(0); diff --git a/DRAMSys/library/src/common/utils.h b/DRAMSys/library/src/common/utils.h index 184b6efe..a0b90f26 100644 --- a/DRAMSys/library/src/common/utils.h +++ b/DRAMSys/library/src/common/utils.h @@ -34,6 +34,7 @@ * Matthias Jung * Eder F. Zulian * Luiza Correa + * Derek Christ */ #ifndef UTILS_H @@ -44,7 +45,6 @@ #include #include #include "dramExtensions.h" -#include "../common/third_party/nlohmann/single_include/nlohmann/json.hpp" class TimeInterval { @@ -63,12 +63,6 @@ constexpr const char headline[] = std::string getPhaseName(const tlm::tlm_phase &phase); -nlohmann::json parseJSON(const std::string &path); -bool parseBool(nlohmann::json &spec, const std::string &name); -unsigned int parseUint(nlohmann::json &spec, const std::string &name); -double parseUdouble(nlohmann::json &spec, const std::string &name); -std::string parseString(nlohmann::json &spec, const std::string &name); - void setUpDummy(tlm::tlm_generic_payload &payload, uint64_t channelPayloadID, Rank rank = Rank(0), BankGroup bankGroup = BankGroup(0), Bank bank = Bank(0)); diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 41d8a994..76636cd4 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -36,6 +36,7 @@ * Felipe S. Prado * Lukas Steiner * Luiza Correa + * Derek Christ */ #include "Configuration.h" @@ -53,10 +54,6 @@ #include "memspec/MemSpecSTTMRAM.h" using namespace sc_core; -using json = nlohmann::json; - -std::string Configuration::memspecUri; -std::string Configuration::mcconfigUri; enum sc_time_unit string2TimeUnit(const std::string &s) { @@ -79,270 +76,265 @@ enum sc_time_unit string2TimeUnit(const std::string &s) } } -void Configuration::setParameter(const std::string &name, const nlohmann::json &value) +void Configuration::loadSimConfig(Configuration &config, const DRAMSysConfiguration::SimConfig &simConfig) { - // MCConfig - if (name == "PagePolicy") - { - if (value == "Open") - pagePolicy = PagePolicy::Open; - else if (value == "Closed") - pagePolicy = PagePolicy::Closed; - else if (value == "OpenAdaptive") - pagePolicy = PagePolicy::OpenAdaptive; - else if (value == "ClosedAdaptive") - pagePolicy = PagePolicy::ClosedAdaptive; - else - SC_REPORT_FATAL("Configuration", "Unsupported page policy!"); - } - else if (name == "Scheduler") - { - if (value == "Fifo") - scheduler = Scheduler::Fifo; - else if (value == "FrFcfs") - scheduler = Scheduler::FrFcfs; - else if (value == "FrFcfsGrp") - scheduler = Scheduler::FrFcfsGrp; - else - SC_REPORT_FATAL("Configuration", "Unsupported scheduler!"); - } - else if (name == "SchedulerBuffer") - { - if (value == "Bankwise") - schedulerBuffer = SchedulerBuffer::Bankwise; - else if (value == "ReadWrite") - schedulerBuffer = SchedulerBuffer::ReadWrite; - else if (value == "Shared") - schedulerBuffer = SchedulerBuffer::Shared; - else - SC_REPORT_FATAL("Configuration", "Unsupported scheduler buffer!"); - } - else if (name == "RequestBufferSize") - { - requestBufferSize = value; - if (requestBufferSize == 0) - SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!"); - } - else if (name == "CmdMux") - { - if (value == "Oldest") - cmdMux = CmdMux::Oldest; - else if (value == "Strict") - cmdMux = CmdMux::Strict; - else - SC_REPORT_FATAL("Configuration", "Unsupported cmd mux!"); - } - else if (name == "RespQueue") - { - if (value == "Fifo") - respQueue = RespQueue::Fifo; - else if (value == "Reorder") - respQueue = RespQueue::Reorder; - else - SC_REPORT_FATAL("Configuration", "Unsupported response queue!"); - } - else if (name == "Arbiter") - { - if (value == "Simple") - arbiter = Arbiter::Simple; - else if (value == "Fifo") - arbiter = Arbiter::Fifo; - else if (value == "Reorder") - arbiter = Arbiter::Reorder; - else - SC_REPORT_FATAL("Configuration", "Unsupported arbiter!"); - } - else if (name == "RefreshPolicy") - { - if (value == "NoRefresh") - refreshPolicy = RefreshPolicy::NoRefresh; - else if (value == "AllBank" || value == "Rankwise") - refreshPolicy = RefreshPolicy::AllBank; - else if (value == "PerBank" || value == "Bankwise") - refreshPolicy = RefreshPolicy::PerBank; - else if (value == "Per2Bank") - refreshPolicy = RefreshPolicy::Per2Bank; - else if (value == "SameBank" || value == "Groupwise") - refreshPolicy = RefreshPolicy::SameBank; - else - SC_REPORT_FATAL("Configuration", "Unsupported refresh policy!"); - } - else if (name == "RefreshMaxPostponed") - refreshMaxPostponed = value; - else if (name == "RefreshMaxPulledin") - refreshMaxPulledin = value; - else if (name == "PowerDownPolicy") - { - if (value == "NoPowerDown") - powerDownPolicy = PowerDownPolicy::NoPowerDown; - else if (value == "Staggered") - powerDownPolicy = PowerDownPolicy::Staggered; - else - SC_REPORT_FATAL("Configuration", "Unsupported power down policy!"); - } - else if (name == "RefreshManagement") - refreshManagement = value; - else if (name == "PowerDownTimeout") - powerDownTimeout = value; - else if (name == "MaxActiveTransactions") - maxActiveTransactions = value; - else if (name == "ArbitrationDelayFw") - arbitrationDelayFw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; - else if (name == "ArbitrationDelayBw") - arbitrationDelayBw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; - else if (name == "ThinkDelayFw") - thinkDelayFw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; - else if (name == "ThinkDelayBw") - thinkDelayBw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; - else if (name == "PhyDelayFw") - phyDelayFw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; - else if (name == "PhyDelayBw") - phyDelayBw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; - //SimConfig------------------------------------------------ - else if (name == "SimulationName") - simulationName = value; - else if (name == "DatabaseRecording") - databaseRecording = value; - else if (name == "PowerAnalysis") - powerAnalysis = value; - else if (name == "EnableWindowing") - enableWindowing = value; - else if (name == "WindowSize") - { - windowSize = value; - if (windowSize == 0) + if (const auto &addressOffset = simConfig.addressOffset) + config.addressOffset = *addressOffset; + + if (const auto &checkTLM2Protocol = simConfig.checkTLM2Protocol) + config.checkTLM2Protocol = *checkTLM2Protocol; + + if (const auto &databaseRecording = simConfig.databaseRecording) + config.databaseRecording = *databaseRecording; + + if (const auto &debug = simConfig.debug) + config.debug = *debug; + + if (const auto &enableWindowing = simConfig.enableWindowing) + config.enableWindowing = *enableWindowing; + + if (const auto &powerAnalysis = simConfig.powerAnalysis) + config.powerAnalysis = *powerAnalysis; + + if (const auto &simulationName = simConfig.simulationName) + config.simulationName = *simulationName; + + if (const auto &simulationProgressBar = simConfig.simulationProgressBar) + config.simulationProgressBar = *simulationProgressBar; + + if (const auto &thermalSimulation = simConfig.thermalSimulation) + config.thermalSimulation = *thermalSimulation; + + if (const auto &useMalloc = simConfig.useMalloc) + config.useMalloc = *useMalloc; + + if (const auto &windowSize = simConfig.windowSize) + config.windowSize = *windowSize; + + if (config.windowSize == 0) SC_REPORT_FATAL("Configuration", "Minimum window size is 1"); - } - else if (name == "Debug") - debug = value; - else if (name == "ThermalSimulation") - thermalSimulation = value; - else if (name == "SimulationProgressBar") - simulationProgressBar = value; - else if (name == "AddressOffset") - addressOffset = value; - else if (name == "UseMalloc") - useMalloc = value; - else if (name == "CheckTLM2Protocol") - checkTLM2Protocol = value; - // Specification for ErrorChipSeed, ErrorCSVFile path and StoreMode - else if (name == "ErrorChipSeed") - errorChipSeed = value; - else if (name == "ErrorCSVFile") - errorCSVFile = value; - else if (name == "StoreMode") - { - if (value == "NoStorage") - storeMode = StoreMode::NoStorage; - else if (value == "Store") - storeMode = StoreMode::Store; - else if (value == "ErrorModel") - storeMode = StoreMode::ErrorModel; + + if (const auto &errorCsvFile = simConfig.errorCsvFile) + config.errorCSVFile = *errorCsvFile; + + if (const auto &errorChipSeed = simConfig.errorChipSeed) + config.errorChipSeed = *errorChipSeed; + + if (const auto &storeMode = simConfig.storeMode) + config.storeMode = [=] { + if (storeMode == DRAMSysConfiguration::StoreMode::NoStorage) + return StoreMode::NoStorage; + else if (storeMode == DRAMSysConfiguration::StoreMode::Store) + return StoreMode::Store; + else + return StoreMode::ErrorModel; + }(); +} + +void Configuration::loadTemperatureSimConfig(Configuration &config, const DRAMSysConfiguration::ThermalConfig &thermalConfig) +{ + config.temperatureSim.temperatureScale = [=] { + if (thermalConfig.temperatureScale == DRAMSysConfiguration::TemperatureScale::Celsius) + return TemperatureSimConfig::TemperatureScale::Celsius; + else if (thermalConfig.temperatureScale == DRAMSysConfiguration::TemperatureScale::Fahrenheit) + return TemperatureSimConfig::TemperatureScale::Fahrenheit; else - SC_REPORT_FATAL("Configuration", "Unsupported store mode!"); - } + return TemperatureSimConfig::TemperatureScale::Kelvin; + }(); - // Temperature Simulation related - else if (name == "TemperatureScale") + config.temperatureSim.staticTemperatureDefaultValue = thermalConfig.staticTemperatureDefaultValue; + config.temperatureSim.thermalSimPeriod = thermalConfig.thermalSimPeriod; + + config.temperatureSim.thermalSimUnit = [=] { + if (thermalConfig.thermalSimUnit == DRAMSysConfiguration::ThermalSimUnit::Seconds) + return sc_core::SC_SEC; + else if (thermalConfig.thermalSimUnit == DRAMSysConfiguration::ThermalSimUnit::Milliseconds) + return sc_core::SC_MS; + else if (thermalConfig.thermalSimUnit == DRAMSysConfiguration::ThermalSimUnit::Microseconds) + return sc_core::SC_US; + else if (thermalConfig.thermalSimUnit == DRAMSysConfiguration::ThermalSimUnit::Nanoseconds) + return sc_core::SC_NS; + else if (thermalConfig.thermalSimUnit == DRAMSysConfiguration::ThermalSimUnit::Picoseconds) + return sc_core::SC_PS; + else + return sc_core::SC_FS; + }(); + + for (const auto &channel : thermalConfig.powerInfo.channels) { - if (value != "Celsius" && value != "Fahrenheit" && value != "Kelvin") - SC_REPORT_FATAL("Configuration", - ("Invalid value for parameter " + name + ".").c_str()); - temperatureSim.temperatureScale = value; + config.temperatureSim.powerInitialValues.push_back(channel.init_pow); + config.temperatureSim.powerThresholds.push_back(channel.threshold); } - else if (name == "StaticTemperatureDefaultValue") - temperatureSim.staticTemperatureDefaultValue = value; - else if (name == "ThermalSimPeriod") - temperatureSim.thermalSimPeriod = value; - else if (name == "ThermalSimUnit") - temperatureSim.thermalSimUnit = string2TimeUnit(value); - else if (name == "PowerInfoFile") + + config.temperatureSim.iceServerIp = thermalConfig.iceServerIp; + config.temperatureSim.iceServerPort = thermalConfig.iceServerPort; + config.temperatureSim.simPeriodAdjustFactor = thermalConfig.simPeriodAdjustFactor; + config.temperatureSim.nPowStableCyclesToIncreasePeriod = thermalConfig.nPowStableCyclesToIncreasePeriod; + config.temperatureSim.generateTemperatureMap = thermalConfig.generateTemperatureMap; + config.temperatureSim.generatePowerMap = thermalConfig.generatePowerMap; + + config.temperatureSim.showTemperatureSimConfig(); +} + +void Configuration::loadMCConfig(Configuration &config, const DRAMSysConfiguration::McConfig &mcConfig) +{ + if (const auto &pagePolicy = mcConfig.pagePolicy) + config.pagePolicy = [=] { + if (pagePolicy == DRAMSysConfiguration::PagePolicy::Open) + return PagePolicy::Open; + else if (pagePolicy == DRAMSysConfiguration::PagePolicy::OpenAdaptive) + return PagePolicy::OpenAdaptive; + else if (pagePolicy == DRAMSysConfiguration::PagePolicy::Closed) + return PagePolicy::Closed; + else + return PagePolicy::ClosedAdaptive; + }(); + + if (const auto &scheduler = mcConfig.scheduler) + config.scheduler = [=] { + if (scheduler == DRAMSysConfiguration::Scheduler::Fifo) + return Scheduler::Fifo; + else if (scheduler == DRAMSysConfiguration::Scheduler::FrFcfs) + return Scheduler::FrFcfs; + else + return Scheduler::FrFcfsGrp; + }(); + + if (const auto &schedulerBuffer = mcConfig.schedulerBuffer) + config.schedulerBuffer = [=] { + if (schedulerBuffer == DRAMSysConfiguration::SchedulerBuffer::Bankwise) + return SchedulerBuffer::Bankwise; + else if (schedulerBuffer == DRAMSysConfiguration::SchedulerBuffer::ReadWrite) + return SchedulerBuffer::ReadWrite; + else + return SchedulerBuffer::Shared; + }(); + + if (const auto &requestBufferSize = mcConfig.requestBufferSize) + config.requestBufferSize = *mcConfig.requestBufferSize; + + if (config.requestBufferSize == 0) + SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!"); + + if (const auto &cmdMux = mcConfig.cmdMux) + config.cmdMux = [=] { + if (cmdMux == DRAMSysConfiguration::CmdMux::Oldest) + return CmdMux::Oldest; + else + return CmdMux::Strict; + }(); + + if (const auto &respQueue = mcConfig.respQueue) + config.respQueue = [=] { + if (respQueue == DRAMSysConfiguration::RespQueue::Fifo) + return RespQueue::Fifo; + else + return RespQueue::Reorder; + }(); + + if (const auto &refreshPolicy = mcConfig.refreshPolicy) + config.refreshPolicy = [=] { + if (refreshPolicy == DRAMSysConfiguration::RefreshPolicy::NoRefresh) + return RefreshPolicy::NoRefresh; + else if (refreshPolicy == DRAMSysConfiguration::RefreshPolicy::AllBank) + return RefreshPolicy::AllBank; + else if (refreshPolicy == DRAMSysConfiguration::RefreshPolicy::PerBank) + return RefreshPolicy::PerBank; + else if (refreshPolicy == DRAMSysConfiguration::RefreshPolicy::Per2Bank) + return RefreshPolicy::Per2Bank; + else // if (policy == DRAMSysConfiguration::RefreshPolicy::SameBank) + return RefreshPolicy::SameBank; + }(); + + if (const auto &refreshMaxPostponed = mcConfig.refreshMaxPostponed) + config.refreshMaxPostponed = *refreshMaxPostponed; + + if (const auto &refreshMaxPulledin = mcConfig.refreshMaxPulledin) + config.refreshMaxPulledin = *refreshMaxPulledin; + + if (const auto &powerDownPolicy = mcConfig.powerDownPolicy) + config.powerDownPolicy = [=] { + if (powerDownPolicy == DRAMSysConfiguration::PowerDownPolicy::NoPowerDown) + return PowerDownPolicy::NoPowerDown; + else + return PowerDownPolicy::Staggered; + }(); + + if (const auto &arbiter = mcConfig.arbiter) + config.arbiter = [=] { + if (arbiter == DRAMSysConfiguration::Arbiter::Simple) + return Arbiter::Simple; + else if (arbiter == DRAMSysConfiguration::Arbiter::Fifo) + return Arbiter::Fifo; + else + return Arbiter::Reorder; + }(); + + if (const auto &maxActiveTransactions = mcConfig.maxActiveTransactions) + config.maxActiveTransactions = *maxActiveTransactions; + + if (const auto &refreshManagement = mcConfig.refreshManagement) + config.refreshManagement = *refreshManagement; + + if (const auto &arbitrationDelayFw = mcConfig.arbitrationDelayFw) { - temperatureSim.powerInfoFile = value; - temperatureSim.parsePowerInfoFile(); + config.arbitrationDelayFw = std::round(sc_time(*arbitrationDelayFw, SC_NS) / config.memSpec->tCK) * config.memSpec->tCK; + } + + if (const auto &arbitrationDelayBw = mcConfig.arbitrationDelayBw) + { + config.arbitrationDelayBw = std::round(sc_time(*arbitrationDelayBw, SC_NS) / config.memSpec->tCK) * config.memSpec->tCK; + } + + if (const auto &thinkDelayFw = mcConfig.thinkDelayFw) + { + config.thinkDelayFw = std::round(sc_time(*thinkDelayFw, SC_NS) / config.memSpec->tCK) * config.memSpec->tCK; + } + + if (const auto &thinkDelayBw = mcConfig.thinkDelayBw) + { + config.thinkDelayBw = std::round(sc_time(*thinkDelayBw, SC_NS) / config.memSpec->tCK) * config.memSpec->tCK; + } + + if (const auto &phyDelayFw = mcConfig.phyDelayFw) + { + config.phyDelayFw = std::round(sc_time(*phyDelayFw, SC_NS) / config.memSpec->tCK) * config.memSpec->tCK; + } + + if (const auto &phyDelayBw = mcConfig.phyDelayBw) + { + config.phyDelayBw = std::round(sc_time(*phyDelayBw, SC_NS) / config.memSpec->tCK) * config.memSpec->tCK; } - else if (name == "IceServerIp") - temperatureSim.iceServerIp = value; - else if (name == "IceServerPort") - temperatureSim.iceServerPort = value; - else if (name == "SimPeriodAdjustFactor") - temperatureSim.simPeriodAdjustFactor = value; - else if (name == "NPowStableCyclesToIncreasePeriod") - temperatureSim.nPowStableCyclesToIncreasePeriod = value; - else if (name == "GenerateTemperatureMap") - temperatureSim.generateTemperatureMap = value; - else if (name == "GeneratePowerMap") - temperatureSim.generatePowerMap = value; - else - SC_REPORT_WARNING("Configuration", - ("Parameter " + name + " not defined in Configuration").c_str()); } -void Configuration::setPathToResources(const std::string &path) +void Configuration::loadMemSpec(Configuration &config, const DRAMSysConfiguration::MemSpec &memSpecConfig) { - temperatureSim.setPathToResources(path); -} - -void Configuration::loadSimConfig(Configuration &config, const std::string &simconfigUri) -{ - json doc = parseJSON(simconfigUri); - if (doc["simconfig"].empty()) - SC_REPORT_FATAL("Configuration", "simconfig is empty."); - for (auto& x : doc["simconfig"].items()) - config.setParameter(x.key(), x.value()); -} - -void Configuration::loadTemperatureSimConfig(Configuration &config, const std::string &thermalsimconfigUri) -{ - json doc = parseJSON(thermalsimconfigUri); - if (doc["thermalsimconfig"].empty()) - SC_REPORT_FATAL("Configuration", "thermalsimconfig is empty."); - for (auto& x : doc["thermalsimconfig"].items()) - config.setParameter(x.key(), x.value()); -} - -void Configuration::loadMCConfig(Configuration &config, const std::string &_mcconfigUri) -{ - Configuration::mcconfigUri = _mcconfigUri; - json doc = parseJSON(_mcconfigUri); - if (doc["mcconfig"].empty()) - SC_REPORT_FATAL("Configuration", "mcconfig is empty."); - for (auto& x : doc["mcconfig"].items()) - config.setParameter(x.key(), x.value()); -} - -void Configuration::loadMemSpec(Configuration &config, const std::string &_memspecUri) -{ - Configuration::memspecUri = _memspecUri; - json doc = parseJSON(_memspecUri); - json jMemSpec = doc["memspec"]; - - std::string memoryType = jMemSpec["memoryType"]; + std::string memoryType = memSpecConfig.memoryType; if (memoryType == "DDR3") - memSpec = new MemSpecDDR3(jMemSpec); + config.memSpec = new MemSpecDDR3(memSpecConfig); else if (memoryType == "DDR4") - memSpec = new MemSpecDDR4(jMemSpec); + config.memSpec = new MemSpecDDR4(memSpecConfig); else if (memoryType == "DDR5") - memSpec = new MemSpecDDR5(jMemSpec); + config.memSpec = new MemSpecDDR5(memSpecConfig); else if (memoryType == "LPDDR4") - memSpec = new MemSpecLPDDR4(jMemSpec); + config.memSpec = new MemSpecLPDDR4(memSpecConfig); else if (memoryType == "LPDDR5") - memSpec = new MemSpecLPDDR5(jMemSpec); + config.memSpec = new MemSpecLPDDR5(memSpecConfig); else if (memoryType == "WIDEIO_SDR") - memSpec = new MemSpecWideIO(jMemSpec); + config.memSpec = new MemSpecWideIO(memSpecConfig); else if (memoryType == "WIDEIO2") - memSpec = new MemSpecWideIO2(jMemSpec); + config.memSpec = new MemSpecWideIO2(memSpecConfig); else if (memoryType == "HBM2") - memSpec = new MemSpecHBM2(jMemSpec); + config.memSpec = new MemSpecHBM2(memSpecConfig); else if (memoryType == "GDDR5") - memSpec = new MemSpecGDDR5(jMemSpec); + config.memSpec = new MemSpecGDDR5(memSpecConfig); else if (memoryType == "GDDR5X") - memSpec = new MemSpecGDDR5X(jMemSpec); + config.memSpec = new MemSpecGDDR5X(memSpecConfig); else if (memoryType == "GDDR6") - memSpec = new MemSpecGDDR6(jMemSpec); + config.memSpec = new MemSpecGDDR6(memSpecConfig); else if (memoryType == "STT-MRAM") - memSpec = new MemSpecSTTMRAM(jMemSpec); + config.memSpec = new MemSpecSTTMRAM(memSpecConfig); else SC_REPORT_FATAL("Configuration", "Unsupported DRAM type"); } diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index 71f590eb..946b48c7 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -36,13 +36,14 @@ * Felipe S. Prado * Lukas Steiner * Luiza Correa + * Derek Christ */ #ifndef CONFIGURATION_H #define CONFIGURATION_H #include - +#include #include #include "memspec/MemSpec.h" #include "TemperatureSimConfig.h" @@ -61,9 +62,6 @@ private: Configuration &operator = (const Configuration &); public: - static std::string memspecUri; - static std::string mcconfigUri; - // MCConfig: enum class PagePolicy {Open, Closed, OpenAdaptive, ClosedAdaptive} pagePolicy = PagePolicy::Open; enum class Scheduler {Fifo, FrFcfs, FrFcfsGrp} scheduler = Scheduler::FrFcfs; @@ -99,25 +97,21 @@ public: bool useMalloc = false; unsigned long long int addressOffset = 0; - // MemSpec (from DRAM-Power) - const MemSpec *memSpec = nullptr; - - void setParameter(const std::string &name, const nlohmann::json &value); - //Configs for Seed, csv file and StorageMode unsigned int errorChipSeed = 0; std::string errorCSVFile = "not defined."; enum class StoreMode {NoStorage, Store, ErrorModel} storeMode = StoreMode::NoStorage; + // MemSpec (from DRAM-Power) + const MemSpec *memSpec = nullptr; + // Temperature Simulation related TemperatureSimConfig temperatureSim; - void setPathToResources(const std::string &path); - - static void loadMCConfig(Configuration &config, const std::string &_mcconfigUri); - static void loadSimConfig(Configuration &config, const std::string &simconfigUri); - void loadMemSpec(Configuration &config, const std::string &_memspecUri); - static void loadTemperatureSimConfig(Configuration &config, const std::string &simconfigUri); + static void loadMCConfig(Configuration &config, const DRAMSysConfiguration::McConfig &mcConfig); + static void loadSimConfig(Configuration &config, const DRAMSysConfiguration::SimConfig &simConfig); + static void loadMemSpec(Configuration &config, const DRAMSysConfiguration::MemSpec &memSpec); + static void loadTemperatureSimConfig(Configuration &config, const DRAMSysConfiguration::ThermalConfig &thermalConfig); }; #endif // CONFIGURATION_H diff --git a/DRAMSys/library/src/configuration/TemperatureSimConfig.h b/DRAMSys/library/src/configuration/TemperatureSimConfig.h index 48f0169e..9f0e67bf 100644 --- a/DRAMSys/library/src/configuration/TemperatureSimConfig.h +++ b/DRAMSys/library/src/configuration/TemperatureSimConfig.h @@ -33,6 +33,7 @@ * Eder F. Zulian * Matthias Jung * Luiza Correa + * Derek Christ */ #ifndef TEMPERATURESIMCONFIG_H @@ -40,7 +41,7 @@ #include #include - +#include #include #include #include "../common/DebugManager.h" @@ -48,13 +49,7 @@ struct TemperatureSimConfig { // Temperature Scale - std::string temperatureScale; - std::string pathToResources; - - void setPathToResources(std::string path) - { - pathToResources = std::move(path); - } + enum class TemperatureScale {Celsius, Fahrenheit, Kelvin} temperatureScale; // Static Temperature Simulation parameters int staticTemperatureDefaultValue; @@ -70,47 +65,9 @@ struct TemperatureSimConfig bool generatePowerMap; // Power related information - std::string powerInfoFile; std::vector powerInitialValues; std::vector powerThresholds; - void parsePowerInfoFile() - { - PRINTDEBUGMESSAGE("TemperatureSimConfig", "Power Info File: " + powerInfoFile); - - powerInfoFile = pathToResources - + "/configs/thermalsim/" - + powerInfoFile; - - // Load the JSON file into memory and parse it - nlohmann::json powInfoElem = parseJSON(powerInfoFile); - - if (powInfoElem["powerInfo"].empty()) - { - // Invalid file - std::string errormsg = "Invalid Power Info File " + powerInfoFile; - PRINTDEBUGMESSAGE("TemperatureSimConfig", errormsg); - SC_REPORT_FATAL("Temperature Sim Config", errormsg.c_str()); - } - else - { - for (const auto& it : powInfoElem["powerInfo"].items()) - { - // Load initial power values for all devices - auto value = it.value(); - float pow = value["init_pow"]; - powerInitialValues.push_back(pow); - - // Load power thresholds for all devices - //Changes in power dissipation that exceed the threshods - //will make the thermal simulation to be executed more often) - float thr = value["threshold"]; - powerThresholds.push_back(thr); - } - } - showTemperatureSimConfig(); - } - void showTemperatureSimConfig() { NDEBUG_UNUSED(int i) = 0; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp index 65714153..dd455897 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp @@ -31,15 +31,16 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include "MemSpec.h" using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpec::MemSpec(json &memspec, MemoryType memoryType, +MemSpec::MemSpec(const DRAMSysConfiguration::MemSpec &memSpec, + MemoryType memoryType, unsigned numberOfChannels, unsigned numberOfRanks, unsigned banksPerRank, unsigned groupsPerRank, unsigned banksPerGroup, @@ -53,19 +54,21 @@ MemSpec::MemSpec(json &memspec, MemoryType memoryType, numberOfBanks(numberOfBanks), numberOfBankGroups(numberOfBankGroups), numberOfDevices(numberOfDevices), - numberOfRows(parseUint(memspec["memarchitecturespec"], "nbrOfRows")), - numberOfColumns(parseUint(memspec["memarchitecturespec"], "nbrOfColumns")), - defaultBurstLength(parseUint(memspec["memarchitecturespec"], "burstLength")), - maxBurstLength(memspec["memarchitecturespec"]["maxBurstLength"].is_number_unsigned() ? - static_cast(memspec["memarchitecturespec"]["maxBurstLength"]) : defaultBurstLength), - dataRate(parseUint(memspec["memarchitecturespec"], "dataRate")), - bitWidth(parseUint(memspec["memarchitecturespec"], "width")), + numberOfRows(memSpec.memArchitectureSpec.entries.at("nbrOfRows")), + numberOfColumns(memSpec.memArchitectureSpec.entries.at("nbrOfColumns")), + defaultBurstLength(memSpec.memArchitectureSpec.entries.at("burstLength")), + maxBurstLength(memSpec.memArchitectureSpec.entries.find("maxBurstLength") != + memSpec.memArchitectureSpec.entries.end() + ? memSpec.memArchitectureSpec.entries.at("maxBurstLength") + : defaultBurstLength), + dataRate(memSpec.memArchitectureSpec.entries.at("dataRate")), + bitWidth(memSpec.memArchitectureSpec.entries.at("width")), dataBusWidth(bitWidth * numberOfDevices), defaultBytesPerBurst((defaultBurstLength * dataBusWidth) / 8), maxBytesPerBurst((maxBurstLength * dataBusWidth) / 8), - fCKMHz(parseUdouble(memspec["memtimingspec"], "clkMhz")), + fCKMHz(memSpec.memTimingSpec.entries.at("clkMhz")), tCK(sc_time(1.0 / fCKMHz, SC_US)), - memoryId(parseString(memspec, "memoryId")), + memoryId(memSpec.memoryId), memoryType(memoryType), burstDuration(tCK * (static_cast(defaultBurstLength) / dataRate)), memorySizeBytes(0) diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index e1ada5a4..0051705c 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -33,6 +33,7 @@ * Janik Schlemminger * Matthias Jung * Lukas Steiner + * Derek Christ */ #ifndef MEMSPEC_H @@ -40,11 +41,10 @@ #include #include - +#include #include #include #include "../../common/utils.h" -#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" #include "../../controller/Command.h" class MemSpec @@ -98,7 +98,8 @@ public: uint64_t getSimMemSizeInBytes() const; protected: - MemSpec(nlohmann::json &memspec, MemoryType memoryType, + MemSpec(const DRAMSysConfiguration::MemSpec &memSpec, + MemoryType memoryType, unsigned numberOfChannels, unsigned numberOfRanks, unsigned banksPerRank, unsigned groupsPerRank, unsigned banksPerGroup, diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp index 1e599c99..b17601f1 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include @@ -40,63 +41,65 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpecDDR3::MemSpecDDR3(json &memspec) - : MemSpec(memspec, MemoryType::DDR3, - parseUint(memspec["memarchitecturespec"],"nbrOfChannels"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), +MemSpecDDR3::MemSpecDDR3(const DRAMSysConfiguration::MemSpec &memSpec) + : MemSpec(memSpec, MemoryType::DDR3, + memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), 1, - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfDevices")), - tCKE (tCK * parseUint(memspec["memtimingspec"], "CKE")), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), + tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")), tPD (tCKE), - tCKESR (tCK * parseUint(memspec["memtimingspec"], "CKESR")), - tDQSCK (tCK * parseUint(memspec["memtimingspec"], "DQSCK")), - tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), - tRC (tCK * parseUint(memspec["memtimingspec"], "RC")), - tRCD (tCK * parseUint(memspec["memtimingspec"], "RCD")), - tRL (tCK * parseUint(memspec["memtimingspec"], "RL")), - tRTP (tCK * parseUint(memspec["memtimingspec"], "RTP")), - tWL (tCK * parseUint(memspec["memtimingspec"], "WL")), - tWR (tCK * parseUint(memspec["memtimingspec"], "WR")), - tXP (tCK * parseUint(memspec["memtimingspec"], "XP")), - tXS (tCK * parseUint(memspec["memtimingspec"], "XS")), - tCCD (tCK * parseUint(memspec["memtimingspec"], "CCD")), - tFAW (tCK * parseUint(memspec["memtimingspec"], "FAW")), - tREFI (tCK * parseUint(memspec["memtimingspec"], "REFI")), - tRFC (tCK * parseUint(memspec["memtimingspec"], "RFC")), - tRP (tCK * parseUint(memspec["memtimingspec"], "RP")), - tRRD (tCK * parseUint(memspec["memtimingspec"], "RRD")), - tWTR (tCK * parseUint(memspec["memtimingspec"], "WTR")), - tAL (tCK * parseUint(memspec["memtimingspec"], "AL")), - tXPDLL (tCK * parseUint(memspec["memtimingspec"], "XPDLL")), - tXSDLL (tCK * parseUint(memspec["memtimingspec"], "XSDLL")), - tACTPDEN (tCK * parseUint(memspec["memtimingspec"], "ACTPDEN")), - tPRPDEN (tCK * parseUint(memspec["memtimingspec"], "PRPDEN")), - tREFPDEN (tCK * parseUint(memspec["memtimingspec"], "REFPDEN")), - tRTRS (tCK * parseUint(memspec["memtimingspec"], "RTRS")), - iDD0 (parseUdouble(memspec["mempowerspec"], "idd0")), - iDD2N (parseUdouble(memspec["mempowerspec"], "idd2n")), - iDD3N (parseUdouble(memspec["mempowerspec"], "idd3n")), - iDD4R (parseUdouble(memspec["mempowerspec"], "idd4r")), - iDD4W (parseUdouble(memspec["mempowerspec"], "idd4w")), - iDD5 (parseUdouble(memspec["mempowerspec"], "idd5")), - iDD6 (parseUdouble(memspec["mempowerspec"], "idd6")), - vDD (parseUdouble(memspec["mempowerspec"], "vdd")), - iDD2P0 (parseUdouble(memspec["mempowerspec"], "idd2p0")), - iDD2P1 (parseUdouble(memspec["mempowerspec"], "idd2p1")), - iDD3P0 (parseUdouble(memspec["mempowerspec"], "idd3p0")), - iDD3P1 (parseUdouble(memspec["mempowerspec"], "idd3p1")) + tCKESR (tCK * memSpec.memTimingSpec.entries.at("CKESR")), + tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")), + tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), + tRC (tCK * memSpec.memTimingSpec.entries.at("RC")), + tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")), + tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), + tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")), + tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), + tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), + tXP (tCK * memSpec.memTimingSpec.entries.at("XP")), + tXS (tCK * memSpec.memTimingSpec.entries.at("XS")), + tCCD (tCK * memSpec.memTimingSpec.entries.at("CCD")), + tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), + tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")), + tRFC (tCK * memSpec.memTimingSpec.entries.at("RFC")), + tRP (tCK * memSpec.memTimingSpec.entries.at("RP")), + tRRD (tCK * memSpec.memTimingSpec.entries.at("RRD")), + tWTR (tCK * memSpec.memTimingSpec.entries.at("WTR")), + tAL (tCK * memSpec.memTimingSpec.entries.at("AL")), + tXPDLL (tCK * memSpec.memTimingSpec.entries.at("XPDLL")), + tXSDLL (tCK * memSpec.memTimingSpec.entries.at("XSDLL")), + tACTPDEN (tCK * memSpec.memTimingSpec.entries.at("ACTPDEN")), + tPRPDEN (tCK * memSpec.memTimingSpec.entries.at("PRPDEN")), + tREFPDEN (tCK * memSpec.memTimingSpec.entries.at("REFPDEN")), + tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")), + iDD0 (memSpec.memPowerSpec.value().entries.at("idd0")), + iDD2N (memSpec.memPowerSpec.value().entries.at("idd2n")), + iDD3N (memSpec.memPowerSpec.value().entries.at("idd3n")), + iDD4R (memSpec.memPowerSpec.value().entries.at("idd4r")), + iDD4W (memSpec.memPowerSpec.value().entries.at("idd4w")), + iDD5 (memSpec.memPowerSpec.value().entries.at("idd5")), + iDD6 (memSpec.memPowerSpec.value().entries.at("idd6")), + vDD (memSpec.memPowerSpec.value().entries.at("vdd")), + iDD2P0 (memSpec.memPowerSpec.value().entries.at("idd2p0")), + iDD2P1 (memSpec.memPowerSpec.value().entries.at("idd2p1")), + iDD3P0 (memSpec.memPowerSpec.value().entries.at("idd3p0")), + iDD3P1 (memSpec.memPowerSpec.value().entries.at("idd3p1")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; memorySizeBytes = deviceSizeBytes * numberOfDevices * numberOfRanks * numberOfChannels; + if (!memSpec.memPowerSpec.has_value()) + SC_REPORT_FATAL("MemSpec", "No power spec defined!"); + std::cout << headline << std::endl; std::cout << "Memory Configuration:" << std::endl << std::endl; std::cout << " Memory type: " << "DDR3" << std::endl; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h index 711df6d5..beb5629f 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h @@ -31,19 +31,21 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #ifndef MEMSPECDDR3_H #define MEMSPECDDR3_H -#include #include "MemSpec.h" -#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" + +#include +#include class MemSpecDDR3 final : public MemSpec { public: - explicit MemSpecDDR3(nlohmann::json &memspec); + explicit MemSpecDDR3(const DRAMSysConfiguration::MemSpec &memSpec); // Memspec Variables: const sc_core::sc_time tCKE; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp index b8b119de..428584ab 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include @@ -40,81 +41,83 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpecDDR4::MemSpecDDR4(json &memspec) - : MemSpec(memspec, MemoryType::DDR4, - parseUint(memspec["memarchitecturespec"],"nbrOfChannels"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - / parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfDevices")), - tCKE (tCK * parseUint(memspec["memtimingspec"], "CKE")), +MemSpecDDR4::MemSpecDDR4(const DRAMSysConfiguration::MemSpec &memSpec) + : MemSpec(memSpec, MemoryType::DDR4, + memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + / memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), + tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")), tPD (tCKE), - tCKESR (tCK * parseUint(memspec["memtimingspec"], "CKESR")), - tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), - tRC (tCK * parseUint(memspec["memtimingspec"], "RC")), - tRCD (tCK * parseUint(memspec["memtimingspec"], "RCD")), - tRL (tCK * parseUint(memspec["memtimingspec"], "RL")), - tRPRE (tCK * parseUint(memspec["memtimingspec"], "RPRE")), - tRTP (tCK * parseUint(memspec["memtimingspec"], "RTP")), - tWL (tCK * parseUint(memspec["memtimingspec"], "WL")), - tWPRE (tCK * parseUint(memspec["memtimingspec"], "WPRE")), - tWR (tCK * parseUint(memspec["memtimingspec"], "WR")), - tXP (tCK * parseUint(memspec["memtimingspec"], "XP")), - tXS (tCK * parseUint(memspec["memtimingspec"], "XS")), - tREFI ((parseUint(memspec["memtimingspec"], "REFM") == 4) ? - (tCK * (static_cast(parseUint(memspec["memtimingspec"], "REFI")) / 4)) : - ((parseUint(memspec["memtimingspec"], "REFM") == 2) ? - (tCK * (static_cast(parseUint(memspec["memtimingspec"], "REFI")) / 2)) : - (tCK * parseUint(memspec["memtimingspec"], "REFI")))), - tRFC ((parseUint(memspec["memtimingspec"], "REFM") == 4) ? - (tCK * parseUint(memspec["memtimingspec"], "RFC4")) : - ((parseUint(memspec["memtimingspec"], "REFM") == 2) ? - (tCK * parseUint(memspec["memtimingspec"], "RFC2")) : - (tCK * parseUint(memspec["memtimingspec"], "RFC")))), - tRP (tCK * parseUint(memspec["memtimingspec"], "RP")), - tDQSCK (tCK * parseUint(memspec["memtimingspec"], "DQSCK")), - tCCD_S (tCK * parseUint(memspec["memtimingspec"], "CCD_S")), - tCCD_L (tCK * parseUint(memspec["memtimingspec"], "CCD_L")), - tFAW (tCK * parseUint(memspec["memtimingspec"], "FAW")), - tRRD_S (tCK * parseUint(memspec["memtimingspec"], "RRD_S")), - tRRD_L (tCK * parseUint(memspec["memtimingspec"], "RRD_L")), - tWTR_S (tCK * parseUint(memspec["memtimingspec"], "WTR_S")), - tWTR_L (tCK * parseUint(memspec["memtimingspec"], "WTR_L")), - tAL (tCK * parseUint(memspec["memtimingspec"], "AL")), - tXPDLL (tCK * parseUint(memspec["memtimingspec"], "XPDLL")), - tXSDLL (tCK * parseUint(memspec["memtimingspec"], "XSDLL")), - tACTPDEN (tCK * parseUint(memspec["memtimingspec"], "ACTPDEN")), - tPRPDEN (tCK * parseUint(memspec["memtimingspec"], "PRPDEN")), - tREFPDEN (tCK * parseUint(memspec["memtimingspec"], "REFPDEN")), - tRTRS (tCK * parseUint(memspec["memtimingspec"], "RTRS")), - iDD0 (parseUdouble(memspec["mempowerspec"], "idd0")), - iDD2N (parseUdouble(memspec["mempowerspec"], "idd2n")), - iDD3N (parseUdouble(memspec["mempowerspec"], "idd3n")), - iDD4R (parseUdouble(memspec["mempowerspec"], "idd4r")), - iDD4W (parseUdouble(memspec["mempowerspec"], "idd4w")), - iDD5 (parseUdouble(memspec["mempowerspec"], "idd5")), - iDD6 (parseUdouble(memspec["mempowerspec"], "idd6")), - vDD (parseUdouble(memspec["mempowerspec"], "vdd")), - iDD02 (parseUdouble(memspec["mempowerspec"], "idd02")), - iDD2P0 (parseUdouble(memspec["mempowerspec"], "idd2p0")), - iDD2P1 (parseUdouble(memspec["mempowerspec"], "idd2p1")), - iDD3P0 (parseUdouble(memspec["mempowerspec"], "idd3p0")), - iDD3P1 (parseUdouble(memspec["mempowerspec"], "idd3p1")), - iDD62 (parseUdouble(memspec["mempowerspec"], "idd62")), - vDD2 (parseUdouble(memspec["mempowerspec"], "vdd2")) + tCKESR (tCK * memSpec.memTimingSpec.entries.at("CKESR")), + tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), + tRC (tCK * memSpec.memTimingSpec.entries.at("RC")), + tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")), + tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), + tRPRE (tCK * memSpec.memTimingSpec.entries.at("RPRE")), + tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")), + tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), + tWPRE (tCK * memSpec.memTimingSpec.entries.at("WPRE")), + tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), + tXP (tCK * memSpec.memTimingSpec.entries.at("XP")), + tXS (tCK * memSpec.memTimingSpec.entries.at("XS")), + tREFI ((memSpec.memTimingSpec.entries.at("REFM") == 4) ? + (tCK * (static_cast(memSpec.memTimingSpec.entries.at("REFI")) / 4)) : + ((memSpec.memTimingSpec.entries.at("REFM") == 2) ? + (tCK * (static_cast(memSpec.memTimingSpec.entries.at("REFI")) / 2)) : + (tCK * memSpec.memTimingSpec.entries.at("REFI")))), + tRFC ((memSpec.memTimingSpec.entries.at("REFM") == 4) ? + (tCK * memSpec.memTimingSpec.entries.at("RFC4")) : + ((memSpec.memTimingSpec.entries.at("REFM") == 2) ? + (tCK * memSpec.memTimingSpec.entries.at("RFC2")) : + (tCK * memSpec.memTimingSpec.entries.at("RFC")))), + tRP (tCK * memSpec.memTimingSpec.entries.at("RP")), + tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")), + tCCD_S (tCK * memSpec.memTimingSpec.entries.at("CCD_S")), + tCCD_L (tCK * memSpec.memTimingSpec.entries.at("CCD_L")), + tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), + tRRD_S (tCK * memSpec.memTimingSpec.entries.at("RRD_S")), + tRRD_L (tCK * memSpec.memTimingSpec.entries.at("RRD_L")), + tWTR_S (tCK * memSpec.memTimingSpec.entries.at("WTR_S")), + tWTR_L (tCK * memSpec.memTimingSpec.entries.at("WTR_L")), + tAL (tCK * memSpec.memTimingSpec.entries.at("AL")), + tXPDLL (tCK * memSpec.memTimingSpec.entries.at("XPDLL")), + tXSDLL (tCK * memSpec.memTimingSpec.entries.at("XSDLL")), + tACTPDEN (tCK * memSpec.memTimingSpec.entries.at("ACTPDEN")), + tPRPDEN (tCK * memSpec.memTimingSpec.entries.at("PRPDEN")), + tREFPDEN (tCK * memSpec.memTimingSpec.entries.at("REFPDEN")), + tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")), + iDD0 (memSpec.memPowerSpec.value().entries.at("idd0")), + iDD2N (memSpec.memPowerSpec.value().entries.at("idd2n")), + iDD3N (memSpec.memPowerSpec.value().entries.at("idd3n")), + iDD4R (memSpec.memPowerSpec.value().entries.at("idd4r")), + iDD4W (memSpec.memPowerSpec.value().entries.at("idd4w")), + iDD5 (memSpec.memPowerSpec.value().entries.at("idd5")), + iDD6 (memSpec.memPowerSpec.value().entries.at("idd6")), + vDD (memSpec.memPowerSpec.value().entries.at("vdd")), + iDD02 (memSpec.memPowerSpec.value().entries.at("idd02")), + iDD2P0 (memSpec.memPowerSpec.value().entries.at("idd2p0")), + iDD2P1 (memSpec.memPowerSpec.value().entries.at("idd2p1")), + iDD3P0 (memSpec.memPowerSpec.value().entries.at("idd3p0")), + iDD3P1 (memSpec.memPowerSpec.value().entries.at("idd3p1")), + iDD62 (memSpec.memPowerSpec.value().entries.at("idd62")), + vDD2 (memSpec.memPowerSpec.value().entries.at("vdd2")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; memorySizeBytes = deviceSizeBytes * numberOfDevices * numberOfRanks * numberOfChannels; + if (!memSpec.memPowerSpec.has_value()) + SC_REPORT_FATAL("MemSpec", "No power spec defined!"); + std::cout << headline << std::endl; std::cout << "Memory Configuration:" << std::endl << std::endl; std::cout << " Memory type: " << "DDR4" << std::endl; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h index 14adddd7..e7db402b 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #ifndef MEMSPECDDR4_H @@ -38,12 +39,11 @@ #include #include "MemSpec.h" -#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" class MemSpecDDR4 final : public MemSpec { public: - explicit MemSpecDDR4(nlohmann::json &memspec); + explicit MemSpecDDR4(const DRAMSysConfiguration::MemSpec &memSpec); // Memspec Variables: const sc_core::sc_time tCKE; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp index 40648435..23b6db52 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include @@ -40,84 +41,83 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpecDDR5::MemSpecDDR5(json &memspec) - : MemSpec(memspec, MemoryType::DDR5, - parseUint(memspec["memarchitecturespec"], "nbrOfChannels"), - parseUint(memspec["memarchitecturespec"], "nbrOfRanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - / parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfDevices")), - numberOfDIMMRanks(parseUint(memspec["memarchitecturespec"], "nbrOfDIMMRanks")), - physicalRanksPerDIMMRank(parseUint(memspec["memarchitecturespec"], "nbrOfPhysicalRanks")), +MemSpecDDR5::MemSpecDDR5(const DRAMSysConfiguration::MemSpec &memSpec) + : MemSpec(memSpec, MemoryType::DDR5, + memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + / memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), + numberOfDIMMRanks(memSpec.memArchitectureSpec.entries.at("nbrOfDIMMRanks")), + physicalRanksPerDIMMRank(memSpec.memArchitectureSpec.entries.at("nbrOfPhysicalRanks")), numberOfPhysicalRanks(physicalRanksPerDIMMRank * numberOfDIMMRanks), - logicalRanksPerPhysicalRank(parseUint(memspec["memarchitecturespec"], "nbrOfLogicalRanks")), + logicalRanksPerPhysicalRank(memSpec.memArchitectureSpec.entries.at("nbrOfLogicalRanks")), numberOfLogicalRanks(logicalRanksPerPhysicalRank * numberOfPhysicalRanks), - cmdMode(parseUint(memspec["memarchitecturespec"], "cmdMode")), - refMode(parseUint(memspec["memarchitecturespec"], "refMode")), - RAAIMT(parseUint(memspec["memarchitecturespec"], "RAAIMT")), - RAAMMT(parseUint(memspec["memarchitecturespec"], "RAAMMT")), - RAACDR(parseUint(memspec["memarchitecturespec"], "RAACDR")), - tRCD (tCK * parseUint(memspec["memtimingspec"], "RCD")), - tPPD (tCK * parseUint(memspec["memtimingspec"], "PPD")), - tRP (tCK * parseUint(memspec["memtimingspec"], "RP")), - tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), + cmdMode(memSpec.memArchitectureSpec.entries.at("cmdMode")), + refMode(memSpec.memArchitectureSpec.entries.at("refMode")), + RAAIMT(memSpec.memArchitectureSpec.entries.at("RAAIMT")), + RAAMMT(memSpec.memArchitectureSpec.entries.at("RAAMMT")), + RAACDR(memSpec.memArchitectureSpec.entries.at("RAACDR")), + tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")), + tPPD (tCK * memSpec.memTimingSpec.entries.at("PPD")), + tRP (tCK * memSpec.memTimingSpec.entries.at("RP")), + tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), tRC (tRAS + tRP), - tRL (tCK * parseUint(memspec["memtimingspec"], "RL")), - tRTP (tCK * parseUint(memspec["memtimingspec"], "RTP")), - tRPRE (tCK * parseUint(memspec["memtimingspec"], "RPRE")), - tRPST (tCK * parseUint(memspec["memtimingspec"], "RPST")), - tRDDQS (tCK * parseUint(memspec["memtimingspec"], "RDDQS")), - tWL (tCK * parseUint(memspec["memtimingspec"], "WL")), - tWPRE (tCK * parseUint(memspec["memtimingspec"], "WPRE")), - tWPST (tCK * parseUint(memspec["memtimingspec"], "WPST")), - tWR (tCK * parseUint(memspec["memtimingspec"], "WR")), - tCCD_L_slr (tCK * parseUint(memspec["memtimingspec"], "CCD_L_slr")), - tCCD_L_WR_slr (tCK * parseUint(memspec["memtimingspec"], "CCD_L_WR_slr")), - tCCD_L_WR2_slr (tCK * parseUint(memspec["memtimingspec"], "CCD_L_WR2_slr")), - tCCD_S_slr (tCK * parseUint(memspec["memtimingspec"], "CCD_S_slr")), - tCCD_S_WR_slr (tCK * parseUint(memspec["memtimingspec"], "CCD_S_WR_slr")), - tCCD_dlr (tCK * parseUint(memspec["memtimingspec"], "CCD_dlr")), - tCCD_WR_dlr (tCK * parseUint(memspec["memtimingspec"], "CCD_WR_dlr")), - tCCD_WR_dpr (tCK * parseUint(memspec["memtimingspec"], "CCD_WR_dpr")), - tRRD_L_slr (tCK * parseUint(memspec["memtimingspec"], "RRD_L_slr")), - tRRD_S_slr (tCK * parseUint(memspec["memtimingspec"], "RRD_S_slr")), - tRRD_dlr (tCK * parseUint(memspec["memtimingspec"], "RRD_dlr")), - tFAW_slr (tCK * parseUint(memspec["memtimingspec"], "FAW_slr")), - tFAW_dlr (tCK * parseUint(memspec["memtimingspec"], "FAW_dlr")), - tWTR_L (tCK * parseUint(memspec["memtimingspec"], "WTR_L")), - tWTR_S (tCK * parseUint(memspec["memtimingspec"], "WTR_S")), - tRFC_slr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"], "RFC1_slr") - : tCK * parseUint(memspec["memtimingspec"], "RFC2_slr")), - tRFC_dlr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"], "RFC1_dlr") - : tCK * parseUint(memspec["memtimingspec"], "RFC2_dlr")), - tRFC_dpr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"], "RFC1_dpr") - : tCK * parseUint(memspec["memtimingspec"], "RFC2_dpr")), - tRFCsb_slr (tCK * parseUint(memspec["memtimingspec"], "RFCsb_slr")), - tRFCsb_dlr (tCK * parseUint(memspec["memtimingspec"], "RFCsb_dlr")), - tREFI ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"], "REFI1") - : tCK * parseUint(memspec["memtimingspec"], "REFI2")), - tREFIsb (tCK * parseUint(memspec["memtimingspec"], "REFISB")), - tREFSBRD_slr (tCK * parseUint(memspec["memtimingspec"], "REFSBRD_slr")), - tREFSBRD_dlr (tCK * parseUint(memspec["memtimingspec"], "REFSBRD_dlr")), - tRTRS (tCK * parseUint(memspec["memtimingspec"], "RTRS")), - tCPDED (tCK * parseUint(memspec["memtimingspec"], "CPDED")), - tPD (tCK * parseUint(memspec["memtimingspec"], "PD")), - tXP (tCK * parseUint(memspec["memtimingspec"], "XP")), - tACTPDEN (tCK * parseUint(memspec["memtimingspec"], "ACTPDEN")), - tPRPDEN (tCK * parseUint(memspec["memtimingspec"], "PRPDEN")), - tREFPDEN (tCK * parseUint(memspec["memtimingspec"], "REFPDEN")), + tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), + tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")), + tRPRE (tCK * memSpec.memTimingSpec.entries.at("RPRE")), + tRPST (tCK * memSpec.memTimingSpec.entries.at("RPST")), + tRDDQS (tCK * memSpec.memTimingSpec.entries.at("RDDQS")), + tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), + tWPRE (tCK * memSpec.memTimingSpec.entries.at("WPRE")), + tWPST (tCK * memSpec.memTimingSpec.entries.at("WPST")), + tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), + tCCD_L_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_L_slr")), + tCCD_L_WR_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_L_WR_slr")), + tCCD_L_WR2_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_L_WR2_slr")), + tCCD_S_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_S_slr")), + tCCD_S_WR_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_S_WR_slr")), + tCCD_dlr (tCK * memSpec.memTimingSpec.entries.at("CCD_dlr")), + tCCD_WR_dlr (tCK * memSpec.memTimingSpec.entries.at("CCD_WR_dlr")), + tCCD_WR_dpr (tCK * memSpec.memTimingSpec.entries.at("CCD_WR_dpr")), + tRRD_L_slr (tCK * memSpec.memTimingSpec.entries.at("RRD_L_slr")), + tRRD_S_slr (tCK * memSpec.memTimingSpec.entries.at("RRD_S_slr")), + tRRD_dlr (tCK * memSpec.memTimingSpec.entries.at("RRD_dlr")), + tFAW_slr (tCK * memSpec.memTimingSpec.entries.at("FAW_slr")), + tFAW_dlr (tCK * memSpec.memTimingSpec.entries.at("FAW_dlr")), + tWTR_L (tCK * memSpec.memTimingSpec.entries.at("WTR_L")), + tWTR_S (tCK * memSpec.memTimingSpec.entries.at("WTR_S")), + tRFC_slr ((refMode == 1) ? tCK * memSpec.memTimingSpec.entries.at("RFC1_slr") + : tCK * memSpec.memTimingSpec.entries.at("RFC2_slr")), + tRFC_dlr ((refMode == 1) ? tCK * memSpec.memTimingSpec.entries.at("RFC1_dlr") + : tCK * memSpec.memTimingSpec.entries.at("RFC2_dlr")), + tRFC_dpr ((refMode == 1) ? tCK * memSpec.memTimingSpec.entries.at("RFC1_dpr") + : tCK * memSpec.memTimingSpec.entries.at("RFC2_dpr")), + tRFCsb_slr (tCK * memSpec.memTimingSpec.entries.at("RFCsb_slr")), + tRFCsb_dlr (tCK * memSpec.memTimingSpec.entries.at("RFCsb_dlr")), + tREFI ((refMode == 1) ? tCK * memSpec.memTimingSpec.entries.at("REFI1") + : tCK * memSpec.memTimingSpec.entries.at("REFI2")), + tREFIsb (tCK * memSpec.memTimingSpec.entries.at("REFISB")), + tREFSBRD_slr (tCK * memSpec.memTimingSpec.entries.at("REFSBRD_slr")), + tREFSBRD_dlr (tCK * memSpec.memTimingSpec.entries.at("REFSBRD_dlr")), + tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")), + tCPDED (tCK * memSpec.memTimingSpec.entries.at("CPDED")), + tPD (tCK * memSpec.memTimingSpec.entries.at("PD")), + tXP (tCK * memSpec.memTimingSpec.entries.at("XP")), + tACTPDEN (tCK * memSpec.memTimingSpec.entries.at("ACTPDEN")), + tPRPDEN (tCK * memSpec.memTimingSpec.entries.at("PRPDEN")), + tREFPDEN (tCK * memSpec.memTimingSpec.entries.at("REFPDEN")), shortCmdOffset (cmdMode == 2 ? 1 * tCK : 0 * tCK), longCmdOffset (cmdMode == 2 ? 3 * tCK : 1 * tCK), - tBURST16(tCK * 8), - tBURST32(tCK * 16) + tBURST16 (tCK * 8), + tBURST32 (tCK * 16) { if (cmdMode == 1) { diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h index 44e344f8..178cca5c 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #ifndef MEMSPECDDR5_H @@ -38,12 +39,11 @@ #include #include "MemSpec.h" -#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" class MemSpecDDR5 final : public MemSpec { public: - explicit MemSpecDDR5(nlohmann::json &memspec); + explicit MemSpecDDR5(const DRAMSysConfiguration::MemSpec &memSpec); const unsigned numberOfDIMMRanks; const unsigned physicalRanksPerDIMMRank; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp index f498f21b..a0d7b5a8 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include @@ -40,55 +41,54 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpecGDDR5::MemSpecGDDR5(json &memspec) - : MemSpec(memspec, MemoryType::GDDR5, - parseUint(memspec["memarchitecturespec"],"nbrOfChannels"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - / parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfDevices")), - tRP (tCK * parseUint(memspec["memtimingspec"], "RP")), - tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), - tRC (tCK * parseUint(memspec["memtimingspec"], "RC")), - tRCDRD (tCK * parseUint(memspec["memtimingspec"], "RCDRD")), - tRCDWR (tCK * parseUint(memspec["memtimingspec"], "RCDWR")), - tRTP (tCK * parseUint(memspec["memtimingspec"], "RTP")), - tRRDS (tCK * parseUint(memspec["memtimingspec"], "RRDS")), - tRRDL (tCK * parseUint(memspec["memtimingspec"], "RRDL")), - tCCDS (tCK * parseUint(memspec["memtimingspec"], "CCDS")), - tCCDL (tCK * parseUint(memspec["memtimingspec"], "CCDL")), - tCL (tCK * parseUint(memspec["memtimingspec"], "CL")), - tWCK2CKPIN (tCK * parseUint(memspec["memtimingspec"], "WCK2CKPIN")), - tWCK2CK (tCK * parseUint(memspec["memtimingspec"], "WCK2CK")), - tWCK2DQO (tCK * parseUint(memspec["memtimingspec"], "WCK2DQO")), - tRTW (tCK * parseUint(memspec["memtimingspec"], "RTW")), - tWL (tCK * parseUint(memspec["memtimingspec"], "WL")), - tWCK2DQI (tCK * parseUint(memspec["memtimingspec"], "WCK2DQI")), - tWR (tCK * parseUint(memspec["memtimingspec"], "WR")), - tWTRS (tCK * parseUint(memspec["memtimingspec"], "WTRS")), - tWTRL (tCK * parseUint(memspec["memtimingspec"], "WTRL")), - tCKE (tCK * parseUint(memspec["memtimingspec"], "CKE")), - tPD (tCK * parseUint(memspec["memtimingspec"], "PD")), - tXPN (tCK * parseUint(memspec["memtimingspec"], "XPN")), - tREFI (tCK * parseUint(memspec["memtimingspec"], "REFI")), - tREFIPB (tCK * parseUint(memspec["memtimingspec"], "REFIPB")), - tRFC (tCK * parseUint(memspec["memtimingspec"], "RFC")), - tRFCPB (tCK * parseUint(memspec["memtimingspec"], "RFCPB")), - tRREFD (tCK * parseUint(memspec["memtimingspec"], "RREFD")), - tXS (tCK * parseUint(memspec["memtimingspec"], "XS")), - tFAW (tCK * parseUint(memspec["memtimingspec"], "FAW")), - t32AW (tCK * parseUint(memspec["memtimingspec"], "32AW")), - tPPD (tCK * parseUint(memspec["memtimingspec"], "PPD")), - tLK (tCK * parseUint(memspec["memtimingspec"], "LK")), - tRTRS (tCK * parseUint(memspec["memtimingspec"], "RTRS")) +MemSpecGDDR5::MemSpecGDDR5(const DRAMSysConfiguration::MemSpec &memSpec) + : MemSpec(memSpec, MemoryType::GDDR5, + memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + / memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), + tRP (tCK * memSpec.memTimingSpec.entries.at("RP")), + tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), + tRC (tCK * memSpec.memTimingSpec.entries.at("RC")), + tRCDRD (tCK * memSpec.memTimingSpec.entries.at("RCDRD")), + tRCDWR (tCK * memSpec.memTimingSpec.entries.at("RCDWR")), + tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")), + tRRDS (tCK * memSpec.memTimingSpec.entries.at("RRDS")), + tRRDL (tCK * memSpec.memTimingSpec.entries.at("RRDL")), + tCCDS (tCK * memSpec.memTimingSpec.entries.at("CCDS")), + tCCDL (tCK * memSpec.memTimingSpec.entries.at("CCDL")), + tCL (tCK * memSpec.memTimingSpec.entries.at("CL")), + tWCK2CKPIN (tCK * memSpec.memTimingSpec.entries.at("WCK2CKPIN")), + tWCK2CK (tCK * memSpec.memTimingSpec.entries.at("WCK2CK")), + tWCK2DQO (tCK * memSpec.memTimingSpec.entries.at("WCK2DQO")), + tRTW (tCK * memSpec.memTimingSpec.entries.at("RTW")), + tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), + tWCK2DQI (tCK * memSpec.memTimingSpec.entries.at("WCK2DQI")), + tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), + tWTRS (tCK * memSpec.memTimingSpec.entries.at("WTRS")), + tWTRL (tCK * memSpec.memTimingSpec.entries.at("WTRL")), + tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")), + tPD (tCK * memSpec.memTimingSpec.entries.at("PD")), + tXPN (tCK * memSpec.memTimingSpec.entries.at("XPN")), + tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")), + tREFIPB (tCK * memSpec.memTimingSpec.entries.at("REFIPB")), + tRFC (tCK * memSpec.memTimingSpec.entries.at("RFC")), + tRFCPB (tCK * memSpec.memTimingSpec.entries.at("RFCPB")), + tRREFD (tCK * memSpec.memTimingSpec.entries.at("RREFD")), + tXS (tCK * memSpec.memTimingSpec.entries.at("XS")), + tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), + t32AW (tCK * memSpec.memTimingSpec.entries.at("32AW")), + tPPD (tCK * memSpec.memTimingSpec.entries.at("PPD")), + tLK (tCK * memSpec.memTimingSpec.entries.at("LK")), + tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h index b66df343..f5998776 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #ifndef MEMSPECGDDR5_H @@ -38,12 +39,11 @@ #include #include "MemSpec.h" -#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" class MemSpecGDDR5 final : public MemSpec { public: - explicit MemSpecGDDR5(nlohmann::json &memspec); + explicit MemSpecGDDR5(const DRAMSysConfiguration::MemSpec &memSpec); // Memspec Variables: const sc_core::sc_time tRP; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp index af98befb..9ff6768b 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include @@ -39,55 +40,54 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpecGDDR5X::MemSpecGDDR5X(json &memspec) - : MemSpec(memspec, MemoryType::GDDR5X, - parseUint(memspec["memarchitecturespec"],"nbrOfChannels"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - / parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfDevices")), - tRP (tCK * parseUint(memspec["memtimingspec"], "RP")), - tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), - tRC (tCK * parseUint(memspec["memtimingspec"], "RC")), - tRCDRD (tCK * parseUint(memspec["memtimingspec"], "RCDRD")), - tRCDWR (tCK * parseUint(memspec["memtimingspec"], "RCDWR")), - tRTP (tCK * parseUint(memspec["memtimingspec"], "RTP")), - tRRDS (tCK * parseUint(memspec["memtimingspec"], "RRDS")), - tRRDL (tCK * parseUint(memspec["memtimingspec"], "RRDL")), - tCCDS (tCK * parseUint(memspec["memtimingspec"], "CCDS")), - tCCDL (tCK * parseUint(memspec["memtimingspec"], "CCDL")), - tRL (tCK * parseUint(memspec["memtimingspec"], "CL")), - tWCK2CKPIN (tCK * parseUint(memspec["memtimingspec"], "WCK2CKPIN")), - tWCK2CK (tCK * parseUint(memspec["memtimingspec"], "WCK2CK")), - tWCK2DQO (tCK * parseUint(memspec["memtimingspec"], "WCK2DQO")), - tRTW (tCK * parseUint(memspec["memtimingspec"], "RTW")), - tWL (tCK * parseUint(memspec["memtimingspec"], "WL")), - tWCK2DQI (tCK * parseUint(memspec["memtimingspec"], "WCK2DQI")), - tWR (tCK * parseUint(memspec["memtimingspec"], "WR")), - tWTRS (tCK * parseUint(memspec["memtimingspec"], "WTRS")), - tWTRL (tCK * parseUint(memspec["memtimingspec"], "WTRL")), - tCKE (tCK * parseUint(memspec["memtimingspec"], "CKE")), - tPD (tCK * parseUint(memspec["memtimingspec"], "PD")), - tXP (tCK * parseUint(memspec["memtimingspec"], "XP")), - tREFI (tCK * parseUint(memspec["memtimingspec"], "REFI")), - tREFIPB (tCK * parseUint(memspec["memtimingspec"], "REFIPB")), - tRFC (tCK * parseUint(memspec["memtimingspec"], "RFC")), - tRFCPB (tCK * parseUint(memspec["memtimingspec"], "RFCPB")), - tRREFD (tCK * parseUint(memspec["memtimingspec"], "RREFD")), - tXS (tCK * parseUint(memspec["memtimingspec"], "XS")), - tFAW (tCK * parseUint(memspec["memtimingspec"], "FAW")), - t32AW (tCK * parseUint(memspec["memtimingspec"], "32AW")), - tPPD (tCK * parseUint(memspec["memtimingspec"], "PPD")), - tLK (tCK * parseUint(memspec["memtimingspec"], "LK")), - tRTRS (tCK * parseUint(memspec["memtimingspec"], "RTRS")) +MemSpecGDDR5X::MemSpecGDDR5X(const DRAMSysConfiguration::MemSpec &memSpec) + : MemSpec(memSpec, MemoryType::GDDR5X, + memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + / memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), + tRP (tCK * memSpec.memTimingSpec.entries.at("RP")), + tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), + tRC (tCK * memSpec.memTimingSpec.entries.at("RC")), + tRCDRD (tCK * memSpec.memTimingSpec.entries.at("RCDRD")), + tRCDWR (tCK * memSpec.memTimingSpec.entries.at("RCDWR")), + tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")), + tRRDS (tCK * memSpec.memTimingSpec.entries.at("RRDS")), + tRRDL (tCK * memSpec.memTimingSpec.entries.at("RRDL")), + tCCDS (tCK * memSpec.memTimingSpec.entries.at("CCDS")), + tCCDL (tCK * memSpec.memTimingSpec.entries.at("CCDL")), + tRL (tCK * memSpec.memTimingSpec.entries.at("CL")), + tWCK2CKPIN (tCK * memSpec.memTimingSpec.entries.at("WCK2CKPIN")), + tWCK2CK (tCK * memSpec.memTimingSpec.entries.at("WCK2CK")), + tWCK2DQO (tCK * memSpec.memTimingSpec.entries.at("WCK2DQO")), + tRTW (tCK * memSpec.memTimingSpec.entries.at("RTW")), + tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), + tWCK2DQI (tCK * memSpec.memTimingSpec.entries.at("WCK2DQI")), + tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), + tWTRS (tCK * memSpec.memTimingSpec.entries.at("WTRS")), + tWTRL (tCK * memSpec.memTimingSpec.entries.at("WTRL")), + tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")), + tPD (tCK * memSpec.memTimingSpec.entries.at("PD")), + tXP (tCK * memSpec.memTimingSpec.entries.at("XP")), + tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")), + tREFIPB (tCK * memSpec.memTimingSpec.entries.at("REFIPB")), + tRFC (tCK * memSpec.memTimingSpec.entries.at("RFC")), + tRFCPB (tCK * memSpec.memTimingSpec.entries.at("RFCPB")), + tRREFD (tCK * memSpec.memTimingSpec.entries.at("RREFD")), + tXS (tCK * memSpec.memTimingSpec.entries.at("XS")), + tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), + t32AW (tCK * memSpec.memTimingSpec.entries.at("32AW")), + tPPD (tCK * memSpec.memTimingSpec.entries.at("PPD")), + tLK (tCK * memSpec.memTimingSpec.entries.at("LK")), + tRTRS (tCK * memSpec.memTimingSpec.entries.at("TRS")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h index 4d181f12..432ea1e0 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #ifndef MEMSPECGDDR5X_H @@ -38,12 +39,11 @@ #include #include "MemSpec.h" -#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" class MemSpecGDDR5X final : public MemSpec { public: - explicit MemSpecGDDR5X(nlohmann::json &memspec); + explicit MemSpecGDDR5X(const DRAMSysConfiguration::MemSpec &memSpec); // Memspec Variables: const sc_core::sc_time tRP; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp index a7690dba..0e065766 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include @@ -40,58 +41,57 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpecGDDR6::MemSpecGDDR6(json &memspec) - : MemSpec(memspec, MemoryType::GDDR6, - parseUint(memspec["memarchitecturespec"],"nbrOfChannels"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - / parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfDevices")), - per2BankOffset(parseUint(memspec["memarchitecturespec"], "per2BankOffset")), - tRP (tCK * parseUint(memspec["memtimingspec"], "RP")), - tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), - tRC (tCK * parseUint(memspec["memtimingspec"], "RC")), - tRCDRD (tCK * parseUint(memspec["memtimingspec"], "RCDRD")), - tRCDWR (tCK * parseUint(memspec["memtimingspec"], "RCDWR")), - tRTP (tCK * parseUint(memspec["memtimingspec"], "RTP")), - tRRDS (tCK * parseUint(memspec["memtimingspec"], "RRDS")), - tRRDL (tCK * parseUint(memspec["memtimingspec"], "RRDL")), - tCCDS (tCK * parseUint(memspec["memtimingspec"], "CCDS")), - tCCDL (tCK * parseUint(memspec["memtimingspec"], "CCDL")), - tRL (tCK * parseUint(memspec["memtimingspec"], "RL")), - tWCK2CKPIN (tCK * parseUint(memspec["memtimingspec"], "WCK2CKPIN")), - tWCK2CK (tCK * parseUint(memspec["memtimingspec"], "WCK2CK")), - tWCK2DQO (tCK * parseUint(memspec["memtimingspec"], "WCK2DQO")), - tRTW (tCK * parseUint(memspec["memtimingspec"], "RTW")), - tWL (tCK * parseUint(memspec["memtimingspec"], "WL")), - tWCK2DQI (tCK * parseUint(memspec["memtimingspec"], "WCK2DQI")), - tWR (tCK * parseUint(memspec["memtimingspec"], "WR")), - tWTRS (tCK * parseUint(memspec["memtimingspec"], "WTRS")), - tWTRL (tCK * parseUint(memspec["memtimingspec"], "WTRL")), - tPD (tCK * parseUint(memspec["memtimingspec"], "PD")), - tCKESR (tCK * parseUint(memspec["memtimingspec"], "CKESR")), - tXP (tCK * parseUint(memspec["memtimingspec"], "XP")), - tREFI (tCK * parseUint(memspec["memtimingspec"], "REFI")), - tREFIpb (tCK * parseUint(memspec["memtimingspec"], "REFIpb")), - tRFCab (tCK * parseUint(memspec["memtimingspec"], "RFCab")), - tRFCpb (tCK * parseUint(memspec["memtimingspec"], "RFCpb")), - tRREFD (tCK * parseUint(memspec["memtimingspec"], "RREFD")), - tXS (tCK * parseUint(memspec["memtimingspec"], "XS")), - tFAW (tCK * parseUint(memspec["memtimingspec"], "FAW")), - tPPD (tCK * parseUint(memspec["memtimingspec"], "PPD")), - tLK (tCK * parseUint(memspec["memtimingspec"], "LK")), - tACTPDE (tCK * parseUint(memspec["memtimingspec"], "ACTPDE")), - tPREPDE (tCK * parseUint(memspec["memtimingspec"], "PREPDE")), - tREFPDE (tCK * parseUint(memspec["memtimingspec"], "REFPDE")), - tRTRS (tCK * parseUint(memspec["memtimingspec"], "RTRS")) +MemSpecGDDR6::MemSpecGDDR6(const DRAMSysConfiguration::MemSpec &memSpec) + : MemSpec(memSpec, MemoryType::GDDR6, + memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memArchitectureSpec.entries.at( "nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + / memSpec.memArchitectureSpec.entries.at( "nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at( "nbrOfBankGroups") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), + per2BankOffset(memSpec.memArchitectureSpec.entries.at("per2BankOffset")), + tRP (tCK * memSpec.memTimingSpec.entries.at("RP")), + tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), + tRC (tCK * memSpec.memTimingSpec.entries.at("RC")), + tRCDRD (tCK * memSpec.memTimingSpec.entries.at("RCDRD")), + tRCDWR (tCK * memSpec.memTimingSpec.entries.at("RCDWR")), + tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")), + tRRDS (tCK * memSpec.memTimingSpec.entries.at("RRDS")), + tRRDL (tCK * memSpec.memTimingSpec.entries.at("RRDL")), + tCCDS (tCK * memSpec.memTimingSpec.entries.at("CCDS")), + tCCDL (tCK * memSpec.memTimingSpec.entries.at("CCDL")), + tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), + tWCK2CKPIN (tCK * memSpec.memTimingSpec.entries.at("WCK2CKPIN")), + tWCK2CK (tCK * memSpec.memTimingSpec.entries.at("WCK2CK")), + tWCK2DQO (tCK * memSpec.memTimingSpec.entries.at("WCK2DQO")), + tRTW (tCK * memSpec.memTimingSpec.entries.at("RTW")), + tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), + tWCK2DQI (tCK * memSpec.memTimingSpec.entries.at("WCK2DQI")), + tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), + tWTRS (tCK * memSpec.memTimingSpec.entries.at("WTRS")), + tWTRL (tCK * memSpec.memTimingSpec.entries.at("WTRL")), + tPD (tCK * memSpec.memTimingSpec.entries.at("PD")), + tCKESR (tCK * memSpec.memTimingSpec.entries.at("CKESR")), + tXP (tCK * memSpec.memTimingSpec.entries.at("XP")), + tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")), + tREFIpb (tCK * memSpec.memTimingSpec.entries.at("REFIpb")), + tRFCab (tCK * memSpec.memTimingSpec.entries.at("RFCab")), + tRFCpb (tCK * memSpec.memTimingSpec.entries.at("RFCpb")), + tRREFD (tCK * memSpec.memTimingSpec.entries.at("RREFD")), + tXS (tCK * memSpec.memTimingSpec.entries.at("XS")), + tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), + tPPD (tCK * memSpec.memTimingSpec.entries.at("PPD")), + tLK (tCK * memSpec.memTimingSpec.entries.at("LK")), + tACTPDE (tCK * memSpec.memTimingSpec.entries.at("ACTPDE")), + tPREPDE (tCK * memSpec.memTimingSpec.entries.at("PREPDE")), + tREFPDE (tCK * memSpec.memTimingSpec.entries.at("REFPDE")), + tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h index 8deb3605..e96c8513 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #ifndef MEMSPECGDDR6_H @@ -38,12 +39,11 @@ #include #include "MemSpec.h" -#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" struct MemSpecGDDR6 final : public MemSpec { public: - explicit MemSpecGDDR6(nlohmann::json &memspec); + explicit MemSpecGDDR6(const DRAMSysConfiguration::MemSpec &memSpec); // Memspec Variables: const sc_core::sc_time tRP; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp index 6d382555..156e07e5 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include @@ -40,50 +41,49 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpecHBM2::MemSpecHBM2(json &memspec) - : MemSpec(memspec, MemoryType::HBM2, - parseUint(memspec["memarchitecturespec"],"nbrOfChannels"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - / parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfDevices")), - tDQSCK (tCK * parseUint(memspec["memtimingspec"], "DQSCK")), - tRC (tCK * parseUint(memspec["memtimingspec"], "RC")), - tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), - tRCDRD (tCK * parseUint(memspec["memtimingspec"], "RCDRD")), - tRCDWR (tCK * parseUint(memspec["memtimingspec"], "RCDWR")), - tRRDL (tCK * parseUint(memspec["memtimingspec"], "RRDL")), - tRRDS (tCK * parseUint(memspec["memtimingspec"], "RRDS")), - tFAW (tCK * parseUint(memspec["memtimingspec"], "FAW")), - tRTP (tCK * parseUint(memspec["memtimingspec"], "RTP")), - tRP (tCK * parseUint(memspec["memtimingspec"], "RP")), - tRL (tCK * parseUint(memspec["memtimingspec"], "RL")), - tWL (tCK * parseUint(memspec["memtimingspec"], "WL")), - tPL (tCK * parseUint(memspec["memtimingspec"], "PL")), - tWR (tCK * parseUint(memspec["memtimingspec"], "WR")), - tCCDL (tCK * parseUint(memspec["memtimingspec"], "CCDL")), - tCCDS (tCK * parseUint(memspec["memtimingspec"], "CCDS")), - tWTRL (tCK * parseUint(memspec["memtimingspec"], "WTRL")), - tWTRS (tCK * parseUint(memspec["memtimingspec"], "WTRS")), - tRTW (tCK * parseUint(memspec["memtimingspec"], "RTW")), - tXP (tCK * parseUint(memspec["memtimingspec"], "XP")), - tCKE (tCK * parseUint(memspec["memtimingspec"], "CKE")), +MemSpecHBM2::MemSpecHBM2(const DRAMSysConfiguration::MemSpec &memSpec) + : MemSpec(memSpec, MemoryType::HBM2, + memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + / memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), + tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")), + tRC (tCK * memSpec.memTimingSpec.entries.at("RC")), + tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), + tRCDRD (tCK * memSpec.memTimingSpec.entries.at("RCDRD")), + tRCDWR (tCK * memSpec.memTimingSpec.entries.at("RCDWR")), + tRRDL (tCK * memSpec.memTimingSpec.entries.at("RRDL")), + tRRDS (tCK * memSpec.memTimingSpec.entries.at("RRDS")), + tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), + tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")), + tRP (tCK * memSpec.memTimingSpec.entries.at("RP")), + tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), + tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), + tPL (tCK * memSpec.memTimingSpec.entries.at("PL")), + tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), + tCCDL (tCK * memSpec.memTimingSpec.entries.at("CCDL")), + tCCDS (tCK * memSpec.memTimingSpec.entries.at("CCDS")), + tWTRL (tCK * memSpec.memTimingSpec.entries.at("WTRL")), + tWTRS (tCK * memSpec.memTimingSpec.entries.at("WTRS")), + tRTW (tCK * memSpec.memTimingSpec.entries.at("RTW")), + tXP (tCK * memSpec.memTimingSpec.entries.at("XP")), + tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")), tPD (tCKE), tCKESR (tCKE + tCK), - tXS (tCK * parseUint(memspec["memtimingspec"], "XS")), - tRFC (tCK * parseUint(memspec["memtimingspec"], "RFC")), - tRFCSB (tCK * parseUint(memspec["memtimingspec"], "RFCSB")), - tRREFD (tCK * parseUint(memspec["memtimingspec"], "RREFD")), - tREFI (tCK * parseUint(memspec["memtimingspec"], "REFI")), - tREFISB (tCK * parseUint(memspec["memtimingspec"], "REFISB")) + tXS (tCK * memSpec.memTimingSpec.entries.at("XS")), + tRFC (tCK * memSpec.memTimingSpec.entries.at("RFC")), + tRFCSB (tCK * memSpec.memTimingSpec.entries.at("RFCSB")), + tRREFD (tCK * memSpec.memTimingSpec.entries.at("RREFD")), + tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")), + tREFISB (tCK * memSpec.memTimingSpec.entries.at("REFISB")) { commandLengthInCycles[Command::ACT] = 2; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h index 5eeb6355..71dffc76 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #ifndef MEMSPECHBM2_H @@ -38,12 +39,11 @@ #include #include "MemSpec.h" -#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" class MemSpecHBM2 final : public MemSpec { public: - explicit MemSpecHBM2(nlohmann::json &memspec); + explicit MemSpecHBM2(const DRAMSysConfiguration::MemSpec &memSpec); // Memspec Variables: const sc_core::sc_time tDQSCK; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp index 53647408..7e1efd8f 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include @@ -40,50 +41,49 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpecLPDDR4::MemSpecLPDDR4(json &memspec) - : MemSpec(memspec, MemoryType::LPDDR4, - parseUint(memspec["memarchitecturespec"],"nbrOfChannels"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), +MemSpecLPDDR4::MemSpecLPDDR4(const DRAMSysConfiguration::MemSpec &memSpec) + : MemSpec(memSpec, MemoryType::LPDDR4, + memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), 1, - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfDevices")), - tREFI (tCK * parseUint(memspec["memtimingspec"], "REFI")), - tREFIpb (tCK * parseUint(memspec["memtimingspec"], "REFIPB")), - tRFCab (tCK * parseUint(memspec["memtimingspec"], "RFCAB")), - tRFCpb (tCK * parseUint(memspec["memtimingspec"], "RFCPB")), - tRPab (tCK * parseUint(memspec["memtimingspec"], "RPAB")), - tRPpb (tCK * parseUint(memspec["memtimingspec"], "RPPB")), - tRCab (tCK * parseUint(memspec["memtimingspec"], "RCAB")), - tRCpb (tCK * parseUint(memspec["memtimingspec"], "RCPB")), - tPPD (tCK * parseUint(memspec["memtimingspec"], "PPD")), - tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), - tRCD (tCK * parseUint(memspec["memtimingspec"], "RCD")), - tFAW (tCK * parseUint(memspec["memtimingspec"], "FAW")), - tRRD (tCK * parseUint(memspec["memtimingspec"], "RRD")), - tCCD (tCK * parseUint(memspec["memtimingspec"], "CCD")), - tRL (tCK * parseUint(memspec["memtimingspec"], "RL")), - tRPST (tCK * parseUint(memspec["memtimingspec"], "RPST")), - tDQSCK (tCK * parseUint(memspec["memtimingspec"], "DQSCK")), - tRTP (tCK * parseUint(memspec["memtimingspec"], "RTP")), - tWL (tCK * parseUint(memspec["memtimingspec"], "WL")), - tDQSS (tCK * parseUint(memspec["memtimingspec"], "DQSS")), - tDQS2DQ (tCK * parseUint(memspec["memtimingspec"], "DQS2DQ")), - tWR (tCK * parseUint(memspec["memtimingspec"], "WR")), - tWPRE (tCK * parseUint(memspec["memtimingspec"], "WPRE")), - tWTR (tCK * parseUint(memspec["memtimingspec"], "WTR")), - tXP (tCK * parseUint(memspec["memtimingspec"], "XP")), - tSR (tCK * parseUint(memspec["memtimingspec"], "SR")), - tXSR (tCK * parseUint(memspec["memtimingspec"], "XSR")), - tESCKE (tCK * parseUint(memspec["memtimingspec"], "ESCKE")), - tCKE (tCK * parseUint(memspec["memtimingspec"], "CKE")), - tCMDCKE (tCK * parseUint(memspec["memtimingspec"], "CMDCKE")), - tRTRS (tCK * parseUint(memspec["memtimingspec"], "RTRS")) + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), + tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")), + tREFIpb (tCK * memSpec.memTimingSpec.entries.at("REFIPB")), + tRFCab (tCK * memSpec.memTimingSpec.entries.at("RFCAB")), + tRFCpb (tCK * memSpec.memTimingSpec.entries.at("RFCPB")), + tRPab (tCK * memSpec.memTimingSpec.entries.at("RPAB")), + tRPpb (tCK * memSpec.memTimingSpec.entries.at("RPPB")), + tRCab (tCK * memSpec.memTimingSpec.entries.at("RCAB")), + tRCpb (tCK * memSpec.memTimingSpec.entries.at("RCPB")), + tPPD (tCK * memSpec.memTimingSpec.entries.at("PPD")), + tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), + tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")), + tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), + tRRD (tCK * memSpec.memTimingSpec.entries.at("RRD")), + tCCD (tCK * memSpec.memTimingSpec.entries.at("CCD")), + tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), + tRPST (tCK * memSpec.memTimingSpec.entries.at("RPST")), + tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")), + tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")), + tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), + tDQSS (tCK * memSpec.memTimingSpec.entries.at("DQSS")), + tDQS2DQ (tCK * memSpec.memTimingSpec.entries.at("DQS2DQ")), + tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), + tWPRE (tCK * memSpec.memTimingSpec.entries.at("WPRE")), + tWTR (tCK * memSpec.memTimingSpec.entries.at("WTR")), + tXP (tCK * memSpec.memTimingSpec.entries.at("XP")), + tSR (tCK * memSpec.memTimingSpec.entries.at("SR")), + tXSR (tCK * memSpec.memTimingSpec.entries.at("XSR")), + tESCKE (tCK * memSpec.memTimingSpec.entries.at("ESCKE")), + tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")), + tCMDCKE (tCK * memSpec.memTimingSpec.entries.at("CMDCKE")), + tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")) { commandLengthInCycles[Command::ACT] = 4; commandLengthInCycles[Command::PREPB] = 2; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h index 129328ae..d93cf8cc 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #ifndef MEMSPECLPDDR4_H @@ -38,12 +39,11 @@ #include #include "MemSpec.h" -#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" class MemSpecLPDDR4 final : public MemSpec { public: - explicit MemSpecLPDDR4(nlohmann::json &memspec); + explicit MemSpecLPDDR4(const DRAMSysConfiguration::MemSpec &memSpec); // Memspec Variables: const sc_core::sc_time tREFI; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.cpp index 50532945..95fcfd9c 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.cpp @@ -40,44 +40,43 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpecLPDDR5::MemSpecLPDDR5(json &memspec) - : MemSpec(memspec, MemoryType::LPDDR5, - parseUint(memspec["memarchitecturespec"],"nbrOfChannels"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - / parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"], "nbrOfBankGroups") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfDevices")), - per2BankOffset(parseUint(memspec["memarchitecturespec"], "per2BankOffset")), - tREFI (tCK * parseUint(memspec["memtimingspec"], "REFI")), - tREFIpb (tCK * parseUint(memspec["memtimingspec"], "REFIpb")), - tRFCab (tCK * parseUint(memspec["memtimingspec"], "RFCab")), - tRFCpb (tCK * parseUint(memspec["memtimingspec"], "RFCpb")), - tRPab (tCK * parseUint(memspec["memtimingspec"], "RPab")), - tRPpb (tCK * parseUint(memspec["memtimingspec"], "RPpb")), - tRCab (tCK * parseUint(memspec["memtimingspec"], "RCab")), - tRCpb (tCK * parseUint(memspec["memtimingspec"], "RCpb")), - tPPD (tCK * parseUint(memspec["memtimingspec"], "PPD")), - tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), - tRCD (tCK * parseUint(memspec["memtimingspec"], "RCD")), - tFAW (tCK * parseUint(memspec["memtimingspec"], "FAW")), - tRRD (tCK * parseUint(memspec["memtimingspec"], "RRD")), +MemSpecLPDDR5::MemSpecLPDDR5(const DRAMSysConfiguration::MemSpec &memSpec) + : MemSpec(memSpec, MemoryType::LPDDR5, + memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + / memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), + per2BankOffset(memSpec.memArchitectureSpec.entries.at("per2BankOffset")), + tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")), + tREFIpb (tCK * memSpec.memTimingSpec.entries.at("REFIpb")), + tRFCab (tCK * memSpec.memTimingSpec.entries.at("RFCab")), + tRFCpb (tCK * memSpec.memTimingSpec.entries.at("RFCpb")), + tRPab (tCK * memSpec.memTimingSpec.entries.at("RPab")), + tRPpb (tCK * memSpec.memTimingSpec.entries.at("RPpb")), + tRCab (tCK * memSpec.memTimingSpec.entries.at("RCab")), + tRCpb (tCK * memSpec.memTimingSpec.entries.at("RCpb")), + tPPD (tCK * memSpec.memTimingSpec.entries.at("PPD")), + tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), + tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")), + tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), + tRRD (tCK * memSpec.memTimingSpec.entries.at("RRD")), //tCCD (tCK * parseUint(memspec["memtimingspec"], "CCD")), - tRL (tCK * parseUint(memspec["memtimingspec"], "RL")), + tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), //tRPST (tCK * parseUint(memspec["memtimingspec"], "RPST")), //tDQSCK (tCK * parseUint(memspec["memtimingspec"], "DQSCK")), - tRBTP (tCK * parseUint(memspec["memtimingspec"], "RBTP")), - tWL (tCK * parseUint(memspec["memtimingspec"], "WL")), + tRBTP (tCK * memSpec.memTimingSpec.entries.at("RBTP")), + tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), //tDQSS (tCK * parseUint(memspec["memtimingspec"], "DQSS")), //tDQS2DQ (tCK * parseUint(memspec["memtimingspec"], "DQS2DQ")), - tWR (tCK * parseUint(memspec["memtimingspec"], "WR")), + tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), //tWPRE (tCK * parseUint(memspec["memtimingspec"], "WPRE")), //tWTR (tCK * parseUint(memspec["memtimingspec"], "WTR")), //tXP (tCK * parseUint(memspec["memtimingspec"] "XP")), @@ -86,20 +85,20 @@ MemSpecLPDDR5::MemSpecLPDDR5(json &memspec) //tESCKE (tCK * parseUint(memspec["memtimingspec"], "ESCKE")), //tCKE (tCK * parseUint(memspec["memtimingspec"], "CKE")), //tCMDCKE (tCK * parseUint(memspec["memtimingspec"], "CMDCKE")), - BL_n_min_16(tCK * parseUint(memspec["memtimingspec"], "BL_n_min_16")), - BL_n_max_16(tCK * parseUint(memspec["memtimingspec"], "BL_n_max_16")), - BL_n_L_16(tCK * parseUint(memspec["memtimingspec"], "BL_n_L_16")), - BL_n_S_16(tCK * parseUint(memspec["memtimingspec"], "BL_n_S_16")), - BL_n_min_32(tCK * parseUint(memspec["memtimingspec"], "BL_n_min_32")), - BL_n_max_32(tCK * parseUint(memspec["memtimingspec"], "BL_n_max_32")), - BL_n_L_32(tCK * parseUint(memspec["memtimingspec"], "BL_n_L_32")), - BL_n_S_32(tCK * parseUint(memspec["memtimingspec"], "BL_n_S_32")), - tWTR_L (tCK * parseUint(memspec["memtimingspec"], "WTR_L")), - tWTR_S (tCK * parseUint(memspec["memtimingspec"], "WTR_S")), - tWCK2DQO(tCK * parseUint(memspec["memtimingspec"], "WCK2DQO")), - tpbR2act(tCK * parseUint(memspec["memtimingspec"], "pbR2act")), - tpbR2pbR(tCK * parseUint(memspec["memtimingspec"], "pbR2pbR")), - tRTRS (tCK * parseUint(memspec["memtimingspec"], "RTRS")) + BL_n_min_16(tCK * memSpec.memTimingSpec.entries.at("BL_n_min_16")), + BL_n_max_16(tCK * memSpec.memTimingSpec.entries.at("BL_n_max_16")), + BL_n_L_16(tCK * memSpec.memTimingSpec.entries.at("BL_n_L_16")), + BL_n_S_16(tCK * memSpec.memTimingSpec.entries.at("BL_n_S_16")), + BL_n_min_32(tCK * memSpec.memTimingSpec.entries.at("BL_n_min_32")), + BL_n_max_32(tCK * memSpec.memTimingSpec.entries.at("BL_n_max_32")), + BL_n_L_32(tCK * memSpec.memTimingSpec.entries.at("BL_n_L_32")), + BL_n_S_32(tCK * memSpec.memTimingSpec.entries.at("BL_n_S_32")), + tWTR_L (tCK * memSpec.memTimingSpec.entries.at("WTR_L")), + tWTR_S (tCK * memSpec.memTimingSpec.entries.at("WTR_S")), + tWCK2DQO(tCK * memSpec.memTimingSpec.entries.at("WCK2DQO")), + tpbR2act(tCK * memSpec.memTimingSpec.entries.at("pbR2act")), + tpbR2pbR(tCK * memSpec.memTimingSpec.entries.at("pbR2pbR")), + tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")) { commandLengthInCycles[Command::ACT] = 2; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.h index 48fc7b2c..1635b384 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.h @@ -43,7 +43,7 @@ class MemSpecLPDDR5 final : public MemSpec { public: - explicit MemSpecLPDDR5(nlohmann::json &memspec); + explicit MemSpecLPDDR5(const DRAMSysConfiguration::MemSpec &memSpec); // Memspec Variables: const sc_core::sc_time tREFI; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp index 198f5de7..08c82005 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include @@ -40,43 +41,42 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpecSTTMRAM::MemSpecSTTMRAM(json &memspec) - : MemSpec(memspec, MemoryType::STTMRAM, - parseUint(memspec["memarchitecturespec"],"nbrOfChannels"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), +MemSpecSTTMRAM::MemSpecSTTMRAM(const DRAMSysConfiguration::MemSpec &memSpec) + : MemSpec(memSpec, MemoryType::STTMRAM, + memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), 1, - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfDevices")), - tCKE (tCK * parseUint(memspec["memtimingspec"], "CKE")), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), + tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")), tPD (tCKE), - tCKESR (tCK * parseUint(memspec["memtimingspec"], "CKESR")), - tDQSCK (tCK * parseUint(memspec["memtimingspec"], "DQSCK")), - tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), - tRC (tCK * parseUint(memspec["memtimingspec"], "RC")), - tRCD (tCK * parseUint(memspec["memtimingspec"], "RCD")), - tRL (tCK * parseUint(memspec["memtimingspec"], "RL")), - tRTP (tCK * parseUint(memspec["memtimingspec"], "RTP")), - tWL (tCK * parseUint(memspec["memtimingspec"], "WL")), - tWR (tCK * parseUint(memspec["memtimingspec"], "WR")), - tXP (tCK * parseUint(memspec["memtimingspec"], "XP")), - tXS (tCK * parseUint(memspec["memtimingspec"], "XS")), - tCCD (tCK * parseUint(memspec["memtimingspec"], "CCD")), - tFAW (tCK * parseUint(memspec["memtimingspec"], "FAW")), - tRP (tCK * parseUint(memspec["memtimingspec"], "RP")), - tRRD (tCK * parseUint(memspec["memtimingspec"], "RRD")), - tWTR (tCK * parseUint(memspec["memtimingspec"], "WTR")), - tAL (tCK * parseUint(memspec["memtimingspec"], "AL")), - tXPDLL (tCK * parseUint(memspec["memtimingspec"], "XPDLL")), - tXSDLL (tCK * parseUint(memspec["memtimingspec"], "XSDLL")), - tACTPDEN (tCK * parseUint(memspec["memtimingspec"], "ACTPDEN")), - tPRPDEN (tCK * parseUint(memspec["memtimingspec"], "PRPDEN")), - tRTRS (tCK * parseUint(memspec["memtimingspec"], "RTRS")) + tCKESR (tCK * memSpec.memTimingSpec.entries.at("CKESR")), + tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")), + tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), + tRC (tCK * memSpec.memTimingSpec.entries.at("RC")), + tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")), + tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), + tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")), + tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), + tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), + tXP (tCK * memSpec.memTimingSpec.entries.at("XP")), + tXS (tCK * memSpec.memTimingSpec.entries.at("XS")), + tCCD (tCK * memSpec.memTimingSpec.entries.at("CCD")), + tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), + tRP (tCK * memSpec.memTimingSpec.entries.at("RP")), + tRRD (tCK * memSpec.memTimingSpec.entries.at("RRD")), + tWTR (tCK * memSpec.memTimingSpec.entries.at("WTR")), + tAL (tCK * memSpec.memTimingSpec.entries.at("AL")), + tXPDLL (tCK * memSpec.memTimingSpec.entries.at("XPDLL")), + tXSDLL (tCK * memSpec.memTimingSpec.entries.at("XSDLL")), + tACTPDEN (tCK * memSpec.memTimingSpec.entries.at("ACTPDEN")), + tPRPDEN (tCK * memSpec.memTimingSpec.entries.at("PRPDEN")), + tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h index e30b22b2..33a91056 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #ifndef MEMSPECSTTMRAM_H @@ -38,12 +39,11 @@ #include #include "MemSpec.h" -#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" class MemSpecSTTMRAM final : public MemSpec { public: - explicit MemSpecSTTMRAM(nlohmann::json &memspec); + explicit MemSpecSTTMRAM(const DRAMSysConfiguration::MemSpec &memSpec); // Memspec Variables: const sc_core::sc_time tCKE; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp index e363d1a5..9b84c30f 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include @@ -40,69 +41,71 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpecWideIO::MemSpecWideIO(json &memspec) - : MemSpec(memspec, MemoryType::WideIO, - parseUint(memspec["memarchitecturespec"],"nbrOfChannels"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), +MemSpecWideIO::MemSpecWideIO(const DRAMSysConfiguration::MemSpec &memSpec) + : MemSpec(memSpec, MemoryType::WideIO, + memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), 1, - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfDevices")), - tCKE (tCK * parseUint(memspec["memtimingspec"], "CKE")), - tCKESR (tCK * parseUint(memspec["memtimingspec"], "CKESR")), - tDQSCK (tCK * parseUint(memspec["memtimingspec"], "DQSCK")), - tAC (tCK * parseUint(memspec["memtimingspec"], "AC")), - tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), - tRC (tCK * parseUint(memspec["memtimingspec"], "RC")), - tRCD (tCK * parseUint(memspec["memtimingspec"], "RCD")), - tRL (tCK * parseUint(memspec["memtimingspec"], "RL")), - tWL (tCK * parseUint(memspec["memtimingspec"], "WL")), - tWR (tCK * parseUint(memspec["memtimingspec"], "WR")), - tXP (tCK * parseUint(memspec["memtimingspec"], "XP")), - tXSR (tCK * parseUint(memspec["memtimingspec"], "XSR")), - tCCD_R (tCK * parseUint(memspec["memtimingspec"], "CCD_R")), - tCCD_W (tCK * parseUint(memspec["memtimingspec"], "CCD_W")), - tREFI (tCK * parseUint(memspec["memtimingspec"], "REFI")), - tRFC (tCK * parseUint(memspec["memtimingspec"], "RFC")), - tRP (tCK * parseUint(memspec["memtimingspec"], "RP")), - tRRD (tCK * parseUint(memspec["memtimingspec"], "RRD")), - tTAW (tCK * parseUint(memspec["memtimingspec"], "TAW")), - tWTR (tCK * parseUint(memspec["memtimingspec"], "WTR")), - tRTRS (tCK * parseUint(memspec["memtimingspec"], "RTRS")), - iDD0 (parseUdouble(memspec["mempowerspec"], "idd0")), - iDD2N (parseUdouble(memspec["mempowerspec"], "idd2n")), - iDD3N (parseUdouble(memspec["mempowerspec"], "idd3n")), - iDD4R (parseUdouble(memspec["mempowerspec"], "idd4r")), - iDD4W (parseUdouble(memspec["mempowerspec"], "idd4w")), - iDD5 (parseUdouble(memspec["mempowerspec"], "idd5")), - iDD6 (parseUdouble(memspec["mempowerspec"], "idd6")), - vDD (parseUdouble(memspec["mempowerspec"], "vdd")), - iDD02 (parseUdouble(memspec["mempowerspec"], "idd02")), - iDD2P0 (parseUdouble(memspec["mempowerspec"], "idd2p0")), - iDD2P02 (parseUdouble(memspec["mempowerspec"], "idd2p02")), - iDD2P1 (parseUdouble(memspec["mempowerspec"], "idd2p1")), - iDD2P12 (parseUdouble(memspec["mempowerspec"], "idd2p12")), - iDD2N2 (parseUdouble(memspec["mempowerspec"], "idd2n2")), - iDD3P0 (parseUdouble(memspec["mempowerspec"], "idd3p0")), - iDD3P02 (parseUdouble(memspec["mempowerspec"], "idd3p02")), - iDD3P1 (parseUdouble(memspec["mempowerspec"], "idd3p1")), - iDD3P12 (parseUdouble(memspec["mempowerspec"], "idd3p12")), - iDD3N2 (parseUdouble(memspec["mempowerspec"], "idd3n2")), - iDD4R2 (parseUdouble(memspec["mempowerspec"], "idd4r2")), - iDD4W2 (parseUdouble(memspec["mempowerspec"], "idd4w2")), - iDD52 (parseUdouble(memspec["mempowerspec"], "idd52")), - iDD62 (parseUdouble(memspec["mempowerspec"], "idd62")), - vDD2 (parseUdouble(memspec["mempowerspec"], "vdd2")) + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), + tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")), + tCKESR (tCK * memSpec.memTimingSpec.entries.at("CKESR")), + tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")), + tAC (tCK * memSpec.memTimingSpec.entries.at("AC")), + tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), + tRC (tCK * memSpec.memTimingSpec.entries.at("RC")), + tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")), + tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), + tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), + tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), + tXP (tCK * memSpec.memTimingSpec.entries.at("XP")), + tXSR (tCK * memSpec.memTimingSpec.entries.at("XSR")), + tCCD_R (tCK * memSpec.memTimingSpec.entries.at("CCD_R")), + tCCD_W (tCK * memSpec.memTimingSpec.entries.at("CCD_W")), + tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")), + tRFC (tCK * memSpec.memTimingSpec.entries.at("RFC")), + tRP (tCK * memSpec.memTimingSpec.entries.at("RP")), + tRRD (tCK * memSpec.memTimingSpec.entries.at("RRD")), + tTAW (tCK * memSpec.memTimingSpec.entries.at("TAW")), + tWTR (tCK * memSpec.memTimingSpec.entries.at("WTR")), + tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")), + iDD0 (memSpec.memPowerSpec.value().entries.at("idd0")), + iDD2N (memSpec.memPowerSpec.value().entries.at("idd2n")), + iDD3N (memSpec.memPowerSpec.value().entries.at("idd3n")), + iDD4R (memSpec.memPowerSpec.value().entries.at("idd4r")), + iDD4W (memSpec.memPowerSpec.value().entries.at("idd4w")), + iDD5 (memSpec.memPowerSpec.value().entries.at("idd5")), + iDD6 (memSpec.memPowerSpec.value().entries.at("idd6")), + vDD (memSpec.memPowerSpec.value().entries.at("vdd")), + iDD02 (memSpec.memPowerSpec.value().entries.at("idd02")), + iDD2P0 (memSpec.memPowerSpec.value().entries.at("idd2p0")), + iDD2P02 (memSpec.memPowerSpec.value().entries.at("idd2p02")), + iDD2P1 (memSpec.memPowerSpec.value().entries.at("idd2p1")), + iDD2P12 (memSpec.memPowerSpec.value().entries.at("idd2p12")), + iDD2N2 (memSpec.memPowerSpec.value().entries.at("idd2n2")), + iDD3P0 (memSpec.memPowerSpec.value().entries.at("idd3p0")), + iDD3P02 (memSpec.memPowerSpec.value().entries.at("idd3p02")), + iDD3P1 (memSpec.memPowerSpec.value().entries.at("idd3p1")), + iDD3P12 (memSpec.memPowerSpec.value().entries.at("idd3p12")), + iDD3N2 (memSpec.memPowerSpec.value().entries.at("idd3n2")), + iDD4R2 (memSpec.memPowerSpec.value().entries.at("idd4r2")), + iDD4W2 (memSpec.memPowerSpec.value().entries.at("idd4w2")), + iDD52 (memSpec.memPowerSpec.value().entries.at("idd52")), + iDD62 (memSpec.memPowerSpec.value().entries.at("idd62")), + vDD2 (memSpec.memPowerSpec.value().entries.at("vdd2")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; memorySizeBytes = deviceSizeBytes * numberOfRanks * numberOfChannels; + if (!memSpec.memPowerSpec.has_value()) + SC_REPORT_FATAL("MemSpec", "No power spec defined!"); + std::cout << headline << std::endl; std::cout << "Memory Configuration:" << std::endl << std::endl; std::cout << " Memory type: " << "Wide I/O" << std::endl; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h index 3b952621..ef300a2c 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #ifndef MEMSPECWIDEIO_H @@ -38,12 +39,11 @@ #include #include "MemSpec.h" -#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" class MemSpecWideIO final : public MemSpec { public: - explicit MemSpecWideIO(nlohmann::json &memspec); + explicit MemSpecWideIO(const DRAMSysConfiguration::MemSpec &memSpec); // Memspec Variables: const sc_core::sc_time tCKE; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp index 275529e4..31f5ef5f 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include @@ -40,46 +41,45 @@ using namespace sc_core; using namespace tlm; -using json = nlohmann::json; -MemSpecWideIO2::MemSpecWideIO2(json &memspec) - : MemSpec(memspec, MemoryType::WideIO2, - parseUint(memspec["memarchitecturespec"],"nbrOfChannels"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), +MemSpecWideIO2::MemSpecWideIO2(const DRAMSysConfiguration::MemSpec &memSpec) + : MemSpec(memSpec, MemoryType::WideIO2, + memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), 1, - parseUint(memspec["memarchitecturespec"],"nbrOfBanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfRanks"), - parseUint(memspec["memarchitecturespec"],"nbrOfDevices")), - tDQSCK (tCK * parseUint(memspec["memtimingspec"], "DQSCK")), - tDQSS (tCK * parseUint(memspec["memtimingspec"], "DQSS")), - tCKE (tCK * parseUint(memspec["memtimingspec"], "CKE")), - tRL (tCK * parseUint(memspec["memtimingspec"], "RL")), - tWL (tCK * parseUint(memspec["memtimingspec"], "WL")), - tRCpb (tCK * parseUint(memspec["memtimingspec"], "RCPB")), - tRCab (tCK * parseUint(memspec["memtimingspec"], "RCAB")), - tCKESR (tCK * parseUint(memspec["memtimingspec"], "CKESR")), - tXSR (tCK * parseUint(memspec["memtimingspec"], "XSR")), - tXP (tCK * parseUint(memspec["memtimingspec"], "XP")), - tCCD (tCK * parseUint(memspec["memtimingspec"], "CCD")), - tRTP (tCK * parseUint(memspec["memtimingspec"], "RTP")), - tRCD (tCK * parseUint(memspec["memtimingspec"], "RCD")), - tRPpb (tCK * parseUint(memspec["memtimingspec"], "RPPB")), - tRPab (tCK * parseUint(memspec["memtimingspec"], "RPAB")), - tRAS (tCK * parseUint(memspec["memtimingspec"], "RAS")), - tWR (tCK * parseUint(memspec["memtimingspec"], "WR")), - tWTR (tCK * parseUint(memspec["memtimingspec"], "WTR")), - tRRD (tCK * parseUint(memspec["memtimingspec"], "RRD")), - tFAW (tCK * parseUint(memspec["memtimingspec"], "FAW")), - tREFI (tCK * static_cast(parseUint(memspec["memtimingspec"], "REFI") - * parseUdouble(memspec["memtimingspec"], "REFM"))), - tREFIpb (tCK * static_cast(parseUint(memspec["memtimingspec"], "REFIPB") - * parseUdouble(memspec["memtimingspec"], "REFM"))), - tRFCab (tCK * parseUint(memspec["memtimingspec"], "RFCAB")), - tRFCpb (tCK * parseUint(memspec["memtimingspec"], "RFCPB")), - tRTRS (tCK * parseUint(memspec["memtimingspec"], "RTRS")) + memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfBanks") + * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), + memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), + tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")), + tDQSS (tCK * memSpec.memTimingSpec.entries.at("DQSS")), + tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")), + tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), + tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), + tRCpb (tCK * memSpec.memTimingSpec.entries.at("RCPB")), + tRCab (tCK * memSpec.memTimingSpec.entries.at("RCAB")), + tCKESR (tCK * memSpec.memTimingSpec.entries.at("CKESR")), + tXSR (tCK * memSpec.memTimingSpec.entries.at("XSR")), + tXP (tCK * memSpec.memTimingSpec.entries.at("XP")), + tCCD (tCK * memSpec.memTimingSpec.entries.at("CCD")), + tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")), + tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")), + tRPpb (tCK * memSpec.memTimingSpec.entries.at("RPPB")), + tRPab (tCK * memSpec.memTimingSpec.entries.at("RPAB")), + tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), + tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), + tWTR (tCK * memSpec.memTimingSpec.entries.at("WTR")), + tRRD (tCK * memSpec.memTimingSpec.entries.at("RRD")), + tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), + tREFI (tCK * static_cast(memSpec.memTimingSpec.entries.at("REFI") + * memSpec.memTimingSpec.entries.at("REFM"))), + tREFIpb (tCK * static_cast(memSpec.memTimingSpec.entries.at("REFIPB") + * memSpec.memTimingSpec.entries.at("REFM"))), + tRFCab (tCK * memSpec.memTimingSpec.entries.at("RFCAB")), + tRFCpb (tCK * memSpec.memTimingSpec.entries.at("RFCPB")), + tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h index e2fff51a..4746d792 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #ifndef MEMSPECWIDEIO2_H @@ -38,12 +39,11 @@ #include #include "MemSpec.h" -#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" class MemSpecWideIO2 final : public MemSpec { public: - explicit MemSpecWideIO2(nlohmann::json &memspec); + explicit MemSpecWideIO2(const DRAMSysConfiguration::MemSpec &memSpec); // Memspec Variables: const sc_core::sc_time tDQSCK; diff --git a/DRAMSys/library/src/simulation/AddressDecoder.cpp b/DRAMSys/library/src/simulation/AddressDecoder.cpp index d08ea36f..178fa6db 100644 --- a/DRAMSys/library/src/simulation/AddressDecoder.cpp +++ b/DRAMSys/library/src/simulation/AddressDecoder.cpp @@ -33,6 +33,7 @@ * Johannes Feldmann * Lukas Steiner * Luiza Correa + * Derek Christ */ #include @@ -44,87 +45,50 @@ #include "../common/utils.h" #include "../configuration/Configuration.h" -using json = nlohmann::json; - -unsigned int AddressDecoder::getUnsignedAttrFromJson(json &obj, const std::string &strName) +AddressDecoder::AddressDecoder(const DRAMSysConfiguration::AddressMapping &addressMapping) { - if (!obj[strName].empty()) + if (const auto &channelBits = addressMapping.channelBits) { - if (obj[strName].is_number_unsigned()) + std::copy(channelBits->begin(), channelBits->end(), std::back_inserter(vChannelBits)); + } + + if (const auto &rankBits = addressMapping.rankBits) + { + std::copy(rankBits->begin(), rankBits->end(), std::back_inserter(vRankBits)); + } + + if (const auto &bankGroupBits = addressMapping.bankGroupBits) + { + std::copy(bankGroupBits->begin(), bankGroupBits->end(), std::back_inserter(vBankGroupBits)); + } + + if (const auto &byteBits = addressMapping.byteBits) + { + std::copy(byteBits->begin(), byteBits->end(), std::back_inserter(vByteBits)); + } + + if (const auto &xorBits = addressMapping.xorBits) + { + for (const auto &xorBit : *xorBits) { - return obj[strName]; - } - else - { - SC_REPORT_FATAL("AddressDecoder", ("Attribute " + strName + " is not a number.").c_str()); - return static_cast(-1); + vXor.emplace_back(xorBit.first, xorBit.second); } } - else - { - SC_REPORT_FATAL("AddressDecoder", ("Attribute " + strName + " is empty or not found.").c_str()); - return static_cast(-1); - } -} -std::vector AddressDecoder::getAttrToVectorFromJson(json &obj, const std::string &strName) -{ - std::vector vParameter; - if (!obj[strName].empty()) + if (const auto &bankBits = addressMapping.bankBits) { - for (const auto& it : obj[strName].items()) - { - auto valor = it.value(); - if (valor.is_number_unsigned()) - vParameter.push_back(it.value()); - else - SC_REPORT_FATAL("AddressDecoder", ("Attribute " + strName + " is not a number.").c_str()); - } - } - return vParameter; -} - -AddressDecoder::AddressDecoder(const std::string &pathToAddressMapping) -{ - json addrFile = parseJSON(pathToAddressMapping); - json mapping; - if (addrFile["CONGEN"].empty()) - SC_REPORT_FATAL("AddressDecorder", "Root node name differs from \"CONGEN\". File format not supported."); - - // Load address mapping - if (!addrFile["CONGEN"]["SOLUTION"].empty()) - { - bool foundID0 = false; - for (const auto& it : addrFile["CONGEN"]["SOLUTION"].items()) - { - if (getUnsignedAttrFromJson(it.value(), "ID") == 0) - { - foundID0 = true; - mapping = it.value(); - break; - } - } - if (!foundID0) - SC_REPORT_FATAL("AddressDecoder", "No mapping with ID 0 was found."); - } - else - mapping = addrFile["CONGEN"]; - - for (const auto& xorItem : mapping["XOR"].items()) - { - auto value = xorItem.value(); - if (!value.empty()) - vXor.emplace_back(getUnsignedAttrFromJson(value, "FIRST"), - getUnsignedAttrFromJson(value, "SECOND")); + std::copy(bankBits->begin(), bankBits->end(), std::back_inserter(vBankBits)); } - vChannelBits = getAttrToVectorFromJson(mapping,"CHANNEL_BIT"); - vRankBits = getAttrToVectorFromJson(mapping,"RANK_BIT"); - vBankGroupBits = getAttrToVectorFromJson(mapping,"BANKGROUP_BIT"); - vBankBits = getAttrToVectorFromJson(mapping,"BANK_BIT"); - vRowBits = getAttrToVectorFromJson(mapping,"ROW_BIT"); - vColumnBits = getAttrToVectorFromJson(mapping,"COLUMN_BIT"); - vByteBits = getAttrToVectorFromJson(mapping,"BYTE_BIT"); + if (const auto &rowBits = addressMapping.rowBits) + { + std::copy(rowBits->begin(), rowBits->end(), std::back_inserter(vRowBits)); + } + + if (const auto &columnBits = addressMapping.columnBits) + { + std::copy(columnBits->begin(), columnBits->end(), std::back_inserter(vColumnBits)); + } unsigned channels = std::lround(std::pow(2.0, vChannelBits.size())); unsigned ranks = std::lround(std::pow(2.0, vRankBits.size())); diff --git a/DRAMSys/library/src/simulation/AddressDecoder.h b/DRAMSys/library/src/simulation/AddressDecoder.h index 4a971469..12a77627 100644 --- a/DRAMSys/library/src/simulation/AddressDecoder.h +++ b/DRAMSys/library/src/simulation/AddressDecoder.h @@ -33,6 +33,7 @@ * Johannes Feldmann * Lukas Steiner * Luiza Correa + * Derek Christ */ #ifndef ADDRESSDECODER_H @@ -40,8 +41,7 @@ #include #include - -#include "../common/third_party/nlohmann/single_include/nlohmann/json.hpp" +#include struct DecodedAddress { @@ -67,14 +67,11 @@ struct DecodedAddress class AddressDecoder { public: - explicit AddressDecoder(const std::string &pathToAddressMapping); + explicit AddressDecoder(const DRAMSysConfiguration::AddressMapping &addressMapping); DecodedAddress decodeAddress(uint64_t addr); void print(); private: - static std::vector getAttrToVectorFromJson(nlohmann::json &obj, const std::string &strName); - static unsigned int getUnsignedAttrFromJson(nlohmann::json &obj, const std::string &strName); - unsigned banksPerGroup; unsigned bankgroupsPerRank; diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 9e973b37..00646789 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -34,16 +34,19 @@ * Matthias Jung * Eder F. Zulian * Lukas Steiner + * Derek Christ */ #include "Arbiter.h" #include "AddressDecoder.h" #include "../configuration/Configuration.h" +#include + using namespace sc_core; using namespace tlm; -Arbiter::Arbiter(const sc_module_name &name, const std::string &pathToAddressMapping) : +Arbiter::Arbiter(const sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping) : sc_module(name), payloadEventQueue(this, &Arbiter::peqCallback), tCK(Configuration::getInstance().memSpec->tCK), arbitrationDelayFw(Configuration::getInstance().arbitrationDelayFw), @@ -53,21 +56,21 @@ Arbiter::Arbiter(const sc_module_name &name, const std::string &pathToAddressMap tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw); tSocket.register_transport_dbg(this, &Arbiter::transport_dbg); - addressDecoder = new AddressDecoder(pathToAddressMapping); + addressDecoder = new AddressDecoder(addressMapping); addressDecoder->print(); bytesPerBeat = Configuration::getInstance().memSpec->dataBusWidth / 8; } -ArbiterSimple::ArbiterSimple(const sc_module_name &name, const std::string &pathToAddressMapping) : - Arbiter(name, pathToAddressMapping) {} +ArbiterSimple::ArbiterSimple(const sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping) : + Arbiter(name, addressMapping) {} -ArbiterFifo::ArbiterFifo(const sc_module_name &name, const std::string &pathToAddressMapping) : - Arbiter(name, pathToAddressMapping), +ArbiterFifo::ArbiterFifo(const sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping) : + Arbiter(name, addressMapping), maxActiveTransactions(Configuration::getInstance().maxActiveTransactions) {} -ArbiterReorder::ArbiterReorder(const sc_module_name &name, const std::string &pathToAddressMapping) : - Arbiter(name, pathToAddressMapping), +ArbiterReorder::ArbiterReorder(const sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping) : + Arbiter(name, addressMapping), maxActiveTransactions(Configuration::getInstance().maxActiveTransactions) {} Arbiter::~Arbiter() diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 99f07323..4ee8ceb3 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -34,6 +34,7 @@ * Matthias Jung * Eder F. Zulian * Lukas Steiner + * Derek Christ */ #ifndef ARBITER_H @@ -64,7 +65,7 @@ public: ~Arbiter() override; protected: - Arbiter(const sc_core::sc_module_name &name, const std::string &pathToAddressMapping); + Arbiter(const sc_core::sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping); SC_HAS_PROCESS(Arbiter); void end_of_elaboration() override; @@ -98,7 +99,7 @@ protected: class ArbiterSimple final : public Arbiter { public: - ArbiterSimple(const sc_core::sc_module_name &name, const std::string &pathToAddressMapping); + ArbiterSimple(const sc_core::sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping); SC_HAS_PROCESS(ArbiterSimple); private: @@ -111,7 +112,7 @@ private: class ArbiterFifo final : public Arbiter { public: - ArbiterFifo(const sc_core::sc_module_name &name, const std::string &pathToAddressMapping); + ArbiterFifo(const sc_core::sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping); SC_HAS_PROCESS(ArbiterFifo); private: @@ -131,7 +132,7 @@ private: class ArbiterReorder final : public Arbiter { public: - ArbiterReorder(const sc_core::sc_module_name &name, const std::string &pathToAddressMapping); + ArbiterReorder(const sc_core::sc_module_name &name, const DRAMSysConfiguration::AddressMapping &addressMapping); SC_HAS_PROCESS(ArbiterReorder); private: diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 21c9962e..c1fb3065 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -35,6 +35,7 @@ * Eder F. Zulian * Felipe S. Prado * Lukas Steiner + * Derek Christ */ #include @@ -43,7 +44,6 @@ #include #include "DRAMSys.h" -#include "../common/third_party/nlohmann/single_include/nlohmann/json.hpp" #include "../common/DebugManager.h" #include "../common/utils.h" #include "../simulation/TemperatureController.h" @@ -63,44 +63,25 @@ #include "../controller/Controller.h" DRAMSys::DRAMSys(const sc_core::sc_module_name &name, - const std::string &simulationToRun, - const std::string &pathToResources) - : DRAMSys(name, simulationToRun, pathToResources, true) + const DRAMSysConfiguration::Configuration &config) + : DRAMSys(name, config, true) {} DRAMSys::DRAMSys(const sc_core::sc_module_name &name, - const std::string &simulationToRun, - const std::string &pathToResources, + const DRAMSysConfiguration::Configuration &config, bool initAndBind) : sc_module(name), tSocket("DRAMSys_tSocket") { logo(); - // Read Configuration Setup: - nlohmann::json simulationdoc = parseJSON(simulationToRun); - - Configuration::getInstance().setPathToResources(pathToResources); - // Load config and initialize modules - Configuration::getInstance().loadMemSpec(Configuration::getInstance(), - pathToResources - + "configs/memspecs/" - + std::string(simulationdoc["simulation"]["memspec"])); + // Important: The memSpec needs to be the first configuration to be loaded! + Configuration::loadMemSpec(Configuration::getInstance(), config.memSpec); + Configuration::loadMCConfig(Configuration::getInstance(), config.mcConfig); + Configuration::loadSimConfig(Configuration::getInstance(), config.simConfig); - Configuration::loadMCConfig(Configuration::getInstance(), - pathToResources - + "configs/mcconfigs/" - + std::string(simulationdoc["simulation"]["mcconfig"])); - - Configuration::loadSimConfig(Configuration::getInstance(), - pathToResources - + "configs/simulator/" - + std::string(simulationdoc["simulation"]["simconfig"])); - - Configuration::loadTemperatureSimConfig(Configuration::getInstance(), - pathToResources - + "configs/thermalsim/" - + std::string(simulationdoc["simulation"]["thermalconfig"])); + if (const auto &thermalConfig = config.thermalConfig) + Configuration::loadTemperatureSimConfig(Configuration::getInstance(), *thermalConfig); // Setup the debug manager: setupDebugManager(Configuration::getInstance().simulationName); @@ -108,8 +89,7 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name &name, if (initAndBind) { // Instantiate all internal DRAMSys modules: - std::string amconfig = simulationdoc["simulation"]["addressmapping"]; - instantiateModules(pathToResources, amconfig); + instantiateModules(config.addressMapping); // Connect all internal DRAMSys modules: bindSockets(); report(headline); @@ -161,8 +141,7 @@ void DRAMSys::setupDebugManager(NDEBUG_UNUSED(const std::string &traceName)) #endif } -void DRAMSys::instantiateModules(const std::string &pathToResources, - const std::string &amconfig) +void DRAMSys::instantiateModules(const DRAMSysConfiguration::AddressMapping &addressMapping) { // The first call to getInstance() creates the Temperature Controller. // The same instance will be accessed by all other modules. @@ -171,11 +150,11 @@ void DRAMSys::instantiateModules(const std::string &pathToResources, // Create arbiter if (config.arbiter == Configuration::Arbiter::Simple) - arbiter = std::unique_ptr(new ArbiterSimple("arbiter", pathToResources + "configs/amconfigs/" + amconfig)); + arbiter = std::unique_ptr(new ArbiterSimple("arbiter", addressMapping)); else if (config.arbiter == Configuration::Arbiter::Fifo) - arbiter = std::unique_ptr(new ArbiterFifo("arbiter", pathToResources + "configs/amconfigs/" + amconfig)); + arbiter = std::unique_ptr(new ArbiterFifo("arbiter", addressMapping)); else if (config.arbiter == Configuration::Arbiter::Reorder) - arbiter = std::unique_ptr(new ArbiterReorder("arbiter", pathToResources + "configs/amconfigs/" + amconfig)); + arbiter = std::unique_ptr(new ArbiterReorder("arbiter", addressMapping)); // Create controllers and DRAMs MemSpec::MemoryType memoryType = config.memSpec->memoryType; diff --git a/DRAMSys/library/src/simulation/DRAMSys.h b/DRAMSys/library/src/simulation/DRAMSys.h index f7fbf4ae..9c31fc21 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.h +++ b/DRAMSys/library/src/simulation/DRAMSys.h @@ -35,25 +35,27 @@ * Eder F. Zulian * Felipe S. Prado * Lukas Steiner + * Derek Christ */ #ifndef DRAMSYS_H #define DRAMSYS_H -#include -#include -#include - -#include #include "dram/Dram.h" #include "Arbiter.h" #include "ReorderBuffer.h" -#include -#include #include "../common/tlm2_base_protocol_checker.h" #include "../error/eccbaseclass.h" #include "../controller/ControllerIF.h" +#include +#include +#include +#include +#include +#include +#include + class DRAMSys : public sc_core::sc_module { public: @@ -61,13 +63,11 @@ public: SC_HAS_PROCESS(DRAMSys); DRAMSys(const sc_core::sc_module_name &name, - const std::string &simulationToRun, - const std::string &pathToResources); + const DRAMSysConfiguration::Configuration &config); protected: DRAMSys(const sc_core::sc_module_name &name, - const std::string &simulationToRun, - const std::string &pathToResources, + const DRAMSysConfiguration::Configuration &config, bool initAndBind); void end_of_simulation() override; @@ -93,8 +93,7 @@ protected: private: static void logo(); - void instantiateModules(const std::string &pathToResources, - const std::string &amconfig); + void instantiateModules(const DRAMSysConfiguration::AddressMapping &addressMapping); static void setupDebugManager(const std::string &traceName); }; diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp index bc395f60..73a76bd8 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #include "DRAMSysRecordable.h" @@ -55,27 +56,22 @@ using namespace sc_core; DRAMSysRecordable::DRAMSysRecordable(const sc_module_name &name, - const std::string &simulationToRun, - const std::string &pathToResources) - : DRAMSys(name, simulationToRun, pathToResources, false) + const DRAMSysConfiguration::Configuration &configuration) + : DRAMSys(name, configuration, 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()) + if (!configuration.simulationId.empty()) { - std::string sid = simulationdoc["simulation"]["simulationid"]; + std::string sid = configuration.simulationId; traceName = sid + '_' + Configuration::getInstance().simulationName; } else traceName = Configuration::getInstance().simulationName; - std::string amconfig = simulationdoc["simulation"]["addressmapping"]; - instantiateModules(traceName, pathToResources, amconfig); + instantiateModules(traceName, configuration); bindSockets(); report(headline); } @@ -93,7 +89,7 @@ void DRAMSysRecordable::end_of_simulation() tlmRecorder.finalize(); } -void DRAMSysRecordable::setupTlmRecorders(const std::string &traceName) +void DRAMSysRecordable::setupTlmRecorders(const std::string &traceName, const DRAMSysConfiguration::Configuration &configuration) { // Create TLM Recorders, one per channel. for (std::size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) @@ -102,15 +98,14 @@ void DRAMSysRecordable::setupTlmRecorders(const std::string &traceName) std::string recorderName = "tlmRecorder" + std::to_string(i); tlmRecorders.emplace_back(recorderName, dbName); - tlmRecorders.back().recordMcConfig(Configuration::mcconfigUri); - tlmRecorders.back().recordMemspec(Configuration::memspecUri); + tlmRecorders.back().recordMcConfig(DRAMSysConfiguration::dump(configuration.mcConfig)); + tlmRecorders.back().recordMemspec(DRAMSysConfiguration::dump(configuration.memSpec)); tlmRecorders.back().recordTraceNames(Configuration::getInstance().simulationName); } } void DRAMSysRecordable::instantiateModules(const std::string &traceName, - const std::string &pathToResources, - const std::string &amconfig) + const DRAMSysConfiguration::Configuration &configuration) { // The first call to getInstance() creates the Temperature Controller. // The same instance will be accessed by all other modules. @@ -120,15 +115,15 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, // Create and properly initialize TLM recorders. // They need to be ready before creating some modules. - setupTlmRecorders(traceName); + setupTlmRecorders(traceName, configuration); // Create arbiter if (config.arbiter == Configuration::Arbiter::Simple) - arbiter = std::unique_ptr(new ArbiterSimple("arbiter", pathToResources + "configs/amconfigs/" + amconfig)); + arbiter = std::unique_ptr(new ArbiterSimple("arbiter", configuration.addressMapping)); else if (config.arbiter == Configuration::Arbiter::Fifo) - arbiter = std::unique_ptr(new ArbiterFifo("arbiter", pathToResources + "configs/amconfigs/" + amconfig)); + arbiter = std::unique_ptr(new ArbiterFifo("arbiter", configuration.addressMapping)); else if (config.arbiter == Configuration::Arbiter::Reorder) - arbiter = std::unique_ptr(new ArbiterReorder("arbiter", pathToResources + "configs/amconfigs/" + amconfig)); + arbiter = std::unique_ptr(new ArbiterReorder("arbiter", configuration.addressMapping)); // Create controllers and DRAMs MemSpec::MemoryType memoryType = config.memSpec->memoryType; diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.h b/DRAMSys/library/src/simulation/DRAMSysRecordable.h index cf4da80b..3a909082 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.h +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.h @@ -31,6 +31,7 @@ * * Authors: * Lukas Steiner + * Derek Christ */ #ifndef DRAMSYSRECORDABLE_H @@ -39,12 +40,13 @@ #include "DRAMSys.h" #include "../common/TlmRecorder.h" +#include + class DRAMSysRecordable : public DRAMSys { public: DRAMSysRecordable(const sc_core::sc_module_name &name, - const std::string &simulationToRun, - const std::string &pathToResources); + const DRAMSysConfiguration::Configuration &configuration); protected: void end_of_simulation() override; @@ -54,11 +56,11 @@ private: // They generate the output databases. std::vector tlmRecorders; - void setupTlmRecorders(const std::string &traceName); + void setupTlmRecorders(const std::string &traceName, const DRAMSysConfiguration::Configuration &configuration); void instantiateModules(const std::string &traceName, - const std::string &pathToResources, - const std::string &amconfig); + const DRAMSysConfiguration::Configuration &configuration); + }; #endif // DRAMSYSRECORDABLE_H diff --git a/DRAMSys/library/src/simulation/TemperatureController.cpp b/DRAMSys/library/src/simulation/TemperatureController.cpp index 3aa92634..77ef5d1e 100644 --- a/DRAMSys/library/src/simulation/TemperatureController.cpp +++ b/DRAMSys/library/src/simulation/TemperatureController.cpp @@ -32,6 +32,7 @@ * Authors: * Eder F. Zulian * Matthias Jung + * Derek Christ */ #include @@ -43,9 +44,9 @@ using namespace sc_core; double TemperatureController::temperatureConvert(double tKelvin) { - if (temperatureScale == "Celsius") { + if (temperatureScale == TemperatureSimConfig::TemperatureScale::Celsius) { return tKelvin - 273.15; - } else if (temperatureScale == "Fahrenheit") { + } else if (temperatureScale == TemperatureSimConfig::TemperatureScale::Fahrenheit) { return (tKelvin - 273.15) * 1.8 + 32; } @@ -148,7 +149,7 @@ double TemperatureController::adjustThermalSimPeriod() cyclesSinceLastPeriodAdjust++; if (cyclesSinceLastPeriodAdjust >= nPowStableCyclesToIncreasePeriod) { cyclesSinceLastPeriodAdjust = 0; - period = period * (periodAdjustFactor / 2); + period = period * ((double)periodAdjustFactor / 2); if (period > targetPeriod) period = targetPeriod; PRINTDEBUGMESSAGE(name(), "Thermal Simulation period increased to " diff --git a/DRAMSys/library/src/simulation/TemperatureController.h b/DRAMSys/library/src/simulation/TemperatureController.h index ac5e96e4..c2d49e03 100644 --- a/DRAMSys/library/src/simulation/TemperatureController.h +++ b/DRAMSys/library/src/simulation/TemperatureController.h @@ -32,6 +32,7 @@ * Authors: * Eder F. Zulian * Matthias Jung + * Derek Christ */ #ifndef TEMPERATURECONTROLLER_H @@ -115,7 +116,7 @@ public: double getTemperature(int deviceId, float currentPower); private: - std::string temperatureScale; + TemperatureSimConfig::TemperatureScale temperatureScale; double temperatureConvert(double tKelvin); double staticTemperature; diff --git a/DRAMSys/simulator/CMakeLists.txt b/DRAMSys/simulator/CMakeLists.txt index 43b59dd2..507d6a71 100644 --- a/DRAMSys/simulator/CMakeLists.txt +++ b/DRAMSys/simulator/CMakeLists.txt @@ -39,7 +39,7 @@ cmake_minimum_required(VERSION 3.10) project(DRAMSysSimulator) # Configuration: -set(CMAKE_CXX_STANDARD 11 CACHE STRING "C++ Version") +set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ Version") set(DCMAKE_SH="CMAKE_SH-NOTFOUND") find_package(Threads REQUIRED) diff --git a/DRAMSys/simulator/TraceSetup.cpp b/DRAMSys/simulator/TraceSetup.cpp index ab55f0cf..fd6d8e54 100644 --- a/DRAMSys/simulator/TraceSetup.cpp +++ b/DRAMSys/simulator/TraceSetup.cpp @@ -35,193 +35,141 @@ * Derek Christ */ -#include #include "TraceSetup.h" #include "StlPlayer.h" #include "TrafficGenerator.h" +#include +#include +#include using namespace sc_core; using namespace tlm; -TraceSetup::TraceSetup(const std::string &uri, - const std::string &pathToResources, +TraceSetup::TraceSetup(const DRAMSysConfiguration::TraceSetup &traceSetup, const std::string &pathToResources, std::vector> &players) { - // Load Simulation: - nlohmann::json simulationdoc = parseJSON(uri); + if (traceSetup.initiators.empty()) + SC_REPORT_FATAL("TraceSetup", "No traffic initiators specified"); - if (simulationdoc["simulation"].empty()) - SC_REPORT_FATAL("TraceSetup", - "Cannot load simulation: simulation node expected"); - - // Load TrafficInitiators: - if (simulationdoc["simulation"]["tracesetup"].empty()) - SC_REPORT_FATAL("TraceSetup", "tracesetup is empty"); - for (auto &it : simulationdoc["simulation"]["tracesetup"].items()) + for (const auto &initiator : traceSetup.initiators) { - nlohmann::json value = it.value(); - if (!value.empty()) + std::visit( + [&](auto &&initiator) + { + std::string name = initiator.name; + double frequencyMHz = initiator.clkMhz; + sc_time playerClk = sc_time(1.0 / frequencyMHz, SC_US); + + unsigned int maxPendingReadRequests = [=]() -> unsigned int + { + if (const auto &maxPendingReadRequests = initiator.maxPendingReadRequests) + return *maxPendingReadRequests; + else + return 0; + }(); + + unsigned int maxPendingWriteRequests = [=]() -> unsigned int + { + if (const auto &maxPendingWriteRequests = initiator.maxPendingWriteRequests) + return *maxPendingWriteRequests; + else + return 0; + }(); + + bool addLengthConverter = [=]() -> bool + { + if (const auto &addLengthConverter = initiator.addLengthConverter) + return *addLengthConverter; + else + return false; + }(); + + using T = std::decay_t; + if constexpr (std::is_same_v) + { + size_t pos = name.rfind('.'); + if (pos == std::string::npos) + throw std::runtime_error("Name of the trace file does not contain a valid extension."); + + // Get the extension and make it lower case + std::string ext = name.substr(pos + 1); + std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); + + std::stringstream stlFileStream; + stlFileStream << pathToResources << "/traces/" << name; + std::string stlFile = stlFileStream.str(); + std::string moduleName = name; + + // replace all '.' to '_' + std::replace(moduleName.begin(), moduleName.end(), '.', '_'); + + StlPlayer *player; + if (ext == "stl") + player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, maxPendingReadRequests, + maxPendingWriteRequests, addLengthConverter, this, false); + else if (ext == "rstl") + player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, maxPendingReadRequests, + maxPendingWriteRequests, addLengthConverter, this, true); + else + throw std::runtime_error("Unsupported file extension in " + name); + + players.push_back(std::unique_ptr(player)); + totalTransactions += player->getNumberOfLines(); + } + else if constexpr (std::is_same_v) + { + TrafficGenerator *trafficGenerator = new TrafficGenerator(name.c_str(), initiator, this); + players.push_back(std::unique_ptr(trafficGenerator)); + + totalTransactions += trafficGenerator->getTotalTransactions(); + } + else // if constexpr (std::is_same_v) + { + uint64_t numRequests = initiator.numRequests; + uint64_t rowIncrement = initiator.rowIncrement; + + players.push_back( + std::unique_ptr(new TrafficGeneratorHammer(name.c_str(), initiator, this))); + totalTransactions += numRequests; + } + }, + initiator); + } + + for (const auto &inititatorConf : traceSetup.initiators) + { + if (auto generatorConf = std::get_if(&inititatorConf)) { - sc_time playerClk; - if (!value["clkMhz"].is_number() || value["clkMhz"] <= 0) - SC_REPORT_FATAL("TraceSetup", "Frequency is not a positive number."); - - double frequencyMHz = value["clkMhz"]; - playerClk = sc_time(1.0 / frequencyMHz, SC_US); - - if (!value["name"].is_string()) - SC_REPORT_FATAL("TraceSetup", "No trace name defined."); - - std::string name = value["name"]; - - unsigned int maxPendingReadRequests = 0; - unsigned int maxPendingWriteRequests = 0; - - if (value["maxPendingReadRequests"].is_number_unsigned()) - maxPendingReadRequests = value["maxPendingReadRequests"]; - - if (value["maxPendingWriteRequests"].is_number_unsigned()) - maxPendingWriteRequests = value["maxPendingWriteRequests"]; - - bool addLengthConverter = false; - if (value["addLengthConverter"].is_boolean()) - addLengthConverter = value["addLengthConverter"]; - - std::string type; - - // Defaulting to type "player" when not specified - if (!value["type"].is_string()) - type = "player"; - else - type = value["type"]; - - if (type == "player") + if (const auto &idleUntil = generatorConf->idleUntil) { - size_t pos = name.rfind('.'); - if (pos == std::string::npos) - throw std::runtime_error("Name of the trace file does not contain a valid extension."); + const std::string name = generatorConf->name; + auto listenerIt = std::find_if(players.begin(), players.end(), + [&name](const std::unique_ptr &initiator) + { return initiator->name() == name; }); - // Get the extension and make it lower case - std::string ext = name.substr(pos + 1); - std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); + // Should be found + auto listener = dynamic_cast(listenerIt->get()); - std::stringstream stlFileStream; - stlFileStream << pathToResources << "traces/" << name; - std::string stlFile = stlFileStream.str(); - std::string moduleName = name; + auto notifierIt = + std::find_if(players.begin(), players.end(), + [&idleUntil](const std::unique_ptr &initiator) + { + if (auto generator = dynamic_cast(initiator.get())) + { + if (generator->hasStateTransitionEvent(*idleUntil)) + return true; + } - // replace all '.' to '_' - std::replace(moduleName.begin(), moduleName.end(), '.', '_'); + return false; + }); - StlPlayer *player; - if (ext == "stl") - player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, - maxPendingReadRequests, maxPendingWriteRequests, - addLengthConverter, this, false); - else if (ext == "rstl") - player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, - maxPendingReadRequests, maxPendingWriteRequests, - addLengthConverter, this, true); - else - throw std::runtime_error("Unsupported file extension in " + name); + if (notifierIt == players.end()) + SC_REPORT_FATAL("TraceSetup", "Event to listen on not found."); - totalTransactions += player->getNumberOfLines(); - players.push_back(std::unique_ptr(player)); - } - else if (type == "generator") - { - if (!value["numRequests"].is_number_unsigned()) - SC_REPORT_FATAL("TraceSetup", "Number of requests is not a number."); - - uint64_t numRequests = value["numRequests"]; - - if (!value["rwRatio"].is_number() || value["rwRatio"] < 0 || value["rwRatio"] > 1) - SC_REPORT_FATAL("TraceSetup", "Read/Write ratio is not a number between 0 and 1."); - - float rwRatio = value["rwRatio"]; - - if (!value["addressDistribution"].is_string()) - SC_REPORT_FATAL("TraceSetup", "Address distribution not defined."); - - std::string addressDistribution = value["addressDistribution"]; - if (addressDistribution != "sequential" && addressDistribution != "random") - SC_REPORT_FATAL("TraceSetup", "Address distribution must either be sequential or random."); - - unsigned int seed = 0; - if (!value["seed"].empty()) - { - if (value["seed"].is_number_unsigned()) - seed = value["seed"]; - else - SC_REPORT_FATAL("TraceSetup", "Seed is not an unsigned number."); - } - - uint64_t minAddress = 0; - if (!value["minAddress"].empty()) - { - if (value["minAddress"].is_number_unsigned()) - { - minAddress = value["minAddress"]; - if (minAddress > Configuration::getInstance().memSpec->getSimMemSizeInBytes() - 1) - SC_REPORT_FATAL("TraceSetup", "minAddress is out of range."); - } - else - SC_REPORT_FATAL("TraceSetup", "minAddress is not an unsigned number."); - } - - uint64_t maxAddress = Configuration::getInstance().memSpec->getSimMemSizeInBytes() - 1; - if (!value["maxAddress"].empty()) - { - if (value["maxAddress"].is_number_unsigned()) - { - maxAddress = value["maxAddress"]; - if (maxAddress > Configuration::getInstance().memSpec->getSimMemSizeInBytes() - 1) - SC_REPORT_FATAL("TraceSetup", "maxAddress is out of range."); - } - else - SC_REPORT_FATAL("TraceSetup", "maxAddress is not an unsigned number."); - } - - if (maxAddress < minAddress) - SC_REPORT_FATAL("TraceSetup", "maxAddress is smaller than minAddress."); - - if (addressDistribution == "sequential") - { - uint64_t addressIncrement = 0x0; - if (!value["addressIncrement"].is_number_unsigned()) - SC_REPORT_FATAL("TraceSetup", "Address increment is not an unsigned number."); - else - addressIncrement = value["addressIncrement"]; - - players.push_back(std::unique_ptr(new TrafficGeneratorSequential(name.c_str(), - playerClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests, addLengthConverter, - minAddress, maxAddress, rwRatio, addressIncrement, seed, this))); - } - else - { - players.push_back(std::unique_ptr(new TrafficGeneratorRandom(name.c_str(), - playerClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests, addLengthConverter, - minAddress, maxAddress, rwRatio, seed, this))); - } - - totalTransactions += numRequests; - } - else if (type == "hammer") - { - if (!value["numRequests"].is_number_unsigned()) - SC_REPORT_FATAL("TraceSetup", "Number of requests is not a number."); - uint64_t numRequests = value["numRequests"]; - - if (!value["rowIncrement"].is_number_unsigned()) - SC_REPORT_FATAL("TraceSetup", "Row increment is not a number."); - uint64_t rowIncrement = value["rowIncrement"]; - - players.push_back(std::unique_ptr(new TrafficGeneratorHammer(name.c_str(), playerClk, - numRequests, rowIncrement, this))); + auto notifier = dynamic_cast(notifierIt->get()); + listener->waitUntil(¬ifier->getStateTransitionEvent(*idleUntil)); } } - else - SC_REPORT_FATAL("TraceSetup", "Empty trace setup item."); } remainingTransactions = totalTransactions; @@ -262,7 +210,7 @@ void TraceSetup::loadBar(uint64_t x, uint64_t n, unsigned int w, unsigned int gr if ((n < 100) || ((x != n) && (x % (n / 100 * granularity) != 0))) return; - float ratio = x / (float) n; + float ratio = x / (float)n; unsigned int c = (ratio * w); float rest = (ratio * w) - c; std::cout << std::setw(3) << round(ratio * 100) << "% |"; diff --git a/DRAMSys/simulator/TraceSetup.h b/DRAMSys/simulator/TraceSetup.h index 064bfd13..6dd60e91 100644 --- a/DRAMSys/simulator/TraceSetup.h +++ b/DRAMSys/simulator/TraceSetup.h @@ -37,11 +37,12 @@ #ifndef TRACESETUP_H #define TRACESETUP_H +#include #include #include #include - #include + #include "MemoryManager.h" class TrafficInitiator; @@ -49,7 +50,7 @@ class TrafficInitiator; class TraceSetup { public: - TraceSetup(const std::string &uri, + TraceSetup(const DRAMSysConfiguration::TraceSetup &traceSetup, const std::string &pathToResources, std::vector> &devices); diff --git a/DRAMSys/simulator/TrafficGenerator.cpp b/DRAMSys/simulator/TrafficGenerator.cpp index 959ad86d..33e90032 100644 --- a/DRAMSys/simulator/TrafficGenerator.cpp +++ b/DRAMSys/simulator/TrafficGenerator.cpp @@ -37,51 +37,39 @@ */ #include "TrafficGenerator.h" +#include "TraceSetup.h" + +#include using namespace sc_core; using namespace tlm; -TrafficGenerator::TrafficGenerator(const sc_module_name &name, - const sc_time &generatorClk, - uint64_t numRequests, - unsigned int maxPendingReadRequests, - unsigned int maxPendingWriteRequests, - bool addLengthConverter, - float rwRatio, - unsigned int seed, - TraceSetup *setup) : - TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests, addLengthConverter), - generatorClk(generatorClk), numRequests(numRequests), rwRatio(rwRatio), - randomGenerator(std::default_random_engine(seed)) -{} - -void TrafficGenerator::sendNextPayload() +TrafficGeneratorIf::TrafficGeneratorIf(const sc_core::sc_module_name &name, TraceSetup *setup, + unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, bool addLengthConverter) + : TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests, addLengthConverter) { - if (transactionsSent >= numRequests) - { - finished = true; - return; - } +} - tlm_generic_payload *payload = setup->allocatePayload(); - payload->acquire(); +void TrafficGeneratorIf::sendNextPayload() +{ + prepareNextPayload(); + + if (finished) + return; // TODO: column / burst breite uint64_t address = getNextAddress(); - tlm_command command; - if (randomRwDistribution(randomGenerator) < rwRatio) - { - command = tlm::TLM_READ_COMMAND; - pendingReadRequests++; - } - else - { - command = tlm::TLM_WRITE_COMMAND; - pendingWriteRequests++; - } + tlm_command command = getNextCommand(); + if (command == tlm::TLM_READ_COMMAND) + pendingReadRequests++; + else if (command == tlm::TLM_WRITE_COMMAND) + pendingWriteRequests++; + + tlm_generic_payload *payload = setup->allocatePayload(); + payload->acquire(); payload->set_address(address); payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); payload->set_dmi_allowed(false); @@ -89,79 +77,319 @@ void TrafficGenerator::sendNextPayload() payload->set_data_length(defaultDataLength); payload->set_command(command); + sc_time generatorClk = getGeneratorClk(); sc_time sendingOffset; if (transactionsSent == 0) - sendingOffset = SC_ZERO_TIME; + sendingOffset = SC_ZERO_TIME + generatorClk * clksToIdle(); else - sendingOffset = generatorClk - (sc_time_stamp() % generatorClk); + sendingOffset = (generatorClk * clksPerRequest()) - (sc_time_stamp() % generatorClk) + generatorClk * clksToIdle(); // TODO: do not send two requests in the same cycle sendToTarget(*payload, tlm::BEGIN_REQ, sendingOffset); transactionsSent++; PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent)); + payloadSent(); } -TrafficGeneratorRandom::TrafficGeneratorRandom(const sc_core::sc_module_name &name, - const sc_core::sc_time &generatorClk, - uint64_t numRequests, - unsigned int maxPendingReadRequests, - unsigned int maxPendingWriteRequests, - bool addLengthConverter, - uint64_t minAddress, - uint64_t maxAddress, - float rwRatio, - unsigned int seed, - TraceSetup *setup) : - TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests, - addLengthConverter, rwRatio, seed, setup) +TrafficGenerator::TrafficGenerator(const sc_module_name &name, const DRAMSysConfiguration::TraceGenerator &conf, + TraceSetup *setup) + : TrafficGeneratorIf(name, setup, conf.maxPendingReadRequests.value_or(defaultMaxPendingReadRequests), + conf.maxPendingWriteRequests.value_or(defaultMaxPendingWriteRequests), + conf.addLengthConverter.value_or(false)), + generatorClk(TrafficInitiator::evaluateGeneratorClk(conf)), conf(conf), + maxTransactions(conf.maxTransactions.value_or(std::numeric_limits::max())), + randomGenerator(std::default_random_engine(conf.seed.value_or(defaultSeed))) { - randomAddressDistribution = std::uniform_int_distribution (minAddress, maxAddress); + // Perform checks for all states + for (const auto &state : conf.states) + { + if (auto trafficState = std::get_if(&state.second)) + { + uint64_t minAddress = evaluateMinAddress(*trafficState); + uint64_t maxAddress = evaluateMaxAddress(*trafficState); + double rwRatio = (*trafficState).rwRatio; + + if (minAddress > Configuration::getInstance().memSpec->getSimMemSizeInBytes() - 1) + SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); + + if (maxAddress > Configuration::getInstance().memSpec->getSimMemSizeInBytes() - 1) + SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); + + if (maxAddress < minAddress) + SC_REPORT_FATAL("TrafficGenerator", "maxAddress is smaller than minAddress."); + + if (rwRatio < 0 || rwRatio > 1) + SC_REPORT_FATAL("TraceSetup", "Read/Write ratio is not a number between 0 and 1."); + + if (const auto &eventName = trafficState->notify) + { + stateTranstitionEvents.emplace(std::piecewise_construct, std::forward_as_tuple(*eventName), + std::forward_as_tuple(eventName->c_str(), state.first)); + } + } + } + + if (auto trafficState = + std::get_if(&conf.states.at(currentState))) + { + uint64_t minAddress = evaluateMinAddress(*trafficState); + uint64_t maxAddress = evaluateMaxAddress(*trafficState); + randomAddressDistribution = std::uniform_int_distribution(minAddress, maxAddress); + currentClksPerRequest = trafficState->clksPerRequest.value_or(defaultClksPerRequest); + } + + calculateTransitions(); } -uint64_t TrafficGeneratorRandom::getNextAddress() +void TrafficGenerator::calculateTransitions() { - return randomAddressDistribution(randomGenerator); + unsigned int state = 0; + uint64_t totalTransactions = 0; + stateSequence.push_back(state); + + while (true) + { + auto transitionsIt = conf.transitions.equal_range(state); + float propabilityAccumulated = 0.0f; + std::map> transitionsDistribution; + + for (auto it = transitionsIt.first; it != transitionsIt.second; ++it) + { + float lowerLimit = propabilityAccumulated; + propabilityAccumulated += it->second.propability; + float upperLimit = propabilityAccumulated; + transitionsDistribution[it->second.to] = {lowerLimit, upperLimit}; + } + + if (propabilityAccumulated > 1.001f) + SC_REPORT_WARNING("TrafficGenerator", "Sum of transition propabilities greater than 1."); + + float random = randomDistribution(randomGenerator); + bool transitionFound = false; + + for (const auto &transition : transitionsDistribution) + { + auto to = transition.first; + auto limits = transition.second; + + if (limits.first < random && limits.second > random) + { + state = to; + stateSequence.push_back(state); + transitionFound = true; + break; + } + } + + if (transitionFound) + { + if (auto trafficState = + std::get_if(&conf.states.at(state))) + totalTransactions += trafficState->numRequests; + + if (totalTransactions < maxTransactions) + continue; + } + + break; + } + + stateIt = stateSequence.cbegin(); } -TrafficGeneratorSequential::TrafficGeneratorSequential(const sc_core::sc_module_name &name, - const sc_core::sc_time &generatorClk, - uint64_t numRequests, - unsigned int maxPendingReadRequests, - unsigned int maxPendingWriteRequests, - bool addLengthConverter, - uint64_t minAddress, - uint64_t maxAddress, - float rwRatio, - uint64_t addressIncrement, - unsigned int seed, - TraceSetup *setup) : - TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests, - addLengthConverter, rwRatio, seed, setup), - minAddress(minAddress), maxAddress(maxAddress), addressIncrement(addressIncrement), - currentAddress(minAddress) +bool TrafficGenerator::hasStateTransitionEvent(const std::string &eventName) const { + auto it = stateTranstitionEvents.find(eventName); + + if (it == stateTranstitionEvents.end()) + return false; + + return true; } -uint64_t TrafficGeneratorSequential::getNextAddress() +const sc_core::sc_event &TrafficGenerator::getStateTransitionEvent(const std::string &eventName) const { - uint64_t address = currentAddress; - currentAddress += addressIncrement; - if (currentAddress > maxAddress) - currentAddress = minAddress; - return address; + auto it = stateTranstitionEvents.find(eventName); + + if (it == stateTranstitionEvents.end()) + SC_REPORT_FATAL("TraceSetup", "StateTransitionEvent not found."); + + return it->second.event; } +uint64_t TrafficGenerator::getTotalTransactions() const +{ + uint64_t totalTransactions = 0; + + for (auto state : stateSequence) + { + if (auto trafficState = std::get_if(&conf.states.at(state))) + totalTransactions += trafficState->numRequests; + } + + if (totalTransactions > maxTransactions) + totalTransactions = maxTransactions; + + return totalTransactions; +} + +void TrafficGenerator::waitUntil(const sc_core::sc_event *ev) +{ + startEvent = ev; +} + +void TrafficGenerator::transitionToNextState() +{ + ++stateIt; + + if (stateIt == stateSequence.cend() || transactionsSent >= maxTransactions) + { + // No transition performed. + finished = true; + return; + } + + currentState = *stateIt; + + // Notify + for (auto &it : stateTranstitionEvents) + { + if (it.second.stateId == currentState) + it.second.event.notify(); + } + + if (auto idleState = std::get_if(&conf.states.at(currentState))) + { + currentClksToIdle += idleState->idleClks; + transitionToNextState(); + return; + } + else if (auto trafficState = + std::get_if(&conf.states.at(currentState))) + { + uint64_t minAddress = evaluateMinAddress(*trafficState); + uint64_t maxAddress = evaluateMaxAddress(*trafficState); + randomAddressDistribution = std::uniform_int_distribution(minAddress, maxAddress); + currentClksPerRequest = trafficState->clksPerRequest.value_or(defaultClksPerRequest); + } + + currentAddress = 0x00; + transactionsSentInCurrentState = 0; +} + +void TrafficGenerator::prepareNextPayload() +{ + if (transactionsSent >= maxTransactions) + { + finished = true; + return; + } + + if (startEvent && transactionsSent == 0) + wait(*startEvent); + + if (auto trafficState = + std::get_if(&conf.states.at(currentState))) + { + if (transactionsSentInCurrentState >= trafficState->numRequests) + transitionToNextState(); + } + + // In case we are in an idle state right at the beginning of the simulation, + // set the clksToIdle and transition to the next state. + if (auto idleState = + std::get_if(&conf.states.at(currentState))) + { + currentClksToIdle = idleState->idleClks; + transitionToNextState(); + } +} + +void TrafficGenerator::payloadSent() +{ + // Reset clks to idle. + currentClksToIdle = 0; + + transactionsSentInCurrentState++; +} + +tlm::tlm_command TrafficGenerator::getNextCommand() +{ + // An idle state should never reach this method. + auto &state = std::get(conf.states.at(currentState)); + + tlm_command command; + if (randomDistribution(randomGenerator) < state.rwRatio) + command = tlm::TLM_READ_COMMAND; + else + command = tlm::TLM_WRITE_COMMAND; + + return command; +} + +sc_core::sc_time TrafficGenerator::getGeneratorClk() const +{ + return generatorClk; +} + +uint64_t TrafficGenerator::getNextAddress() +{ + using DRAMSysConfiguration::AddressDistribution; + + // An idle state should never reach this method. + auto &state = std::get(conf.states.at(currentState)); + + uint64_t minAddress = evaluateMinAddress(state); + uint64_t maxAddress = evaluateMaxAddress(state); + + if (state.addressDistribution == AddressDistribution::Sequential) + { + uint64_t addressIncrement = state.addressIncrement.value_or(defaultAddressIncrement); + + uint64_t address = currentAddress; + currentAddress += addressIncrement; + if (currentAddress > maxAddress) + currentAddress = minAddress; + return address; + } + else if (state.addressDistribution == AddressDistribution::Random) + { + return randomAddressDistribution(randomGenerator); + } + else + { + return 0x00; + } +} + +uint64_t TrafficGenerator::evaluateMinAddress(const DRAMSysConfiguration::TraceGeneratorTrafficState &state) +{ + return state.minAddress.value_or(0x00); +} + +uint64_t TrafficGenerator::evaluateMaxAddress(const DRAMSysConfiguration::TraceGeneratorTrafficState &state) +{ + return state.maxAddress.value_or(Configuration::getInstance().memSpec->getSimMemSizeInBytes() - 1); +} TrafficGeneratorHammer::TrafficGeneratorHammer(const sc_core::sc_module_name &name, - const sc_core::sc_time &generatorClk, - uint64_t numRequests, - uint64_t rowIncrement, - TraceSetup *setup) : - TrafficGenerator(name, generatorClk, numRequests, 1, 1, false, 1.0f, 1, setup), rowIncrement(rowIncrement) + const DRAMSysConfiguration::TraceHammer &conf, TraceSetup *setup) + : TrafficGeneratorIf(name, setup, 1, 1, false), generatorClk(evaluateGeneratorClk(conf)), rowIncrement(conf.rowIncrement), + numRequests(conf.numRequests) { } +tlm::tlm_command TrafficGeneratorHammer::getNextCommand() +{ + return tlm::TLM_READ_COMMAND; +} + +sc_core::sc_time TrafficGeneratorHammer::getGeneratorClk() const +{ + return generatorClk; +} + uint64_t TrafficGeneratorHammer::getNextAddress() { if (currentAddress == 0x0) @@ -171,3 +399,9 @@ uint64_t TrafficGeneratorHammer::getNextAddress() return currentAddress; } + +void TrafficGeneratorHammer::prepareNextPayload() +{ + if (transactionsSent >= numRequests) + finished = true; +} diff --git a/DRAMSys/simulator/TrafficGenerator.h b/DRAMSys/simulator/TrafficGenerator.h index ceb254a2..e623dd48 100644 --- a/DRAMSys/simulator/TrafficGenerator.h +++ b/DRAMSys/simulator/TrafficGenerator.h @@ -39,98 +39,109 @@ #ifndef TRAFFICGENERATOR_H #define TRAFFICGENERATOR_H -#include - #include "TrafficInitiator.h" #include "TraceSetup.h" -class TrafficGenerator : public TrafficInitiator +#include +#include +#include + +class TrafficGeneratorIf : public TrafficInitiator { -protected: - TrafficGenerator(const sc_core::sc_module_name &name, - const sc_core::sc_time &generatorClk, - uint64_t numRequests, - unsigned int maxPendingReadRequests, - unsigned int maxPendingWriteRequests, - bool addLengthConverter, - float rwRatio, - unsigned int seed, +public: + TrafficGeneratorIf(const sc_core::sc_module_name &name, TraceSetup *setup, unsigned int maxPendingReadRequests, + unsigned int maxPendingWriteRequests, bool addLengthConverter); + +private: + void sendNextPayload() override; + virtual void prepareNextPayload(){}; + virtual uint64_t getNextAddress() = 0; + virtual tlm::tlm_command getNextCommand() = 0; + virtual sc_core::sc_time getGeneratorClk() const = 0; + virtual void payloadSent(){}; + virtual uint64_t clksPerRequest() const { return 1; } + virtual uint64_t clksToIdle() const { return 0; } +}; + +class TrafficGenerator : public TrafficGeneratorIf +{ +public: + TrafficGenerator(const sc_core::sc_module_name &name, const DRAMSysConfiguration::TraceGenerator &conf, TraceSetup *setup); - void sendNextPayload() override; - virtual uint64_t getNextAddress() = 0; + uint64_t getTotalTransactions() const; + void waitUntil(const sc_core::sc_event *ev); + bool hasStateTransitionEvent(const std::string &eventName) const; + const sc_core::sc_event &getStateTransitionEvent(const std::string &eventName) const; + +private: + static uint64_t evaluateMinAddress(const DRAMSysConfiguration::TraceGeneratorTrafficState &state); + static uint64_t evaluateMaxAddress(const DRAMSysConfiguration::TraceGeneratorTrafficState &state); + + void prepareNextPayload() override; + uint64_t getNextAddress() override; + tlm::tlm_command getNextCommand() override; + sc_core::sc_time getGeneratorClk() const override; + void payloadSent() override; + uint64_t clksPerRequest() const override { return currentClksPerRequest; }; + uint64_t clksToIdle() const override { return currentClksToIdle; } + + void calculateTransitions(); + void transitionToNextState(); + + sc_core::sc_time generatorClk; + + const DRAMSysConfiguration::TraceGenerator &conf; + unsigned int currentState = 0; + uint64_t currentAddress = 0x00; + uint64_t currentClksPerRequest = 1; + uint64_t transactionsSentInCurrentState = 0; + + const uint64_t maxTransactions; + + uint64_t currentClksToIdle = 0; + + std::vector stateSequence; + std::vector::const_iterator stateIt; + + struct EventPair + { + EventPair(const std::string &name, unsigned int id) : event(name.c_str()), stateId(id) + { + } + sc_core::sc_event event; + unsigned int stateId; + }; + std::map stateTranstitionEvents; + + bool idleAtStart = false; + const sc_core::sc_event *startEvent = nullptr; std::default_random_engine randomGenerator; - -private: - sc_core::sc_time generatorClk; - uint64_t numRequests; - float rwRatio; - - std::uniform_real_distribution randomRwDistribution - = std::uniform_real_distribution(0.0f, 1.0f); -}; - -class TrafficGeneratorRandom final : public TrafficGenerator -{ -public: - TrafficGeneratorRandom(const sc_core::sc_module_name &name, - const sc_core::sc_time &generatorClk, - uint64_t numRequests, - unsigned int maxPendingReadRequests, - unsigned int maxPendingWriteRequests, - bool addLengthConverter, - uint64_t minAddress, - uint64_t maxAddress, - float rwRatio, - unsigned int seed, - TraceSetup *setup); - -private: - uint64_t getNextAddress() override; - + std::uniform_real_distribution randomDistribution = std::uniform_real_distribution(0.0f, 1.0f); std::uniform_int_distribution randomAddressDistribution; + + static constexpr uint64_t defaultSeed = 0; + static constexpr uint64_t defaultClksPerRequest = 1; + static constexpr uint64_t defaultAddressIncrement = 0x00; }; -class TrafficGeneratorSequential final : public TrafficGenerator +class TrafficGeneratorHammer final : public TrafficGeneratorIf { public: - TrafficGeneratorSequential(const sc_core::sc_module_name &name, - const sc_core::sc_time &generatorClk, - uint64_t numRequests, - unsigned int maxPendingReadRequests, - unsigned int maxPendingWriteRequests, - bool addLengthConverter, - uint64_t minAddress, - uint64_t maxAddress, - float rwRatio, - uint64_t addressIncrement, - unsigned int seed, - TraceSetup *setup); - -private: - uint64_t getNextAddress() override; - - uint64_t currentAddress; - uint64_t addressIncrement; - uint64_t minAddress; - uint64_t maxAddress; -}; - -class TrafficGeneratorHammer final : public TrafficGenerator -{ -public: - TrafficGeneratorHammer(const sc_core::sc_module_name &name, - const sc_core::sc_time &generatorClk, - uint64_t numRequests, - uint64_t rowIncrement, + TrafficGeneratorHammer(const sc_core::sc_module_name &name, const DRAMSysConfiguration::TraceHammer &conf, TraceSetup *setup); private: + void prepareNextPayload() override; uint64_t getNextAddress() override; + tlm::tlm_command getNextCommand() override; + sc_core::sc_time getGeneratorClk() const override; + sc_core::sc_time generatorClk; uint64_t rowIncrement; uint64_t currentAddress = 0x0; + uint64_t numRequests; }; #endif // TRAFFICGENERATOR_H diff --git a/DRAMSys/simulator/TrafficInitiator.cpp b/DRAMSys/simulator/TrafficInitiator.cpp index 10a5ff36..4a2f74af 100644 --- a/DRAMSys/simulator/TrafficInitiator.cpp +++ b/DRAMSys/simulator/TrafficInitiator.cpp @@ -46,15 +46,15 @@ using namespace tlm; TrafficInitiator::TrafficInitiator(const sc_module_name &name, TraceSetup *setup, unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, bool addLengthConverter) : sc_module(name), + addLengthConverter(addLengthConverter), payloadEventQueue(this, &TrafficInitiator::peqCallback), setup(setup), maxPendingReadRequests(maxPendingReadRequests), maxPendingWriteRequests(maxPendingWriteRequests), - addLengthConverter(addLengthConverter), defaultDataLength(Configuration::getInstance().memSpec->defaultBytesPerBurst), storageEnabled(Configuration::getInstance().storeMode != Configuration::StoreMode::NoStorage) { - SC_METHOD(sendNextPayload); + SC_THREAD(sendNextPayload); iSocket.register_nb_transport_bw(this, &TrafficInitiator::nb_transport_bw); } @@ -129,3 +129,11 @@ bool TrafficInitiator::nextPayloadSendable() const else return true; } + +sc_core::sc_time TrafficInitiator::evaluateGeneratorClk(const DRAMSysConfiguration::TrafficInitiator &conf) +{ + double frequencyMHz = conf.clkMhz; + sc_time playerClk = sc_time(1.0 / frequencyMHz, SC_US); + return playerClk; +} + diff --git a/DRAMSys/simulator/TrafficInitiator.h b/DRAMSys/simulator/TrafficInitiator.h index df1f39d0..3b456d29 100644 --- a/DRAMSys/simulator/TrafficInitiator.h +++ b/DRAMSys/simulator/TrafficInitiator.h @@ -63,6 +63,8 @@ public: const bool addLengthConverter = false; protected: + static sc_core::sc_time evaluateGeneratorClk(const DRAMSysConfiguration::TrafficInitiator &conf); + tlm_utils::peq_with_cb_and_phase payloadEventQueue; void terminate(); TraceSetup *setup; @@ -73,13 +75,19 @@ protected: uint64_t transactionsSent = 0; unsigned int pendingReadRequests = 0; unsigned int pendingWriteRequests = 0; + const unsigned int maxPendingReadRequests = 0; const unsigned int maxPendingWriteRequests = 0; + bool payloadPostponed = false; bool finished = false; const unsigned int defaultDataLength = 64; const bool storageEnabled = false; + // 0 disables the max value. + static constexpr unsigned int defaultMaxPendingWriteRequests = 0; + static constexpr unsigned int defaultMaxPendingReadRequests = 0; + private: tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_core::sc_time &bwDelay); diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index 56a965ed..5fed42be 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -34,6 +34,7 @@ * Matthias Jung * Luiza Correa * Lukas Steiner + * Derek Christ */ #include @@ -42,9 +43,10 @@ #include #include #include +#include #include - #include + #include "simulation/DRAMSys.h" #include "TraceSetup.h" #include "TrafficInitiator.h" @@ -52,7 +54,6 @@ #ifdef RECORDING #include "simulation/DRAMSysRecordable.h" -#include "common/third_party/nlohmann/single_include/nlohmann/json.hpp" using json = nlohmann::json; #endif @@ -101,21 +102,23 @@ int sc_main(int argc, char **argv) std::vector> players; std::vector> lengthConverters; + DRAMSysConfiguration::Configuration conf = DRAMSysConfiguration::from_path(simulationJson, resources); + // Instantiate DRAMSys: std::unique_ptr dramSys; -#ifdef RECORDING - json simulationdoc = parseJSON(simulationJson); - json simulatordoc = parseJSON(resources + "configs/simulator/" - + std::string(simulationdoc["simulation"]["simconfig"])); - if (simulatordoc["simconfig"]["DatabaseRecording"].is_boolean() && simulatordoc["simconfig"]["DatabaseRecording"]) - dramSys = std::unique_ptr(new DRAMSysRecordable("DRAMSys", simulationJson, resources)); +#ifdef RECORDING + if (conf.simConfig.databaseRecording.value_or(false)) + dramSys = std::unique_ptr(new DRAMSysRecordable("DRAMSys", conf)); else #endif - dramSys = std::unique_ptr(new DRAMSys("DRAMSys", simulationJson, resources)); + dramSys = std::unique_ptr(new DRAMSys("DRAMSys", conf)); - // Instantiate STL Players (config of DRAMSys required!): - TraceSetup setup(simulationJson, resources, players); + if (!conf.traceSetup.has_value()) + SC_REPORT_FATAL("sc_main", "No tracesetup section provided."); + + // Instantiate STL Players: + TraceSetup setup(conf.traceSetup.value(), resources, players); // Bind STL Players with DRAMSys: for (auto& player : players) diff --git a/DRAMSys/traceAnalyzer/.directory b/DRAMSys/traceAnalyzer/.directory new file mode 100644 index 00000000..407ff9bc --- /dev/null +++ b/DRAMSys/traceAnalyzer/.directory @@ -0,0 +1,8 @@ +[Dolphin] +Timestamp=2022,2,16,16,1,1.259 +Version=4 +ViewMode=1 +VisibleRoles=Details_text,Details_type,Details_size,Details_modificationtime,CustomizedDetails + +[Settings] +HiddenFilesShown=true diff --git a/DRAMSys/traceAnalyzer/CMakeLists.txt b/DRAMSys/traceAnalyzer/CMakeLists.txt index 09333b01..3ce4cceb 100644 --- a/DRAMSys/traceAnalyzer/CMakeLists.txt +++ b/DRAMSys/traceAnalyzer/CMakeLists.txt @@ -66,7 +66,7 @@ set(CMAKE_AUTORCC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) # Configure: -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) set(DCMAKE_SH="CMAKE_SH-NOTFOUND") add_executable(TraceAnalyzer @@ -108,6 +108,7 @@ add_executable(TraceAnalyzer presentation/traceselector.cpp businessObjects/configmodels.cpp businessObjects/commentmodel.cpp + simulationdialog.cpp selectmetrics.ui preferences.ui @@ -116,6 +117,7 @@ add_executable(TraceAnalyzer tracefiletab.ui queryeditor.ui traceanalyzer.ui + simulationdialog.ui scripts/memUtil.py scripts/metrics.py @@ -139,4 +141,5 @@ target_link_libraries(TraceAnalyzer PRIVATE ${QWT_LIBRARY} PRIVATE Qt5::Widgets PRIVATE Qt5::Sql + PRIVATE DRAMSysConfiguration ) diff --git a/DRAMSys/traceAnalyzer/simulationdialog.cpp b/DRAMSys/traceAnalyzer/simulationdialog.cpp new file mode 100644 index 00000000..cc0f6958 --- /dev/null +++ b/DRAMSys/traceAnalyzer/simulationdialog.cpp @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#include "simulationdialog.h" +#include "TraceSetup.h" + +#include +#include +#include +#include +#include +#include +#include + +SimulationDialog::SimulationDialog(QWidget *parent) : QWidget(parent), ui(new Ui::SimulationDialog) +{ + ui->setupUi(this); + + showStopButton(false); + + // Try to find path to DRAMSys + { + QFileInfo fileInfo; + + fileInfo.setFile("../simulator/DRAMSys"); + if (fileInfo.isFile()) + ui->dramSysPath->setText(fileInfo.absoluteFilePath()); + + fileInfo.setFile("../simulator/DRAMSys.exe"); + if (fileInfo.isFile()) + ui->dramSysPath->setText(fileInfo.absoluteFilePath()); + + fileInfo.setFile("simulator/DRAMSys"); + if (fileInfo.isFile()) + ui->dramSysPath->setText(fileInfo.absoluteFilePath()); + + fileInfo.setFile("simulator/DRAMSys.exe"); + if (fileInfo.isFile()) + ui->dramSysPath->setText(fileInfo.absoluteFilePath()); + } + + ui->outputDirLineEdit->setText(QDir::currentPath()); +} + +void SimulationDialog::on_browseDramSysButton_clicked() +{ + QString fileName = + QFileDialog::getOpenFileName(this, ui->browseDramSysButton->text(), {}, "DRAMSys executable (*)"); + ui->dramSysPath->setText(fileName); +} + +void SimulationDialog::on_browseConfigButton_clicked() +{ + QString fileName = + QFileDialog::getOpenFileName(this, ui->browseConfigButton->text(), {}, "Configuration file (*.json)"); + ui->jsonPath->setText(fileName); + + loadConfigurationFromPath(); +} + +void SimulationDialog::on_browseOutputButton_clicked() +{ + QString fileName = QFileDialog::getExistingDirectory(this, ui->browseOutputButton->text(), {}); + ui->outputDirLineEdit->setText(fileName); + + loadConfigurationFromPath(); +} + +void SimulationDialog::on_browseResourceDirButton_clicked() +{ + QString fileName = QFileDialog::getExistingDirectory(this, ui->browseResourceDirButton->text(), {}); + ui->resourceDirLineEdit->setText(fileName); + + loadConfigurationFromPath(); +} + +void SimulationDialog::on_simulateButton_clicked() +{ + saveConfiguration(temporaryConfigurationFile); + + ui->tabWidget->setCurrentWidget(ui->outputTab); + ui->progressBar->setEnabled(true); + ui->progressBar->setValue(0); + + showStopButton(true); + + // Spawn the DRAMSys process + simulatorProcess = new QProcess(this); + + QObject::connect(simulatorProcess, &QIODevice::readyRead, this, + [=] + { + QByteArray msg = simulatorProcess->read(4096); + msg = msg.trimmed(); + processMessage(msg.toStdString()); + }); + + QObject::connect(simulatorProcess, QOverload::of(&QProcess::finished), this, + [=](int exitCode, QProcess::ExitStatus exitStatus) + { + Q_UNUSED(exitStatus) + + showStopButton(false); + + // Clear all the contents so that the user is not asked + // next time to overwrite the temp file. + temporaryConfigurationFile.resize(0); + + if (exitCode == 0) + { + ui->progressBar->setValue(100); + + QMessageBox msgBox; + msgBox.setText("Simulation done."); + msgBox.setInformativeText("Do you want to open the results?"); + msgBox.setStandardButtons(QMessageBox::Open | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Open); + int ret = msgBox.exec(); + + if (ret == QMessageBox::Open) + { + auto results = getSimulationResults(); + openSimulationResults(results); + } + } + }); + + QStringList argumentList; + argumentList << temporaryConfigurationFile.fileName(); + + if (!ui->resourceDirLineEdit->text().isEmpty()) + argumentList << ui->resourceDirLineEdit->text(); + + simulatorProcess->setWorkingDirectory(ui->outputDirLineEdit->text()); + simulatorProcess->start(ui->dramSysPath->text(), argumentList); +} + +void SimulationDialog::on_reloadButton_clicked() +{ + loadConfigurationFromPath(); + + ui->outputPlainTextEdit->clear(); +} + +void SimulationDialog::on_saveButton_clicked() +{ + QFile file(ui->jsonPath->text()); + saveConfiguration(file); +} + +void SimulationDialog::on_stopButton_clicked() +{ + if (simulatorProcess) + simulatorProcess->terminate(); +} + +void SimulationDialog::showStopButton(bool val) +{ + ui->simulateButton->setVisible(!val); + ui->stopButton->setVisible(val); +} + +void SimulationDialog::saveConfiguration(QFile &file) +{ + if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) + return; + + if (file.size() != 0) + { + QMessageBox msgBox; + msgBox.setText("The configuration file will be overwritten."); + msgBox.setInformativeText("Do you want to save your changes?"); + msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Save); + int ret = msgBox.exec(); + + if (ret != QMessageBox::Save) + return; + } + + // Clear the file + file.resize(0); + + QTextStream out(&file); + + loadConfigurationFromTextFields(); + + std::string dump = DRAMSysConfiguration::dump(configuration, 4); + out << dump.c_str(); +} + +void SimulationDialog::processMessage(const std::string &msg) +{ + // Get percentages + QRegularExpression re("(\\d+(\\.\\d+)?|\\.\\d+) ?%"); + QRegularExpressionMatch match = re.match(msg.c_str()); + + if (match.hasMatch()) + { + unsigned int percentage = match.captured(1).toUInt(); + + ui->progressBar->setValue(percentage); + } + + ui->outputPlainTextEdit->appendPlainText(msg.c_str()); +} + +void SimulationDialog::loadConfigurationFromTextFields() +{ + using namespace DRAMSysConfiguration; + + AddressMapping addressMapping; + McConfig mcConfig; + MemSpec memSpec; + SimConfig simConfig; + std::string simulationId; + ThermalConfig thermalConfig; + TraceSetup traceSetup; + + simulationId = ui->simulationIdLineEdit->text().toStdString(); + + try + { + from_dump(ui->addressMappingTextEdit->toPlainText().toStdString(), addressMapping); + from_dump(ui->mcConfigTextEdit->toPlainText().toStdString(), mcConfig); + from_dump(ui->memSpecTextEdit->toPlainText().toStdString(), memSpec); + from_dump(ui->simConfigTextEdit->toPlainText().toStdString(), simConfig); + + if (!ui->thermalConfigTextEdit->toPlainText().toStdString().empty()) + from_dump(ui->thermalConfigTextEdit->toPlainText().toStdString(), thermalConfig); + + if (!ui->traceSetupTextEdit->toPlainText().toStdString().empty()) + from_dump(ui->traceSetupTextEdit->toPlainText().toStdString(), traceSetup); + } + catch (const std::exception &e) + { + qWarning() << "Error while parsing json:" << e.what(); + return; + } + + configuration = DRAMSysConfiguration::Configuration{addressMapping, + mcConfig, + memSpec, + simConfig, + simulationId, + std::make_optional(std::move(thermalConfig)), + std::make_optional(std::move(traceSetup))}; + + loadConfiguration(); +} + +void SimulationDialog::loadConfigurationFromPath() +{ + QFileInfo fileInfo(ui->jsonPath->text()); + + if (!fileInfo.isFile()) + return; + + try + { + configuration = DRAMSysConfiguration::from_path(ui->jsonPath->text().toStdString()); + } + catch (const std::exception &e) + { + qWarning() << "Error while parsing json:" << e.what(); + return; + } + + loadConfiguration(); +} + +void SimulationDialog::loadConfiguration() +{ + ui->simulationIdLabel->setEnabled(true); + ui->simulationId->setEnabled(true); + ui->simulationId->setText(configuration.simulationId.c_str()); + + ui->simulationIdLineEdit->setText(configuration.simulationId.c_str()); + + loadSimConfig(); + loadMcConfig(); + loadMemSpec(); + loadAddressMapping(); + loadThermalConfig(); + loadTraceSetup(); + loadPreview(); +} + +void SimulationDialog::loadSimConfig() +{ + ui->simConfigTextEdit->clear(); + + std::string dump = DRAMSysConfiguration::dump(configuration.simConfig, 4); + ui->simConfigTextEdit->setText(dump.c_str()); +} + +void SimulationDialog::loadMcConfig() +{ + ui->mcConfigTextEdit->clear(); + + std::string dump = DRAMSysConfiguration::dump(configuration.mcConfig, 4); + ui->mcConfigTextEdit->setText(dump.c_str()); +} + +void SimulationDialog::loadMemSpec() +{ + ui->memSpecTextEdit->clear(); + + std::string dump = DRAMSysConfiguration::dump(configuration.memSpec, 4); + ui->memSpecTextEdit->setText(dump.c_str()); +} + +void SimulationDialog::loadAddressMapping() +{ + ui->addressMappingTextEdit->clear(); + + std::string dump = DRAMSysConfiguration::dump(configuration.addressMapping, 4); + ui->addressMappingTextEdit->setText(dump.c_str()); +} + +void SimulationDialog::loadThermalConfig() +{ + ui->thermalConfigTextEdit->clear(); + + if (const auto &thermalConfig = configuration.thermalConfig) + { + std::string dump = DRAMSysConfiguration::dump(*thermalConfig, 4); + ui->thermalConfigTextEdit->setText(dump.c_str()); + } +} + +void SimulationDialog::loadTraceSetup() +{ + ui->traceSetupTextEdit->clear(); + + if (const auto &traceSetup = configuration.traceSetup) + { + std::string dump = DRAMSysConfiguration::dump(*traceSetup, 4); + ui->traceSetupTextEdit->setText(dump.c_str()); + } +} + +void SimulationDialog::loadPreview() +{ + ui->previewTextEdit->clear(); + + std::string dump = DRAMSysConfiguration::dump(configuration, 4); + ui->previewTextEdit->setText(dump.c_str()); +} + +QFileInfoList SimulationDialog::getSimulationResults() +{ + QFileInfoList list; + + // Get the path where the tracefiles are located + QDir baseDir(ui->outputDirLineEdit->text()); + + for (const auto &fileInfo : baseDir.entryInfoList()) + { + if (fileInfo.baseName().startsWith(configuration.simulationId.c_str())) + { + // Dont open tracefiles that are older than a few seconds + if (fileInfo.metadataChangeTime().secsTo(QDateTime::currentDateTime()) > 30) + continue; + + list << fileInfo; + } + } + + return list; +} + +void SimulationDialog::openSimulationResults(const QFileInfoList &fileInfos) +{ + for (const auto &fileInfo : fileInfos) + openFileRequested(fileInfo.absoluteFilePath()); +} diff --git a/DRAMSys/traceAnalyzer/simulationdialog.h b/DRAMSys/traceAnalyzer/simulationdialog.h new file mode 100644 index 00000000..311714d3 --- /dev/null +++ b/DRAMSys/traceAnalyzer/simulationdialog.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021, Technische Universität 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: + * Derek Christ + */ + +#ifndef SIMULATIONDIALOG_H +#define SIMULATIONDIALOG_H + +#include "ui_simulationdialog.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace Ui +{ +class SimulationDialog; +} + +class SimulationDialog : public QWidget +{ + Q_OBJECT + +public: + explicit SimulationDialog(QWidget *parent = nullptr); + +signals: + void openFileRequested(const QString &path); + +private Q_SLOTS: + void on_browseDramSysButton_clicked(); + void on_browseConfigButton_clicked(); + void on_browseOutputButton_clicked(); + void on_browseResourceDirButton_clicked(); + void on_simulateButton_clicked(); + void on_reloadButton_clicked(); + void on_saveButton_clicked(); + void on_stopButton_clicked(); + +private: + void loadConfigurationFromPath(); + void loadConfigurationFromTextFields(); + + void loadConfiguration(); + void loadSimConfig(); + void loadMcConfig(); + void loadMemSpec(); + void loadAddressMapping(); + void loadThermalConfig(); + void loadTraceSetup(); + void loadPreview(); + + void showStopButton(bool val); + void saveConfiguration(QFile &file); + void processMessage(const std::string &msg); + + QFileInfoList getSimulationResults(); + void openSimulationResults(const QFileInfoList &fileInfos); + + QTemporaryFile temporaryConfigurationFile; + DRAMSysConfiguration::Configuration configuration; + + QPointer simulatorProcess; + + Ui::SimulationDialog *ui; +}; + +#endif diff --git a/DRAMSys/traceAnalyzer/simulationdialog.ui b/DRAMSys/traceAnalyzer/simulationdialog.ui new file mode 100644 index 00000000..f3dda234 --- /dev/null +++ b/DRAMSys/traceAnalyzer/simulationdialog.ui @@ -0,0 +1,394 @@ + + + SimulationDialog + + + + 0 + 0 + 920 + 620 + + + + + + + Simulation + + + + + + Simulation + + + + + + + + + + + Path to resource directory... (optional) + + + + + + + Browse... + + + + + + + Base configuration: + + + + + + + Browse... + + + + + + + DRAMSys: + + + + + + + Output directory: + + + + + + + Path to DRAMSys... + + + + + + + Browse... + + + + + + + Browse... + + + + + + + Path to output directory... + + + + + + + Path to Json configuration... + + + + + + + Resource directory: + + + + + + + + + + + false + + + Simulation Id: + + + + + + + false + + + + + + + + + + + + + + false + + + 0 + + + + + + + Start Simulation + + + + + + + Stop Simulation + + + + + + + + + + + + 0 + + + + SimConfig + + + + + + + + + + + + + + McConfig + + + + + + + + + + + + + + MemSpec + + + + + + + + + + + + + + ThermalConfig + + + + + + + + + + + + + + TraceSetup + + + + + + + + + + + + + + AddressMapping + + + + + + + + + + + + + + Preview Configuration + + + + + + + + + true + + + + + + + + Output + + + + + + + + + QPlainTextEdit::NoWrap + + + true + + + + + + + + + + + + + Reload + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Simulation Id + + + + + + + Save + + + false + + + + + + + Close + + + + + + + + + dramSysPath + outputDirLineEdit + jsonPath + resourceDirLineEdit + browseDramSysButton + browseOutputButton + browseConfigButton + browseResourceDirButton + simulateButton + stopButton + tabWidget + reloadButton + simulationIdLineEdit + saveButton + closeButton + simConfigTextEdit + outputPlainTextEdit + memSpecTextEdit + thermalConfigTextEdit + traceSetupTextEdit + addressMappingTextEdit + mcConfigTextEdit + previewTextEdit + + + + + closeButton + clicked() + SimulationDialog + close() + + + 836 + 507 + + + 830 + 575 + + + + + diff --git a/DRAMSys/traceAnalyzer/traceanalyzer.cpp b/DRAMSys/traceAnalyzer/traceanalyzer.cpp index b0159918..1cc0db53 100644 --- a/DRAMSys/traceAnalyzer/traceanalyzer.cpp +++ b/DRAMSys/traceAnalyzer/traceanalyzer.cpp @@ -37,8 +37,10 @@ */ #include "traceanalyzer.h" +#include "simulationdialog.h" #include "tracefiletab.h" #include "ui_traceanalyzer.h" + #include #include #include @@ -281,3 +283,13 @@ void TraceAnalyzer::closeEvent(QCloseEvent *event) event->accept(); } + +void TraceAnalyzer::on_actionSimulate_triggered() +{ + SimulationDialog *simulationDialog = new SimulationDialog(this); + simulationDialog->setWindowFlag(Qt::Window); + + QObject::connect(simulationDialog, &SimulationDialog::openFileRequested, this, &TraceAnalyzer::openTracefileTab); + + simulationDialog->show(); +} diff --git a/DRAMSys/traceAnalyzer/traceanalyzer.h b/DRAMSys/traceAnalyzer/traceanalyzer.h index a2aab12d..b5e8cdd1 100644 --- a/DRAMSys/traceAnalyzer/traceanalyzer.h +++ b/DRAMSys/traceAnalyzer/traceanalyzer.h @@ -97,6 +97,7 @@ private Q_SLOTS: void on_actionClose_triggered(); void on_actionClose_all_triggered(); void on_actionAbout_triggered(); + void on_actionSimulate_triggered(); public Q_SLOTS: void statusChanged(const QString &message); diff --git a/DRAMSys/traceAnalyzer/traceanalyzer.ui b/DRAMSys/traceAnalyzer/traceanalyzer.ui index f382563d..5fec0849 100644 --- a/DRAMSys/traceAnalyzer/traceanalyzer.ui +++ b/DRAMSys/traceAnalyzer/traceanalyzer.ui @@ -78,7 +78,14 @@ + + + &Run + + + + @@ -225,6 +232,14 @@ Save &as... + + + + + + &Simulate... + +