Merge branch 'work/new_json_format_rebased' into 'develop'

Introduce a common json configuration library

See merge request ems/astdm/modeling.dram/dram.sys!345
This commit is contained in:
Lukas Steiner
2022-02-28 15:18:17 +00:00
86 changed files with 5217 additions and 1541 deletions

View File

@@ -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)

View File

@@ -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
)

View File

@@ -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<int64_t>(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<char>(mcconfig_stream)), (std::istreambuf_iterator<char>()));
std::string memspec_dump((std::istreambuf_iterator<char>(memspec_stream)), (std::istreambuf_iterator<char>()));
sqlite3_bind_text(insertGeneralInfoStatement, 8, mcconfig_dump.c_str(), static_cast<int>(mcconfig_dump.length()), nullptr);
sqlite3_bind_text(insertGeneralInfoStatement, 9, memspec_dump.c_str(), static_cast<int>(memspec_dump.length()), nullptr);
sqlite3_bind_text(insertGeneralInfoStatement, 8, mcconfig.c_str(), static_cast<int>(mcconfig.length()), nullptr);
sqlite3_bind_text(insertGeneralInfoStatement, 9, memspec.c_str(), static_cast<int>(memspec.length()), nullptr);
sqlite3_bind_text(insertGeneralInfoStatement, 10, traces.c_str(), static_cast<int>(traces.length()), nullptr);
if (Configuration::getInstance().enableWindowing)
sqlite3_bind_int64(insertGeneralInfoStatement, 11, static_cast<int64_t>((Configuration::getInstance().memSpec->tCK

View File

@@ -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 <iostream>
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

View File

@@ -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 <nlohmann/json.hpp>
#include <optional>
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<std::vector<unsigned int>> byteBits;
std::optional<std::vector<unsigned int>> columnBits;
std::optional<std::vector<unsigned int>> bankBits;
std::optional<std::vector<unsigned int>> bankGroupBits;
std::optional<std::vector<unsigned int>> rowBits;
std::optional<std::vector<unsigned int>> channelBits;
std::optional<std::vector<unsigned int>> rankBits;
std::optional<std::vector<XorPair>> 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

View File

@@ -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)

View File

@@ -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 <exception>
#include <fstream>
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<DRAMSysConfiguration::Configuration>();
}
else
{
throw std::runtime_error("Failed to open file " + path);
}
}
} // namespace DRAMSysConfiguration

View File

