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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
120
DRAMSys/library/src/common/configuration/AddressMapping.cpp
Normal file
120
DRAMSys/library/src/common/configuration/AddressMapping.cpp
Normal 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
|
||||
79
DRAMSys/library/src/common/configuration/AddressMapping.h
Normal file
79
DRAMSys/library/src/common/configuration/AddressMapping.h
Normal 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
|
||||
62
DRAMSys/library/src/common/configuration/CMakeLists.txt
Normal file
62
DRAMSys/library/src/common/configuration/CMakeLists.txt
Normal 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)
|
||||
100
DRAMSys/library/src/common/configuration/Configuration.cpp
Normal file
100
DRAMSys/library/src/common/configuration/Configuration.cpp
Normal 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
|
||||
88
DRAMSys/library/src/common/configuration/Configuration.h
Normal file
88
DRAMSys/library/src/common/configuration/Configuration.h
Normal 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
|
||||
183
DRAMSys/library/src/common/configuration/McConfig.cpp
Normal file
183
DRAMSys/library/src/common/configuration/McConfig.cpp
Normal 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
|
||||
183
DRAMSys/library/src/common/configuration/McConfig.h
Normal file
183
DRAMSys/library/src/common/configuration/McConfig.h
Normal 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
|
||||
121
DRAMSys/library/src/common/configuration/SimConfig.cpp
Normal file
121
DRAMSys/library/src/common/configuration/SimConfig.cpp
Normal 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
|
||||
89
DRAMSys/library/src/common/configuration/SimConfig.h
Normal file
89
DRAMSys/library/src/common/configuration/SimConfig.h
Normal 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
|
||||
122
DRAMSys/library/src/common/configuration/ThermalConfig.cpp
Normal file
122
DRAMSys/library/src/common/configuration/ThermalConfig.cpp
Normal 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
|
||||
120
DRAMSys/library/src/common/configuration/ThermalConfig.h
Normal file
120
DRAMSys/library/src/common/configuration/ThermalConfig.h
Normal 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
|
||||
315
DRAMSys/library/src/common/configuration/TraceSetup.cpp
Normal file
315
DRAMSys/library/src/common/configuration/TraceSetup.cpp
Normal 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
|
||||
144
DRAMSys/library/src/common/configuration/TraceSetup.h
Normal file
144
DRAMSys/library/src/common/configuration/TraceSetup.h
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
78
DRAMSys/library/src/common/configuration/memspec/MemSpec.cpp
Normal file
78
DRAMSys/library/src/common/configuration/memspec/MemSpec.cpp
Normal 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
|
||||
70
DRAMSys/library/src/common/configuration/memspec/MemSpec.h
Normal file
70
DRAMSys/library/src/common/configuration/memspec/MemSpec.h
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
58
DRAMSys/library/src/common/configuration/tests/converter.cpp
Normal file
58
DRAMSys/library/src/common/configuration/tests/converter.cpp
Normal 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;
|
||||
}
|
||||
226
DRAMSys/library/src/common/configuration/tests/simpletest.cpp
Normal file
226
DRAMSys/library/src/common/configuration/tests/simpletest.cpp
Normal 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);
|
||||
}
|
||||
61
DRAMSys/library/src/common/configuration/util.cpp
Normal file
61
DRAMSys/library/src/common/configuration/util.cpp
Normal 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
|
||||
144
DRAMSys/library/src/common/configuration/util.h
Normal file
144
DRAMSys/library/src/common/configuration/util.h
Normal 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
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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(¬ifier->getStateTransitionEvent(*idleUntil));
|
||||
}
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("TraceSetup", "Empty trace setup item.");
|
||||
}
|
||||
|
||||
remainingTransactions = totalTransactions;
|
||||
@@ -262,7 +210,7 @@ void TraceSetup::loadBar(uint64_t x, uint64_t n, unsigned int w, unsigned int gr
|
||||
if ((n < 100) || ((x != n) && (x % (n / 100 * granularity) != 0)))
|
||||
return;
|
||||
|
||||
float ratio = x / (float) n;
|
||||
float ratio = x / (float)n;
|
||||
unsigned int c = (ratio * w);
|
||||
float rest = (ratio * w) - c;
|
||||
std::cout << std::setw(3) << round(ratio * 100) << "% |";
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
8
DRAMSys/traceAnalyzer/.directory
Normal file
8
DRAMSys/traceAnalyzer/.directory
Normal 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
|
||||
@@ -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
|
||||
)
|
||||
|
||||
409
DRAMSys/traceAnalyzer/simulationdialog.cpp
Normal file
409
DRAMSys/traceAnalyzer/simulationdialog.cpp
Normal 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());
|
||||
}
|
||||
102
DRAMSys/traceAnalyzer/simulationdialog.h
Normal file
102
DRAMSys/traceAnalyzer/simulationdialog.h
Normal 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
|
||||
394
DRAMSys/traceAnalyzer/simulationdialog.ui
Normal file
394
DRAMSys/traceAnalyzer/simulationdialog.ui
Normal 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>
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -78,7 +78,14 @@
|
||||
</property>
|
||||
<addaction name="actionAbout"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuRun">
|
||||
<property name="title">
|
||||
<string>&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 &as...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSimulate">
|
||||
<property name="icon">
|
||||
<iconset theme="system-run"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Simulate...</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
|
||||
Reference in New Issue
Block a user