Files
DRAMSys/tests/tests_configuration/test_configuration.cpp

576 lines
19 KiB
C++

/*
* 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 <DRAMSys/config/DRAMSysConfiguration.h>
#include <DRAMSys/util/json.h>
#include <fstream>
#include <gtest/gtest.h>
#include <iostream>
#include <unordered_map>
using namespace DRAMSys::Config;
class ConfigurationTest : public ::testing::Test
{
protected:
ConfigurationTest()
: memSpec(createMemSpec()),
tracePlayer(createTracePlayer()),
traceGeneratorOneState(createTraceGeneratorOneState()),
traceGeneratorMultipleStates(createTraceGeneratorMultipleStates()),
traceHammer(createTraceHammer())
{
}
static DRAMSys::Config::MemSpec createMemSpec();
static DRAMSys::Config::TracePlayer createTracePlayer();
static DRAMSys::Config::TrafficGenerator createTraceGeneratorOneState();
static DRAMSys::Config::TrafficGeneratorStateMachine createTraceGeneratorMultipleStates();
static DRAMSys::Config::RowHammer createTraceHammer();
DRAMSys::Config::AddressMapping 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}},
std::nullopt,
std::nullopt,
std::nullopt};
DRAMSys::Config::McConfig mcConfig{PagePolicyType::Open,
SchedulerType::FrFcfs,
0,
0,
SchedulerBufferType::Bankwise,
8,
CmdMuxType::Oldest,
RespQueueType::Fifo,
RefreshPolicyType::AllBank,
0,
0,
PowerDownPolicyType::NoPowerDown,
ArbiterType::Simple,
128,
{}};
DRAMSys::Config::SimConfig simConfig{0,
false,
true,
false,
false,
{"error.csv"},
42,
false,
{"ddr5"},
true,
DRAMSys::Config::StoreModeType::NoStorage,
false,
false,
1000};
DRAMSys::Config::MemSpec memSpec;
DRAMSys::Config::TracePlayer tracePlayer;
DRAMSys::Config::TrafficGenerator traceGeneratorOneState;
DRAMSys::Config::TrafficGeneratorStateMachine traceGeneratorMultipleStates;
DRAMSys::Config::RowHammer traceHammer;
DRAMSys::Config::TraceSetup traceSetup{{tracePlayer, traceGeneratorOneState, traceGeneratorMultipleStates, traceHammer}};
DRAMSys::Config::Configuration configuration{
addressMapping,
mcConfig,
memSpec,
simConfig,
"std::string_simulationId",
traceSetup
};
};
DRAMSys::Config::MemSpec ConfigurationTest::createMemSpec()
{
MemArchitectureSpecType memArchitectureSpec{{{"burstLength", 16},
{"dataRate", 2},
{"nbrOfBankGroups", 8},
{"nbrOfBanks", 16},
{"nbrOfColumns", 2048},
{"nbrOfRanks", 1},
{"nbrOfDIMMRanks", 1},
{"nbrOfPhysicalRanks", 1},
{"nbrOfLogicalRanks", 1},
{"nbrOfRows", 65536},
{"width", 4},
{"nbrOfDevices", 8},
{"nbrOfChannels", 2},
{"cmdMode", 1},
{"refMode", 1},
{"RAAIMT", 32},
{"RAAMMT", 96},
{"RAADEC", 1}}};
MemTimingSpecType memTimingSpec{{{
{"RCD", 22}, {"PPD", 2}, {"RP", 22}, {"RAS", 52},
{"RL", 22}, {"RTP", 12}, {"RPRE", 1}, {"RPST", 0},
{"RDDQS", 0}, {"WL", 20}, {"WPRE", 2}, {"WPST", 0},
{"WR", 48}, {"CCD_L_slr", 8}, {"CCD_L_WR_slr", 32}, {"CCD_L_WR2_slr", 16},
{"CCD_S_slr", 8}, {"CCD_S_WR_slr", 8}, {"CCD_dlr", 0}, {"CCD_WR_dlr", 0},
{"CCD_WR_dpr", 0}, {"RRD_L_slr", 8}, {"RRD_S_slr", 8}, {"RRD_dlr", 0},
{"FAW_slr", 32}, {"FAW_dlr", 0}, {"WTR_L", 16}, {"WTR_S", 4},
{"RFC1_slr", 312}, {"RFC2_slr", 208}, {"RFC1_dlr", 0}, {"RFC2_dlr", 0},
{"RFC1_dpr", 0}, {"RFC2_dpr", 0}, {"RFCsb_slr", 184}, {"RFCsb_dlr", 0},
{"REFI1", 6240}, {"REFI2", 3120}, {"REFISB", 1560}, {"REFSBRD_slr", 48},
{"REFSBRD_dlr", 0}, {"RTRS", 2}, {"CPDED", 8}, {"PD", 12},
{"XP", 12}, {"ACTPDEN", 2}, {"PRPDEN", 2}, {"REFPDEN", 2},
{"clkMhz", 1600},
}}};
return {memArchitectureSpec, "JEDEC_2x8x2Gbx4_DDR5-3200A", "DDR5", memTimingSpec, {}};
}
DRAMSys::Config::TracePlayer ConfigurationTest::createTracePlayer()
{
DRAMSys::Config::TracePlayer player;
player.clkMhz = 100;
player.name = "mytrace.stl";
return player;
}
DRAMSys::Config::TrafficGenerator ConfigurationTest::createTraceGeneratorOneState()
{
DRAMSys::Config::TrafficGenerator gen;
gen.clkMhz = 100;
gen.name = "MyTestGen";
gen.numRequests = 1000;
gen.rwRatio = 0.5;
gen.addressDistribution = DRAMSys::Config::AddressDistribution::Random;
gen.addressIncrement = {};
gen.minAddress = {};
gen.maxAddress = {};
return gen;
}
DRAMSys::Config::TrafficGeneratorStateMachine ConfigurationTest::createTraceGeneratorMultipleStates()
{
DRAMSys::Config::TrafficGeneratorStateMachine gen;
gen.clkMhz = 100;
gen.name = "MyTestGen";
gen.maxPendingReadRequests = 8;
DRAMSys::Config::TrafficGeneratorActiveState state0;
state0.numRequests = 1000;
state0.rwRatio = 0.5;
state0.addressDistribution = DRAMSys::Config::AddressDistribution::Sequential;
state0.addressIncrement = 256;
state0.minAddress = {};
state0.maxAddress = 1024;
state0.id = 0;
DRAMSys::Config::TrafficGeneratorActiveState state1;
state1.numRequests = 100;
state1.rwRatio = 0.75;
state1.addressDistribution = DRAMSys::Config::AddressDistribution::Sequential;
state1.addressIncrement = 512;
state1.minAddress = 1024;
state1.maxAddress = 2048;
state1.id = 1;
gen.states.push_back(state0);
gen.states.push_back(state1);
DRAMSys::Config::TrafficGeneratorStateTransition transistion0{0, 1, 1.0};
gen.transitions.push_back(transistion0);
return gen;
}
DRAMSys::Config::RowHammer ConfigurationTest::createTraceHammer()
{
DRAMSys::Config::RowHammer hammer;
hammer.clkMhz = 100;
hammer.name = "MyTestHammer";
hammer.numRequests = 4000;
hammer.rowIncrement = 2097152;
return hammer;
}
TEST_F(ConfigurationTest, ToJson)
{
json_t config_json;
config_json["simulation"] = configuration;
std::ifstream file("reference.json");
ASSERT_TRUE(file.is_open());
json_t reference_json = json_t::parse(file);
std::cout << reference_json.dump(4) << std::endl;
EXPECT_EQ(config_json, reference_json);
}
TEST(Configuration, FromToJson)
{
std::ifstream file("reference.json");
ASSERT_TRUE(file.is_open());
json_t reference_json = json_t::parse(file);
DRAMSys::Config::Configuration reference_configuration =
reference_json["simulation"].get<DRAMSys::Config::Configuration>();
json_t new_json;
new_json["simulation"] = reference_configuration;
EXPECT_EQ(new_json, reference_json);
}
TEST_F(ConfigurationTest, DumpConfiguration)
{
// This test does not test anything. It just dumps the configuration to stdout for manual
// inspection.
json_t json;
json["simulation"] = configuration;
std::cout << json.dump(4) << std::endl;
}
TEST(Configuration, ResourceDirectory)
{
// Test should not throw exceptions
Configuration config = from_path("resources/ddr5-example.json", "resources");
}
TEST(Configuration, FromPath)
{
// Test should not throw exceptions
Configuration config = from_path("reference.json");
}
TEST(RefreshPolicyType, BackwardsCompatibility)
{
// Deserializing
EXPECT_EQ(json_t("Rankwise").get<RefreshPolicyType>(), RefreshPolicyType::AllBank);
EXPECT_EQ(json_t("Bankwise").get<RefreshPolicyType>(), RefreshPolicyType::PerBank);
EXPECT_EQ(json_t("Groupwise").get<RefreshPolicyType>(), RefreshPolicyType::SameBank);
// Serializing
EXPECT_EQ(json_t(RefreshPolicyType::AllBank).get<std::string>(), "AllBank");
EXPECT_EQ(json_t(RefreshPolicyType::PerBank).get<std::string>(), "PerBank");
EXPECT_EQ(json_t(RefreshPolicyType::SameBank).get<std::string>(), "SameBank");
}
TEST_F(ConfigurationTest, SimConfig)
{
std::string_view simconfig_string = R"(
{
"simconfig": {
"AddressOffset": 0,
"CheckTLM2Protocol": false,
"DatabaseRecording": true,
"Debug": false,
"EnableWindowing": false,
"ErrorCSVFile": "error.csv",
"ErrorChipSeed": 42,
"PowerAnalysis": false,
"SimulationName": "ddr5",
"SimulationProgressBar": true,
"StoreMode": "NoStorage",
"ThermalSimulation": false,
"UseMalloc": false,
"WindowSize": 1000
}
}
)";
json_t simconfig_reference = json_t::parse(simconfig_string);
json_t simconfig_test;
simconfig_test[SimConfig::KEY] = simConfig;
EXPECT_EQ(simconfig_test, simconfig_reference);
}
TEST_F(ConfigurationTest, McConfig)
{
std::string_view mcconfig_string = R"(
{
"mcconfig": {
"Arbiter": "Simple",
"CmdMux": "Oldest",
"HighWatermark": 0,
"LowWatermark": 0,
"MaxActiveTransactions": 128,
"PagePolicy": "Open",
"PowerDownPolicy": "NoPowerDown",
"RefreshMaxPostponed": 0,
"RefreshMaxPulledin": 0,
"RefreshPolicy": "AllBank",
"RequestBufferSize": 8,
"RespQueue": "Fifo",
"Scheduler": "FrFcfs",
"SchedulerBuffer": "Bankwise"
}
}
)";
json_t mcconfig_reference = json_t::parse(mcconfig_string);
json_t mcconfig_test;
mcconfig_test[McConfig::KEY] = mcConfig;
EXPECT_EQ(mcconfig_test, mcconfig_reference);
}
TEST_F(ConfigurationTest, MemSpec)
{
std::string_view memspec_string = R"(
{
"memspec": {
"memarchitecturespec": {
"RAADEC": 1,
"RAAIMT": 32,
"RAAMMT": 96,
"burstLength": 16,
"cmdMode": 1,
"dataRate": 2,
"nbrOfBankGroups": 8,
"nbrOfBanks": 16,
"nbrOfChannels": 2,
"nbrOfColumns": 2048,
"nbrOfDIMMRanks": 1,
"nbrOfDevices": 8,
"nbrOfLogicalRanks": 1,
"nbrOfPhysicalRanks": 1,
"nbrOfRanks": 1,
"nbrOfRows": 65536,
"refMode": 1,
"width": 4
},
"memoryId": "JEDEC_2x8x2Gbx4_DDR5-3200A",
"memoryType": "DDR5",
"memtimingspec": {
"ACTPDEN": 2,
"CCD_L_WR2_slr": 16,
"CCD_L_WR_slr": 32,
"CCD_L_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_S_slr": 8,
"CCD_WR_dlr": 0,
"CCD_WR_dpr": 0,
"CCD_dlr": 0,
"CPDED": 8,
"FAW_dlr": 0,
"FAW_slr": 32,
"PD": 12,
"PPD": 2,
"PRPDEN": 2,
"RAS": 52,
"RCD": 22,
"RDDQS": 0,
"REFI1": 6240,
"REFI2": 3120,
"REFISB": 1560,
"REFPDEN": 2,
"REFSBRD_dlr": 0,
"REFSBRD_slr": 48,
"RFC1_dlr": 0,
"RFC1_dpr": 0,
"RFC1_slr": 312,
"RFC2_dlr": 0,
"RFC2_dpr": 0,
"RFC2_slr": 208,
"RFCsb_dlr": 0,
"RFCsb_slr": 184,
"RL": 22,
"RP": 22,
"RPRE": 1,
"RPST": 0,
"RRD_L_slr": 8,
"RRD_S_slr": 8,
"RRD_dlr": 0,
"RTP": 12,
"RTRS": 2,
"WL": 20,
"WPRE": 2,
"WPST": 0,
"WR": 48,
"WTR_L": 16,
"WTR_S": 4,
"XP": 12,
"clkMhz": 1600
}
}
}
)";
json_t memspec_reference = json_t::parse(memspec_string);
json_t memspec_test;
memspec_test[MemSpec::KEY] = memSpec;
EXPECT_EQ(memspec_test, memspec_reference);
}
TEST_F(ConfigurationTest, AddressMapping)
{
std::string_view addressmapping_string = R"(
{
"addressmapping": {
"BANKGROUP_BIT": [
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32
],
"BANK_BIT": [
13,
14,
15
],
"BYTE_BIT": [
0,
1
],
"COLUMN_BIT": [
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12
],
"RANK_BIT": [
33
],
"ROW_BIT": [
16
]
}
}
)";
json_t addressmapping_reference = json_t::parse(addressmapping_string);
json_t addressmapping_test;
addressmapping_test[AddressMapping::KEY] = addressMapping;
EXPECT_EQ(addressmapping_test, addressmapping_reference);
}
TEST_F(ConfigurationTest, TraceSetup)
{
std::string_view tracesetup_string = R"(
{
"tracesetup": [
{
"clkMhz": 100,
"name": "mytrace.stl"
},
{
"addressDistribution": "random",
"clkMhz": 100,
"name": "MyTestGen",
"numRequests": 1000,
"rwRatio": 0.5
},
{
"clkMhz": 100,
"maxPendingReadRequests": 8,
"name": "MyTestGen",
"states": [
{
"addressDistribution": "sequential",
"addressIncrement": 256,
"id": 0,
"maxAddress": 1024,
"numRequests": 1000,
"rwRatio": 0.5
},
{
"addressDistribution": "sequential",
"addressIncrement": 512,
"id": 1,
"maxAddress": 2048,
"minAddress": 1024,
"numRequests": 100,
"rwRatio": 0.75
}
],
"transitions": [
{
"from": 0,
"probability": 1.0,
"to": 1
}
]
},
{
"clkMhz": 100,
"name": "MyTestHammer",
"numRequests": 4000,
"rowIncrement": 2097152
}
]
}
)";
json_t tracesetup_reference = json_t::parse(tracesetup_string);
json_t tracesetup_test;
tracesetup_test[TraceSetupConstants::KEY] = traceSetup;
EXPECT_EQ(tracesetup_test, tracesetup_reference);
}