@@ -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 <nlohmann/json.hpp>
#include <optional>
#include <string>
/**
* 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> thermalConfig;
std::optional<TraceSetup> 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

View File

@@ -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 <iostream>
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

View File

@@ -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 <nlohmann/json.hpp>
#include <optional>
#include <utility>
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> pagePolicy;
std::optional<Scheduler> scheduler;
std::optional<SchedulerBuffer> schedulerBuffer;
std::optional<unsigned int> requestBufferSize;
std::optional<CmdMux> cmdMux;
std::optional<RespQueue> respQueue;
std::optional<RefreshPolicy> refreshPolicy;
std::optional<unsigned int> refreshMaxPostponed;
std::optional<unsigned int> refreshMaxPulledin;
std::optional<PowerDownPolicy> powerDownPolicy;
std::optional<Arbiter> arbiter;
std::optional<unsigned int> maxActiveTransactions;
std::optional<bool> refreshManagement;
std::optional<unsigned int> arbitrationDelayFw;
std::optional<unsigned int> arbitrationDelayBw;
std::optional<unsigned int> thinkDelayFw;
std::optional<unsigned int> thinkDelayBw;
std::optional<unsigned int> phyDelayFw;
std::optional<unsigned int> 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

View File

@@ -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

View File

@@ -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 <nlohmann/json.hpp>
#include <optional>
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<uint64_t> addressOffset;
std::optional<bool> checkTLM2Protocol;
std::optional<bool> databaseRecording;
std::optional<bool> debug;
std::optional<bool> enableWindowing;
std::optional<std::string> errorCsvFile;
std::optional<unsigned int> errorChipSeed;
std::optional<bool> powerAnalysis;
std::optional<std::string> simulationName;
std::optional<bool> simulationProgressBar;
std::optional<StoreMode> storeMode;
std::optional<bool> thermalSimulation;
std::optional<bool> useMalloc;
std::optional<unsigned int> 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

View File

@@ -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

View File

@@ -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 <nlohmann/json.hpp>
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<DramDieChannel> 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

View File

@@ -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 <variant>
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<decltype(initiator)>;
if constexpr (std::is_same_v<T, TraceGenerator>)
{
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<decltype(state)>;
if constexpr (std::is_same_v<U, TraceGeneratorTrafficState>)
{
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<U, TraceGeneratorIdleState>)
{
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<decltype(state)>;
if constexpr (std::is_same_v<U, TraceGeneratorTrafficState>)
{
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<U, TraceGeneratorIdleState>)
{
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<T, TraceHammer>)
{
initiator_j["type"] = "hammer";
initiator_j["numRequests"] = initiator.numRequests;
initiator_j["rowIncrement"] = initiator.rowIncrement;
}
else // if constexpr (std::is_same_v<T, TracePlayer>)
{
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<TracePlayer, TraceGenerator, TraceHammer> initiator;
if (type == TrafficInitiatorType::Player)
{
initiator = TracePlayer{};
}
else if (type == TrafficInitiatorType::Generator)
{
TraceGenerator generator;
auto process_state = [](const json &state_j)
-> std::pair<unsigned int, std::variant<TraceGeneratorIdleState, TraceGeneratorTrafficState>>
{
std::variant<TraceGeneratorIdleState, TraceGeneratorTrafficState> 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

View File

@@ -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 <nlohmann/json.hpp>
#include <optional>
#include <variant>
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<unsigned int> maxPendingReadRequests;
std::optional<unsigned int> maxPendingWriteRequests;
std::optional<bool> addLengthConverter;
};
struct TracePlayer : public TrafficInitiator
{
};
struct TraceGeneratorState
{
virtual ~TraceGeneratorState() = 0;
};
struct TraceGeneratorTrafficState : public TraceGeneratorState
{
uint64_t numRequests;
double rwRatio;
AddressDistribution addressDistribution;
std::optional<uint64_t> addressIncrement;
std::optional<uint64_t> minAddress;
std::optional<uint64_t> maxAddress;
std::optional<uint64_t> clksPerRequest;
std::optional<std::string> notify;
};
struct TraceGeneratorIdleState : public TraceGeneratorState
{
uint64_t idleClks;
};
struct TraceGeneratorStateTransition
{
unsigned int to;
float propability;
};
struct TraceGenerator : public TrafficInitiator
{
std::optional<uint64_t> seed;
std::optional<uint64_t> maxTransactions;
std::map<unsigned int, std::variant<TraceGeneratorIdleState, TraceGeneratorTrafficState>> states;
std::multimap<unsigned int, TraceGeneratorStateTransition> transitions;
std::optional<std::string> idleUntil;
};
struct TraceHammer : public TrafficInitiator
{
uint64_t numRequests;
uint64_t rowIncrement;
};
struct TraceSetup
{
std::vector<std::variant<TracePlayer, TraceGenerator, TraceHammer>> 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

View File

@@ -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

View File

@@ -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 <nlohmann/json.hpp>
#include <unordered_map>
namespace DRAMSysConfiguration
{
using json = nlohmann::json;
struct MemArchitectureSpec
{
std::unordered_map<std::string, unsigned int> entries;
};
void to_json(json &j, const MemArchitectureSpec &c);
void from_json(const json &j, MemArchitectureSpec &c);
} // namespace Configuration
#endif

View File

@@ -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

View File

@@ -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 <nlohmann/json.hpp>
#include <unordered_map>
namespace DRAMSysConfiguration
{
using json = nlohmann::json;
struct MemPowerSpec
{
std::unordered_map<std::string, double> entries;
};
void to_json(json &j, const MemPowerSpec &c);
void from_json(const json &j, MemPowerSpec &c);
} // namespace Configuration
#endif

View File

@@ -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

View File

@@ -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 <nlohmann/json.hpp>
#include <optional>
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> 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

View File

@@ -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

View File

@@ -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 <nlohmann/json.hpp>
#include <unordered_map>
namespace DRAMSysConfiguration
{
using json = nlohmann::json;
struct MemTimingSpec
{
std::unordered_map<std::string, unsigned int> entries;
};
void to_json(json &j, const MemTimingSpec &c);
void from_json(const json &j, MemTimingSpec &c);
} // namespace Configuration
#endif

View File

@@ -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)

View File

@@ -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 <nlohmann/json.hpp>
#include <fstream>
#include <iostream>
#include <Configuration.h>
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;
}

View File

@@ -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 <Configuration.h>
#include <fstream>
#include <iostream>
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<DRAMSysConfiguration::DramDieChannel> 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<std::variant<TracePlayer, TraceGenerator, TraceHammer>> 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<DRAMSysConfiguration::Configuration>();
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<DRAMSysConfiguration::Configuration>();
std::ofstream fileoldout("myjson2.json");
json j_oldconfconv;
j_oldconfconv["simulation"] = ddr5_old_config;
fileoldout << j_oldconfconv.dump(4);
}

View File

@@ -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 <fstream>
#include <iostream>
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

View File

@@ -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 <nlohmann/json.hpp>
#include <optional>
#include <utility>
namespace DRAMSysConfiguration
{
using json = nlohmann::json;
// template <typename T>
// class Optional : public std::pair<T, bool>
// {
// public:
// Optional() : std::pair<T, bool>{{}, false}
// {
// }
// Optional(const T &v) : std::pair<T, bool>{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 <typename T>
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<std::string> 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 <typename T>
void to_json(nlohmann::json &j, const std::optional<T> &v)
{
if (v.has_value())
j = v.value();
else
j = nullptr;
}
template <typename T>
void from_json(const nlohmann::json &j, std::optional<T> &v)
{
if (j.is_null())
v = std::nullopt;
else
{
v = j.get<T>();
}
}
} // namespace nlohmann
#endif

View File

@@ -34,6 +34,7 @@
* Robert Gernhardt
* Matthias Jung
* Luiza Correa
* Derek Christ
*/
#include <sstream>
@@ -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);

View File

@@ -34,6 +34,7 @@
* Matthias Jung
* Eder F. Zulian
* Luiza Correa
* Derek Christ
*/
#ifndef UTILS_H
@@ -44,7 +45,6 @@
#include <systemc>
#include <tlm>
#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));

View File

@@ -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");
}

View File

@@ -36,13 +36,14 @@
* Felipe S. Prado
* Lukas Steiner
* Luiza Correa
* Derek Christ
*/
#ifndef CONFIGURATION_H
#define CONFIGURATION_H
#include <string>
#include <Configuration.h>
#include <systemc>
#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

View File

@@ -33,6 +33,7 @@
* Eder F. Zulian
* Matthias Jung
* Luiza Correa
* Derek Christ
*/
#ifndef TEMPERATURESIMCONFIG_H
@@ -40,7 +41,7 @@
#include <string>
#include <vector>
#include <Configuration.h>
#include <systemc>
#include <utility>
#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<float> powerInitialValues;
std::vector<float> 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;

View File

@@ -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<unsigned>(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<double>(defaultBurstLength) / dataRate)),
memorySizeBytes(0)

View File

@@ -33,6 +33,7 @@
* Janik Schlemminger
* Matthias Jung
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPEC_H
@@ -40,11 +41,10 @@
#include <vector>
#include <string>
#include <Configuration.h>
#include <systemc>
#include <tlm>
#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,

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#include <iostream>
@@ -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<uint64_t>(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;

View File

@@ -31,19 +31,21 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPECDDR3_H
#define MEMSPECDDR3_H
#include <systemc>
#include "MemSpec.h"
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
#include <systemc>
#include <Configuration.h>
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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#include <iostream>
@@ -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<double>(parseUint(memspec["memtimingspec"], "REFI")) / 4)) :
((parseUint(memspec["memtimingspec"], "REFM") == 2) ?
(tCK * (static_cast<double>(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<double>(memSpec.memTimingSpec.entries.at("REFI")) / 4)) :
((memSpec.memTimingSpec.entries.at("REFM") == 2) ?
(tCK * (static_cast<double>(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<uint64_t>(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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPECDDR4_H
@@ -38,12 +39,11 @@
#include <systemc>
#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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#include <iostream>
@@ -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)
{

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPECDDR5_H
@@ -38,12 +39,11 @@
#include <systemc>
#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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#include <iostream>
@@ -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<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPECGDDR5_H
@@ -38,12 +39,11 @@
#include <systemc>
#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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#include <iostream>
@@ -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<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPECGDDR5X_H
@@ -38,12 +39,11 @@
#include <systemc>
#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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#include <iostream>
@@ -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<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPECGDDR6_H
@@ -38,12 +39,11 @@
#include <systemc>
#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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#include <iostream>
@@ -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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPECHBM2_H
@@ -38,12 +39,11 @@
#include <systemc>
#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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#include <iostream>
@@ -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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPECLPDDR4_H
@@ -38,12 +39,11 @@
#include <systemc>
#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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#include <iostream>
@@ -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<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPECSTTMRAM_H
@@ -38,12 +39,11 @@
#include <systemc>
#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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#include <iostream>
@@ -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<uint64_t>(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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPECWIDEIO_H
@@ -38,12 +39,11 @@
#include <systemc>
#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;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#include <iostream>
@@ -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<unsigned>(parseUint(memspec["memtimingspec"], "REFI")
* parseUdouble(memspec["memtimingspec"], "REFM"))),
tREFIpb (tCK * static_cast<unsigned>(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<unsigned>(memSpec.memTimingSpec.entries.at("REFI")
* memSpec.memTimingSpec.entries.at("REFM"))),
tREFIpb (tCK * static_cast<unsigned>(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<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPECWIDEIO2_H
@@ -38,12 +39,11 @@
#include <systemc>
#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;

View File

@@ -33,6 +33,7 @@
* Johannes Feldmann
* Lukas Steiner
* Luiza Correa
* Derek Christ
*/
#include <cmath>
@@ -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<unsigned>(-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<unsigned>(-1);
}
}
std::vector<unsigned> AddressDecoder::getAttrToVectorFromJson(json &obj, const std::string &strName)
{
std::vector<unsigned> 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()));

View File

@@ -33,6 +33,7 @@
* Johannes Feldmann
* Lukas Steiner
* Luiza Correa
* Derek Christ
*/
#ifndef ADDRESSDECODER_H
@@ -40,8 +41,7 @@
#include <vector>
#include <utility>
#include "../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
#include <Configuration.h>
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<unsigned> getAttrToVectorFromJson(nlohmann::json &obj, const std::string &strName);
static unsigned int getUnsignedAttrFromJson(nlohmann::json &obj, const std::string &strName);
unsigned banksPerGroup;
unsigned bankgroupsPerRank;

View File

@@ -34,16 +34,19 @@
* Matthias Jung
* Eder F. Zulian
* Lukas Steiner
* Derek Christ
*/
#include "Arbiter.h"
#include "AddressDecoder.h"
#include "../configuration/Configuration.h"
#include <Configuration.h>
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()

View File

@@ -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:

View File

@@ -35,6 +35,7 @@
* Eder F. Zulian
* Felipe S. Prado
* Lukas Steiner
* Derek Christ
*/
#include <cstdlib>
@@ -43,7 +44,6 @@
#include <stdexcept>
#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<Arbiter>(new ArbiterSimple("arbiter", pathToResources + "configs/amconfigs/" + amconfig));
arbiter = std::unique_ptr<Arbiter>(new ArbiterSimple("arbiter", addressMapping));
else if (config.arbiter == Configuration::Arbiter::Fifo)
arbiter = std::unique_ptr<Arbiter>(new ArbiterFifo("arbiter", pathToResources + "configs/amconfigs/" + amconfig));
arbiter = std::unique_ptr<Arbiter>(new ArbiterFifo("arbiter", addressMapping));
else if (config.arbiter == Configuration::Arbiter::Reorder)
arbiter = std::unique_ptr<Arbiter>(new ArbiterReorder("arbiter", pathToResources + "configs/amconfigs/" + amconfig));
arbiter = std::unique_ptr<Arbiter>(new ArbiterReorder("arbiter", addressMapping));
// Create controllers and DRAMs
MemSpec::MemoryType memoryType = config.memSpec->memoryType;

View File

@@ -35,25 +35,27 @@
* Eder F. Zulian
* Felipe S. Prado
* Lukas Steiner
* Derek Christ
*/
#ifndef DRAMSYS_H
#define DRAMSYS_H
#include <string>
#include <list>
#include <memory>
#include <systemc>
#include "dram/Dram.h"
#include "Arbiter.h"
#include "ReorderBuffer.h"
#include <tlm_utils/multi_passthrough_target_socket.h>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include "../common/tlm2_base_protocol_checker.h"
#include "../error/eccbaseclass.h"
#include "../controller/ControllerIF.h"
#include <Configuration.h>
#include <string>
#include <systemc>
#include <list>
#include <memory>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include <tlm_utils/multi_passthrough_target_socket.h>
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);
};

View File

@@ -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<Arbiter>(new ArbiterSimple("arbiter", pathToResources + "configs/amconfigs/" + amconfig));
arbiter = std::unique_ptr<Arbiter>(new ArbiterSimple("arbiter", configuration.addressMapping));
else if (config.arbiter == Configuration::Arbiter::Fifo)
arbiter = std::unique_ptr<Arbiter>(new ArbiterFifo("arbiter", pathToResources + "configs/amconfigs/" + amconfig));
arbiter = std::unique_ptr<Arbiter>(new ArbiterFifo("arbiter", configuration.addressMapping));
else if (config.arbiter == Configuration::Arbiter::Reorder)
arbiter = std::unique_ptr<Arbiter>(new ArbiterReorder("arbiter", pathToResources + "configs/amconfigs/" + amconfig));
arbiter = std::unique_ptr<Arbiter>(new ArbiterReorder("arbiter", configuration.addressMapping));
// Create controllers and DRAMs
MemSpec::MemoryType memoryType = config.memSpec->memoryType;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#ifndef DRAMSYSRECORDABLE_H
@@ -39,12 +40,13 @@
#include "DRAMSys.h"
#include "../common/TlmRecorder.h"
#include <Configuration.h>
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<TlmRecorder> 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

View File

@@ -32,6 +32,7 @@
* Authors:
* Eder F. Zulian
* Matthias Jung
* Derek Christ
*/
#include <cmath>
@@ -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 "

View File

@@ -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;

View File

@@ -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)

View File

@@ -35,193 +35,141 @@
* Derek Christ
*/
#include <iomanip>
#include "TraceSetup.h"
#include "StlPlayer.h"
#include "TrafficGenerator.h"
#include <algorithm>
#include <iomanip>
#include <map>
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<std::unique_ptr<TrafficInitiator>> &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<decltype(initiator)>;
if constexpr (std::is_same_v<T, DRAMSysConfiguration::TracePlayer>)
{
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<TrafficInitiator>(player));
totalTransactions += player->getNumberOfLines();
}
else if constexpr (std::is_same_v<T, DRAMSysConfiguration::TraceGenerator>)
{
TrafficGenerator *trafficGenerator = new TrafficGenerator(name.c_str(), initiator, this);
players.push_back(std::unique_ptr<TrafficInitiator>(trafficGenerator));
totalTransactions += trafficGenerator->getTotalTransactions();
}
else // if constexpr (std::is_same_v<T, DRAMSysConfiguration::TraceHammer>)
{
uint64_t numRequests = initiator.numRequests;
uint64_t rowIncrement = initiator.rowIncrement;
players.push_back(
std::unique_ptr<TrafficInitiator>(new TrafficGeneratorHammer(name.c_str(), initiator, this)));
totalTransactions += numRequests;
}
},
initiator);
}
for (const auto &inititatorConf : traceSetup.initiators)
{
if (auto generatorConf = std::get_if<DRAMSysConfiguration::TraceGenerator>(&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<TrafficInitiator> &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<TrafficGenerator *>(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<TrafficInitiator> &initiator)
{
if (auto generator = dynamic_cast<const TrafficGenerator *>(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<TrafficInitiator>(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<TrafficInitiator>(new TrafficGeneratorSequential(name.c_str(),
playerClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests, addLengthConverter,
minAddress, maxAddress, rwRatio, addressIncrement, seed, this)));
}
else
{
players.push_back(std::unique_ptr<TrafficInitiator>(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<TrafficInitiator>(new TrafficGeneratorHammer(name.c_str(), playerClk,
numRequests, rowIncrement, this)));
auto notifier = dynamic_cast<TrafficGenerator *>(notifierIt->get());
listener->waitUntil(&notifier->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) << "% |";

View File

@@ -37,11 +37,12 @@
#ifndef TRACESETUP_H
#define TRACESETUP_H
#include <Configuration.h>
#include <vector>
#include <string>
#include <memory>
#include <tlm>
#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<std::unique_ptr<TrafficInitiator>> &devices);

View File

@@ -37,51 +37,39 @@
*/
#include "TrafficGenerator.h"
#include "TraceSetup.h"
#include <limits>
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<uint64_t>::max())),
randomGenerator(std::default_random_engine(conf.seed.value_or(defaultSeed)))
{
randomAddressDistribution = std::uniform_int_distribution<uint64_t> (minAddress, maxAddress);
// Perform checks for all states
for (const auto &state : conf.states)
{
if (auto trafficState = std::get_if<DRAMSysConfiguration::TraceGeneratorTrafficState>(&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<DRAMSysConfiguration::TraceGeneratorTrafficState>(&conf.states.at(currentState)))
{
uint64_t minAddress = evaluateMinAddress(*trafficState);
uint64_t maxAddress = evaluateMaxAddress(*trafficState);
randomAddressDistribution = std::uniform_int_distribution<uint64_t>(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<unsigned int, std::pair<float, float>> 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<DRAMSysConfiguration::TraceGeneratorTrafficState>(&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<DRAMSysConfiguration::TraceGeneratorTrafficState>(&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<DRAMSysConfiguration::TraceGeneratorIdleState>(&conf.states.at(currentState)))
{
currentClksToIdle += idleState->idleClks;
transitionToNextState();
return;
}
else if (auto trafficState =
std::get_if<DRAMSysConfiguration::TraceGeneratorTrafficState>(&conf.states.at(currentState)))
{
uint64_t minAddress = evaluateMinAddress(*trafficState);
uint64_t maxAddress = evaluateMaxAddress(*trafficState);
randomAddressDistribution = std::uniform_int_distribution<uint64_t>(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<DRAMSysConfiguration::TraceGeneratorTrafficState>(&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<DRAMSysConfiguration::TraceGeneratorIdleState>(&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<DRAMSysConfiguration::TraceGeneratorTrafficState>(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<DRAMSysConfiguration::TraceGeneratorTrafficState>(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;
}

View File

@@ -39,98 +39,109 @@
#ifndef TRAFFICGENERATOR_H
#define TRAFFICGENERATOR_H
#include <random>
#include "TrafficInitiator.h"
#include "TraceSetup.h"
class TrafficGenerator : public TrafficInitiator
#include <cstdint>
#include <map>
#include <random>
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<unsigned int> stateSequence;
std::vector<unsigned int>::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<std::string, EventPair> 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<float> randomRwDistribution
= std::uniform_real_distribution<float>(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<float> randomDistribution = std::uniform_real_distribution<float>(0.0f, 1.0f);
std::uniform_int_distribution<uint64_t> 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

View File

@@ -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;
}

View File

@@ -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<TrafficInitiator> 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);

View File

@@ -34,6 +34,7 @@
* Matthias Jung
* Luiza Correa
* Lukas Steiner
* Derek Christ
*/
#include <iostream>
@@ -42,9 +43,10 @@
#include <vector>
#include <list>
#include <chrono>
#include <Configuration.h>
#include <memory>
#include <systemc>
#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<std::unique_ptr<TrafficInitiator>> players;
std::vector<std::unique_ptr<LengthConverter>> lengthConverters;
DRAMSysConfiguration::Configuration conf = DRAMSysConfiguration::from_path(simulationJson, resources);
// Instantiate DRAMSys:
std::unique_ptr<DRAMSys> 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<DRAMSys>(new DRAMSysRecordable("DRAMSys", simulationJson, resources));
#ifdef RECORDING
if (conf.simConfig.databaseRecording.value_or(false))
dramSys = std::unique_ptr<DRAMSys>(new DRAMSysRecordable("DRAMSys", conf));
else
#endif
dramSys = std::unique_ptr<DRAMSys>(new DRAMSys("DRAMSys", simulationJson, resources));
dramSys = std::unique_ptr<DRAMSys>(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)

View File

@@ -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

View File

@@ -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
)

View File

@@ -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 <QDateTime>
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QRegularExpression>
#include <optional>
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<int, QProcess::ExitStatus>::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<ThermalConfig>(std::move(thermalConfig)),
std::make_optional<TraceSetup>(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());
}

View File

@@ -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 <Configuration.h>
#include <QFileInfo>
#include <QPointer>
#include <QProcess>
#include <QSyntaxHighlighter>
#include <QTemporaryFile>
#include <QWidget>
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<QProcess> simulatorProcess;
Ui::SimulationDialog *ui;
};
#endif

View File

@@ -0,0 +1,394 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SimulationDialog</class>
<widget class="QWidget" name="SimulationDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>920</width>
<height>620</height>
</rect>
</property>
<property name="font">
<font/>
</property>
<property name="windowTitle">
<string>Simulation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Simulation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="browseLayout">
<item row="3" column="2">
<widget class="QLineEdit" name="resourceDirLineEdit">
<property name="text">
<string/>
</property>
<property name="placeholderText">
<string>Path to resource directory... (optional)</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="browseOutputButton">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="configurationLabel">
<property name="text">
<string>Base configuration:</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QPushButton" name="browseConfigButton">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="dramSysLabel">
<property name="text">
<string>DRAMSys:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="outputDirLabel">
<property name="text">
<string>Output directory:</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="dramSysPath">
<property name="placeholderText">
<string>Path to DRAMSys...</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QPushButton" name="browseResourceDirButton">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="browseDramSysButton">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="outputDirLineEdit">
<property name="placeholderText">
<string>Path to output directory...</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="jsonPath">
<property name="placeholderText">
<string>Path to Json configuration...</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="resourceDirectoryLabel">
<property name="text">
<string>Resource directory:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="simulationIdLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Simulation Id:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="simulationId">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QProgressBar" name="progressBar">
<property name="enabled">
<bool>false</bool>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="simulateButton">
<property name="text">
<string>Start Simulation</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stopButton">
<property name="text">
<string>Stop Simulation</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="simConfigTab">
<attribute name="title">
<string>SimConfig</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QTextEdit" name="simConfigTextEdit">
<property name="font">
<font/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="mcConfigTab">
<attribute name="title">
<string>McConfig</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QTextEdit" name="mcConfigTextEdit">
<property name="font">
<font/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="memSpecTab">
<attribute name="title">
<string>MemSpec</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QTextEdit" name="memSpecTextEdit">
<property name="font">
<font/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="thermalConfigTab">
<attribute name="title">
<string>ThermalConfig</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QTextEdit" name="thermalConfigTextEdit">
<property name="font">
<font/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="traceSetupTab">
<attribute name="title">
<string>TraceSetup</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QTextEdit" name="traceSetupTextEdit">
<property name="font">
<font/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="addressMappingTab">
<attribute name="title">
<string>AddressMapping</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_9">
<item row="0" column="0">
<widget class="QTextEdit" name="addressMappingTextEdit">
<property name="font">
<font/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="previewTab">
<attribute name="title">
<string>Preview Configuration</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_8">
<item row="0" column="0">
<widget class="QTextEdit" name="previewTextEdit">
<property name="font">
<font/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="outputTab">
<attribute name="title">
<string>Output</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QPlainTextEdit" name="outputPlainTextEdit">
<property name="font">
<font/>
</property>
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="reloadButton">
<property name="text">
<string>Reload</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLineEdit" name="simulationIdLineEdit">
<property name="placeholderText">
<string>Simulation Id</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveButton">
<property name="text">
<string>Save</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="closeButton">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>dramSysPath</tabstop>
<tabstop>outputDirLineEdit</tabstop>
<tabstop>jsonPath</tabstop>
<tabstop>resourceDirLineEdit</tabstop>
<tabstop>browseDramSysButton</tabstop>
<tabstop>browseOutputButton</tabstop>
<tabstop>browseConfigButton</tabstop>
<tabstop>browseResourceDirButton</tabstop>
<tabstop>simulateButton</tabstop>
<tabstop>stopButton</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>reloadButton</tabstop>
<tabstop>simulationIdLineEdit</tabstop>
<tabstop>saveButton</tabstop>
<tabstop>closeButton</tabstop>
<tabstop>simConfigTextEdit</tabstop>
<tabstop>outputPlainTextEdit</tabstop>
<tabstop>memSpecTextEdit</tabstop>
<tabstop>thermalConfigTextEdit</tabstop>
<tabstop>traceSetupTextEdit</tabstop>
<tabstop>addressMappingTextEdit</tabstop>
<tabstop>mcConfigTextEdit</tabstop>
<tabstop>previewTextEdit</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>closeButton</sender>
<signal>clicked()</signal>
<receiver>SimulationDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>836</x>
<y>507</y>
</hint>
<hint type="destinationlabel">
<x>830</x>
<y>575</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -37,8 +37,10 @@
*/
#include "traceanalyzer.h"
#include "simulationdialog.h"
#include "tracefiletab.h"
#include "ui_traceanalyzer.h"
#include <QCloseEvent>
#include <QDateTime>
#include <QFileDialog>
@@ -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();
}

View File

@@ -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);

View File

@@ -78,7 +78,14 @@
</property>
<addaction name="actionAbout"/>
</widget>
<widget class="QMenu" name="menuRun">
<property name="title">
<string>&amp;Run</string>
</property>
<addaction name="actionSimulate"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuRun"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
@@ -225,6 +232,14 @@
<string>Save &amp;as...</string>
</property>
</action>
<action name="actionSimulate">
<property name="icon">
<iconset theme="system-run"/>
</property>
<property name="text">
<string>&amp;Simulate...</string>
</property>
</action>
</widget>
<resources/>
<connections>