From d27a29ca80ea91741262e06019e85c8c77b9e544 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Fri, 16 Dec 2022 12:39:47 +0100 Subject: [PATCH 01/20] Refactor configuration library The configuration library has been refactored to make use of nlohmann macros to reduce boilerplate code. The nlohmann parser callback is used to decide whether to include configuration json objects directly, or if they need to be loaded from a sperate file. --- .../apps/traceAnalyzer/simulationdialog.cpp | 32 +- .../configuration/memspec/MemSpecDDR5.cpp | 140 ++--- .../configuration/memspec/MemSpecHBM3.cpp | 86 +-- .../configuration/memspec/MemSpecLPDDR5.cpp | 88 +-- .../DRAMSys/config/AddressMapping.cpp | 79 --- .../DRAMSys/config/AddressMapping.h | 46 +- .../DRAMSys/config/ConfigUtil.cpp | 18 +- src/configuration/DRAMSys/config/ConfigUtil.h | 48 -- .../DRAMSys/config/DRAMSysConfiguration.cpp | 133 +++-- .../DRAMSys/config/DRAMSysConfiguration.h | 34 +- src/configuration/DRAMSys/config/McConfig.cpp | 152 +---- src/configuration/DRAMSys/config/McConfig.h | 156 +++-- .../DRAMSys/config/SimConfig.cpp | 80 --- src/configuration/DRAMSys/config/SimConfig.h | 62 +- .../DRAMSys/config/TraceSetup.cpp | 274 +-------- src/configuration/DRAMSys/config/TraceSetup.h | 122 +++- .../config/memspec/MemArchitectureSpec.cpp | 4 +- .../config/memspec/MemArchitectureSpec.h | 6 +- .../DRAMSys/config/memspec/MemSpec.cpp | 37 -- .../DRAMSys/config/memspec/MemSpec.h | 18 +- .../DRAMSys/config/memspec/MemTimingSpec.cpp | 4 +- .../DRAMSys/config/memspec/MemTimingSpec.h | 6 +- .../DRAMSys/configuration/Configuration.cpp | 112 ++-- .../DRAMSys/configuration/memspec/MemSpec.cpp | 18 +- .../configuration/memspec/MemSpecDDR3.cpp | 94 +-- .../configuration/memspec/MemSpecDDR4.cpp | 132 ++-- .../configuration/memspec/MemSpecGDDR5.cpp | 90 +-- .../configuration/memspec/MemSpecGDDR5X.cpp | 90 +-- .../configuration/memspec/MemSpecGDDR6.cpp | 96 +-- .../configuration/memspec/MemSpecHBM2.cpp | 78 +-- .../configuration/memspec/MemSpecLPDDR4.cpp | 78 +-- .../configuration/memspec/MemSpecSTTMRAM.cpp | 62 +- .../configuration/memspec/MemSpecWideIO.cpp | 108 ++-- .../configuration/memspec/MemSpecWideIO2.cpp | 70 +-- .../DRAMSys/simulation/AddressDecoder.cpp | 18 +- src/libdramsys/DRAMSys/simulation/DRAMSys.cpp | 8 +- .../DRAMSys/simulation/DRAMSysRecordable.cpp | 10 +- src/simulator/simulator/main.cpp | 6 +- src/util/DRAMSys/util/json.h | 88 +++ tests/tests_configuration/CMakeLists.txt | 30 +- .../{converter.cpp => jsonconverter.cpp} | 4 +- tests/tests_configuration/reference.json | 212 +++++++ .../am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json | 50 ++ .../resources/ddr5-example.json | 11 + .../resources/mcconfig/fr_fcfs.json | 17 + .../memspec/JEDEC_2x8x2Gbx4_DDR5-3200A.json | 77 +++ .../resources/simconfig/ddr5.json | 19 + .../resources/tracesetup/ddr5-trace.json | 28 + .../test_configuration.cpp | 564 ++++++++++++++++++ tests/tests_dramsys/CommandMuxTests.cpp | 110 ---- 50 files changed, 2194 insertions(+), 1711 deletions(-) rename tests/tests_configuration/{converter.cpp => jsonconverter.cpp} (100%) create mode 100644 tests/tests_configuration/reference.json create mode 100644 tests/tests_configuration/resources/addressmapping/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json create mode 100644 tests/tests_configuration/resources/ddr5-example.json create mode 100644 tests/tests_configuration/resources/mcconfig/fr_fcfs.json create mode 100644 tests/tests_configuration/resources/memspec/JEDEC_2x8x2Gbx4_DDR5-3200A.json create mode 100644 tests/tests_configuration/resources/simconfig/ddr5.json create mode 100644 tests/tests_configuration/resources/tracesetup/ddr5-trace.json create mode 100644 tests/tests_configuration/test_configuration.cpp delete mode 100644 tests/tests_dramsys/CommandMuxTests.cpp diff --git a/extensions/apps/traceAnalyzer/simulationdialog.cpp b/extensions/apps/traceAnalyzer/simulationdialog.cpp index df72ec9a..6f72b807 100644 --- a/extensions/apps/traceAnalyzer/simulationdialog.cpp +++ b/extensions/apps/traceAnalyzer/simulationdialog.cpp @@ -217,7 +217,7 @@ void SimulationDialog::saveConfiguration(QFile &file) loadConfigurationFromTextFields(); - std::string dump = DRAMSys::Config::dump(configuration, 4); + std::string dump = nlohmann::json(configuration).dump(4); out << dump.c_str(); } @@ -252,13 +252,13 @@ void SimulationDialog::loadConfigurationFromTextFields() 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); + nlohmann::json::parse(ui->addressMappingTextEdit->toPlainText().toStdString()).get_to(addressMapping); + nlohmann::json::parse(ui->mcConfigTextEdit->toPlainText().toStdString()).get_to(mcConfig); + nlohmann::json::parse(ui->memSpecTextEdit->toPlainText().toStdString()).get_to(memSpec); + nlohmann::json::parse(ui->simConfigTextEdit->toPlainText().toStdString()).get_to(simConfig); if (!ui->traceSetupTextEdit->toPlainText().toStdString().empty()) - from_dump(ui->traceSetupTextEdit->toPlainText().toStdString(), traceSetup); + nlohmann::json::parse(ui->traceSetupTextEdit->toPlainText().toStdString()).get_to(traceSetup); } catch (const std::exception &e) { @@ -300,9 +300,9 @@ void SimulationDialog::loadConfiguration() { ui->simulationIdLabel->setEnabled(true); ui->simulationId->setEnabled(true); - ui->simulationId->setText(configuration.simulationId.c_str()); + ui->simulationId->setText(configuration.simulationid.c_str()); - ui->simulationIdLineEdit->setText(configuration.simulationId.c_str()); + ui->simulationIdLineEdit->setText(configuration.simulationid.c_str()); loadSimConfig(); loadMcConfig(); @@ -316,7 +316,7 @@ void SimulationDialog::loadSimConfig() { ui->simConfigTextEdit->clear(); - std::string dump = DRAMSys::Config::dump(configuration.simConfig, 4); + std::string dump = nlohmann::json(configuration.simconfig).dump(4); ui->simConfigTextEdit->setText(dump.c_str()); } @@ -324,7 +324,7 @@ void SimulationDialog::loadMcConfig() { ui->mcConfigTextEdit->clear(); - std::string dump = DRAMSys::Config::dump(configuration.mcConfig, 4); + std::string dump = nlohmann::json(configuration.mcconfig).dump(4); ui->mcConfigTextEdit->setText(dump.c_str()); } @@ -332,7 +332,7 @@ void SimulationDialog::loadMemSpec() { ui->memSpecTextEdit->clear(); - std::string dump = DRAMSys::Config::dump(configuration.memSpec, 4); + std::string dump = nlohmann::json(configuration.memspec).dump(4); ui->memSpecTextEdit->setText(dump.c_str()); } @@ -340,7 +340,7 @@ void SimulationDialog::loadAddressMapping() { ui->addressMappingTextEdit->clear(); - std::string dump = DRAMSys::Config::dump(configuration.addressMapping, 4); + std::string dump = nlohmann::json(configuration.addressmapping).dump(4); ui->addressMappingTextEdit->setText(dump.c_str()); } @@ -348,9 +348,9 @@ void SimulationDialog::loadTraceSetup() { ui->traceSetupTextEdit->clear(); - if (const auto &traceSetup = configuration.traceSetup) + if (const auto &traceSetup = configuration.tracesetup) { - std::string dump = DRAMSys::Config::dump(*traceSetup, 4); + std::string dump = nlohmann::json(*traceSetup).dump(4); ui->traceSetupTextEdit->setText(dump.c_str()); } } @@ -359,7 +359,7 @@ void SimulationDialog::loadPreview() { ui->previewTextEdit->clear(); - std::string dump = DRAMSys::Config::dump(configuration, 4); + std::string dump = nlohmann::json(configuration).dump(4); ui->previewTextEdit->setText(dump.c_str()); } @@ -372,7 +372,7 @@ QFileInfoList SimulationDialog::getSimulationResults() for (const auto &fileInfo : baseDir.entryInfoList()) { - if (fileInfo.baseName().startsWith(configuration.simulationId.c_str())) + 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) diff --git a/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.cpp b/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.cpp index f58f086b..ab201a8d 100644 --- a/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.cpp +++ b/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.cpp @@ -45,80 +45,80 @@ using namespace tlm; MemSpecDDR5::MemSpecDDR5(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::DDR5, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), 1, - 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")), - dimmRanksPerChannel(memSpec.memArchitectureSpec.entries.at("nbrOfDIMMRanks")), - physicalRanksPerDimmRank(memSpec.memArchitectureSpec.entries.at("nbrOfPhysicalRanks")), + 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")), + dimmRanksPerChannel(memSpec.memarchitecturespec.entries.at("nbrOfDIMMRanks")), + physicalRanksPerDimmRank(memSpec.memarchitecturespec.entries.at("nbrOfPhysicalRanks")), physicalRanksPerChannel(physicalRanksPerDimmRank * dimmRanksPerChannel), - logicalRanksPerPhysicalRank(memSpec.memArchitectureSpec.entries.at("nbrOfLogicalRanks")), + logicalRanksPerPhysicalRank(memSpec.memarchitecturespec.entries.at("nbrOfLogicalRanks")), logicalRanksPerChannel(logicalRanksPerPhysicalRank * physicalRanksPerChannel), - 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")), + 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 * 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_M_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_M_slr")), - tCCD_M_WR_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_M_WR_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_M (tCK * memSpec.memTimingSpec.entries.at("WTR_M")), - 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")), + 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_M_slr (tCK * memSpec.memtimingspec.entries.at("CCD_M_slr")), + tCCD_M_WR_slr (tCK * memSpec.memtimingspec.entries.at("CCD_M_WR_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_M (tCK * memSpec.memtimingspec.entries.at("WTR_M")), + 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), diff --git a/extensions/standards/HBM3/DRAMSys/configuration/memspec/MemSpecHBM3.cpp b/extensions/standards/HBM3/DRAMSys/configuration/memspec/MemSpecHBM3.cpp index 7a4251c7..c717c23d 100644 --- a/extensions/standards/HBM3/DRAMSys/configuration/memspec/MemSpecHBM3.cpp +++ b/extensions/standards/HBM3/DRAMSys/configuration/memspec/MemSpecHBM3.cpp @@ -44,51 +44,51 @@ using namespace tlm; MemSpecHBM3::MemSpecHBM3(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::HBM3, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), - memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"), - memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"), - 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("nbrOfPseudoChannels"), - memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups") - * memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"), - memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), - RAAIMT(memSpec.memArchitectureSpec.entries.at("RAAIMT")), - RAAMMT(memSpec.memArchitectureSpec.entries.at("RAAMMT")), - RAACDR(memSpec.memArchitectureSpec.entries.at("RAACDR")), - 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")), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"), + 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("nbrOfPseudoChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfBankGroups") + * memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfDevices")), + RAAIMT(memSpec.memarchitecturespec.entries.at("RAAIMT")), + RAAMMT(memSpec.memarchitecturespec.entries.at("RAAMMT")), + RAACDR(memSpec.memarchitecturespec.entries.at("RAACDR")), + 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 * memSpec.memTimingSpec.entries.at("XS")), - tRFC (tCK * memSpec.memTimingSpec.entries.at("RFC")), - tRFCPB (tCK * memSpec.memTimingSpec.entries.at("RFCPB")), - tRREFD (tCK * memSpec.memTimingSpec.entries.at("RREFD")), - tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")), - tREFIPB (tCK * memSpec.memTimingSpec.entries.at("REFIPB")), - tPPD (tCK * memSpec.memTimingSpec.entries.at("PPD")) + tXS (tCK * memSpec.memtimingspec.entries.at("XS")), + tRFC (tCK * memSpec.memtimingspec.entries.at("RFC")), + tRFCPB (tCK * memSpec.memtimingspec.entries.at("RFCPB")), + tRREFD (tCK * memSpec.memtimingspec.entries.at("RREFD")), + tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")), + tREFIPB (tCK * memSpec.memtimingspec.entries.at("REFIPB")), + tPPD (tCK * memSpec.memtimingspec.entries.at("PPD")) { commandLengthInCycles[Command::ACT] = 1.5; commandLengthInCycles[Command::PREPB] = 0.5; diff --git a/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.cpp b/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.cpp index e805852c..7fb0469b 100644 --- a/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.cpp +++ b/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.cpp @@ -44,42 +44,42 @@ using namespace tlm; MemSpecLPDDR5::MemSpecLPDDR5(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::LPDDR5, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), 1, - 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_L (tCK * memSpec.memTimingSpec.entries.at("RCD_L")), - tRCD_S (tCK * memSpec.memTimingSpec.entries.at("RCD_S")), - tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), - tRRD (tCK * memSpec.memTimingSpec.entries.at("RRD")), + 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_L (tCK * memSpec.memtimingspec.entries.at("RCD_L")), + tRCD_S (tCK * memSpec.memtimingspec.entries.at("RCD_S")), + tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")), + tRRD (tCK * memSpec.memtimingspec.entries.at("RRD")), //tCCD (tCK * parseUint(memspec["memtimingspec"], "CCD")), - tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), + tRL (tCK * memSpec.memtimingspec.entries.at("RL")), //tRPST (tCK * parseUint(memspec["memtimingspec"], "RPST")), //tDQSCK (tCK * parseUint(memspec["memtimingspec"], "DQSCK")), - tRBTP (tCK * memSpec.memTimingSpec.entries.at("RBTP")), - tWL (tCK * memSpec.memTimingSpec.entries.at("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 * memSpec.memTimingSpec.entries.at("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")), @@ -88,20 +88,20 @@ MemSpecLPDDR5::MemSpecLPDDR5(const DRAMSys::Config::MemSpec &memSpec) //tESCKE (tCK * parseUint(memspec["memtimingspec"], "ESCKE")), //tCKE (tCK * parseUint(memspec["memtimingspec"], "CKE")), //tCMDCKE (tCK * parseUint(memspec["memtimingspec"], "CMDCKE")), - 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")), + 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")), tBURST16(tCK * 16 / dataRate), tBURST32(tCK * 32 / dataRate), bankMode(groupsPerRank != 1 ? BankMode::MBG : (banksPerRank == 16 ? BankMode::M16B : BankMode::M8B)) diff --git a/src/configuration/DRAMSys/config/AddressMapping.cpp b/src/configuration/DRAMSys/config/AddressMapping.cpp index 8123c88f..857683b2 100644 --- a/src/configuration/DRAMSys/config/AddressMapping.cpp +++ b/src/configuration/DRAMSys/config/AddressMapping.cpp @@ -40,83 +40,4 @@ namespace DRAMSys::Config { -void to_json(json_t &j, const AddressMapping &m) -{ - auto congen = json_t{{"BYTE_BIT", m.byteBits}, - {"COLUMN_BIT", m.columnBits}, - {"ROW_BIT", m.rowBits}, - {"BANK_BIT", m.bankBits}, - {"BANKGROUP_BIT", m.bankGroupBits}, - {"RANK_BIT", m.rankBits}, - {"CHANNEL_BIT", m.channelBits}, - {"XOR", m.xorBits}}; - - remove_null_values(congen); - - j["CONGEN"] = congen; -} - -void from_json(const json_t &j, AddressMapping &m) -{ - json_t j_addressmapping = get_config_json(j, addressMappingPath, "CONGEN"); - - json_t congen; - if (j_addressmapping["CONGEN"].is_null()) - congen = j_addressmapping; - else - congen = j_addressmapping["CONGEN"]; - - if (congen.contains("BYTE_BIT")) - congen.at("BYTE_BIT").get_to(m.byteBits); - - if (congen.contains("COLUMN_BIT")) - congen.at("COLUMN_BIT").get_to(m.columnBits); - - if (congen.contains("ROW_BIT")) - congen.at("ROW_BIT").get_to(m.rowBits); - - if (congen.contains("BANK_BIT")) - congen.at("BANK_BIT").get_to(m.bankBits); - - if (congen.contains("BANKGROUP_BIT")) - congen.at("BANKGROUP_BIT").get_to(m.bankGroupBits); - - if (congen.contains("RANK_BIT")) - congen.at("RANK_BIT").get_to(m.rankBits); - - // HBM pseudo channels are internally modelled as ranks - if (congen.contains("PSEUDOCHANNEL_BIT")) - congen.at("PSEUDOCHANNEL_BIT").get_to(m.rankBits); - - if (congen.contains("CHANNEL_BIT")) - congen.at("CHANNEL_BIT").get_to(m.channelBits); - - if (congen.contains("XOR")) - congen.at("XOR").get_to(m.xorBits); -} - -void to_json(json_t &j, const XorPair &x) -{ - j = json_t{{"FIRST", x.first}, {"SECOND", x.second}}; -} - -void from_json(const json_t &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_t json_addressmapping = json_t::parse(dump).at("addressmapping"); - json_addressmapping.get_to(c); -} - -std::string dump(const AddressMapping &c, unsigned int indentation) -{ - json_t json_addressmapping; - json_addressmapping["addressmapping"] = c; - return json_addressmapping.dump(indentation); -} - } // namespace DRAMSys::Config diff --git a/src/configuration/DRAMSys/config/AddressMapping.h b/src/configuration/DRAMSys/config/AddressMapping.h index 4426ff8d..0d435bd1 100644 --- a/src/configuration/DRAMSys/config/AddressMapping.h +++ b/src/configuration/DRAMSys/config/AddressMapping.h @@ -42,34 +42,46 @@ namespace DRAMSys::Config { -const std::string addressMappingPath = "addressmapping"; struct XorPair { - unsigned int first; - unsigned int second; + unsigned int FIRST; + unsigned int SECOND; }; -void to_json(json_t &j, const XorPair &x); -void from_json(const json_t &j, XorPair &x); +NLOHMANN_JSONIFY_ALL_THINGS(XorPair, FIRST, SECOND) struct AddressMapping { - std::optional> byteBits; - std::optional> columnBits; - std::optional> rowBits; - std::optional> bankBits; - std::optional> bankGroupBits; - std::optional> rankBits; - std::optional> channelBits; - std::optional> xorBits; + static constexpr std::string_view KEY = "addressmapping"; + static constexpr std::string_view INNER_KEY = "CONGEN"; + static constexpr std::string_view PATH = "addressmapping"; + + struct ConGen { + std::optional> BYTE_BIT; + std::optional> COLUMN_BIT; + std::optional> ROW_BIT; + std::optional> BANK_BIT; + std::optional> BANKGROUP_BIT; + std::optional> RANK_BIT; + std::optional> PSEUDOCHANNEL_BIT; + std::optional> CHANNEL_BIT; + std::optional> XOR; + } CONGEN; }; -void to_json(json_t &j, const AddressMapping &m); -void from_json(const json_t &j, AddressMapping &m); +NLOHMANN_JSONIFY_ALL_THINGS(AddressMapping, CONGEN) -void from_dump(const std::string &dump, AddressMapping &c); -std::string dump(const AddressMapping &c, unsigned int indentation = -1); +NLOHMANN_JSONIFY_ALL_THINGS(AddressMapping::ConGen, + BYTE_BIT, + COLUMN_BIT, + ROW_BIT, + BANK_BIT, + BANKGROUP_BIT, + RANK_BIT, + PSEUDOCHANNEL_BIT, + CHANNEL_BIT, + XOR) } // namespace Configuration diff --git a/src/configuration/DRAMSys/config/ConfigUtil.cpp b/src/configuration/DRAMSys/config/ConfigUtil.cpp index 8024cfee..9c57324c 100644 --- a/src/configuration/DRAMSys/config/ConfigUtil.cpp +++ b/src/configuration/DRAMSys/config/ConfigUtil.cpp @@ -37,27 +37,11 @@ #include "DRAMSys/config/DRAMSysConfiguration.h" +#include #include #include namespace DRAMSys::Config { - json_t get_config_json(const json_t& 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_t j_object = json_t::parse(file); - return j_object.at(objectName); - } - } - } // namespace DRAMSys::Config diff --git a/src/configuration/DRAMSys/config/ConfigUtil.h b/src/configuration/DRAMSys/config/ConfigUtil.h index 9c45aa5b..81fe55ea 100644 --- a/src/configuration/DRAMSys/config/ConfigUtil.h +++ b/src/configuration/DRAMSys/config/ConfigUtil.h @@ -43,52 +43,6 @@ namespace DRAMSys::Config { - //using json_t = nlohmann::json; - - // template - // class Optional : public std::pair - // { - // public: - // Optional() : std::pair{{}, false} - // { - // } - // Optional(const T &v) : std::pair{v, true} - // { - // } - - // bool isValid() const - // { - // return this->second; - // } - - // const T &getValue() const - // { - // assert(this->second == true); - // return this->first; - // } - - // void setValue(const T &v) - // { - // this->first = v; - // this->second = true; - // } - - // void invalidate() - // { - // this->second = false; - // } - - // /** - // * This methods only purpose is to make a optional type - // * valid so that it can be written to by reference. - // */ - // T &setByReference() - // { - // this->second = true; - // return this->first; - // } - // }; - template void invalidateEnum(T& value) { @@ -96,8 +50,6 @@ namespace DRAMSys::Config value.reset(); } - json_t get_config_json(const json_t& j, const std::string& configPath, const std::string& objectName); - inline void remove_null_values(json_t& j) { std::vector keysToRemove; diff --git a/src/configuration/DRAMSys/config/DRAMSysConfiguration.cpp b/src/configuration/DRAMSys/config/DRAMSysConfiguration.cpp index c93f9002..0b6f546c 100644 --- a/src/configuration/DRAMSys/config/DRAMSysConfiguration.cpp +++ b/src/configuration/DRAMSys/config/DRAMSysConfiguration.cpp @@ -35,62 +35,103 @@ #include "DRAMSysConfiguration.h" -#include "DRAMSys/config/ConfigUtil.h" +#include "ConfigUtil.h" #include +#include namespace DRAMSys::Config { -std::string Configuration::resourceDirectory; - -void to_json(json_t &j, const Configuration &c) +Configuration from_path(std::string_view path, std::string_view resourceDirectory) { - j = json_t{{"addressmapping", c.addressMapping}, {"mcconfig", c.mcConfig}, {"memspec", c.memSpec}, - {"simulationid", c.simulationId}, {"simconfig", c.simConfig}, {"tracesetup", c.traceSetup}}; + std::ifstream file(path.data()); - remove_null_values(j); -} - -void from_json(const json_t &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("tracesetup")) - j.at("tracesetup").get_to(c.traceSetup); -} - -void from_dump(const std::string &dump, Configuration &c) -{ - json_t json_simulation = json_t::parse(dump).at("simulation"); - json_simulation.get_to(c); -} - -std::string dump(const Configuration &c, unsigned int indentation) -{ - json_t 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()) + enum class SubConfig { - json_t simulation = json_t::parse(file).at("simulation"); + MemSpec, + AddressMapping, + McConfig, + SimConfig, + TraceSetup, + Unkown + } current_sub_config; + + std::function + parser_callback; + parser_callback = + [&parser_callback, ¤t_sub_config, resourceDirectory]( + int depth, nlohmann::detail::parse_event_t event, json_t &parsed) -> bool { + using nlohmann::detail::parse_event_t; + + if (depth != 2) + return true; + + if (event == parse_event_t::key) { + assert(parsed.is_string()); + + if (parsed == MemSpec::KEY) + current_sub_config = SubConfig::MemSpec; + else if (parsed == AddressMapping::KEY) + current_sub_config = SubConfig::AddressMapping; + else if (parsed == McConfig::KEY) + current_sub_config = SubConfig::McConfig; + else if (parsed == SimConfig::KEY) + current_sub_config = SubConfig::SimConfig; + else if (parsed == TraceSetupConstants::KEY) + current_sub_config = SubConfig::TraceSetup; + else + current_sub_config = SubConfig::Unkown; + } + + if (event == parse_event_t::value && current_sub_config != SubConfig::Unkown) { + // Replace name of json file with actual json data + auto parse_json = [&parser_callback, + resourceDirectory](std::string_view base_dir, + std::string_view sub_config_key, + const std::string &filename) -> json_t { + std::filesystem::path path(resourceDirectory); + path /= base_dir; + path /= filename; + + std::ifstream json_file(path); + + if (!json_file.is_open()) + throw std::runtime_error("Failed to open file " + std::string(path)); + + json_t json = + json_t::parse(json_file, parser_callback, true, true).at(sub_config_key); + return json; + }; + + if (current_sub_config == SubConfig::MemSpec) + parsed = parse_json(MemSpec::PATH, MemSpec::KEY, parsed); + else if (current_sub_config == SubConfig::AddressMapping) + { + parsed = parse_json(AddressMapping::PATH, AddressMapping::INNER_KEY, parsed); + + if (!parsed.contains(AddressMapping::INNER_KEY)) { + auto temp = parsed; + parsed = json_t(); + parsed[AddressMapping::INNER_KEY] = temp; + } + } + else if (current_sub_config == SubConfig::McConfig) + parsed = parse_json(McConfig::PATH, McConfig::KEY, parsed); + else if (current_sub_config == SubConfig::SimConfig) + parsed = parse_json(SimConfig::PATH, SimConfig::KEY, parsed); + else if (current_sub_config == SubConfig::TraceSetup) + parsed = parse_json(TraceSetupConstants::PATH, TraceSetupConstants::KEY, parsed); + } + + return true; + }; + + if (file.is_open()) { + json_t simulation = json_t::parse(file, parser_callback, true, true).at(Configuration::KEY); return simulation.get(); - } - else - { - throw std::runtime_error("Failed to open file " + path); + } else { + throw std::runtime_error("Failed to open file " + std::string(path)); } } diff --git a/src/configuration/DRAMSys/config/DRAMSysConfiguration.h b/src/configuration/DRAMSys/config/DRAMSysConfiguration.h index 2f2e4e52..18e45805 100644 --- a/src/configuration/DRAMSys/config/DRAMSysConfiguration.h +++ b/src/configuration/DRAMSys/config/DRAMSysConfiguration.h @@ -54,29 +54,35 @@ * values will be provided by DRAMSys itself. * * To achieve static polymorphism, std::variant is used. + * + * To achieve backwards compatibility, this library manipulates the json + * data type as it is parsed in to substitute paths to sub-configurations + * with the actual json object that is stored at this path. */ namespace DRAMSys::Config { struct Configuration { - AddressMapping addressMapping; - McConfig mcConfig; - MemSpec memSpec; - SimConfig simConfig; - std::string simulationId; - std::optional traceSetup; - - static std::string resourceDirectory; + static constexpr std::string_view KEY = "simulation"; + + AddressMapping addressmapping; + McConfig mcconfig; + MemSpec memspec; + SimConfig simconfig; + std::string simulationid; + std::optional tracesetup; }; -void to_json(json &j, const Configuration &p); -void from_json(const json &j, Configuration &p); +NLOHMANN_JSONIFY_ALL_THINGS(Configuration, + addressmapping, + mcconfig, + memspec, + simconfig, + simulationid, + tracesetup) -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 = DRAMSYS_RESOURCE_DIR); +Configuration from_path(std::string_view path, std::string_view resourceDirectory = DRAMSYS_RESOURCE_DIR); } // namespace DRAMSys::Config diff --git a/src/configuration/DRAMSys/config/McConfig.cpp b/src/configuration/DRAMSys/config/McConfig.cpp index ff9f479d..6017fe1c 100644 --- a/src/configuration/DRAMSys/config/McConfig.cpp +++ b/src/configuration/DRAMSys/config/McConfig.cpp @@ -38,162 +38,36 @@ namespace DRAMSys::Config { -void to_json(json_t &j, const McConfig &c) +void to_json(json_t &j, const RefreshPolicyType &r) { - j = json_t{{"PagePolicy", c.pagePolicy}, - {"Scheduler", c.scheduler}, - {"HighWatermark", c.highWatermark}, - {"LowWatermark", c.lowWatermark}, - {"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}, - {"RefreshManagement", c.refreshManagement}, - {"ArbitrationDelayFw", c.arbitrationDelayFw}, - {"ArbitrationDelayBw", c.arbitrationDelayBw}, - {"ThinkDelayFw", c.thinkDelayFw}, - {"ThinkDelayBw", c.thinkDelayBw}, - {"PhyDelayFw", c.phyDelayFw}, - {"PhyDelayBw", c.phyDelayBw}, - {"BlockingReadDelay", c.blockingReadDelay}, - {"BlockingWriteDelay", c.blockingWriteDelay}}; - - remove_null_values(j); -} - -void from_json(const json_t &j, McConfig &c) -{ - json_t 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("HighWatermark")) - j_mcconfig.at("HighWatermark").get_to(c.highWatermark); - - if (j_mcconfig.contains("LowWatermark")) - j_mcconfig.at("LowWatermark").get_to(c.lowWatermark); - - 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("RefreshManagement")) - j_mcconfig.at("RefreshManagement").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); - - if (j_mcconfig.contains("BlockingReadDelay")) - j_mcconfig.at("BlockingReadDelay").get_to(c.blockingReadDelay); - - if (j_mcconfig.contains("BlockingWriteDelay")) - j_mcconfig.at("BlockingWriteDelay").get_to(c.blockingWriteDelay); - - 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_t &j, const RefreshPolicy &r) -{ - if (r == RefreshPolicy::NoRefresh) + if (r == RefreshPolicyType::NoRefresh) j = "NoRefresh"; - else if (r == RefreshPolicy::AllBank) + else if (r == RefreshPolicyType::AllBank) j = "AllBank"; - else if (r == RefreshPolicy::PerBank) + else if (r == RefreshPolicyType::PerBank) j = "PerBank"; - else if (r == RefreshPolicy::Per2Bank) + else if (r == RefreshPolicyType::Per2Bank) j = "Per2Bank"; - else if (r == RefreshPolicy::SameBank) + else if (r == RefreshPolicyType::SameBank) j = "SameBank"; else j = nullptr; } -void from_json(const json_t &j, RefreshPolicy &r) +void from_json(const json_t &j, RefreshPolicyType &r) { if (j == "NoRefresh") - r = RefreshPolicy::NoRefresh; + r = RefreshPolicyType::NoRefresh; else if (j == "AllBank" || j == "Rankwise") - r = RefreshPolicy::AllBank; + r = RefreshPolicyType::AllBank; else if (j == "PerBank" || j == "Bankwise") - r = RefreshPolicy::PerBank; + r = RefreshPolicyType::PerBank; else if (j == "SameBank" || j == "Groupwise") - r = RefreshPolicy::SameBank; + r = RefreshPolicyType::SameBank; else if (j == "Per2Bank") - r = RefreshPolicy::Per2Bank; + r = RefreshPolicyType::Per2Bank; else - r = RefreshPolicy::Invalid; -} - -void from_dump(const std::string &dump, McConfig &c) -{ - json_t json_mcconfig = json_t::parse(dump).at("mcconfig"); - json_mcconfig.get_to(c); -} - -std::string dump(const McConfig &c, unsigned int indentation) -{ - json_t json_mcconfig; - json_mcconfig["mcconfig"] = c; - return json_mcconfig.dump(indentation); + r = RefreshPolicyType::Invalid; } } // namespace DRAMSys::Config diff --git a/src/configuration/DRAMSys/config/McConfig.h b/src/configuration/DRAMSys/config/McConfig.h index da697981..f7a9336d 100644 --- a/src/configuration/DRAMSys/config/McConfig.h +++ b/src/configuration/DRAMSys/config/McConfig.h @@ -44,9 +44,8 @@ namespace DRAMSys::Config { -const std::string mcConfigPath = "mcconfig"; -enum class PagePolicy +enum class PagePolicyType { Open, OpenAdaptive, @@ -55,15 +54,15 @@ enum class PagePolicy Invalid = -1 }; -NLOHMANN_JSON_SERIALIZE_ENUM(PagePolicy, { - {PagePolicy::Invalid, nullptr}, - {PagePolicy::Open, "Open"}, - {PagePolicy::OpenAdaptive, "OpenAdaptive"}, - {PagePolicy::Closed, "Closed"}, - {PagePolicy::ClosedAdaptive, "ClosedAdaptive"}, +NLOHMANN_JSON_SERIALIZE_ENUM(PagePolicyType, { + {PagePolicyType::Invalid, nullptr}, + {PagePolicyType::Open, "Open"}, + {PagePolicyType::OpenAdaptive, "OpenAdaptive"}, + {PagePolicyType::Closed, "Closed"}, + {PagePolicyType::ClosedAdaptive, "ClosedAdaptive"}, }) -enum class Scheduler +enum class SchedulerType { Fifo, FrFcfs, @@ -73,14 +72,14 @@ enum class Scheduler Invalid = -1 }; -NLOHMANN_JSON_SERIALIZE_ENUM(Scheduler, {{Scheduler::Invalid, nullptr}, - {Scheduler::Fifo, "Fifo"}, - {Scheduler::FrFcfs, "FrFcfs"}, - {Scheduler::FrFcfsGrp, "FrFcfsGrp"}, - {Scheduler::GrpFrFcfs, "GrpFrFcfs"}, - {Scheduler::GrpFrFcfsWm, "GrpFrFcfsWm"}}) +NLOHMANN_JSON_SERIALIZE_ENUM(SchedulerType, {{SchedulerType::Invalid, nullptr}, + {SchedulerType::Fifo, "Fifo"}, + {SchedulerType::FrFcfs, "FrFcfs"}, + {SchedulerType::FrFcfsGrp, "FrFcfsGrp"}, + {SchedulerType::GrpFrFcfs, "GrpFrFcfs"}, + {SchedulerType::GrpFrFcfsWm, "GrpFrFcfsWm"}}) -enum class SchedulerBuffer +enum class SchedulerBufferType { Bankwise, ReadWrite, @@ -88,33 +87,33 @@ enum class SchedulerBuffer Invalid = -1 }; -NLOHMANN_JSON_SERIALIZE_ENUM(SchedulerBuffer, {{SchedulerBuffer::Invalid, nullptr}, - {SchedulerBuffer::Bankwise, "Bankwise"}, - {SchedulerBuffer::ReadWrite, "ReadWrite"}, - {SchedulerBuffer::Shared, "Shared"}}) +NLOHMANN_JSON_SERIALIZE_ENUM(SchedulerBufferType, {{SchedulerBufferType::Invalid, nullptr}, + {SchedulerBufferType::Bankwise, "Bankwise"}, + {SchedulerBufferType::ReadWrite, "ReadWrite"}, + {SchedulerBufferType::Shared, "Shared"}}) -enum class CmdMux +enum class CmdMuxType { Oldest, Strict, Invalid = -1 }; -NLOHMANN_JSON_SERIALIZE_ENUM(CmdMux, - {{CmdMux::Invalid, nullptr}, {CmdMux::Oldest, "Oldest"}, {CmdMux::Strict, "Strict"}}) +NLOHMANN_JSON_SERIALIZE_ENUM(CmdMuxType, + {{CmdMuxType::Invalid, nullptr}, {CmdMuxType::Oldest, "Oldest"}, {CmdMuxType::Strict, "Strict"}}) -enum class RespQueue +enum class RespQueueType { Fifo, Reorder, Invalid = -1 }; -NLOHMANN_JSON_SERIALIZE_ENUM(RespQueue, {{RespQueue::Invalid, nullptr}, - {RespQueue::Fifo, "Fifo"}, - {RespQueue::Reorder, "Reorder"}}) +NLOHMANN_JSON_SERIALIZE_ENUM(RespQueueType, {{RespQueueType::Invalid, nullptr}, + {RespQueueType::Fifo, "Fifo"}, + {RespQueueType::Reorder, "Reorder"}}) -enum class RefreshPolicy +enum class RefreshPolicyType { NoRefresh, AllBank, @@ -124,18 +123,18 @@ enum class RefreshPolicy Invalid = -1 }; -enum class PowerDownPolicy +enum class PowerDownPolicyType { NoPowerDown, Staggered, Invalid = -1 }; -NLOHMANN_JSON_SERIALIZE_ENUM(PowerDownPolicy, {{PowerDownPolicy::Invalid, nullptr}, - {PowerDownPolicy::NoPowerDown, "NoPowerDown"}, - {PowerDownPolicy::Staggered, "Staggered"}}) +NLOHMANN_JSON_SERIALIZE_ENUM(PowerDownPolicyType, {{PowerDownPolicyType::Invalid, nullptr}, + {PowerDownPolicyType::NoPowerDown, "NoPowerDown"}, + {PowerDownPolicyType::Staggered, "Staggered"}}) -enum class Arbiter +enum class ArbiterType { Simple, Fifo, @@ -143,46 +142,71 @@ enum class Arbiter Invalid = -1 }; -NLOHMANN_JSON_SERIALIZE_ENUM(Arbiter, {{Arbiter::Invalid, nullptr}, - {Arbiter::Simple, "Simple"}, - {Arbiter::Fifo, "Fifo"}, - {Arbiter::Reorder, "Reorder"}}) +NLOHMANN_JSON_SERIALIZE_ENUM(ArbiterType, {{ArbiterType::Invalid, nullptr}, + {ArbiterType::Simple, "Simple"}, + {ArbiterType::Fifo, "Fifo"}, + {ArbiterType::Reorder, "Reorder"}}) struct McConfig { - std::optional pagePolicy; - std::optional scheduler; - std::optional highWatermark; - std::optional lowWatermark; - std::optional schedulerBuffer; - std::optional requestBufferSize; - std::optional cmdMux; - std::optional respQueue; - std::optional refreshPolicy; - std::optional refreshMaxPostponed; - std::optional refreshMaxPulledin; - std::optional powerDownPolicy; - std::optional arbiter; - std::optional maxActiveTransactions; - std::optional refreshManagement; - std::optional arbitrationDelayFw; - std::optional arbitrationDelayBw; - std::optional thinkDelayFw; - std::optional thinkDelayBw; - std::optional phyDelayFw; - std::optional phyDelayBw; - std::optional blockingReadDelay; - std::optional blockingWriteDelay; + static constexpr std::string_view KEY = "mcconfig"; + static constexpr std::string_view PATH = "mcconfig"; + + std::optional PagePolicy; + std::optional Scheduler; + std::optional HighWatermark; + std::optional LowWatermark; + std::optional SchedulerBuffer; + std::optional RequestBufferSize; + std::optional CmdMux; + std::optional RespQueue; + std::optional RefreshPolicy; + std::optional RefreshMaxPostponed; + std::optional RefreshMaxPulledin; + std::optional PowerDownPolicy; + std::optional Arbiter; + std::optional MaxActiveTransactions; + std::optional RefreshManagement; + std::optional ArbitrationDelayFw; + std::optional ArbitrationDelayBw; + std::optional ThinkDelayFw; + std::optional ThinkDelayBw; + std::optional PhyDelayFw; + std::optional PhyDelayBw; + std::optional BlockingReadDelay; + std::optional BlockingWriteDelay; }; -void to_json(json_t &j, const McConfig &c); -void from_json(const json_t &j, McConfig &c); +NLOHMANN_JSONIFY_ALL_THINGS(McConfig, + PagePolicy, + Scheduler, + HighWatermark, + LowWatermark, + SchedulerBuffer, + RequestBufferSize, + CmdMux, + RespQueue, + RefreshPolicy, + RefreshMaxPostponed, + RefreshMaxPulledin, + PowerDownPolicy, + Arbiter, + MaxActiveTransactions, + RefreshManagement, + ArbitrationDelayFw, + ArbitrationDelayBw, + ThinkDelayFw, + ThinkDelayBw, + PhyDelayFw, + PhyDelayBw, + BlockingReadDelay, + BlockingWriteDelay) -void to_json(json_t &j, const RefreshPolicy &r); -void from_json(const json_t &j, RefreshPolicy &r); +void to_json(json_t &j, const RefreshPolicyType &r); +void from_json(const json_t &j, RefreshPolicyType &r); -void from_dump(const std::string &dump, McConfig &c); -std::string dump(const McConfig &c, unsigned int indentation = -1); +// void from_dump(const std::string &dump, McConfig &c); +// std::string dump(const McConfig &c, unsigned int indentation = -1); } // namespace Configuration diff --git a/src/configuration/DRAMSys/config/SimConfig.cpp b/src/configuration/DRAMSys/config/SimConfig.cpp index 83d89ca8..a8fb685e 100644 --- a/src/configuration/DRAMSys/config/SimConfig.cpp +++ b/src/configuration/DRAMSys/config/SimConfig.cpp @@ -38,84 +38,4 @@ namespace DRAMSys::Config { -void to_json(json_t &j, const SimConfig &c) -{ - j = json_t{{"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_t &j, SimConfig &c) -{ - json_t 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_t json_simconfig = json_t::parse(dump).at("simconfig"); - json_simconfig.get_to(c); -} - -std::string dump(const SimConfig &c, unsigned int indentation) -{ - json_t json_simconfig; - json_simconfig["simconfig"] = c; - return json_simconfig.dump(indentation); -} - } // namespace DRAMSys::Config diff --git a/src/configuration/DRAMSys/config/SimConfig.h b/src/configuration/DRAMSys/config/SimConfig.h index 5dee2443..0c283729 100644 --- a/src/configuration/DRAMSys/config/SimConfig.h +++ b/src/configuration/DRAMSys/config/SimConfig.h @@ -42,9 +42,8 @@ namespace DRAMSys::Config { -const std::string simConfigPath = "simconfig"; -enum class StoreMode +enum class StoreModeType { NoStorage, Store, @@ -52,34 +51,47 @@ enum class StoreMode Invalid = -1 }; -NLOHMANN_JSON_SERIALIZE_ENUM(StoreMode, {{StoreMode::Invalid, nullptr}, - {StoreMode::NoStorage, "NoStorage"}, - {StoreMode::Store, "Store"}, - {StoreMode::ErrorModel, "ErrorModel"}}) +NLOHMANN_JSON_SERIALIZE_ENUM(StoreModeType, {{StoreModeType::Invalid, nullptr}, + {StoreModeType::NoStorage, "NoStorage"}, + {StoreModeType::Store, "Store"}, + {StoreModeType::ErrorModel, "ErrorModel"}}) struct SimConfig { - std::optional addressOffset; - std::optional checkTLM2Protocol; - std::optional databaseRecording; - std::optional debug; - std::optional enableWindowing; - std::optional errorCsvFile; - std::optional errorChipSeed; - std::optional powerAnalysis; - std::optional simulationName; - std::optional simulationProgressBar; - std::optional storeMode; - std::optional thermalSimulation; - std::optional useMalloc; - std::optional windowSize; + static constexpr std::string_view KEY = "simconfig"; + static constexpr std::string_view PATH = "simconfig"; + + std::optional AddressOffset; + std::optional CheckTLM2Protocol; + std::optional DatabaseRecording; + std::optional Debug; + std::optional EnableWindowing; + std::optional ErrorCSVFile; + std::optional ErrorChipSeed; + std::optional PowerAnalysis; + std::optional SimulationName; + std::optional SimulationProgressBar; + std::optional StoreMode; + std::optional ThermalSimulation; + std::optional UseMalloc; + std::optional WindowSize; }; -void to_json(json_t &j, const SimConfig &c); -void from_json(const json_t &j, SimConfig &c); - -void from_dump(const std::string &dump, SimConfig &c); -std::string dump(const SimConfig &c, unsigned int indentation = -1); +NLOHMANN_JSONIFY_ALL_THINGS(SimConfig, + AddressOffset, + CheckTLM2Protocol, + DatabaseRecording, + Debug, + EnableWindowing, + ErrorCSVFile, + ErrorChipSeed, + PowerAnalysis, + SimulationName, + SimulationProgressBar, + StoreMode, + ThermalSimulation, + UseMalloc, + WindowSize) } // namespace Configuration diff --git a/src/configuration/DRAMSys/config/TraceSetup.cpp b/src/configuration/DRAMSys/config/TraceSetup.cpp index 9462c838..0b08777c 100644 --- a/src/configuration/DRAMSys/config/TraceSetup.cpp +++ b/src/configuration/DRAMSys/config/TraceSetup.cpp @@ -37,278 +37,6 @@ #include -namespace DRAMSys::Config -{ - -TrafficInitiator::~TrafficInitiator() -{ -} - -TraceGeneratorState::~TraceGeneratorState() -{ -} - -void to_json(json_t &j, const TraceSetup &c) -{ - // Create an empty array - j = json_t::array(); - - for (const auto &initiator : c.initiators) - { - json_t 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; - - using T = std::decay_t; - if constexpr (std::is_same_v) - { - initiator_j["type"] = "generator"; - initiator_j["seed"] = initiator.seed; - initiator_j["maxTransactions"] = initiator.maxTransactions; - initiator_j["idleUntil"] = initiator.idleUntil; - - // When there are less than 2 states, flatten out the json. - if (initiator.states.size() == 1) - { - std::visit( - [&initiator_j](auto &&state) - { - using U = std::decay_t; - - if constexpr (std::is_same_v) - { - initiator_j["numRequests"] = state.numRequests; - initiator_j["rwRatio"] = state.rwRatio; - initiator_j["addressDistribution"] = state.addressDistribution; - initiator_j["addressIncrement"] = state.addressIncrement; - initiator_j["minAddress"] = state.minAddress; - initiator_j["maxAddress"] = state.maxAddress; - initiator_j["clksPerRequest"] = state.clksPerRequest; - initiator_j["notify"] = state.notify; - } - else // if constexpr (std::is_same_v) - { - initiator_j["idleClks"] = state.idleClks; - } - }, - initiator.states.at(0)); - } - else - { - json_t states_j = json_t::array(); - - for (const auto &state : initiator.states) - { - json_t state_j; - state_j["id"] = state.first; - - std::visit( - [&state_j](auto &&state) - { - using U = std::decay_t; - - if constexpr (std::is_same_v) - { - state_j["numRequests"] = state.numRequests; - state_j["rwRatio"] = state.rwRatio; - state_j["addressDistribution"] = state.addressDistribution; - state_j["addressIncrement"] = state.addressIncrement; - state_j["minAddress"] = state.minAddress; - state_j["maxAddress"] = state.maxAddress; - state_j["clksPerRequest"] = state.clksPerRequest; - state_j["notify"] = state.notify; - } - else // if constexpr (std::is_same_v) - { - state_j["idleClks"] = state.idleClks; - } - }, - state.second); - - remove_null_values(state_j); - states_j.insert(states_j.end(), state_j); - } - initiator_j["states"] = states_j; - - json_t transitions_j = json_t::array(); - - for (const auto &transition : initiator.transitions) - { - json_t transition_j; - transition_j["from"] = transition.first; - transition_j["to"] = transition.second.to; - transition_j["probability"] = transition.second.probability; - remove_null_values(transition_j); - transitions_j.insert(transitions_j.end(), transition_j); - } - initiator_j["transitions"] = transitions_j; - } - } - else if constexpr (std::is_same_v) - { - initiator_j["type"] = "hammer"; - initiator_j["numRequests"] = initiator.numRequests; - initiator_j["rowIncrement"] = initiator.rowIncrement; - } - else // if constexpr (std::is_same_v) - { - initiator_j["type"] = "player"; - } - }, - initiator); - - remove_null_values(initiator_j); - j.insert(j.end(), initiator_j); - } -} - -void from_json(const json_t&j, TraceSetup &c) -{ - for (const auto &initiator_j : j) - { - // Default to Player, when not specified - TrafficInitiatorType type = initiator_j.value("type", TrafficInitiatorType::Player); - - std::variant initiator; - - if (type == TrafficInitiatorType::Player) - { - initiator = TracePlayer{}; - } - else if (type == TrafficInitiatorType::Generator) - { - TraceGenerator generator; - - auto process_state = [](const json_t&state_j) - -> std::pair> - { - std::variant state; - - if (state_j.contains("idleClks")) - { - // Idle state - TraceGeneratorIdleState idleState; - state_j.at("idleClks").get_to(idleState.idleClks); - - state = std::move(idleState); - } - else - { - // Traffic state - TraceGeneratorTrafficState trafficState; - state_j.at("numRequests").get_to(trafficState.numRequests); - state_j.at("rwRatio").get_to(trafficState.rwRatio); - state_j.at("addressDistribution").get_to(trafficState.addressDistribution); - - if (state_j.contains("addressIncrement")) - state_j.at("addressIncrement").get_to(trafficState.addressIncrement); - - if (state_j.contains("minAddress")) - state_j.at("minAddress").get_to(trafficState.minAddress); - - if (state_j.contains("maxAddress")) - state_j.at("maxAddress").get_to(trafficState.maxAddress); - - if (state_j.contains("clksPerRequest")) - state_j.at("clksPerRequest").get_to(trafficState.clksPerRequest); - - if (state_j.contains("notify")) - state_j.at("notify").get_to(trafficState.notify); - - state = std::move(trafficState); - } - - // Default to 0 - unsigned int id = 0; - - if (state_j.contains("id")) - id = state_j.at("id"); - - return {id, std::move(state)}; - }; - - if (initiator_j.contains("states")) - { - for (const auto &state_j : initiator_j.at("states")) - { - auto state = process_state(state_j); - generator.states[state.first] = std::move(state.second); - } - - for (const auto &transition_j : initiator_j.at("transitions")) - { - TraceGeneratorStateTransition transition; - unsigned int from = transition_j.at("from"); - transition.to = transition_j.at("to"); - transition.probability = transition_j.at("probability"); - 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("dataLength")) - initiator_j.at("dataLength").get_to(generator.dataLength); - - 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); - }, - initiator); - - c.initiators.emplace_back(std::move(initiator)); - } -} - -void from_dump(const std::string &dump, TraceSetup &c) -{ - json_t json_tracesetup = json_t::parse(dump).at("tracesetup"); - json_tracesetup.get_to(c); -} - -std::string dump(const TraceSetup &c, unsigned int indentation) -{ - json_t json_tracesetup; - json_tracesetup["tracesetup"] = c; - return json_tracesetup.dump(indentation); -} +namespace DRAMSys::Config { } // namespace DRAMSys::Config diff --git a/src/configuration/DRAMSys/config/TraceSetup.h b/src/configuration/DRAMSys/config/TraceSetup.h index 3f14cbe1..cff510f1 100644 --- a/src/configuration/DRAMSys/config/TraceSetup.h +++ b/src/configuration/DRAMSys/config/TraceSetup.h @@ -68,27 +68,21 @@ NLOHMANN_JSON_SERIALIZE_ENUM(AddressDistribution, {{AddressDistribution::Invalid {AddressDistribution::Random, "random"}, {AddressDistribution::Sequential, "sequential"}}) -struct TrafficInitiator +struct TracePlayer { - virtual ~TrafficInitiator() = 0; - uint64_t clkMhz; std::string name; std::optional maxPendingReadRequests; std::optional maxPendingWriteRequests; }; -struct TracePlayer : public TrafficInitiator -{ -}; +NLOHMANN_JSONIFY_ALL_THINGS( + TracePlayer, clkMhz, name, maxPendingReadRequests, maxPendingWriteRequests) -struct TraceGeneratorState +struct TrafficGeneratorActiveState { - virtual ~TraceGeneratorState() = 0; -}; + unsigned int id; -struct TraceGeneratorTrafficState : public TraceGeneratorState -{ uint64_t numRequests; double rwRatio; AddressDistribution addressDistribution; @@ -99,43 +93,123 @@ struct TraceGeneratorTrafficState : public TraceGeneratorState std::optional notify; }; -struct TraceGeneratorIdleState : public TraceGeneratorState +NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorActiveState, + id, + numRequests, + rwRatio, + addressDistribution, + addressIncrement, + minAddress, + maxAddress, + clksPerRequest, + notify) + +struct TrafficGeneratorIdleState { + unsigned int id; + uint64_t idleClks; }; -struct TraceGeneratorStateTransition +NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorIdleState, id, idleClks) + +struct TrafficGeneratorStateTransition { + unsigned int from; unsigned int to; float probability; }; -struct TraceGenerator : public TrafficInitiator +NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorStateTransition, from, to, probability) + +struct TrafficGenerator { + uint64_t clkMhz; + std::string name; + std::optional maxPendingReadRequests; + std::optional maxPendingWriteRequests; + std::optional seed; std::optional maxTransactions; std::optional dataLength; - std::map> states; - std::multimap transitions; + + uint64_t numRequests; + double rwRatio; + AddressDistribution addressDistribution; + std::optional addressIncrement; + std::optional minAddress; + std::optional maxAddress; + std::optional clksPerRequest; + std::optional idleUntil; }; -struct TraceHammer : public TrafficInitiator +NLOHMANN_JSONIFY_ALL_THINGS(TrafficGenerator, + clkMhz, + name, + maxPendingReadRequests, + maxPendingWriteRequests, + seed, + maxTransactions, + dataLength, + numRequests, + rwRatio, + addressDistribution, + addressIncrement, + minAddress, + maxAddress, + clksPerRequest, + idleUntil) + +struct TrafficGeneratorStateMachine { + uint64_t clkMhz; + std::string name; + std::optional maxPendingReadRequests; + std::optional maxPendingWriteRequests; + + std::optional seed; + std::optional maxTransactions; + std::optional dataLength; + std::vector> states; + std::vector transitions; + std::optional idleUntil; +}; + +NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorStateMachine, + clkMhz, + name, + maxPendingReadRequests, + maxPendingWriteRequests, + seed, + maxTransactions, + dataLength, + states, + transitions, + idleUntil) + +struct TraceHammer +{ + uint64_t clkMhz; + std::string name; + std::optional maxPendingReadRequests; + std::optional maxPendingWriteRequests; + uint64_t numRequests; uint64_t rowIncrement; }; -struct TraceSetup +NLOHMANN_JSONIFY_ALL_THINGS( + TraceHammer, clkMhz, name, maxPendingReadRequests, maxPendingWriteRequests, numRequests, rowIncrement) + +struct TraceSetupConstants { - std::vector> initiators; + static constexpr std::string_view KEY = "tracesetup"; + static constexpr std::string_view PATH = "tracesetup"; }; -void to_json(json_t &j, const TraceSetup &c); -void from_json(const json_t &j, TraceSetup &c); - -void from_dump(const std::string &dump, TraceSetup &c); -std::string dump(const TraceSetup &c, unsigned int indentation = -1); +using TraceSetup = std::vector< + std::variant>; } // namespace Configuration diff --git a/src/configuration/DRAMSys/config/memspec/MemArchitectureSpec.cpp b/src/configuration/DRAMSys/config/memspec/MemArchitectureSpec.cpp index 977add14..6bc6527f 100644 --- a/src/configuration/DRAMSys/config/memspec/MemArchitectureSpec.cpp +++ b/src/configuration/DRAMSys/config/memspec/MemArchitectureSpec.cpp @@ -38,7 +38,7 @@ namespace DRAMSys::Config { -void to_json(json_t &j, const MemArchitectureSpec &c) +void to_json(json_t &j, const MemArchitectureSpecType &c) { j = json_t{}; @@ -48,7 +48,7 @@ void to_json(json_t &j, const MemArchitectureSpec &c) } } -void from_json(const json_t &j, MemArchitectureSpec &c) +void from_json(const json_t &j, MemArchitectureSpecType &c) { for (const auto &entry : j.items()) { diff --git a/src/configuration/DRAMSys/config/memspec/MemArchitectureSpec.h b/src/configuration/DRAMSys/config/memspec/MemArchitectureSpec.h index a03604ee..328140a4 100644 --- a/src/configuration/DRAMSys/config/memspec/MemArchitectureSpec.h +++ b/src/configuration/DRAMSys/config/memspec/MemArchitectureSpec.h @@ -43,13 +43,13 @@ namespace DRAMSys::Config { -struct MemArchitectureSpec +struct MemArchitectureSpecType { std::unordered_map entries; }; -void to_json(json_t &j, const MemArchitectureSpec &c); -void from_json(const json_t &j, MemArchitectureSpec &c); +void to_json(json_t &j, const MemArchitectureSpecType &c); +void from_json(const json_t &j, MemArchitectureSpecType &c); } // namespace Configuration diff --git a/src/configuration/DRAMSys/config/memspec/MemSpec.cpp b/src/configuration/DRAMSys/config/memspec/MemSpec.cpp index 2da6b91d..b9aca438 100644 --- a/src/configuration/DRAMSys/config/memspec/MemSpec.cpp +++ b/src/configuration/DRAMSys/config/memspec/MemSpec.cpp @@ -38,41 +38,4 @@ namespace DRAMSys::Config { -void to_json(json &j, const MemSpec &c) -{ - j = json{{"memarchitecturespec", c.memArchitectureSpec}, - {"memoryId", c.memoryId}, - {"memoryType", c.memoryType}, - {"memtimingspec", c.memTimingSpec}, - {"mempowerspec", c.memPowerSpec}}; - - remove_null_values(j); -} - -void from_json(const json &j, MemSpec &c) -{ - json j_memspecs = get_config_json(j, memSpecPath, "memspec"); - - j_memspecs.at("memarchitecturespec").get_to(c.memArchitectureSpec); - j_memspecs.at("memoryId").get_to(c.memoryId); - j_memspecs.at("memoryType").get_to(c.memoryType); - j_memspecs.at("memtimingspec").get_to(c.memTimingSpec); - - if (j_memspecs.contains("mempowerspec")) - j_memspecs.at("mempowerspec").get_to(c.memPowerSpec); -} - -void from_dump(const std::string &dump, MemSpec &c) -{ - json json_memspec = json::parse(dump).at("memspec"); - json_memspec.get_to(c); -} - -std::string dump(const MemSpec &c, unsigned int indentation) -{ - json json_memspec; - json_memspec["memspec"] = c; - return json_memspec.dump(indentation); -} - } // namespace Configuration diff --git a/src/configuration/DRAMSys/config/memspec/MemSpec.h b/src/configuration/DRAMSys/config/memspec/MemSpec.h index d20f0c03..8bc1ba73 100644 --- a/src/configuration/DRAMSys/config/memspec/MemSpec.h +++ b/src/configuration/DRAMSys/config/memspec/MemSpec.h @@ -45,22 +45,20 @@ namespace DRAMSys::Config { -const std::string memSpecPath = "memspec"; - struct MemSpec { - MemArchitectureSpec memArchitectureSpec; + static constexpr std::string_view KEY = "memspec"; + static constexpr std::string_view PATH = "memspec"; + + MemArchitectureSpecType memarchitecturespec; std::string memoryId; std::string memoryType; - MemTimingSpec memTimingSpec; - std::optional memPowerSpec; + MemTimingSpecType memtimingspec; + std::optional mempowerspec; }; -void to_json(json &j, const MemSpec &c); -void from_json(const json &j, MemSpec &c); - -void from_dump(const std::string &dump, MemSpec &c); -std::string dump(const MemSpec &c, unsigned int indentation = -1); +NLOHMANN_JSONIFY_ALL_THINGS( + MemSpec, memarchitecturespec, memoryId, memoryType, memtimingspec, mempowerspec) } // namespace Configuration diff --git a/src/configuration/DRAMSys/config/memspec/MemTimingSpec.cpp b/src/configuration/DRAMSys/config/memspec/MemTimingSpec.cpp index f70e836d..af8b0eda 100644 --- a/src/configuration/DRAMSys/config/memspec/MemTimingSpec.cpp +++ b/src/configuration/DRAMSys/config/memspec/MemTimingSpec.cpp @@ -38,7 +38,7 @@ namespace DRAMSys::Config { -void to_json(json_t &j, const MemTimingSpec &c) +void to_json(json_t &j, const MemTimingSpecType &c) { j = json_t{}; @@ -48,7 +48,7 @@ void to_json(json_t &j, const MemTimingSpec &c) } } -void from_json(const json_t &j, MemTimingSpec &c) +void from_json(const json_t &j, MemTimingSpecType &c) { for (const auto &entry : j.items()) { diff --git a/src/configuration/DRAMSys/config/memspec/MemTimingSpec.h b/src/configuration/DRAMSys/config/memspec/MemTimingSpec.h index 239ac824..4f68bc06 100644 --- a/src/configuration/DRAMSys/config/memspec/MemTimingSpec.h +++ b/src/configuration/DRAMSys/config/memspec/MemTimingSpec.h @@ -44,13 +44,13 @@ namespace DRAMSys::Config { using json = nlohmann::json; -struct MemTimingSpec +struct MemTimingSpecType { std::unordered_map entries; }; -void to_json(json &j, const MemTimingSpec &c); -void from_json(const json &j, MemTimingSpec &c); +void to_json(json &j, const MemTimingSpecType &c); +void from_json(const json &j, MemTimingSpecType &c); } // namespace Configuration diff --git a/src/libdramsys/DRAMSys/configuration/Configuration.cpp b/src/libdramsys/DRAMSys/configuration/Configuration.cpp index b3ae5fe4..e4aa0d80 100644 --- a/src/libdramsys/DRAMSys/configuration/Configuration.cpp +++ b/src/libdramsys/DRAMSys/configuration/Configuration.cpp @@ -87,22 +87,22 @@ enum sc_time_unit string2TimeUnit(const std::string &s) void Configuration::loadSimConfig(const DRAMSys::Config::SimConfig &simConfig) { - if (const auto& _addressOffset = simConfig.addressOffset) + if (const auto& _addressOffset = simConfig.AddressOffset) addressOffset = *_addressOffset; - if (const auto& _checkTLM2Protocol = simConfig.checkTLM2Protocol) + if (const auto& _checkTLM2Protocol = simConfig.CheckTLM2Protocol) checkTLM2Protocol = *_checkTLM2Protocol; - if (const auto& _databaseRecording = simConfig.databaseRecording) + if (const auto& _databaseRecording = simConfig.DatabaseRecording) databaseRecording = *_databaseRecording; - if (const auto& _debug = simConfig.debug) + if (const auto& _debug = simConfig.Debug) debug = *_debug; - if (const auto& _enableWindowing = simConfig.enableWindowing) + if (const auto& _enableWindowing = simConfig.EnableWindowing) enableWindowing = *_enableWindowing; - if (const auto& _powerAnalysis = simConfig.powerAnalysis) + if (const auto& _powerAnalysis = simConfig.PowerAnalysis) { powerAnalysis = *_powerAnalysis; #ifndef DRAMPOWER @@ -111,24 +111,24 @@ void Configuration::loadSimConfig(const DRAMSys::Config::SimConfig &simConfig) #endif } - if (const auto& _simulationName = simConfig.simulationName) + if (const auto& _simulationName = simConfig.SimulationName) simulationName = *_simulationName; - if (const auto& _simulationProgressBar = simConfig.simulationProgressBar) + if (const auto& _simulationProgressBar = simConfig.SimulationProgressBar) simulationProgressBar = *_simulationProgressBar; - if (const auto& _useMalloc = simConfig.useMalloc) + if (const auto& _useMalloc = simConfig.UseMalloc) useMalloc = *_useMalloc; - if (const auto& _windowSize = simConfig.windowSize) + if (const auto& _windowSize = simConfig.WindowSize) windowSize = *_windowSize; if (windowSize == 0) SC_REPORT_FATAL("Configuration", "Minimum window size is 1"); - if (const auto& _storeMode = simConfig.storeMode) + if (const auto& _storeMode = simConfig.StoreMode) storeMode = [=] { - if (_storeMode == DRAMSys::Config::StoreMode::NoStorage) + if (_storeMode == DRAMSys::Config::StoreModeType::NoStorage) return StoreMode::NoStorage; else // (_storeMode == DRAMSys::Config::StoreMode::Store) return StoreMode::Store; @@ -137,151 +137,151 @@ void Configuration::loadSimConfig(const DRAMSys::Config::SimConfig &simConfig) void Configuration::loadMCConfig(const DRAMSys::Config::McConfig &mcConfig) { - if (const auto& _pagePolicy = mcConfig.pagePolicy) + if (const auto& _pagePolicy = mcConfig.PagePolicy) pagePolicy = [=] { - if (_pagePolicy == DRAMSys::Config::PagePolicy::Open) + if (_pagePolicy == DRAMSys::Config::PagePolicyType::Open) return PagePolicy::Open; - else if (_pagePolicy == DRAMSys::Config::PagePolicy::OpenAdaptive) + else if (_pagePolicy == DRAMSys::Config::PagePolicyType::OpenAdaptive) return PagePolicy::OpenAdaptive; - else if (_pagePolicy == DRAMSys::Config::PagePolicy::Closed) + else if (_pagePolicy == DRAMSys::Config::PagePolicyType::Closed) return PagePolicy::Closed; else return PagePolicy::ClosedAdaptive; }(); - if (const auto& _scheduler = mcConfig.scheduler) + if (const auto& _scheduler = mcConfig.Scheduler) scheduler = [=] { - if (_scheduler == DRAMSys::Config::Scheduler::Fifo) + if (_scheduler == DRAMSys::Config::SchedulerType::Fifo) return Scheduler::Fifo; - else if (_scheduler == DRAMSys::Config::Scheduler::FrFcfs) + else if (_scheduler == DRAMSys::Config::SchedulerType::FrFcfs) return Scheduler::FrFcfs; - else if (_scheduler == DRAMSys::Config::Scheduler::FrFcfsGrp) + else if (_scheduler == DRAMSys::Config::SchedulerType::FrFcfsGrp) return Scheduler::FrFcfsGrp; - else if (_scheduler == DRAMSys::Config::Scheduler::GrpFrFcfs) + else if (_scheduler == DRAMSys::Config::SchedulerType::GrpFrFcfs) return Scheduler::GrpFrFcfs; else return Scheduler::GrpFrFcfsWm; }(); - if (const auto& _highWatermark = mcConfig.highWatermark) - highWatermark = *mcConfig.highWatermark; + if (const auto& _highWatermark = mcConfig.HighWatermark) + highWatermark = *mcConfig.HighWatermark; - if (const auto& _lowWatermark = mcConfig.lowWatermark) - lowWatermark = *mcConfig.lowWatermark; + if (const auto& _lowWatermark = mcConfig.LowWatermark) + lowWatermark = *mcConfig.LowWatermark; - if (const auto& _schedulerBuffer = mcConfig.schedulerBuffer) + if (const auto& _schedulerBuffer = mcConfig.SchedulerBuffer) schedulerBuffer = [=] { - if (_schedulerBuffer == DRAMSys::Config::SchedulerBuffer::Bankwise) + if (_schedulerBuffer == DRAMSys::Config::SchedulerBufferType::Bankwise) return SchedulerBuffer::Bankwise; - else if (_schedulerBuffer == DRAMSys::Config::SchedulerBuffer::ReadWrite) + else if (_schedulerBuffer == DRAMSys::Config::SchedulerBufferType::ReadWrite) return SchedulerBuffer::ReadWrite; else return SchedulerBuffer::Shared; }(); - if (const auto& _requestBufferSize = mcConfig.requestBufferSize) - requestBufferSize = *mcConfig.requestBufferSize; + if (const auto& _requestBufferSize = mcConfig.RequestBufferSize) + requestBufferSize = *mcConfig.RequestBufferSize; if (requestBufferSize == 0) SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!"); - if (const auto& _cmdMux = mcConfig.cmdMux) + if (const auto& _cmdMux = mcConfig.CmdMux) cmdMux = [=] { - if (_cmdMux == DRAMSys::Config::CmdMux::Oldest) + if (_cmdMux == DRAMSys::Config::CmdMuxType::Oldest) return CmdMux::Oldest; else return CmdMux::Strict; }(); - if (const auto& _respQueue = mcConfig.respQueue) + if (const auto& _respQueue = mcConfig.RespQueue) respQueue = [=] { - if (_respQueue == DRAMSys::Config::RespQueue::Fifo) + if (_respQueue == DRAMSys::Config::RespQueueType::Fifo) return RespQueue::Fifo; else return RespQueue::Reorder; }(); - if (const auto& _refreshPolicy = mcConfig.refreshPolicy) + if (const auto& _refreshPolicy = mcConfig.RefreshPolicy) refreshPolicy = [=] { - if (_refreshPolicy == DRAMSys::Config::RefreshPolicy::NoRefresh) + if (_refreshPolicy == DRAMSys::Config::RefreshPolicyType::NoRefresh) return RefreshPolicy::NoRefresh; - else if (_refreshPolicy == DRAMSys::Config::RefreshPolicy::AllBank) + else if (_refreshPolicy == DRAMSys::Config::RefreshPolicyType::AllBank) return RefreshPolicy::AllBank; - else if (_refreshPolicy == DRAMSys::Config::RefreshPolicy::PerBank) + else if (_refreshPolicy == DRAMSys::Config::RefreshPolicyType::PerBank) return RefreshPolicy::PerBank; - else if (_refreshPolicy == DRAMSys::Config::RefreshPolicy::Per2Bank) + else if (_refreshPolicy == DRAMSys::Config::RefreshPolicyType::Per2Bank) return RefreshPolicy::Per2Bank; else // if (policy == DRAMSys::Config::RefreshPolicy::SameBank) return RefreshPolicy::SameBank; }(); - if (const auto& _refreshMaxPostponed = mcConfig.refreshMaxPostponed) + if (const auto& _refreshMaxPostponed = mcConfig.RefreshMaxPostponed) refreshMaxPostponed = *_refreshMaxPostponed; - if (const auto& _refreshMaxPulledin = mcConfig.refreshMaxPulledin) + if (const auto& _refreshMaxPulledin = mcConfig.RefreshMaxPulledin) refreshMaxPulledin = *_refreshMaxPulledin; - if (const auto& _powerDownPolicy = mcConfig.powerDownPolicy) + if (const auto& _powerDownPolicy = mcConfig.PowerDownPolicy) powerDownPolicy = [=] { - if (_powerDownPolicy == DRAMSys::Config::PowerDownPolicy::NoPowerDown) + if (_powerDownPolicy == DRAMSys::Config::PowerDownPolicyType::NoPowerDown) return PowerDownPolicy::NoPowerDown; else return PowerDownPolicy::Staggered; }(); - if (const auto& _arbiter = mcConfig.arbiter) + if (const auto& _arbiter = mcConfig.Arbiter) arbiter = [=] { - if (_arbiter == DRAMSys::Config::Arbiter::Simple) + if (_arbiter == DRAMSys::Config::ArbiterType::Simple) return Arbiter::Simple; - else if (_arbiter == DRAMSys::Config::Arbiter::Fifo) + else if (_arbiter == DRAMSys::Config::ArbiterType::Fifo) return Arbiter::Fifo; else return Arbiter::Reorder; }(); - if (const auto& _maxActiveTransactions = mcConfig.maxActiveTransactions) + if (const auto& _maxActiveTransactions = mcConfig.MaxActiveTransactions) maxActiveTransactions = *_maxActiveTransactions; - if (const auto& _refreshManagement = mcConfig.refreshManagement) + if (const auto& _refreshManagement = mcConfig.RefreshManagement) refreshManagement = *_refreshManagement; - if (const auto& _arbitrationDelayFw = mcConfig.arbitrationDelayFw) + if (const auto& _arbitrationDelayFw = mcConfig.ArbitrationDelayFw) { arbitrationDelayFw = std::round(sc_time(*_arbitrationDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK; } - if (const auto& _arbitrationDelayBw = mcConfig.arbitrationDelayBw) + if (const auto& _arbitrationDelayBw = mcConfig.ArbitrationDelayBw) { arbitrationDelayBw = std::round(sc_time(*_arbitrationDelayBw, SC_NS) / memSpec->tCK) * memSpec->tCK; } - if (const auto& _thinkDelayFw = mcConfig.thinkDelayFw) + if (const auto& _thinkDelayFw = mcConfig.ThinkDelayFw) { thinkDelayFw = std::round(sc_time(*_thinkDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK; } - if (const auto& _thinkDelayBw = mcConfig.thinkDelayBw) + if (const auto& _thinkDelayBw = mcConfig.ThinkDelayBw) { thinkDelayBw = std::round(sc_time(*_thinkDelayBw, SC_NS) / memSpec->tCK) * memSpec->tCK; } - if (const auto& _phyDelayFw = mcConfig.phyDelayFw) + if (const auto& _phyDelayFw = mcConfig.PhyDelayFw) { phyDelayFw = std::round(sc_time(*_phyDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK; } - if (const auto& _phyDelayBw = mcConfig.phyDelayBw) + if (const auto& _phyDelayBw = mcConfig.PhyDelayBw) { phyDelayBw = std::round(sc_time(*_phyDelayBw, SC_NS) / memSpec->tCK) * memSpec->tCK; } { - auto _blockingReadDelay = mcConfig.blockingReadDelay.value_or(60); + auto _blockingReadDelay = mcConfig.BlockingReadDelay.value_or(60); blockingReadDelay = std::round(sc_time(_blockingReadDelay, SC_NS) / memSpec->tCK) * memSpec->tCK; } { - auto _blockingWriteDelay = mcConfig.blockingWriteDelay.value_or(60); + auto _blockingWriteDelay = mcConfig.BlockingWriteDelay.value_or(60); blockingWriteDelay = std::round(sc_time(_blockingWriteDelay, SC_NS) / memSpec->tCK) * memSpec->tCK; } } diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpec.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpec.cpp index 6d25dac1..e27e22d1 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpec.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpec.cpp @@ -55,20 +55,20 @@ MemSpec::MemSpec(const DRAMSys::Config::MemSpec& memSpec, banksPerChannel(banksPerChannel), bankGroupsPerChannel(bankGroupsPerChannel), devicesPerRank(devicesPerRank), - rowsPerBank(memSpec.memArchitectureSpec.entries.at("nbrOfRows")), - columnsPerRow(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") + rowsPerBank(memSpec.memarchitecturespec.entries.at("nbrOfRows")), + columnsPerRow(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")), + dataRate(memSpec.memarchitecturespec.entries.at("dataRate")), + bitWidth(memSpec.memarchitecturespec.entries.at("width")), dataBusWidth(bitWidth* devicesPerRank), bytesPerBeat(dataBusWidth / 8), defaultBytesPerBurst((defaultBurstLength* dataBusWidth) / 8), maxBytesPerBurst((maxBurstLength* dataBusWidth) / 8), - fCKMHz(memSpec.memTimingSpec.entries.at("clkMhz")), + fCKMHz(memSpec.memtimingspec.entries.at("clkMhz")), tCK(sc_time(1.0 / fCKMHz, SC_US)), memoryId(memSpec.memoryId), memoryType(memoryType), diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR3.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR3.cpp index 9271fdf5..719b3ba8 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR3.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR3.cpp @@ -45,61 +45,61 @@ using namespace tlm; MemSpecDDR3::MemSpecDDR3(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::DDR3, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), 1, - memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), - memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks"), 1, - 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")), + 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 * 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.has_value() ? memSpec.memPowerSpec.value().entries.at("idd0") : 0), - iDD2N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2n") : 0), - iDD3N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3n") : 0), - iDD4R (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4r") : 0), - iDD4W (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4w") : 0), - iDD5 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd5") : 0), - iDD6 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd6") : 0), - vDD (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd") : 0), - iDD2P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p0") : 0), - iDD2P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p1") : 0), - iDD3P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p0") : 0), - iDD3P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p1") : 0) + 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.has_value() ? memSpec.mempowerspec.value().entries.at("idd0") : 0), + iDD2N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n") : 0), + iDD3N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n") : 0), + iDD4R (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r") : 0), + iDD4W (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w") : 0), + iDD5 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd5") : 0), + iDD6 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd6") : 0), + vDD (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd") : 0), + iDD2P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p0") : 0), + iDD2P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p1") : 0), + iDD3P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p0") : 0), + iDD3P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p1") : 0) { uint64_t deviceSizeBits = static_cast(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; memorySizeBytes = deviceSizeBytes * devicesPerRank * ranksPerChannel * numberOfChannels; - if (!memSpec.memPowerSpec.has_value()) + if (!memSpec.mempowerspec.has_value()) SC_REPORT_FATAL("MemSpec", "No power spec defined!"); std::cout << headline << std::endl; diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR4.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR4.cpp index 594cda9b..89be15b6 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR4.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR4.cpp @@ -45,79 +45,79 @@ using namespace tlm; MemSpecDDR4::MemSpecDDR4(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::DDR4, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), 1, - 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")), + 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 * memSpec.memTimingSpec.entries.at("CKESR")), - tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), - tRC (tCK * memSpec.memTimingSpec.entries.at("RC")), - tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")), - tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), - tRPRE (tCK * memSpec.memTimingSpec.entries.at("RPRE")), - tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")), - tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), - tWPRE (tCK * memSpec.memTimingSpec.entries.at("WPRE")), - tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), - tXP (tCK * memSpec.memTimingSpec.entries.at("XP")), - tXS (tCK * memSpec.memTimingSpec.entries.at("XS")), - tREFI ((memSpec.memTimingSpec.entries.at("REFM") == 4) ? - (tCK * (static_cast(memSpec.memTimingSpec.entries.at("REFI")) / 4)) : - ((memSpec.memTimingSpec.entries.at("REFM") == 2) ? - (tCK * (static_cast(memSpec.memTimingSpec.entries.at("REFI")) / 2)) : - (tCK * memSpec.memTimingSpec.entries.at("REFI")))), - tRFC ((memSpec.memTimingSpec.entries.at("REFM") == 4) ? - (tCK * memSpec.memTimingSpec.entries.at("RFC4")) : - ((memSpec.memTimingSpec.entries.at("REFM") == 2) ? - (tCK * memSpec.memTimingSpec.entries.at("RFC2")) : - (tCK * memSpec.memTimingSpec.entries.at("RFC")))), - tRP (tCK * memSpec.memTimingSpec.entries.at("RP")), - tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")), - tCCD_S (tCK * memSpec.memTimingSpec.entries.at("CCD_S")), - tCCD_L (tCK * memSpec.memTimingSpec.entries.at("CCD_L")), - tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), - tRRD_S (tCK * memSpec.memTimingSpec.entries.at("RRD_S")), - tRRD_L (tCK * memSpec.memTimingSpec.entries.at("RRD_L")), - tWTR_S (tCK * memSpec.memTimingSpec.entries.at("WTR_S")), - tWTR_L (tCK * memSpec.memTimingSpec.entries.at("WTR_L")), - tAL (tCK * memSpec.memTimingSpec.entries.at("AL")), - tXPDLL (tCK * memSpec.memTimingSpec.entries.at("XPDLL")), - tXSDLL (tCK * memSpec.memTimingSpec.entries.at("XSDLL")), - tACTPDEN (tCK * memSpec.memTimingSpec.entries.at("ACTPDEN")), - tPRPDEN (tCK * memSpec.memTimingSpec.entries.at("PRPDEN")), - tREFPDEN (tCK * memSpec.memTimingSpec.entries.at("REFPDEN")), - tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")), - iDD0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd0") : 0), - iDD2N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2n") : 0), - iDD3N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3n") : 0), - iDD4R (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4r") : 0), - iDD4W (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4w") : 0), - iDD5 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd5") : 0), - iDD6 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd6") : 0), - vDD (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd") : 0), - iDD02 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd02") : 0), - iDD2P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p0") : 0), - iDD2P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p1") : 0), - iDD3P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p0") : 0), - iDD3P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p1") : 0), - iDD62 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd62") : 0), - vDD2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd2") : 0) + tCKESR (tCK * memSpec.memtimingspec.entries.at("CKESR")), + tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")), + tRC (tCK * memSpec.memtimingspec.entries.at("RC")), + tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")), + tRL (tCK * memSpec.memtimingspec.entries.at("RL")), + tRPRE (tCK * memSpec.memtimingspec.entries.at("RPRE")), + tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")), + tWL (tCK * memSpec.memtimingspec.entries.at("WL")), + tWPRE (tCK * memSpec.memtimingspec.entries.at("WPRE")), + tWR (tCK * memSpec.memtimingspec.entries.at("WR")), + tXP (tCK * memSpec.memtimingspec.entries.at("XP")), + tXS (tCK * memSpec.memtimingspec.entries.at("XS")), + tREFI ((memSpec.memtimingspec.entries.at("REFM") == 4) ? + (tCK * (static_cast(memSpec.memtimingspec.entries.at("REFI")) / 4)) : + ((memSpec.memtimingspec.entries.at("REFM") == 2) ? + (tCK * (static_cast(memSpec.memtimingspec.entries.at("REFI")) / 2)) : + (tCK * memSpec.memtimingspec.entries.at("REFI")))), + tRFC ((memSpec.memtimingspec.entries.at("REFM") == 4) ? + (tCK * memSpec.memtimingspec.entries.at("RFC4")) : + ((memSpec.memtimingspec.entries.at("REFM") == 2) ? + (tCK * memSpec.memtimingspec.entries.at("RFC2")) : + (tCK * memSpec.memtimingspec.entries.at("RFC")))), + tRP (tCK * memSpec.memtimingspec.entries.at("RP")), + tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")), + tCCD_S (tCK * memSpec.memtimingspec.entries.at("CCD_S")), + tCCD_L (tCK * memSpec.memtimingspec.entries.at("CCD_L")), + tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")), + tRRD_S (tCK * memSpec.memtimingspec.entries.at("RRD_S")), + tRRD_L (tCK * memSpec.memtimingspec.entries.at("RRD_L")), + tWTR_S (tCK * memSpec.memtimingspec.entries.at("WTR_S")), + tWTR_L (tCK * memSpec.memtimingspec.entries.at("WTR_L")), + tAL (tCK * memSpec.memtimingspec.entries.at("AL")), + tXPDLL (tCK * memSpec.memtimingspec.entries.at("XPDLL")), + tXSDLL (tCK * memSpec.memtimingspec.entries.at("XSDLL")), + tACTPDEN (tCK * memSpec.memtimingspec.entries.at("ACTPDEN")), + tPRPDEN (tCK * memSpec.memtimingspec.entries.at("PRPDEN")), + tREFPDEN (tCK * memSpec.memtimingspec.entries.at("REFPDEN")), + tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")), + iDD0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd0") : 0), + iDD2N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n") : 0), + iDD3N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n") : 0), + iDD4R (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r") : 0), + iDD4W (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w") : 0), + iDD5 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd5") : 0), + iDD6 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd6") : 0), + vDD (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd") : 0), + iDD02 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd02") : 0), + iDD2P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p0") : 0), + iDD2P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p1") : 0), + iDD3P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p0") : 0), + iDD3P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p1") : 0), + iDD62 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd62") : 0), + vDD2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd2") : 0) { uint64_t deviceSizeBits = static_cast(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; memorySizeBytes = deviceSizeBytes * devicesPerRank * ranksPerChannel * numberOfChannels; - if (!memSpec.memPowerSpec.has_value()) + if (!memSpec.mempowerspec.has_value()) SC_REPORT_WARNING("MemSpec", "No power spec defined!"); std::cout << headline << std::endl; diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5.cpp index 976f5ae1..10f59aac 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5.cpp @@ -45,52 +45,52 @@ using namespace tlm; MemSpecGDDR5::MemSpecGDDR5(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::GDDR5, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), 1, - 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")) + memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks") + / memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks") + * memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBankGroups") + * memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfDevices")), + tRP (tCK * memSpec.memtimingspec.entries.at("RP")), + tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")), + tRC (tCK * memSpec.memtimingspec.entries.at("RC")), + tRCDRD (tCK * memSpec.memtimingspec.entries.at("RCDRD")), + tRCDWR (tCK * memSpec.memtimingspec.entries.at("RCDWR")), + tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")), + tRRDS (tCK * memSpec.memtimingspec.entries.at("RRDS")), + tRRDL (tCK * memSpec.memtimingspec.entries.at("RRDL")), + tCCDS (tCK * memSpec.memtimingspec.entries.at("CCDS")), + tCCDL (tCK * memSpec.memtimingspec.entries.at("CCDL")), + tCL (tCK * memSpec.memtimingspec.entries.at("CL")), + tWCK2CKPIN (tCK * memSpec.memtimingspec.entries.at("WCK2CKPIN")), + tWCK2CK (tCK * memSpec.memtimingspec.entries.at("WCK2CK")), + tWCK2DQO (tCK * memSpec.memtimingspec.entries.at("WCK2DQO")), + tRTW (tCK * memSpec.memtimingspec.entries.at("RTW")), + tWL (tCK * memSpec.memtimingspec.entries.at("WL")), + tWCK2DQI (tCK * memSpec.memtimingspec.entries.at("WCK2DQI")), + tWR (tCK * memSpec.memtimingspec.entries.at("WR")), + tWTRS (tCK * memSpec.memtimingspec.entries.at("WTRS")), + tWTRL (tCK * memSpec.memtimingspec.entries.at("WTRL")), + tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")), + tPD (tCK * memSpec.memtimingspec.entries.at("PD")), + tXPN (tCK * memSpec.memtimingspec.entries.at("XPN")), + tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")), + tREFIPB (tCK * memSpec.memtimingspec.entries.at("REFIPB")), + tRFC (tCK * memSpec.memtimingspec.entries.at("RFC")), + tRFCPB (tCK * memSpec.memtimingspec.entries.at("RFCPB")), + tRREFD (tCK * memSpec.memtimingspec.entries.at("RREFD")), + tXS (tCK * memSpec.memtimingspec.entries.at("XS")), + tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")), + t32AW (tCK * memSpec.memtimingspec.entries.at("32AW")), + tPPD (tCK * memSpec.memtimingspec.entries.at("PPD")), + tLK (tCK * memSpec.memtimingspec.entries.at("LK")), + tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5X.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5X.cpp index 7b4cf66e..d1e86148 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5X.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5X.cpp @@ -45,52 +45,52 @@ using namespace tlm; MemSpecGDDR5X::MemSpecGDDR5X(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::GDDR5X, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), 1, - 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")) + memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks") + / memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks") + * memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBankGroups") + * memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfDevices")), + tRP (tCK * memSpec.memtimingspec.entries.at("RP")), + tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")), + tRC (tCK * memSpec.memtimingspec.entries.at("RC")), + tRCDRD (tCK * memSpec.memtimingspec.entries.at("RCDRD")), + tRCDWR (tCK * memSpec.memtimingspec.entries.at("RCDWR")), + tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")), + tRRDS (tCK * memSpec.memtimingspec.entries.at("RRDS")), + tRRDL (tCK * memSpec.memtimingspec.entries.at("RRDL")), + tCCDS (tCK * memSpec.memtimingspec.entries.at("CCDS")), + tCCDL (tCK * memSpec.memtimingspec.entries.at("CCDL")), + tRL (tCK * memSpec.memtimingspec.entries.at("CL")), + tWCK2CKPIN (tCK * memSpec.memtimingspec.entries.at("WCK2CKPIN")), + tWCK2CK (tCK * memSpec.memtimingspec.entries.at("WCK2CK")), + tWCK2DQO (tCK * memSpec.memtimingspec.entries.at("WCK2DQO")), + tRTW (tCK * memSpec.memtimingspec.entries.at("RTW")), + tWL (tCK * memSpec.memtimingspec.entries.at("WL")), + tWCK2DQI (tCK * memSpec.memtimingspec.entries.at("WCK2DQI")), + tWR (tCK * memSpec.memtimingspec.entries.at("WR")), + tWTRS (tCK * memSpec.memtimingspec.entries.at("WTRS")), + tWTRL (tCK * memSpec.memtimingspec.entries.at("WTRL")), + tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")), + tPD (tCK * memSpec.memtimingspec.entries.at("PD")), + tXP (tCK * memSpec.memtimingspec.entries.at("XP")), + tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")), + tREFIPB (tCK * memSpec.memtimingspec.entries.at("REFIPB")), + tRFC (tCK * memSpec.memtimingspec.entries.at("RFC")), + tRFCPB (tCK * memSpec.memtimingspec.entries.at("RFCPB")), + tRREFD (tCK * memSpec.memtimingspec.entries.at("RREFD")), + tXS (tCK * memSpec.memtimingspec.entries.at("XS")), + tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")), + t32AW (tCK * memSpec.memtimingspec.entries.at("32AW")), + tPPD (tCK * memSpec.memtimingspec.entries.at("PPD")), + tLK (tCK * memSpec.memtimingspec.entries.at("LK")), + tRTRS (tCK * memSpec.memtimingspec.entries.at("TRS")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR6.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR6.cpp index 64b78b14..127f331e 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR6.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR6.cpp @@ -45,55 +45,55 @@ using namespace tlm; MemSpecGDDR6::MemSpecGDDR6(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::GDDR6, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), 1, - 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")) + memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks"), + memSpec.memarchitecturespec.entries.at( "nbrOfBankGroups"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks") + / memSpec.memarchitecturespec.entries.at( "nbrOfBankGroups"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks") + * memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at( "nbrOfBankGroups") + * memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfDevices")), + per2BankOffset(memSpec.memarchitecturespec.entries.at("per2BankOffset")), + tRP (tCK * memSpec.memtimingspec.entries.at("RP")), + tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")), + tRC (tCK * memSpec.memtimingspec.entries.at("RC")), + tRCDRD (tCK * memSpec.memtimingspec.entries.at("RCDRD")), + tRCDWR (tCK * memSpec.memtimingspec.entries.at("RCDWR")), + tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")), + tRRDS (tCK * memSpec.memtimingspec.entries.at("RRDS")), + tRRDL (tCK * memSpec.memtimingspec.entries.at("RRDL")), + tCCDS (tCK * memSpec.memtimingspec.entries.at("CCDS")), + tCCDL (tCK * memSpec.memtimingspec.entries.at("CCDL")), + tRL (tCK * memSpec.memtimingspec.entries.at("RL")), + tWCK2CKPIN (tCK * memSpec.memtimingspec.entries.at("WCK2CKPIN")), + tWCK2CK (tCK * memSpec.memtimingspec.entries.at("WCK2CK")), + tWCK2DQO (tCK * memSpec.memtimingspec.entries.at("WCK2DQO")), + tRTW (tCK * memSpec.memtimingspec.entries.at("RTW")), + tWL (tCK * memSpec.memtimingspec.entries.at("WL")), + tWCK2DQI (tCK * memSpec.memtimingspec.entries.at("WCK2DQI")), + tWR (tCK * memSpec.memtimingspec.entries.at("WR")), + tWTRS (tCK * memSpec.memtimingspec.entries.at("WTRS")), + tWTRL (tCK * memSpec.memtimingspec.entries.at("WTRL")), + tPD (tCK * memSpec.memtimingspec.entries.at("PD")), + tCKESR (tCK * memSpec.memtimingspec.entries.at("CKESR")), + tXP (tCK * memSpec.memtimingspec.entries.at("XP")), + tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")), + tREFIpb (tCK * memSpec.memtimingspec.entries.at("REFIpb")), + tRFCab (tCK * memSpec.memtimingspec.entries.at("RFCab")), + tRFCpb (tCK * memSpec.memtimingspec.entries.at("RFCpb")), + tRREFD (tCK * memSpec.memtimingspec.entries.at("RREFD")), + tXS (tCK * memSpec.memtimingspec.entries.at("XS")), + tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")), + tPPD (tCK * memSpec.memtimingspec.entries.at("PPD")), + tLK (tCK * memSpec.memtimingspec.entries.at("LK")), + tACTPDE (tCK * memSpec.memtimingspec.entries.at("ACTPDE")), + tPREPDE (tCK * memSpec.memtimingspec.entries.at("PREPDE")), + tREFPDE (tCK * memSpec.memtimingspec.entries.at("REFPDE")), + tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.cpp index 479a9069..d3aa9e1f 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.cpp @@ -45,47 +45,47 @@ using namespace tlm; MemSpecHBM2::MemSpecHBM2(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::HBM2, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), - memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"), - memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"), - 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("nbrOfPseudoChannels"), - memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups") - * memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"), - 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")), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"), + 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("nbrOfPseudoChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfBankGroups") + * memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"), + 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 * 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")) + tXS (tCK * memSpec.memtimingspec.entries.at("XS")), + tRFC (tCK * memSpec.memtimingspec.entries.at("RFC")), + tRFCSB (tCK * memSpec.memtimingspec.entries.at("RFCSB")), + tRREFD (tCK * memSpec.memtimingspec.entries.at("RREFD")), + tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")), + tREFISB (tCK * memSpec.memtimingspec.entries.at("REFISB")) { commandLengthInCycles[Command::ACT] = 2; diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecLPDDR4.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecLPDDR4.cpp index 0c8b80ea..3f72958e 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecLPDDR4.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecLPDDR4.cpp @@ -45,47 +45,47 @@ using namespace tlm; MemSpecLPDDR4::MemSpecLPDDR4(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::LPDDR4, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), 1, - memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), - memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks"), 1, - 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")) + memSpec.memarchitecturespec.entries.at("nbrOfBanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks") + * memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfDevices")), + tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")), + tREFIpb (tCK * memSpec.memtimingspec.entries.at("REFIPB")), + tRFCab (tCK * memSpec.memtimingspec.entries.at("RFCAB")), + tRFCpb (tCK * memSpec.memtimingspec.entries.at("RFCPB")), + tRPab (tCK * memSpec.memtimingspec.entries.at("RPAB")), + tRPpb (tCK * memSpec.memtimingspec.entries.at("RPPB")), + tRCab (tCK * memSpec.memtimingspec.entries.at("RCAB")), + tRCpb (tCK * memSpec.memtimingspec.entries.at("RCPB")), + tPPD (tCK * memSpec.memtimingspec.entries.at("PPD")), + tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")), + tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")), + tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")), + tRRD (tCK * memSpec.memtimingspec.entries.at("RRD")), + tCCD (tCK * memSpec.memtimingspec.entries.at("CCD")), + tRL (tCK * memSpec.memtimingspec.entries.at("RL")), + tRPST (tCK * memSpec.memtimingspec.entries.at("RPST")), + tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")), + tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")), + tWL (tCK * memSpec.memtimingspec.entries.at("WL")), + tDQSS (tCK * memSpec.memtimingspec.entries.at("DQSS")), + tDQS2DQ (tCK * memSpec.memtimingspec.entries.at("DQS2DQ")), + tWR (tCK * memSpec.memtimingspec.entries.at("WR")), + tWPRE (tCK * memSpec.memtimingspec.entries.at("WPRE")), + tWTR (tCK * memSpec.memtimingspec.entries.at("WTR")), + tXP (tCK * memSpec.memtimingspec.entries.at("XP")), + tSR (tCK * memSpec.memtimingspec.entries.at("SR")), + tXSR (tCK * memSpec.memtimingspec.entries.at("XSR")), + tESCKE (tCK * memSpec.memtimingspec.entries.at("ESCKE")), + tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")), + tCMDCKE (tCK * memSpec.memtimingspec.entries.at("CMDCKE")), + tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")) { commandLengthInCycles[Command::ACT] = 4; commandLengthInCycles[Command::PREPB] = 2; diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecSTTMRAM.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecSTTMRAM.cpp index b68f15f0..a46bbdbe 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecSTTMRAM.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecSTTMRAM.cpp @@ -45,40 +45,40 @@ using namespace tlm; MemSpecSTTMRAM::MemSpecSTTMRAM(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::STTMRAM, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), 1, - memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), - memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks"), 1, - 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")), + 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 * 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")) + tCKESR (tCK * memSpec.memtimingspec.entries.at("CKESR")), + tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")), + tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")), + tRC (tCK * memSpec.memtimingspec.entries.at("RC")), + tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")), + tRL (tCK * memSpec.memtimingspec.entries.at("RL")), + tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")), + tWL (tCK * memSpec.memtimingspec.entries.at("WL")), + tWR (tCK * memSpec.memtimingspec.entries.at("WR")), + tXP (tCK * memSpec.memtimingspec.entries.at("XP")), + tXS (tCK * memSpec.memtimingspec.entries.at("XS")), + tCCD (tCK * memSpec.memtimingspec.entries.at("CCD")), + tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")), + tRP (tCK * memSpec.memtimingspec.entries.at("RP")), + tRRD (tCK * memSpec.memtimingspec.entries.at("RRD")), + tWTR (tCK * memSpec.memtimingspec.entries.at("WTR")), + tAL (tCK * memSpec.memtimingspec.entries.at("AL")), + tXPDLL (tCK * memSpec.memtimingspec.entries.at("XPDLL")), + tXSDLL (tCK * memSpec.memtimingspec.entries.at("XSDLL")), + tACTPDEN (tCK * memSpec.memtimingspec.entries.at("ACTPDEN")), + tPRPDEN (tCK * memSpec.memtimingspec.entries.at("PRPDEN")), + tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO.cpp index a47a3e77..9092122f 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO.cpp @@ -45,67 +45,67 @@ using namespace tlm; MemSpecWideIO::MemSpecWideIO(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::WideIO, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), 1, - memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), - memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks"), 1, - 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.has_value() ? memSpec.memPowerSpec.value().entries.at("idd0") : 0), - iDD2N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2n") : 0), - iDD3N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3n") : 0), - iDD4R (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4r") : 0), - iDD4W (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4w") : 0), - iDD5 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd5") : 0), - iDD6 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd6") : 0), - vDD (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd") : 0), - iDD02 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd02") : 0), - iDD2P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p0") : 0), - iDD2P02 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p02") : 0), - iDD2P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p1") : 0), - iDD2P12 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p12") : 0), - iDD2N2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2n2") : 0), - iDD3P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p0") : 0), - iDD3P02 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p02") : 0), - iDD3P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p1") : 0), - iDD3P12 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p12") : 0), - iDD3N2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3n2") : 0), - iDD4R2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4r2") : 0), - iDD4W2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4w2") : 0), - iDD52 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd52") : 0), - iDD62 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd62") : 0), - vDD2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd2") : 0) + 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.has_value() ? memSpec.mempowerspec.value().entries.at("idd0") : 0), + iDD2N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n") : 0), + iDD3N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n") : 0), + iDD4R (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r") : 0), + iDD4W (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w") : 0), + iDD5 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd5") : 0), + iDD6 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd6") : 0), + vDD (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd") : 0), + iDD02 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd02") : 0), + iDD2P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p0") : 0), + iDD2P02 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p02") : 0), + iDD2P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p1") : 0), + iDD2P12 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p12") : 0), + iDD2N2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n2") : 0), + iDD3P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p0") : 0), + iDD3P02 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p02") : 0), + iDD3P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p1") : 0), + iDD3P12 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p12") : 0), + iDD3N2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n2") : 0), + iDD4R2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r2") : 0), + iDD4W2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w2") : 0), + iDD52 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd52") : 0), + iDD62 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd62") : 0), + vDD2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd2") : 0) { uint64_t deviceSizeBits = static_cast(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; memorySizeBytes = deviceSizeBytes * ranksPerChannel * numberOfChannels; - if (!memSpec.memPowerSpec.has_value()) + if (!memSpec.mempowerspec.has_value()) SC_REPORT_FATAL("MemSpec", "No power spec defined!"); std::cout << headline << std::endl; diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO2.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO2.cpp index 2cb5a443..81462f78 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO2.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO2.cpp @@ -45,43 +45,43 @@ using namespace tlm; MemSpecWideIO2::MemSpecWideIO2(const DRAMSys::Config::MemSpec &memSpec) : MemSpec(memSpec, MemoryType::WideIO2, - memSpec.memArchitectureSpec.entries.at("nbrOfChannels"), + memSpec.memarchitecturespec.entries.at("nbrOfChannels"), 1, - memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), - memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), + memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks"), 1, - memSpec.memArchitectureSpec.entries.at("nbrOfBanks"), - memSpec.memArchitectureSpec.entries.at("nbrOfBanks") - * memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), - memSpec.memArchitectureSpec.entries.at("nbrOfRanks"), - memSpec.memArchitectureSpec.entries.at("nbrOfDevices")), - tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")), - tDQSS (tCK * memSpec.memTimingSpec.entries.at("DQSS")), - tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")), - tRL (tCK * memSpec.memTimingSpec.entries.at("RL")), - tWL (tCK * memSpec.memTimingSpec.entries.at("WL")), - tRCpb (tCK * memSpec.memTimingSpec.entries.at("RCPB")), - tRCab (tCK * memSpec.memTimingSpec.entries.at("RCAB")), - tCKESR (tCK * memSpec.memTimingSpec.entries.at("CKESR")), - tXSR (tCK * memSpec.memTimingSpec.entries.at("XSR")), - tXP (tCK * memSpec.memTimingSpec.entries.at("XP")), - tCCD (tCK * memSpec.memTimingSpec.entries.at("CCD")), - tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")), - tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")), - tRPpb (tCK * memSpec.memTimingSpec.entries.at("RPPB")), - tRPab (tCK * memSpec.memTimingSpec.entries.at("RPAB")), - tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")), - tWR (tCK * memSpec.memTimingSpec.entries.at("WR")), - tWTR (tCK * memSpec.memTimingSpec.entries.at("WTR")), - tRRD (tCK * memSpec.memTimingSpec.entries.at("RRD")), - tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")), - tREFI (tCK * static_cast(memSpec.memTimingSpec.entries.at("REFI") - * memSpec.memTimingSpec.entries.at("REFM"))), - tREFIpb (tCK * static_cast(memSpec.memTimingSpec.entries.at("REFIPB") - * memSpec.memTimingSpec.entries.at("REFM"))), - tRFCab (tCK * memSpec.memTimingSpec.entries.at("RFCAB")), - tRFCpb (tCK * memSpec.memTimingSpec.entries.at("RFCPB")), - tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")) + memSpec.memarchitecturespec.entries.at("nbrOfBanks"), + memSpec.memarchitecturespec.entries.at("nbrOfBanks") + * memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfRanks"), + memSpec.memarchitecturespec.entries.at("nbrOfDevices")), + tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")), + tDQSS (tCK * memSpec.memtimingspec.entries.at("DQSS")), + tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")), + tRL (tCK * memSpec.memtimingspec.entries.at("RL")), + tWL (tCK * memSpec.memtimingspec.entries.at("WL")), + tRCpb (tCK * memSpec.memtimingspec.entries.at("RCPB")), + tRCab (tCK * memSpec.memtimingspec.entries.at("RCAB")), + tCKESR (tCK * memSpec.memtimingspec.entries.at("CKESR")), + tXSR (tCK * memSpec.memtimingspec.entries.at("XSR")), + tXP (tCK * memSpec.memtimingspec.entries.at("XP")), + tCCD (tCK * memSpec.memtimingspec.entries.at("CCD")), + tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")), + tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")), + tRPpb (tCK * memSpec.memtimingspec.entries.at("RPPB")), + tRPab (tCK * memSpec.memtimingspec.entries.at("RPAB")), + tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")), + tWR (tCK * memSpec.memtimingspec.entries.at("WR")), + tWTR (tCK * memSpec.memtimingspec.entries.at("WTR")), + tRRD (tCK * memSpec.memtimingspec.entries.at("RRD")), + tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")), + tREFI (tCK * static_cast(memSpec.memtimingspec.entries.at("REFI") + * memSpec.memtimingspec.entries.at("REFM"))), + tREFIpb (tCK * static_cast(memSpec.memtimingspec.entries.at("REFIPB") + * memSpec.memtimingspec.entries.at("REFM"))), + tRFCab (tCK * memSpec.memtimingspec.entries.at("RFCAB")), + tRFCpb (tCK * memSpec.memtimingspec.entries.at("RFCPB")), + tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")) { uint64_t deviceSizeBits = static_cast(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth; uint64_t deviceSizeBytes = deviceSizeBits / 8; diff --git a/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp b/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp index 60f1c6b0..2ec633de 100644 --- a/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp +++ b/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp @@ -45,45 +45,45 @@ AddressDecoder::AddressDecoder(const Configuration& config, const DRAMSys::Config::AddressMapping& addressMapping) { - if (const auto& channelBits = addressMapping.channelBits) + if (const auto &channelBits = addressMapping.CONGEN.CHANNEL_BIT) { std::copy(channelBits->begin(), channelBits->end(), std::back_inserter(vChannelBits)); } - if (const auto& rankBits = addressMapping.rankBits) + if (const auto &rankBits = addressMapping.CONGEN.RANK_BIT) { std::copy(rankBits->begin(), rankBits->end(), std::back_inserter(vRankBits)); } - if (const auto& bankGroupBits = addressMapping.bankGroupBits) + if (const auto& bankGroupBits = addressMapping.CONGEN.BANKGROUP_BIT) { std::copy(bankGroupBits->begin(), bankGroupBits->end(), std::back_inserter(vBankGroupBits)); } - if (const auto& byteBits = addressMapping.byteBits) + if (const auto &byteBits = addressMapping.CONGEN.BYTE_BIT) { std::copy(byteBits->begin(), byteBits->end(), std::back_inserter(vByteBits)); } - if (const auto& xorBits = addressMapping.xorBits) + if (const auto &xorBits = addressMapping.CONGEN.XOR) { for (const auto& xorBit : *xorBits) { - vXor.emplace_back(xorBit.first, xorBit.second); + vXor.emplace_back(xorBit.FIRST, xorBit.SECOND); } } - if (const auto& bankBits = addressMapping.bankBits) + if (const auto &bankBits = addressMapping.CONGEN.BANK_BIT) { std::copy(bankBits->begin(), bankBits->end(), std::back_inserter(vBankBits)); } - if (const auto& rowBits = addressMapping.rowBits) + if (const auto &rowBits = addressMapping.CONGEN.ROW_BIT) { std::copy(rowBits->begin(), rowBits->end(), std::back_inserter(vRowBits)); } - if (const auto& columnBits = addressMapping.columnBits) + if (const auto &columnBits = addressMapping.CONGEN.COLUMN_BIT) { std::copy(columnBits->begin(), columnBits->end(), std::back_inserter(vColumnBits)); } diff --git a/src/libdramsys/DRAMSys/simulation/DRAMSys.cpp b/src/libdramsys/DRAMSys/simulation/DRAMSys.cpp index 7d02beab..6e32e0b5 100644 --- a/src/libdramsys/DRAMSys/simulation/DRAMSys.cpp +++ b/src/libdramsys/DRAMSys/simulation/DRAMSys.cpp @@ -86,9 +86,9 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name& name, // Load configLib and initialize modules // Important: The memSpec needs to be the first configuration to be loaded! - config.loadMemSpec(configLib.memSpec); - config.loadMCConfig(configLib.mcConfig); - config.loadSimConfig(configLib.simConfig); + config.loadMemSpec(configLib.memspec); + config.loadMCConfig(configLib.mcconfig); + config.loadSimConfig(configLib.simconfig); // Setup the debug manager: setupDebugManager(config.simulationName); @@ -96,7 +96,7 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name& name, if (initAndBind) { // Instantiate all internal DRAMSys modules: - instantiateModules(configLib.addressMapping); + instantiateModules(configLib.addressmapping); // Connect all internal DRAMSys modules: bindSockets(); report(headline); diff --git a/src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp b/src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp index 744fd1df..719c8bff 100644 --- a/src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp +++ b/src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp @@ -71,9 +71,9 @@ DRAMSysRecordable::DRAMSysRecordable(const sc_core::sc_module_name& name, const // is prepended to the simulation name if found. std::string traceName; - if (!configLib.simulationId.empty()) + if (!configLib.simulationid.empty()) { - std::string sid = configLib.simulationId; + std::string sid = configLib.simulationid; traceName = sid + '_' + config.simulationName; } else @@ -111,8 +111,8 @@ void DRAMSysRecordable::setupTlmRecorders(const std::string& traceName, std::string recorderName = "tlmRecorder" + std::to_string(i); tlmRecorders.emplace_back(recorderName, config, dbName); - tlmRecorders.back().recordMcConfig(::DRAMSys::Config::dump(configLib.mcConfig)); - tlmRecorders.back().recordMemspec(::DRAMSys::Config::dump(configLib.memSpec)); + tlmRecorders.back().recordMcConfig(nlohmann::json(configLib.mcconfig).dump()); + tlmRecorders.back().recordMemspec(nlohmann::json(configLib.memspec).dump()); tlmRecorders.back().recordTraceNames(config.simulationName); } } @@ -120,7 +120,7 @@ void DRAMSysRecordable::setupTlmRecorders(const std::string& traceName, void DRAMSysRecordable::instantiateModules(const std::string& traceName, const ::DRAMSys::Config::Configuration& configLib) { - addressDecoder = std::make_unique(config, configLib.addressMapping); + addressDecoder = std::make_unique(config, configLib.addressmapping); addressDecoder->print(); // Create and properly initialize TLM recorders. diff --git a/src/simulator/simulator/main.cpp b/src/simulator/simulator/main.cpp index 3f04a683..8513433f 100644 --- a/src/simulator/simulator/main.cpp +++ b/src/simulator/simulator/main.cpp @@ -99,16 +99,16 @@ int sc_main(int argc, char **argv) // Instantiate DRAMSys: std::unique_ptr dramSys; - if (configLib.simConfig.databaseRecording.value_or(false)) + if (configLib.simconfig.DatabaseRecording.value_or(false)) dramSys = std::make_unique("DRAMSys", configLib); else dramSys = std::make_unique("DRAMSys", configLib); - if (!configLib.traceSetup.has_value()) + if (!configLib.tracesetup.has_value()) SC_REPORT_FATAL("sc_main", "No trace setup section provided."); // Instantiate STL Players: - TraceSetup setup(dramSys->getConfig(), configLib.traceSetup.value(), resources, players); + TraceSetup setup(dramSys->getConfig(), configLib.tracesetup.value(), resources, players); // Bind STL Players with DRAMSys: for (auto& player : players) diff --git a/src/util/DRAMSys/util/json.h b/src/util/DRAMSys/util/json.h index f184f8a1..94a24cdf 100644 --- a/src/util/DRAMSys/util/json.h +++ b/src/util/DRAMSys/util/json.h @@ -1,5 +1,9 @@ /* +<<<<<<< HEAD * Copyright (c) 2021, Technische Universität Kaiserslautern +======= + * Copyright (c) 2021, Technische Universit�t Kaiserslautern +>>>>>>> 6a800d9a (Refactor SimConfig to use new jsonify macro) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,11 +44,83 @@ #include "nlohmann/json.hpp" #include +#include +#include using json_t = nlohmann::json; +namespace DRAMSys::util { +// See https://www.kdab.com/jsonify-with-nlohmann-json/ +// Try to set the value of type T into the variant data if it fails, do nothing +template +void variant_from_json(const nlohmann::json &j, std::variant &data) +{ + try { + data = j.get(); + } catch (...) { + } +} + +template +void optional_to_json(nlohmann::json &j, std::string_view name, const std::optional &value) +{ + if (value) + j[name] = *value; +} + +template +void optional_from_json(const nlohmann::json &j, std::string_view name, std::optional &value) +{ + const auto it = j.find(name); + + if (it != j.end()) + value = it->get(); + else + value = std::nullopt; +} + +template +constexpr bool is_optional = false; +template +constexpr bool is_optional> = true; + +template +void extended_to_json(const char *key, nlohmann::json &j, const T &value) +{ + if constexpr (is_optional) + optional_to_json(j, key, value); + else + j[key] = value; +} + +template +void extended_from_json(const char *key, const nlohmann::json &j, T &value) +{ + if constexpr (is_optional) + optional_from_json(j, key, value); + else + j.at(key).get_to(value); +} + +} // namespace DRAMSys::util + NLOHMANN_JSON_NAMESPACE_BEGIN +template +struct adl_serializer> +{ + static void to_json(nlohmann::json &j, const std::variant &data) + { + std::visit([&j](const auto &v) { j = v; }, data); + } + + static void from_json(const nlohmann::json &j, std::variant &data) + { + // Call variant_from_json for all types, only one will succeed + (DRAMSys::util::variant_from_json(j, data), ...); + } +}; + template struct adl_serializer> { static void to_json(json_t& j, const std::optional& opt) { @@ -66,6 +142,18 @@ struct adl_serializer> { } }; + NLOHMANN_JSON_NAMESPACE_END +#define EXTEND_JSON_TO(v1) DRAMSys::util::extended_to_json(#v1, nlohmann_json_j, nlohmann_json_t.v1); +#define EXTEND_JSON_FROM(v1) DRAMSys::util::extended_from_json(#v1, nlohmann_json_j, nlohmann_json_t.v1); + +#define NLOHMANN_JSONIFY_ALL_THINGS(Type, ...) \ + inline void to_json(nlohmann::json &nlohmann_json_j, const Type &nlohmann_json_t) { \ + NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_TO, __VA_ARGS__)) \ + } \ + inline void from_json(const nlohmann::json &nlohmann_json_j, Type &nlohmann_json_t) { \ + NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_FROM, __VA_ARGS__)) \ + } + #endif \ No newline at end of file diff --git a/tests/tests_configuration/CMakeLists.txt b/tests/tests_configuration/CMakeLists.txt index e1eee0f6..97ddf6c8 100644 --- a/tests/tests_configuration/CMakeLists.txt +++ b/tests/tests_configuration/CMakeLists.txt @@ -1,8 +1,26 @@ -add_executable(simpletest "${CMAKE_CURRENT_LIST_DIR}/simpletest.cpp") -target_link_libraries(simpletest PRIVATE DRAMSys::config) -set_target_properties(simpletest PROPERTIES FOLDER tests/configuration) +############################################### +### tests_configuration ### +############################################### +cmake_minimum_required(VERSION 3.1.0) -add_executable(converter "${CMAKE_CURRENT_LIST_DIR}/converter.cpp") -target_link_libraries(converter PRIVATE DRAMSys::config) -set_target_properties(converter PROPERTIES FOLDER tests/configuration) +project(test_configuration) + +add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/test_configuration.cpp) + +set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER tests/configuration) + +target_link_libraries(${PROJECT_NAME} PRIVATE + DRAMSys::config + gtest_main +) + +gtest_discover_tests(${PROJECT_NAME} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_executable(jsonconverter ${CMAKE_CURRENT_SOURCE_DIR}/jsonconverter.cpp) +target_link_libraries(jsonconverter PRIVATE DRAMSys::config) +set_target_properties(jsonconverter PROPERTIES FOLDER tests/configuration) + +build_source_group() diff --git a/tests/tests_configuration/converter.cpp b/tests/tests_configuration/jsonconverter.cpp similarity index 100% rename from tests/tests_configuration/converter.cpp rename to tests/tests_configuration/jsonconverter.cpp index c7f4845d..92f341e3 100644 --- a/tests/tests_configuration/converter.cpp +++ b/tests/tests_configuration/jsonconverter.cpp @@ -33,12 +33,12 @@ * Derek Christ */ +#include + #include #include #include -#include - int main(int argc, char **argv) { if (argc != 2) diff --git a/tests/tests_configuration/reference.json b/tests/tests_configuration/reference.json new file mode 100644 index 00000000..ac8f4a31 --- /dev/null +++ b/tests/tests_configuration/reference.json @@ -0,0 +1,212 @@ +{ + "simulation": { + "addressmapping": { + "CONGEN": { + "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 + ] + } + }, + "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" + }, + "memspec": { + "memarchitecturespec": { + "RAACDR": 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 + } + }, + "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 + }, + "simulationid": "std::string_simulationId", + "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 + } + ] + } +} \ No newline at end of file diff --git a/tests/tests_configuration/resources/addressmapping/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json b/tests/tests_configuration/resources/addressmapping/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json new file mode 100644 index 00000000..bce5038e --- /dev/null +++ b/tests/tests_configuration/resources/addressmapping/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json @@ -0,0 +1,50 @@ +{ + "CONGEN": { + "BYTE_BIT": [ + 0, + 1 + ], + "COLUMN_BIT": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12 + ], + "BANKGROUP_BIT": [ + 13, + 14, + 15 + ], + "BANK_BIT": [ + 16 + ], + "ROW_BIT": [ + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32 + ], + "CHANNEL_BIT": [ + 33 + ] + } +} \ No newline at end of file diff --git a/tests/tests_configuration/resources/ddr5-example.json b/tests/tests_configuration/resources/ddr5-example.json new file mode 100644 index 00000000..2fea61ee --- /dev/null +++ b/tests/tests_configuration/resources/ddr5-example.json @@ -0,0 +1,11 @@ +{ + "simulation": { + "addressmapping": "am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json", + "mcconfig": "fr_fcfs.json", + "memspec": "JEDEC_2x8x2Gbx4_DDR5-3200A.json", + "simconfig": "ddr5.json", + "simulationid": "ddr5-example", + "thermalconfig": "config.json", + "tracesetup": "ddr5-trace.json" + } +} diff --git a/tests/tests_configuration/resources/mcconfig/fr_fcfs.json b/tests/tests_configuration/resources/mcconfig/fr_fcfs.json new file mode 100644 index 00000000..cdaa94b3 --- /dev/null +++ b/tests/tests_configuration/resources/mcconfig/fr_fcfs.json @@ -0,0 +1,17 @@ +{ + "mcconfig": { + "PagePolicy": "Open", + "Scheduler": "FrFcfs", + "SchedulerBuffer": "Bankwise", + "RequestBufferSize": 8, + "CmdMux": "Oldest", + "RespQueue": "Fifo", + "RefreshPolicy": "AllBank", + "RefreshMaxPostponed": 0, + "RefreshMaxPulledin": 0, + "PowerDownPolicy": "NoPowerDown", + "Arbiter": "Simple", + "MaxActiveTransactions": 128, + "RefreshManagement": false + } +} diff --git a/tests/tests_configuration/resources/memspec/JEDEC_2x8x2Gbx4_DDR5-3200A.json b/tests/tests_configuration/resources/memspec/JEDEC_2x8x2Gbx4_DDR5-3200A.json new file mode 100644 index 00000000..9b3e1e4e --- /dev/null +++ b/tests/tests_configuration/resources/memspec/JEDEC_2x8x2Gbx4_DDR5-3200A.json @@ -0,0 +1,77 @@ +{ + "memspec": { + "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, + "RAACDR" : 16 + }, + "memoryId": "JEDEC_2x8x2Gbx4_DDR5-3200A", + "memoryType": "DDR5", + "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 + } + } +} diff --git a/tests/tests_configuration/resources/simconfig/ddr5.json b/tests/tests_configuration/resources/simconfig/ddr5.json new file mode 100644 index 00000000..d3987d37 --- /dev/null +++ b/tests/tests_configuration/resources/simconfig/ddr5.json @@ -0,0 +1,19 @@ +{ + "simconfig": { + "AddressOffset": 0, + "CheckTLM2Protocol": false, + "DatabaseRecording": true, + "Debug": false, + "ECCControllerMode": "Disabled", + "EnableWindowing": false, + "ErrorCSVFile": "", + "ErrorChipSeed": 42, + "PowerAnalysis": false, + "SimulationName": "ddr5", + "SimulationProgressBar": true, + "StoreMode": "NoStorage", + "ThermalSimulation": false, + "UseMalloc": false, + "WindowSize": 1000 + } +} diff --git a/tests/tests_configuration/resources/tracesetup/ddr5-trace.json b/tests/tests_configuration/resources/tracesetup/ddr5-trace.json new file mode 100644 index 00000000..1ca86cfd --- /dev/null +++ b/tests/tests_configuration/resources/tracesetup/ddr5-trace.json @@ -0,0 +1,28 @@ +{ + "tracesetup": [ + { + "clkMhz": 2000, + "name": "ddr3_example.stl" + }, + { + "clkMhz": 2000, + "name": "gen0", + "numRequests": 2000, + "rwRatio": 0.85, + "addressDistribution": "sequential", + "addressIncrement": 256, + "maxPendingReadRequests": 8, + "maxPendingWriteRequests": 8 + }, + { + "clkMhz": 2000, + "name": "gen1", + "numRequests": 2000, + "rwRatio": 0.85, + "addressDistribution": "random", + "seed": 123456, + "maxPendingReadRequests": 8, + "maxPendingWriteRequests": 8 + } + ] +} \ No newline at end of file diff --git a/tests/tests_configuration/test_configuration.cpp b/tests/tests_configuration/test_configuration.cpp new file mode 100644 index 00000000..89f0740d --- /dev/null +++ b/tests/tests_configuration/test_configuration.cpp @@ -0,0 +1,564 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Derek Christ + */ + +#include +#include + +#include +#include +#include +#include + +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::TraceHammer 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::TraceHammer 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}, + {"RAACDR", 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 = {}; + gen.clksPerRequest = {}; + + 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.clksPerRequest = {}; + 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.clksPerRequest = {}; + 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::TraceHammer ConfigurationTest::createTraceHammer() +{ + DRAMSys::Config::TraceHammer 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(); + + 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_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": { + "RAACDR": 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"( + { + "CONGEN": { + "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; + + 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); +} diff --git a/tests/tests_dramsys/CommandMuxTests.cpp b/tests/tests_dramsys/CommandMuxTests.cpp deleted file mode 100644 index 146cf86a..00000000 --- a/tests/tests_dramsys/CommandMuxTests.cpp +++ /dev/null @@ -1,110 +0,0 @@ -///* -// * Copyright (c) 2019, 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: -// * Lukas Steiner -// */ -// -//#include -//#include -//#include -//#include -// -//#include -//#include -// -//using namespace DRAMSys; -// -//class CommandMuxState -//{ -//public: -// Command firstCommand; -// Command secondCommand; -// Command resultCommand; -//}; -// -//class CommandMuxTestBase : public testing::Test -//{ -//public: -// CommandMux *commandMux; -// -// tlm_generic_payload *firstPayload; -// tlm_generic_payload *secondPayload; -// -// std::pair firstPair; -// std::pair secondPair; -// -// std::vector> readyCommands; -// -// std::pair result; -// -// CommandMuxTestBase() -// { -// commandMux = new CommandMux(); -// firstPayload = new tlm_generic_payload(); -// secondPayload = new tlm_generic_payload(); -// } -// -// ~CommandMuxTestBase() -// { -// delete commandMux; -// delete firstPayload; -// delete secondPayload; -// } -//}; -// -//class CommandMuxTestParam : public CommandMuxTestBase, public testing::WithParamInterface -//{ -//public: -// CommandMuxTestParam() -// { -// commandMux->insertPayload(firstPayload); -// commandMux->insertPayload(secondPayload); -// -// firstPair.first = GetParam().firstCommand; -// firstPair.second = firstPayload; -// secondPair.first = GetParam().secondCommand; -// secondPair.second = secondPayload; -// -// readyCommands.push_back(secondPair); -// readyCommands.push_back(firstPair); -// result = commandMux->selectCommand(readyCommands); -// } -//}; -// -//TEST_P(CommandMuxTestParam, satisfiesCommandOrder) -//{ -// EXPECT_EQ(result.first, GetParam().resultCommand); -//} -// -//INSTANTIATE_TEST_CASE_P(Default, CommandMuxTestParam, testing::Values( -// CommandMuxState{Command::RD, Command::WR, Command::RD}, -// CommandMuxState{Command::RD, Command::ACT, Command::ACT})); From 2d0445d5a7ad0814bb719fcda5b140fa545dfb75 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 2 Jan 2023 12:35:34 +0100 Subject: [PATCH 02/20] Introduce demonstrator for new simulator concept --- CMakeLists.txt | 3 +- src/configuration/DRAMSys/config/TraceSetup.h | 23 +- src/configuration/Notes.txt | 6 + src/simulator/CMakeLists.txt | 1 - src/simulator/simulator/Initiator.h | 47 ++ src/simulator/simulator/SimpleInitiator.h | 70 +++ src/simulator/simulator/StlPlayer.cpp | 236 ---------- src/simulator/simulator/TraceSetup.cpp | 237 ---------- src/simulator/simulator/TrafficGenerator.cpp | 412 ------------------ src/simulator/simulator/TrafficGenerator.h | 150 ------- src/simulator/simulator/TrafficInitiator.cpp | 138 ------ .../simulator/generator/RandomProducer.cpp | 79 ++++ .../simulator/generator/RandomProducer.h | 69 +++ .../generator/SequentialProducer.cpp | 82 ++++ .../simulator/generator/SequentialProducer.h | 75 ++++ .../simulator/generator/TrafficGenerator.cpp | 238 ++++++++++ .../simulator/generator/TrafficGenerator.h | 82 ++++ .../simulator/generator/definitions.h | 41 ++ src/simulator/simulator/hammer/RowHammer.cpp | 67 +++ src/simulator/simulator/hammer/RowHammer.h | 61 +++ src/simulator/simulator/main.cpp | 195 ++++++--- src/simulator/simulator/player/StlPlayer.cpp | 221 ++++++++++ .../simulator/{ => player}/StlPlayer.h | 86 ++-- src/simulator/simulator/request/Request.h | 53 +++ .../simulator/request/RequestIssuer.cpp | 153 +++++++ .../RequestIssuer.h} | 106 +++-- .../simulator/request/RequestProducer.h | 49 +++ src/simulator/simulator/util.cpp | 75 ++++ .../simulator/{TraceSetup.h => util.h} | 43 +- src/util/DRAMSys/util/json.h | 1 + .../test_configuration.cpp | 11 +- 31 files changed, 1701 insertions(+), 1409 deletions(-) create mode 100644 src/configuration/Notes.txt create mode 100644 src/simulator/simulator/Initiator.h create mode 100644 src/simulator/simulator/SimpleInitiator.h delete mode 100644 src/simulator/simulator/StlPlayer.cpp delete mode 100644 src/simulator/simulator/TraceSetup.cpp delete mode 100644 src/simulator/simulator/TrafficGenerator.cpp delete mode 100644 src/simulator/simulator/TrafficGenerator.h delete mode 100644 src/simulator/simulator/TrafficInitiator.cpp create mode 100644 src/simulator/simulator/generator/RandomProducer.cpp create mode 100644 src/simulator/simulator/generator/RandomProducer.h create mode 100644 src/simulator/simulator/generator/SequentialProducer.cpp create mode 100644 src/simulator/simulator/generator/SequentialProducer.h create mode 100644 src/simulator/simulator/generator/TrafficGenerator.cpp create mode 100644 src/simulator/simulator/generator/TrafficGenerator.h create mode 100644 src/simulator/simulator/generator/definitions.h create mode 100644 src/simulator/simulator/hammer/RowHammer.cpp create mode 100644 src/simulator/simulator/hammer/RowHammer.h create mode 100644 src/simulator/simulator/player/StlPlayer.cpp rename src/simulator/simulator/{ => player}/StlPlayer.h (57%) create mode 100644 src/simulator/simulator/request/Request.h create mode 100644 src/simulator/simulator/request/RequestIssuer.cpp rename src/simulator/simulator/{TrafficInitiator.h => request/RequestIssuer.h} (55%) create mode 100644 src/simulator/simulator/request/RequestProducer.h create mode 100644 src/simulator/simulator/util.cpp rename src/simulator/simulator/{TraceSetup.h => util.h} (58%) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1be0376..0cdf6184 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,7 +77,7 @@ endif() set(DRAMSYS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src") set(DRAMSYS_LIBRARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib") set(DRAMSYS_TESTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tests") -set(DRAMSYS_RESOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/resources") +set(DRAMSYS_RESOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/configs") set(DRAMSYS_EXTENSIONS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extensions") ### Build options ### @@ -137,6 +137,7 @@ FetchContent_Declare( GIT_REPOSITORY https://github.com/accellera-official/systemc.git GIT_TAG 2.3.4) +set(DISABLE_COPYRIGHT_MESSAGE True) FetchContent_MakeAvailable(systemc) set_target_properties(systemc PROPERTIES FOLDER lib) diff --git a/src/configuration/DRAMSys/config/TraceSetup.h b/src/configuration/DRAMSys/config/TraceSetup.h index cff510f1..af100b30 100644 --- a/src/configuration/DRAMSys/config/TraceSetup.h +++ b/src/configuration/DRAMSys/config/TraceSetup.h @@ -89,8 +89,6 @@ struct TrafficGeneratorActiveState std::optional addressIncrement; std::optional minAddress; std::optional maxAddress; - std::optional clksPerRequest; - std::optional notify; }; NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorActiveState, @@ -100,9 +98,7 @@ NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorActiveState, addressDistribution, addressIncrement, minAddress, - maxAddress, - clksPerRequest, - notify) + maxAddress) struct TrafficGeneratorIdleState { @@ -139,9 +135,6 @@ struct TrafficGenerator std::optional addressIncrement; std::optional minAddress; std::optional maxAddress; - std::optional clksPerRequest; - - std::optional idleUntil; }; NLOHMANN_JSONIFY_ALL_THINGS(TrafficGenerator, @@ -157,9 +150,7 @@ NLOHMANN_JSONIFY_ALL_THINGS(TrafficGenerator, addressDistribution, addressIncrement, minAddress, - maxAddress, - clksPerRequest, - idleUntil) + maxAddress) struct TrafficGeneratorStateMachine { @@ -173,7 +164,6 @@ struct TrafficGeneratorStateMachine std::optional dataLength; std::vector> states; std::vector transitions; - std::optional idleUntil; }; NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorStateMachine, @@ -185,10 +175,9 @@ NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorStateMachine, maxTransactions, dataLength, states, - transitions, - idleUntil) + transitions) -struct TraceHammer +struct RowHammer { uint64_t clkMhz; std::string name; @@ -200,7 +189,7 @@ struct TraceHammer }; NLOHMANN_JSONIFY_ALL_THINGS( - TraceHammer, clkMhz, name, maxPendingReadRequests, maxPendingWriteRequests, numRequests, rowIncrement) + RowHammer, clkMhz, name, maxPendingReadRequests, maxPendingWriteRequests, numRequests, rowIncrement) struct TraceSetupConstants { @@ -209,7 +198,7 @@ struct TraceSetupConstants }; using TraceSetup = std::vector< - std::variant>; + std::variant>; } // namespace Configuration diff --git a/src/configuration/Notes.txt b/src/configuration/Notes.txt new file mode 100644 index 00000000..122aab7b --- /dev/null +++ b/src/configuration/Notes.txt @@ -0,0 +1,6 @@ +Things to refactor in the configuration format: + - Embed the resource directory directly into the base configuration OR + - Specify the full (relative) path to each sub-configuration + + - Remove diverging sub-config base key names in base config and in the sub-config (i.e. remove the INNER_KEYs in the code) + - Remove redundant CONGEN type from the addressmapping diff --git a/src/simulator/CMakeLists.txt b/src/simulator/CMakeLists.txt index 9c2f9032..bae5c739 100644 --- a/src/simulator/CMakeLists.txt +++ b/src/simulator/CMakeLists.txt @@ -54,4 +54,3 @@ target_link_libraries(DRAMSys ) build_source_group() -diagnostics_print(DRAMSys) \ No newline at end of file diff --git a/src/simulator/simulator/Initiator.h b/src/simulator/simulator/Initiator.h new file mode 100644 index 00000000..817fb00e --- /dev/null +++ b/src/simulator/simulator/Initiator.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023, 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 + */ + +#pragma once + +#include + +class Initiator +{ +public: + virtual ~Initiator() = default; + + virtual void bind(tlm_utils::multi_target_base<> &target) = 0; + virtual uint64_t totalRequests() = 0; +}; diff --git a/src/simulator/simulator/SimpleInitiator.h b/src/simulator/simulator/SimpleInitiator.h new file mode 100644 index 00000000..3286ac5e --- /dev/null +++ b/src/simulator/simulator/SimpleInitiator.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023, 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 + */ + +#pragma once + +#include "Initiator.h" +#include "request/RequestIssuer.h" + +template +class SimpleInitiator : public Initiator +{ +public: + SimpleInitiator(sc_core::sc_module_name const &name, + MemoryManager &memoryManager, + std::optional maxPendingReadRequests, + std::optional maxPendingWriteRequests, + std::function transactionFinished, + std::function terminate, + Producer &&producer) + : producer(std::forward(producer)), + issuer( + name, + memoryManager, + maxPendingReadRequests, + maxPendingWriteRequests, + [this] { return this->producer.nextRequest(); }, + std::move(transactionFinished), + std::move(terminate)) + { + } + + void bind(tlm_utils::multi_target_base<> &target) override { issuer.iSocket.bind(target); } + uint64_t totalRequests() override { return producer.totalRequests(); }; + +private: + Producer producer; + RequestIssuer issuer; +}; diff --git a/src/simulator/simulator/StlPlayer.cpp b/src/simulator/simulator/StlPlayer.cpp deleted file mode 100644 index 967206c5..00000000 --- a/src/simulator/simulator/StlPlayer.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2015, 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: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - * Éder F. Zulian - * Felipe S. Prado - * Derek Christ - */ - -#include "StlPlayer.h" - -using namespace sc_core; -using namespace tlm; - -StlPlayer::StlPlayer(const sc_module_name &name, const Configuration& config, const std::string &pathToTrace, - const sc_time &playerClk, unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, - TraceSetup& setup, bool relative) : - TrafficInitiator(name, config, setup, maxPendingReadRequests, maxPendingWriteRequests, - config.memSpec->defaultBytesPerBurst), - file(pathToTrace), relative(relative), playerClk(playerClk) -{ - currentBuffer = &lineContents[0]; - parseBuffer = &lineContents[1]; - - if (!file.is_open()) - SC_REPORT_FATAL("StlPlayer", (std::string("Could not open trace ") + pathToTrace).c_str()); - else - { - std::string line; - while (std::getline(file, line)) - { - if (line.size() > 1 && line[0] != '#') - numberOfLines++; - } - file.clear(); - file.seekg(0); - - if (numberOfLines == 0) - SC_REPORT_FATAL("StlPlayer", "Trace file is empty"); - } - - currentBuffer->reserve(lineBufferSize); - parseBuffer->reserve(lineBufferSize); - - parseTraceFile(); - lineIterator = currentBuffer->cend(); -} - -StlPlayer::~StlPlayer() -{ - if (parserThread.joinable()) - parserThread.join(); -} - -void StlPlayer::sendNextPayload() -{ - if (lineIterator == currentBuffer->cend()) - { - lineIterator = swapBuffers(); - if (lineIterator == currentBuffer->cend()) - { - // The file is empty. Nothing more to do. - finished = true; - return; - } - } - - // Allocate a generic payload for this request. - tlm_generic_payload& payload = setup.allocatePayload(lineIterator->dataLength); - payload.acquire(); - - // Fill up the payload. - payload.set_address(lineIterator->address); - payload.set_response_status(TLM_INCOMPLETE_RESPONSE); - payload.set_dmi_allowed(false); - payload.set_byte_enable_length(0); - payload.set_data_length(lineIterator->dataLength); - payload.set_command(lineIterator->command); - std::copy(lineIterator->data.begin(), lineIterator->data.end(), payload.get_data_ptr()); - - sc_time sendingTime; - sc_time sendingOffset; - - if (transactionsSent == 0) - sendingOffset = SC_ZERO_TIME; - else - sendingOffset = playerClk - (sc_time_stamp() % playerClk); - - if (!relative) - sendingTime = std::max(sc_time_stamp() + sendingOffset, lineIterator->sendingTime); - else - sendingTime = sc_time_stamp() + sendingOffset + lineIterator->sendingTime; - - sendToTarget(payload, BEGIN_REQ, sendingTime - sc_time_stamp()); - - transactionsSent++; - - if (payload.get_command() == tlm::TLM_READ_COMMAND) - pendingReadRequests++; - else if (payload.get_command() == tlm::TLM_WRITE_COMMAND) - pendingWriteRequests++; - - PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent)); - lineIterator++; -} - -void StlPlayer::parseTraceFile() -{ - unsigned parsedLines = 0; - parseBuffer->clear(); - while (file && !file.eof() && parsedLines < lineBufferSize) - { - // Get a new line from the input file. - std::string line; - std::getline(file, line); - lineCnt++; - - // If the line is empty (\n or \r\n) or starts with '#' (comment) the transaction is ignored. - if (line.size() <= 1 || line.at(0) == '#') - continue; - - parsedLines++; - parseBuffer->emplace_back(); - LineContent &content = parseBuffer->back(); - - // Trace files MUST provide timestamp, command and address for every - // transaction. The data information depends on the storage mode - // configuration. - std::string element; - std::istringstream iss; - - iss.str(line); - - // Get the timestamp for the transaction. - iss >> element; - if (element.empty()) - SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); - content.sendingTime = playerClk * static_cast(std::stoull(element)); - - // Get the optional burst length and command - iss >> element; - if (element.empty()) - SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); - if (element.at(0) == '(') - { - element.erase(0, 1); - content.dataLength = std::stoul(element); - iss >> element; - if (element.empty()) - SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); - } - else - content.dataLength = defaultDataLength; - - if (element == "read") - content.command = TLM_READ_COMMAND; - else if (element == "write") - content.command = TLM_WRITE_COMMAND; - else - SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); - - // Get the address. - iss >> element; - if (element.empty()) - SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); - content.address = std::stoull(element, nullptr, 16); - - // Get the data if necessary. - if (storageEnabled && content.command == TLM_WRITE_COMMAND) - { - // The input trace file must provide the data to be stored into the memory. - iss >> element; - - // Check if data length in the trace file is correct. - // We need two characters to represent 1 byte in hexadecimal. Offset for 0x prefix. - if (element.length() != (content.dataLength * 2 + 2)) - SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); - - // Set data - for (unsigned i = 0; i < content.dataLength; i++) - content.data.emplace_back(static_cast - (std::stoi(element.substr(i * 2 + 2, 2), nullptr, 16))); - } - } -} - -std::vector::const_iterator StlPlayer::swapBuffers() -{ - // Wait for parser to finish - if (parserThread.joinable()) - parserThread.join(); - - // Swap buffers - std::swap(currentBuffer, parseBuffer); - - // Start new parser thread - parserThread = std::thread(&StlPlayer::parseTraceFile, this); - - return currentBuffer->cbegin(); -} - -uint64_t StlPlayer::getNumberOfLines() const -{ - return numberOfLines; -} diff --git a/src/simulator/simulator/TraceSetup.cpp b/src/simulator/simulator/TraceSetup.cpp deleted file mode 100644 index 2af57f0a..00000000 --- a/src/simulator/simulator/TraceSetup.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2017, 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: - * Matthias Jung - * Luiza Correa - * Derek Christ - */ - -#include "TraceSetup.h" - -#include "simulator/StlPlayer.h" -#include "simulator/TrafficGenerator.h" - -#include -#include -#include - -using namespace sc_core; -using namespace tlm; - -TraceSetup::TraceSetup(const Configuration& config, - const DRAMSys::Config::TraceSetup& traceSetup, - const std::string& pathToResources, - std::vector>& players) - : memoryManager(config.storeMode != Configuration::StoreMode::NoStorage) -{ - if (traceSetup.initiators.empty()) - SC_REPORT_FATAL("TraceSetup", "No traffic initiators specified"); - - for (const auto &initiator : traceSetup.initiators) - { - 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; - }(); - - using T = std::decay_t; - if constexpr (std::is_same_v) - { - size_t pos = name.rfind('.'); - if (pos == std::string::npos) - throw std::runtime_error("Name of the trace file does not contain a valid extension."); - - // Get the extension and make it lower case - std::string ext = name.substr(pos + 1); - std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); - - std::stringstream stlFileStream; - stlFileStream << pathToResources << "/traces/" << name; - std::string stlFile = stlFileStream.str(); - std::string moduleName = name; - - // replace all '.' to '_' - std::replace(moduleName.begin(), moduleName.end(), '.', '_'); - - StlPlayer *player; - if (ext == "stl") - player = new StlPlayer(moduleName.c_str(), config, stlFile, playerClk, maxPendingReadRequests, - maxPendingWriteRequests, *this, false); - else if (ext == "rstl") - player = new StlPlayer(moduleName.c_str(), config, stlFile, playerClk, maxPendingReadRequests, - maxPendingWriteRequests, *this, true); - else - throw std::runtime_error("Unsupported file extension in " + name); - - players.push_back(std::unique_ptr(player)); - totalTransactions += player->getNumberOfLines(); - } - else if constexpr (std::is_same_v) - { - auto* trafficGenerator = new TrafficGenerator(name.c_str(), config, initiator, *this); - players.push_back(std::unique_ptr(trafficGenerator)); - - totalTransactions += trafficGenerator->getTotalTransactions(); - } - else // if constexpr (std::is_same_v) - { - uint64_t numRequests = initiator.numRequests; - uint64_t rowIncrement = initiator.rowIncrement; - - players.push_back( - std::unique_ptr(new TrafficGeneratorHammer(name.c_str(), config, initiator, *this))); - totalTransactions += numRequests; - } - }, - initiator); - } - - for (const auto &inititatorConf : traceSetup.initiators) - { - if (auto generatorConf = std::get_if(&inititatorConf)) - { - if (const auto &idleUntil = generatorConf->idleUntil) - { - const std::string name = generatorConf->name; - auto listenerIt = std::find_if(players.begin(), players.end(), - [&name](const std::unique_ptr &initiator) - { return initiator->name() == name; }); - - // Should be found - auto listener = dynamic_cast(listenerIt->get()); - - auto notifierIt = - std::find_if(players.begin(), players.end(), - [&idleUntil](const std::unique_ptr &initiator) - { - if (auto generator = dynamic_cast(initiator.get())) - { - if (generator->hasStateTransitionEvent(*idleUntil)) - return true; - } - - return false; - }); - - if (notifierIt == players.end()) - SC_REPORT_FATAL("TraceSetup", "Event to listen on not found."); - - auto notifier = dynamic_cast(notifierIt->get()); - listener->waitUntil(¬ifier->getStateTransitionEvent(*idleUntil)); - } - } - } - - remainingTransactions = totalTransactions; - numberOfTrafficInitiators = players.size(); - defaultDataLength = config.memSpec->defaultBytesPerBurst; -} - -void TraceSetup::trafficInitiatorTerminates() -{ - finishedTrafficInitiators++; - - if (finishedTrafficInitiators == numberOfTrafficInitiators) - sc_stop(); -} - -void TraceSetup::transactionFinished() -{ - remainingTransactions--; - - loadBar(totalTransactions - remainingTransactions, totalTransactions); - - if (remainingTransactions == 0) - std::cout << std::endl; -} - -tlm_generic_payload& TraceSetup::allocatePayload(unsigned dataLength) -{ - return memoryManager.allocate(dataLength); -} - -tlm_generic_payload& TraceSetup::allocatePayload() -{ - return allocatePayload(defaultDataLength); -} - -void TraceSetup::loadBar(uint64_t x, uint64_t n, unsigned int w, unsigned int granularity) -{ - if ((n < 100) || ((x != n) && (x % (n / 100 * granularity) != 0))) - return; - - float ratio = x / (float)n; - unsigned int c = (ratio * w); - float rest = (ratio * w) - c; - std::cout << std::setw(3) << round(ratio * 100) << "% |"; - for (unsigned int x = 0; x < c; x++) - std::cout << "█"; - - if (rest >= 0 && rest < 0.125f && c != w) - std::cout << " "; - if (rest >= 0.125f && rest < 2 * 0.125f) - std::cout << "▏"; - if (rest >= 2 * 0.125f && rest < 3 * 0.125f) - std::cout << "▎"; - if (rest >= 3 * 0.125f && rest < 4 * 0.125f) - std::cout << "▍"; - if (rest >= 4 * 0.125f && rest < 5 * 0.125f) - std::cout << "▌"; - if (rest >= 5 * 0.125f && rest < 6 * 0.125f) - std::cout << "▋"; - if (rest >= 6 * 0.125f && rest < 7 * 0.125f) - std::cout << "▊"; - if (rest >= 7 * 0.125f && rest < 8 * 0.125f) - std::cout << "▉"; - - for (unsigned int x = c; x < (w - 1); x++) - std::cout << " "; - std::cout << "|\r" << std::flush; -} diff --git a/src/simulator/simulator/TrafficGenerator.cpp b/src/simulator/simulator/TrafficGenerator.cpp deleted file mode 100644 index abcc5878..00000000 --- a/src/simulator/simulator/TrafficGenerator.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright (c) 2015, 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: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - * Derek Christ - */ - -#include "TrafficGenerator.h" - -#include "simulator/TraceSetup.h" - -#include - -using namespace sc_core; -using namespace tlm; - -TrafficGeneratorIf::TrafficGeneratorIf(const sc_core::sc_module_name& name, const Configuration& config, - TraceSetup& setup, - unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, - unsigned int dataLength) - : TrafficInitiator(name, config, setup, maxPendingReadRequests, maxPendingWriteRequests, dataLength) -{ -} - -void TrafficGeneratorIf::sendNextPayload() -{ - prepareNextPayload(); - - if (finished) - return; - - // TODO: column / burst breite - - uint64_t address = getNextAddress(); - - 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); - payload.set_byte_enable_length(0); - payload.set_data_length(defaultDataLength); - payload.set_command(command); - - sc_time generatorClk = getGeneratorClk(); - sc_time sendingOffset; - if (transactionsSent == 0) - sendingOffset = SC_ZERO_TIME + generatorClk * clksToIdle(); - else - 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(); -} - -TrafficGenerator::TrafficGenerator(const sc_module_name& name, const Configuration& config, - const DRAMSys::Config::TraceGenerator& conf, TraceSetup& setup) - : TrafficGeneratorIf(name, config, setup, conf.maxPendingReadRequests.value_or(defaultMaxPendingReadRequests), - conf.maxPendingWriteRequests.value_or(defaultMaxPendingWriteRequests), - conf.dataLength.value_or(config.memSpec->defaultBytesPerBurst)), - generatorClk(TrafficInitiator::evaluateGeneratorClk(conf)), conf(conf), - maxTransactions(conf.maxTransactions.value_or(std::numeric_limits::max())), - simMemSizeInBytes(config.memSpec->getSimMemSizeInBytes()), - randomGenerator(std::default_random_engine(conf.seed.value_or(defaultSeed))) -{ - // Perform checks for all states - for (const auto &state : conf.states) - { - if (auto trafficState = std::get_if(&state.second)) - { - uint64_t minAddress = evaluateMinAddress(*trafficState); - uint64_t maxAddress = evaluateMaxAddress(*trafficState, simMemSizeInBytes); - double rwRatio = (*trafficState).rwRatio; - - if (minAddress > config.memSpec->getSimMemSizeInBytes() - 1) - SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); - - if (maxAddress > config.memSpec->getSimMemSizeInBytes() - 1) - SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); - - if (maxAddress < minAddress) - SC_REPORT_FATAL("TrafficGenerator", "maxAddress is smaller than minAddress."); - - if (rwRatio < 0 || rwRatio > 1) - SC_REPORT_FATAL("TraceSetup", "Read/Write ratio is not a number between 0 and 1."); - - if (const auto &eventName = trafficState->notify) - { - stateTranstitionEvents.emplace(std::piecewise_construct, std::forward_as_tuple(*eventName), - std::forward_as_tuple(eventName->c_str(), state.first)); - } - } - } - - if (auto trafficState = - std::get_if(&conf.states.at(currentState))) - { - uint64_t minAddress = evaluateMinAddress(*trafficState); - uint64_t maxAddress = evaluateMaxAddress(*trafficState, simMemSizeInBytes); - randomAddressDistribution = std::uniform_int_distribution(minAddress, maxAddress); - currentClksPerRequest = trafficState->clksPerRequest.value_or(defaultClksPerRequest); - } - - calculateTransitions(); -} - -void TrafficGenerator::calculateTransitions() -{ - unsigned int state = 0; - uint64_t totalTransactions = 0; - stateSequence.push_back(state); - - while (true) - { - auto transitionsIt = conf.transitions.equal_range(state); - float probabilityAccumulated = 0.0f; - std::map> transitionsDistribution; - - for (auto it = transitionsIt.first; it != transitionsIt.second; ++it) - { - float lowerLimit = probabilityAccumulated; - probabilityAccumulated += it->second.probability; - float upperLimit = probabilityAccumulated; - transitionsDistribution[it->second.to] = {lowerLimit, upperLimit}; - } - - if (probabilityAccumulated > 1.001f) - SC_REPORT_WARNING("TrafficGenerator", "Sum of transition probabilities greater than 1."); - - float random = randomDistribution(randomGenerator); - bool transitionFound = false; - - for (const auto &transition : transitionsDistribution) - { - auto to = transition.first; - auto limits = transition.second; - - if (limits.first < random && limits.second > random) - { - state = to; - stateSequence.push_back(state); - transitionFound = true; - break; - } - } - - if (transitionFound) - { - if (auto trafficState = - std::get_if(&conf.states.at(state))) - totalTransactions += trafficState->numRequests; - - if (totalTransactions < maxTransactions) - continue; - } - - break; - } - - stateIt = stateSequence.cbegin(); -} - -bool TrafficGenerator::hasStateTransitionEvent(const std::string &eventName) const -{ - auto it = stateTranstitionEvents.find(eventName); - - if (it == stateTranstitionEvents.end()) - return false; - - return true; -} - -const sc_core::sc_event &TrafficGenerator::getStateTransitionEvent(const std::string &eventName) const -{ - auto it = stateTranstitionEvents.find(eventName); - - if (it == stateTranstitionEvents.end()) - SC_REPORT_FATAL("TraceSetup", "StateTransitionEvent not found."); - - return it->second.event; -} - -uint64_t TrafficGenerator::getTotalTransactions() const -{ - uint64_t totalTransactions = 0; - - for (auto state : stateSequence) - { - if (auto trafficState = std::get_if(&conf.states.at(state))) - totalTransactions += trafficState->numRequests; - } - - if (totalTransactions > maxTransactions) - totalTransactions = maxTransactions; - - return totalTransactions; -} - -void TrafficGenerator::waitUntil(const sc_core::sc_event *ev) -{ - startEvent = ev; -} - -void TrafficGenerator::transitionToNextState() -{ - ++stateIt; - - if (stateIt == stateSequence.cend() || transactionsSent >= maxTransactions) - { - // No transition performed. - finished = true; - return; - } - - currentState = *stateIt; - - // Notify - for (auto &it : stateTranstitionEvents) - { - if (it.second.stateId == currentState) - it.second.event.notify(); - } - - if (auto idleState = std::get_if(&conf.states.at(currentState))) - { - currentClksToIdle += idleState->idleClks; - transitionToNextState(); - return; - } - else if (auto trafficState = - std::get_if(&conf.states.at(currentState))) - { - uint64_t minAddress = evaluateMinAddress(*trafficState); - uint64_t maxAddress = evaluateMaxAddress(*trafficState, simMemSizeInBytes); - randomAddressDistribution = std::uniform_int_distribution(minAddress, maxAddress); - currentClksPerRequest = trafficState->clksPerRequest.value_or(defaultClksPerRequest); - } - - currentAddress = 0x00; - transactionsSentInCurrentState = 0; -} - -void TrafficGenerator::prepareNextPayload() -{ - if (transactionsSent >= maxTransactions) - { - finished = true; - return; - } - - if (startEvent && transactionsSent == 0) - wait(*startEvent); - - if (auto trafficState = - std::get_if(&conf.states.at(currentState))) - { - if (transactionsSentInCurrentState >= trafficState->numRequests) - transitionToNextState(); - } - - // In case we are in an idle state right at the beginning of the simulation, - // set the clksToIdle and transition to the next state. - if (auto idleState = - std::get_if(&conf.states.at(currentState))) - { - currentClksToIdle = idleState->idleClks; - transitionToNextState(); - } -} - -void TrafficGenerator::payloadSent() -{ - // Reset clks to idle. - currentClksToIdle = 0; - - transactionsSentInCurrentState++; -} - -tlm::tlm_command TrafficGenerator::getNextCommand() -{ - // An idle state should never reach this method. - auto &state = std::get(conf.states.at(currentState)); - - tlm_command command; - if (randomDistribution(randomGenerator) < state.rwRatio) - command = tlm::TLM_READ_COMMAND; - else - command = tlm::TLM_WRITE_COMMAND; - - return command; -} - -sc_core::sc_time TrafficGenerator::getGeneratorClk() const -{ - return generatorClk; -} - -uint64_t TrafficGenerator::getNextAddress() -{ - using DRAMSys::Config::AddressDistribution; - - // An idle state should never reach this method. - auto &state = std::get(conf.states.at(currentState)); - - uint64_t minAddress = evaluateMinAddress(state); - uint64_t maxAddress = evaluateMaxAddress(state, simMemSizeInBytes); - - 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 DRAMSys::Config::TraceGeneratorTrafficState &state) -{ - return state.minAddress.value_or(0x00); -} - -uint64_t TrafficGenerator::evaluateMaxAddress(const DRAMSys::Config::TraceGeneratorTrafficState &state, - uint64_t simMemSizeInBytes) -{ - return state.maxAddress.value_or(simMemSizeInBytes - 1); -} - -TrafficGeneratorHammer::TrafficGeneratorHammer(const sc_core::sc_module_name &name, const Configuration& config, - const DRAMSys::Config::TraceHammer &conf, TraceSetup& setup) - : TrafficGeneratorIf(name, config, setup, 1, 1, config.memSpec->defaultBytesPerBurst), - 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) - currentAddress = rowIncrement; - else - currentAddress = 0x0; - - return currentAddress; -} - -void TrafficGeneratorHammer::prepareNextPayload() -{ - if (transactionsSent >= numRequests) - finished = true; -} diff --git a/src/simulator/simulator/TrafficGenerator.h b/src/simulator/simulator/TrafficGenerator.h deleted file mode 100644 index 7732fa9d..00000000 --- a/src/simulator/simulator/TrafficGenerator.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2015, 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: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - * Derek Christ - */ - -#ifndef TRAFFICGENERATOR_H -#define TRAFFICGENERATOR_H - -#include "simulator/TrafficInitiator.h" -#include "simulator/TraceSetup.h" - -#include -#include -#include - -class TrafficGeneratorIf : public TrafficInitiator -{ -public: - TrafficGeneratorIf(const sc_core::sc_module_name &name, const Configuration& config, TraceSetup& setup, - unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, - unsigned int dataLength); - -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 Configuration& config, - const DRAMSys::Config::TraceGenerator &conf, TraceSetup& setup); - - 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 DRAMSys::Config::TraceGeneratorTrafficState& state); - static uint64_t evaluateMaxAddress(const DRAMSys::Config::TraceGeneratorTrafficState& state, - uint64_t simMemSizeInBytes); - - 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 DRAMSys::Config::TraceGenerator &conf; - unsigned int currentState = 0; - uint64_t currentAddress = 0x00; - uint64_t currentClksPerRequest = 1; - uint64_t transactionsSentInCurrentState = 0; - - const uint64_t maxTransactions; - const uint64_t simMemSizeInBytes; - - uint64_t currentClksToIdle = 0; - - std::vector stateSequence; - std::vector::const_iterator stateIt; - - struct EventPair - { - EventPair(const std::string &name, unsigned int id) : event(name.c_str()), stateId(id) - { - } - sc_core::sc_event event; - unsigned int stateId; - }; - std::map stateTranstitionEvents; - - bool idleAtStart = false; - const sc_core::sc_event *startEvent = nullptr; - - std::default_random_engine randomGenerator; - std::uniform_real_distribution randomDistribution = std::uniform_real_distribution(0.0f, 1.0f); - std::uniform_int_distribution randomAddressDistribution; - - static constexpr uint64_t defaultSeed = 0; - static constexpr uint64_t defaultClksPerRequest = 1; - static constexpr uint64_t defaultAddressIncrement = 0x00; -}; - -class TrafficGeneratorHammer final : public TrafficGeneratorIf -{ -public: - TrafficGeneratorHammer(const sc_core::sc_module_name &name, const Configuration& config, - const DRAMSys::Config::TraceHammer &conf, TraceSetup& setup); - -private: - void prepareNextPayload() override; - uint64_t getNextAddress() override; - tlm::tlm_command getNextCommand() override; - sc_core::sc_time getGeneratorClk() const override; - - sc_core::sc_time generatorClk; - uint64_t rowIncrement; - uint64_t currentAddress = 0x0; - uint64_t numRequests; -}; - -#endif // TRAFFICGENERATOR_H diff --git a/src/simulator/simulator/TrafficInitiator.cpp b/src/simulator/simulator/TrafficInitiator.cpp deleted file mode 100644 index 70c4eeae..00000000 --- a/src/simulator/simulator/TrafficInitiator.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2015, 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: - * Robert Gernhardt - * Matthias Jung - * Éder F. Zulian - * Felipe S. Prado - * Derek Christ - */ - -#include "TrafficInitiator.h" - -using namespace sc_core; -using namespace tlm; - -TrafficInitiator::TrafficInitiator(const sc_module_name &name, const Configuration& config, TraceSetup& setup, - unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, unsigned int defaultDataLength) : - sc_module(name), - payloadEventQueue(this, &TrafficInitiator::peqCallback), - setup(setup), - maxPendingReadRequests(maxPendingReadRequests), - maxPendingWriteRequests(maxPendingWriteRequests), - defaultDataLength(defaultDataLength), - storageEnabled(config.storeMode != Configuration::StoreMode::NoStorage), - simulationProgressBar(config.simulationProgressBar) -{ - SC_THREAD(sendNextPayload); - iSocket.register_nb_transport_bw(this, &TrafficInitiator::nb_transport_bw); -} - -void TrafficInitiator::terminate() -{ - std::cout << sc_time_stamp() << " " << this->name() << " terminated " << std::endl; - setup.trafficInitiatorTerminates(); -} - -tlm_sync_enum TrafficInitiator::nb_transport_bw(tlm_generic_payload &payload, - tlm_phase &phase, sc_time &bwDelay) -{ - payloadEventQueue.notify(payload, phase, bwDelay); - return TLM_ACCEPTED; -} - -void TrafficInitiator::peqCallback(tlm_generic_payload &payload, - const tlm_phase &phase) -{ - if (phase == END_REQ) - { - if (nextPayloadSendable()) - sendNextPayload(); - else - payloadPostponed = true; - } - else if (phase == BEGIN_RESP) - { - payload.release(); - sendToTarget(payload, END_RESP, SC_ZERO_TIME); - if (simulationProgressBar) - setup.transactionFinished(); - - transactionsReceived++; - - if (payload.get_command() == tlm::TLM_READ_COMMAND) - pendingReadRequests--; - else if (payload.get_command() == tlm::TLM_WRITE_COMMAND) - pendingWriteRequests--; - - // If the initiator wasn't able to send the next payload in the END_REQ phase, do it now. - if (payloadPostponed && nextPayloadSendable()) - { - sendNextPayload(); - payloadPostponed = false; - } - - // If all answers were received: - if (finished && transactionsSent == transactionsReceived) - terminate(); - } - else - { - SC_REPORT_FATAL("TrafficInitiator", "PEQ was triggered with unknown phase"); - } -} - -void TrafficInitiator::sendToTarget(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) -{ - tlm_phase TPhase = phase; - sc_time TDelay = delay; - iSocket->nb_transport_fw(payload, TPhase, TDelay); -} - -bool TrafficInitiator::nextPayloadSendable() const -{ - // If either the maxPendingReadRequests or maxPendingWriteRequests - // limit is reached, do not send next payload. - if (((pendingReadRequests >= maxPendingReadRequests) && (maxPendingReadRequests != 0)) - || ((pendingWriteRequests >= maxPendingWriteRequests) && (maxPendingWriteRequests != 0))) - return false; - else - return true; -} - -sc_core::sc_time TrafficInitiator::evaluateGeneratorClk(const DRAMSys::Config::TrafficInitiator& conf) -{ - double frequencyMHz = conf.clkMhz; - sc_time playerClk = sc_time(1.0 / frequencyMHz, SC_US); - return playerClk; -} - diff --git a/src/simulator/simulator/generator/RandomProducer.cpp b/src/simulator/simulator/generator/RandomProducer.cpp new file mode 100644 index 00000000..d9e3fbd9 --- /dev/null +++ b/src/simulator/simulator/generator/RandomProducer.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023, 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 "RandomProducer.h" +#include "definitions.h" + +RandomProducer::RandomProducer(uint64_t numRequests, + std::optional seed, + double rwRatio, + unsigned int clkMhz, + std::optional minAddress, + std::optional maxAddress, + uint64_t memorySize, + unsigned int dataLength) + : numberOfRequests(numRequests), + seed(seed.value_or(DEFAULT_SEED)), + rwRatio(rwRatio), + randomGenerator(this->seed), + generatorPeriod(sc_core::sc_time(1.0 / static_cast(clkMhz), sc_core::SC_US)), + dataLength(dataLength), + randomAddressDistribution(minAddress.value_or(DEFAULT_MIN_ADDRESS), + maxAddress.value_or((memorySize / dataLength) - 1)) +{ + if (minAddress > memorySize - 1) + SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); + + if (maxAddress > memorySize - 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."); +} + +Request RandomProducer::nextRequest() +{ + Request request; + request.address = randomAddressDistribution(randomGenerator) * dataLength; + request.command = readWriteDistribution(randomGenerator) < rwRatio ? Request::Command::Read + : Request::Command::Write; + request.length = dataLength; + request.delay = generatorPeriod; + + return request; +} diff --git a/src/simulator/simulator/generator/RandomProducer.h b/src/simulator/simulator/generator/RandomProducer.h new file mode 100644 index 00000000..c0f55322 --- /dev/null +++ b/src/simulator/simulator/generator/RandomProducer.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023, 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 + */ + +#pragma once + +#include "simulator/request/RequestProducer.h" + +#include +#include + +class RandomProducer : public RequestProducer +{ +public: + RandomProducer(uint64_t numRequests, + std::optional seed, + double rwRatio, + unsigned int clkMhz, + std::optional minAddress, + std::optional maxAddress, + uint64_t memorySize, + unsigned int dataLength); + + Request nextRequest() override; + + uint64_t totalRequests() override { return numberOfRequests; } + sc_core::sc_time clkPeriod() override { return generatorPeriod; } + + const uint64_t numberOfRequests; + const uint64_t seed; + const double rwRatio; + const sc_core::sc_time generatorPeriod; + const unsigned int dataLength; + + std::default_random_engine randomGenerator; + std::uniform_real_distribution readWriteDistribution{0.0, 1.0}; + std::uniform_int_distribution randomAddressDistribution; +}; diff --git a/src/simulator/simulator/generator/SequentialProducer.cpp b/src/simulator/simulator/generator/SequentialProducer.cpp new file mode 100644 index 00000000..1ca441fd --- /dev/null +++ b/src/simulator/simulator/generator/SequentialProducer.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2023, 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 "SequentialProducer.h" +#include "definitions.h" + +SequentialProducer::SequentialProducer(uint64_t numRequests, + std::optional seed, + double rwRatio, + unsigned int clkMhz, + std::optional addressIncrement, + std::optional minAddress, + std::optional maxAddress, + uint64_t memorySize, + unsigned int dataLength) + : numberOfRequests(numRequests), + addressIncrement(addressIncrement.value_or(dataLength)), + minAddress(minAddress.value_or(DEFAULT_MIN_ADDRESS)), + maxAddress(maxAddress.value_or(memorySize - 1)), + seed(seed.value_or(DEFAULT_SEED)), + rwRatio(rwRatio), + randomGenerator(this->seed), + generatorPeriod(sc_core::sc_time(1.0 / static_cast(clkMhz), sc_core::SC_US)), + dataLength(dataLength) +{ + if (minAddress > memorySize - 1) + SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); + + if (maxAddress > memorySize - 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."); +} + +Request SequentialProducer::nextRequest() +{ + Request request; + request.address = generatedRequests * addressIncrement % (maxAddress - minAddress) + minAddress; + request.command = readWriteDistribution(randomGenerator) < rwRatio ? Request::Command::Read + : Request::Command::Write; + request.length = dataLength; + request.delay = generatorPeriod; + + generatedRequests++; + return request; +} diff --git a/src/simulator/simulator/generator/SequentialProducer.h b/src/simulator/simulator/generator/SequentialProducer.h new file mode 100644 index 00000000..01f6fd6f --- /dev/null +++ b/src/simulator/simulator/generator/SequentialProducer.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023, 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 + */ + +#pragma once + +#include "simulator/request/RequestProducer.h" + +#include +#include + +class SequentialProducer : public RequestProducer +{ +public: + SequentialProducer(uint64_t numRequests, + std::optional seed, + double rwRatio, + unsigned int clkMhz, + std::optional addressIncrement, + std::optional minAddress, + std::optional maxAddress, + uint64_t memorySize, + unsigned int dataLength); + + Request nextRequest() override; + + uint64_t totalRequests() override { return numberOfRequests; } + sc_core::sc_time clkPeriod() override { return generatorPeriod; } + void reset() override { generatedRequests = 0; } + + const uint64_t numberOfRequests; + const uint64_t addressIncrement; + const uint64_t minAddress; + const uint64_t maxAddress; + const uint64_t seed; + const double rwRatio; + const sc_core::sc_time generatorPeriod; + const unsigned int dataLength; + + std::default_random_engine randomGenerator; + std::uniform_real_distribution readWriteDistribution{0.0, 1.0}; + + uint64_t generatedRequests = 0; +}; diff --git a/src/simulator/simulator/generator/TrafficGenerator.cpp b/src/simulator/simulator/generator/TrafficGenerator.cpp new file mode 100644 index 00000000..59639860 --- /dev/null +++ b/src/simulator/simulator/generator/TrafficGenerator.cpp @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2023, 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 "TrafficGenerator.h" + +TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine const &config, + MemoryManager &memoryManager, + uint64_t memorySize, + unsigned int dataLength, + std::function transactionFinished, + std::function terminateInitiator) + : consumer( + config.name.c_str(), + memoryManager, + config.maxPendingReadRequests, + config.maxPendingWriteRequests, + [this] { return nextRequest(); }, + std::move(transactionFinished), + std::move(terminateInitiator)), + stateTransistions(config.transitions) +{ + for (auto const &state : config.states) + { + std::visit( + [=, &config](auto &&arg) + { + using DRAMSys::Config::TrafficGeneratorActiveState; + using DRAMSys::Config::TrafficGeneratorIdleState; + using T = std::decay_t; + if constexpr (std::is_same_v) + { + auto const &activeState = arg; + if (activeState.addressDistribution == + DRAMSys::Config::AddressDistribution::Random) + { + auto producer = std::make_unique(activeState.numRequests, + config.seed, + activeState.rwRatio, + config.clkMhz, + activeState.minAddress, + activeState.maxAddress, + memorySize, + dataLength); + + producers.emplace(activeState.id, std::move(producer)); + } + else + { + auto producer = + std::make_unique(activeState.numRequests, + config.seed, + activeState.rwRatio, + config.clkMhz, + activeState.addressIncrement, + activeState.minAddress, + activeState.maxAddress, + memorySize, + dataLength); + + producers.emplace(activeState.id, std::move(producer)); + } + } + else if constexpr (std::is_same_v) + { + auto const &idleState = arg; + idleStateClks.emplace(idleState.id, idleState.idleClks); + } + }, + state); + } +} + +TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const &config, + MemoryManager &memoryManager, + uint64_t memorySize, + unsigned int dataLength, + std::function transactionFinished, + std::function terminateInitiator) + : consumer( + config.name.c_str(), + memoryManager, + config.maxPendingReadRequests, + config.maxPendingWriteRequests, + [this] { return nextRequest(); }, + std::move(transactionFinished), + std::move(terminateInitiator)) +{ + if (config.addressDistribution == DRAMSys::Config::AddressDistribution::Random) + { + auto producer = std::make_unique(config.numRequests, + config.seed, + config.rwRatio, + config.clkMhz, + config.minAddress, + config.maxAddress, + memorySize, + dataLength); + producers.emplace(0, std::move(producer)); + } + else + { + auto producer = std::make_unique(config.numRequests, + config.seed, + config.rwRatio, + config.clkMhz, + config.addressIncrement, + config.minAddress, + config.maxAddress, + memorySize, + dataLength); + producers.emplace(0, std::move(producer)); + } +} + +Request TrafficGenerator::nextRequest() +{ + uint64_t clksToIdle = 0; + if (requestsInState >= producers[currentState]->totalRequests()) + { + // Reset current producer to its initial state + producers[currentState]->reset(); + + auto newState = stateTransition(currentState); + + if (!newState.has_value()) + return Request{.command = Request::Command::Stop}; + + auto idleStateIt = idleStateClks.find(newState.value()); + while (idleStateIt != idleStateClks.cend()) + { + clksToIdle += idleStateIt->second; + newState = stateTransition(currentState); + + if (!newState.has_value()) + return Request{.command = Request::Command::Stop}; + + currentState = newState.value(); + idleStateIt = idleStateClks.find(newState.value()); + } + + currentState = newState.value(); + requestsInState = 0; + } + + requestsInState++; + + Request request = producers[currentState]->nextRequest(); + request.delay += producers[currentState]->clkPeriod() * clksToIdle; + return request; +} + +uint64_t TrafficGenerator::totalRequests() +{ + // Store current state of random generator + std::default_random_engine tempGenerator(randomGenerator); + + // Reset generator to initial state + randomGenerator.seed(); + + uint64_t totalRequests = 0; + unsigned int currentState = 0; + + if (producers.find(currentState) != producers.cend()) + totalRequests += producers.at(currentState)->totalRequests(); + + while (auto nextState = stateTransition(currentState)) + { + currentState = nextState.value(); + + if (producers.find(currentState) != producers.cend()) + totalRequests += producers.at(currentState)->totalRequests(); + } + + // Restore state of random generator + randomGenerator = tempGenerator; + + return totalRequests; +} + +std::optional TrafficGenerator::stateTransition(unsigned int from) +{ + using Transition = DRAMSys::Config::TrafficGeneratorStateTransition; + + std::vector relevantTransitions; + std::copy_if(stateTransistions.cbegin(), + stateTransistions.cend(), + std::back_inserter(relevantTransitions), + [from](Transition transition) { return transition.from == from; }); + + if (relevantTransitions.empty()) + return std::nullopt; + + std::vector propabilities; + std::for_each(relevantTransitions.cbegin(), + relevantTransitions.cend(), + [&propabilities](Transition transition) + { propabilities.push_back(transition.probability); }); + + assert(propabilities.size() == relevantTransitions.size()); + + std::discrete_distribution stateTransitionDistribution(propabilities.cbegin(), + propabilities.cend()); + + std::size_t index = stateTransitionDistribution(randomGenerator); + return relevantTransitions[index].to; +} diff --git a/src/simulator/simulator/generator/TrafficGenerator.h b/src/simulator/simulator/generator/TrafficGenerator.h new file mode 100644 index 00000000..015e31b7 --- /dev/null +++ b/src/simulator/simulator/generator/TrafficGenerator.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2023, 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 + */ + +#pragma once + +#include "RandomProducer.h" +#include "SequentialProducer.h" +#include "simulator/Initiator.h" +#include "simulator/MemoryManager.h" +#include "simulator/request/RequestIssuer.h" + +#include + +class TrafficGenerator : public Initiator +{ +public: + TrafficGenerator(DRAMSys::Config::TrafficGenerator const &config, + MemoryManager &memoryManager, + uint64_t memorySize, + unsigned int dataLength, + std::function transactionFinished, + std::function terminateInitiator); + + TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine const &config, + MemoryManager &memoryManager, + uint64_t memorySize, + unsigned int dataLength, + std::function transactionFinished, + std::function terminateInitiator); + + void bind(tlm_utils::multi_target_base<> &target) override { consumer.iSocket.bind(target); } + + uint64_t totalRequests() override; + Request nextRequest(); + + std::optional stateTransition(unsigned int from); + +private: + uint64_t requestsInState = 0; + unsigned int currentState = 0; + const std::vector stateTransistions; + + using IdleClks = uint64_t; + std::unordered_map idleStateClks; + + std::default_random_engine randomGenerator; + + std::unordered_map> producers; + RequestIssuer consumer; +}; diff --git a/src/simulator/simulator/generator/definitions.h b/src/simulator/simulator/generator/definitions.h new file mode 100644 index 00000000..98563553 --- /dev/null +++ b/src/simulator/simulator/generator/definitions.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023, 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 + */ + +#pragma once + +#include + +inline constexpr uint64_t DEFAULT_SEED = 0; +inline constexpr uint64_t DEFAULT_MIN_ADDRESS = 0; diff --git a/src/simulator/simulator/hammer/RowHammer.cpp b/src/simulator/simulator/hammer/RowHammer.cpp new file mode 100644 index 00000000..c1bef363 --- /dev/null +++ b/src/simulator/simulator/hammer/RowHammer.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023, 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 "RowHammer.h" + +RowHammer::RowHammer(uint64_t numRequests, + unsigned int clkMhz, + uint64_t rowIncrement, + unsigned int dataLength) + : numberOfRequests(numRequests), + generatorPeriod(sc_core::sc_time(1.0 / static_cast(clkMhz), sc_core::SC_US)), + dataLength(dataLength), + rowIncrement(rowIncrement) +{ +} + +Request RowHammer::nextRequest() +{ + if (generatedRequests >= numberOfRequests) + return Request{.command = Request::Command::Stop}; + + generatedRequests++; + + if (currentAddress == 0x00) + currentAddress = rowIncrement; + else + currentAddress = 0x00; + + Request request; + request.address = currentAddress; + request.command = Request::Command::Read; + request.length = dataLength; + request.delay = generatorPeriod; + return request; +} diff --git a/src/simulator/simulator/hammer/RowHammer.h b/src/simulator/simulator/hammer/RowHammer.h new file mode 100644 index 00000000..78a7c579 --- /dev/null +++ b/src/simulator/simulator/hammer/RowHammer.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023, 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 + */ + +#pragma once + +#include "simulator/request/RequestProducer.h" + +#include + +class RowHammer : public RequestProducer +{ +public: + RowHammer(uint64_t numRequests, + unsigned int clkMhz, + uint64_t rowIncrement, + unsigned int dataLength); + + Request nextRequest() override; + sc_core::sc_time clkPeriod() override { return generatorPeriod; } + uint64_t totalRequests() override { return numberOfRequests; } + + const uint64_t numberOfRequests; + const sc_core::sc_time generatorPeriod; + const unsigned int dataLength; + const uint64_t rowIncrement; + + uint64_t generatedRequests = 0; + uint64_t currentAddress = 0x00; +}; diff --git a/src/simulator/simulator/main.cpp b/src/simulator/simulator/main.cpp index 8513433f..4c986102 100644 --- a/src/simulator/simulator/main.cpp +++ b/src/simulator/simulator/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Technische Universität Kaiserslautern + * Copyright (c) 2023, Technische Universität Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,105 +30,158 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: - * Robert Gernhardt - * Matthias Jung - * Luiza Correa - * Lukas Steiner * Derek Christ */ -#include "simulator/TraceSetup.h" -#include "simulator/TrafficInitiator.h" +#include "Initiator.h" +#include "MemoryManager.h" +#include "SimpleInitiator.h" +#include "generator/TrafficGenerator.h" +#include "hammer/RowHammer.h" +#include "player/StlPlayer.h" +#include "util.h" -#include "DRAMSys/simulation/DRAMSys.h" -#include "DRAMSys/simulation/DRAMSysRecordable.h" -#include "DRAMSys/config/DRAMSysConfiguration.h" +#include -#include -#include -#include -#include -#include #include +#include +#include +#include -using namespace sc_core; +#include +#include +#include -std::string pathOfFile(const std::string &file) -{ - return file.substr(0, file.find_last_of('/')); -} - -int main(int argc, char **argv) -{ - return sc_main(argc, argv); -} +static constexpr std::string_view TRACE_DIRECTORY = "traces"; int sc_main(int argc, char **argv) { - sc_set_time_resolution(1, SC_PS); - - std::string resources; - std::string simulationJson; - // Run only with default config (ddr3-example.json): - if (argc == 1) + std::filesystem::path resourceDirectory = "configs"; + if (argc >= 3) { - // Get path of resources: - resources = pathOfFile(argv[0]) - + std::string("/../../configs/"); - simulationJson = resources + "ddr4-example.json"; - } - // Run with specific config but default resource folders: - else if (argc == 2) - { - // Get path of resources: - resources = pathOfFile(argv[0]) - + std::string("/../../configs/"); - simulationJson = argv[1]; - } - // Run with specific config and specific resource folder: - else if (argc == 3) - { - simulationJson = argv[1]; - resources = argv[2]; + resourceDirectory = argv[2]; } - std::vector> players; + std::filesystem::path baseConfig = resourceDirectory / "ddr5-example.json"; + if (argc >= 2) + { + baseConfig = argv[1]; + } - DRAMSys::Config::Configuration configLib = DRAMSys::Config::from_path(simulationJson, resources); + DRAMSys::Config::Configuration configuration = DRAMSys::Config::from_path(baseConfig.c_str()); - // Instantiate DRAMSys: - std::unique_ptr dramSys; + if (!configuration.tracesetup.has_value()) + SC_REPORT_FATAL("Simulator", "No traffic initiators specified"); - if (configLib.simconfig.DatabaseRecording.value_or(false)) - dramSys = std::make_unique("DRAMSys", configLib); - else - dramSys = std::make_unique("DRAMSys", configLib); + DRAMSys::DRAMSysRecordable dramSys("DRAMSys", configuration); - if (!configLib.tracesetup.has_value()) - SC_REPORT_FATAL("sc_main", "No trace setup section provided."); + MemoryManager memoryManager(false); - // Instantiate STL Players: - TraceSetup setup(dramSys->getConfig(), configLib.tracesetup.value(), resources, players); + std::vector> initiators; - // Bind STL Players with DRAMSys: - for (auto& player : players) - player->iSocket.bind(dramSys->tSocket); + unsigned int terminatedInitiators = 0; + auto termianteInitiator = [&initiators, &terminatedInitiators]() + { + terminatedInitiators++; + + if (terminatedInitiators == initiators.size()) + sc_core::sc_stop(); + }; + + uint64_t totalTransactions{}; + uint64_t transactionsFinished = 0; + auto transactionFinished = [&totalTransactions, &transactionsFinished]() + { + transactionsFinished++; + loadBar(transactionsFinished, totalTransactions); + }; + + for (auto const &initiator_config : configuration.tracesetup.value()) + { + uint64_t memorySize = dramSys.getConfig().memSpec->getSimMemSizeInBytes(); + unsigned int dataLength = dramSys.getConfig().memSpec->defaultBytesPerBurst; + + auto initiator = std::visit( + [=, &memoryManager](auto &&config) -> std::unique_ptr + { + using T = std::decay_t; + if constexpr (std::is_same_v || + std::is_same_v) + { + return std::make_unique(config, + memoryManager, + memorySize, + dataLength, + transactionFinished, + termianteInitiator); + } + else if constexpr (std::is_same_v) + { + std::filesystem::path tracePath = + resourceDirectory / TRACE_DIRECTORY / config.name; + + StlPlayer::TraceType traceType; + + auto extension = tracePath.extension(); + if (extension == ".stl") + traceType = StlPlayer::TraceType::Absolute; + else if (extension == ".rtl") + traceType = StlPlayer::TraceType::Relative; + else + { + std::string report = extension.string() + " is not a valid trace format."; + SC_REPORT_FATAL("Simulator", report.c_str()); + } + + StlPlayer player( + tracePath.c_str(), config.clkMhz, dataLength, traceType, false); + + return std::make_unique>(config.name.c_str(), + memoryManager, + std::nullopt, + std::nullopt, + transactionFinished, + termianteInitiator, + std::move(player)); + } + else if constexpr (std::is_same_v) + { + RowHammer hammer( + config.numRequests, config.clkMhz, config.rowIncrement, dataLength); + + return std::make_unique>(config.name.c_str(), + memoryManager, + 1, + 1, + transactionFinished, + termianteInitiator, + std::move(hammer)); + } + }, + initiator_config); + + totalTransactions += initiator->totalRequests(); + + initiator->bind(dramSys.tSocket); + initiators.push_back(std::move(initiator)); + } // Store the starting of the simulation in wall-clock time: auto start = std::chrono::high_resolution_clock::now(); - - // Start SystemC Simulation: - sc_set_stop_mode(SC_STOP_FINISH_DELTA); - sc_start(); - - if (!sc_end_of_simulation_invoked()) + + // Start the SystemC simulation + sc_set_stop_mode(sc_core::SC_STOP_FINISH_DELTA); + sc_core::sc_start(); + + if (!sc_core::sc_end_of_simulation_invoked()) { SC_REPORT_WARNING("sc_main", "Simulation stopped without explicit sc_stop()"); - sc_stop(); + sc_core::sc_stop(); } auto finish = std::chrono::high_resolution_clock::now(); std::chrono::duration elapsed = finish - start; std::cout << "Simulation took " + std::to_string(elapsed.count()) + " seconds." << std::endl; + return 0; } diff --git a/src/simulator/simulator/player/StlPlayer.cpp b/src/simulator/simulator/player/StlPlayer.cpp new file mode 100644 index 00000000..2fbda317 --- /dev/null +++ b/src/simulator/simulator/player/StlPlayer.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2023, 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: + * Janik Schlemminger + * Robert Gernhardt + * Matthias Jung + * Éder F. Zulian + * Felipe S. Prado + * Derek Christ + */ + +#include "StlPlayer.h" + +#include + +StlPlayer::StlPlayer(std::string_view tracePath, + unsigned int clkMhz, + unsigned int defaultDataLength, + TraceType traceType, + bool storageEnabled) + : traceFile(tracePath.data()), + playerPeriod(sc_core::sc_time(1.0 / static_cast(clkMhz), sc_core::SC_US)), + defaultDataLength(defaultDataLength), + traceType(traceType), + storageEnabled(storageEnabled), + lineBuffers( + {std::make_shared>(), std::make_shared>()}), + readoutBuffer(lineBuffers.at(0)), + parseBuffer(lineBuffers.at(1)) +{ + readoutBuffer->reserve(LINE_BUFFER_SIZE); + parseBuffer->reserve(LINE_BUFFER_SIZE); + + if (!traceFile.is_open()) + SC_REPORT_FATAL("StlPlayer", + (std::string("Could not open trace ") + tracePath.data()).c_str()); + + { + std::string line; + while (std::getline(traceFile, line)) + { + if (line.size() > 1 && line[0] != '#') + numberOfLines++; + } + traceFile.clear(); + traceFile.seekg(0); + } + + parseTraceFile(); + readoutIt = readoutBuffer->cend(); +} + +Request StlPlayer::nextRequest() +{ + if (readoutIt == readoutBuffer->cend()) + { + readoutIt = swapBuffers(); + if (readoutIt == readoutBuffer->cend()) + { + if (parserThread.joinable()) + parserThread.join(); + + // The file is read in completely. Nothing more to do. + return Request{.command = Request::Command::Stop}; + } + } + + sc_core::sc_time delay = readoutIt->delay; + + if (traceType == TraceType::Absolute) + { + delay = std::max(sc_core::sc_time_stamp(), delay); + delay -= sc_core::sc_time_stamp(); + } + + Request request(std::move(*readoutIt)); + request.delay = delay; + + readoutIt++; + return request; +} + +void StlPlayer::parseTraceFile() +{ + unsigned parsedLines = 0; + parseBuffer->clear(); + + while (traceFile && !traceFile.eof() && parsedLines < LINE_BUFFER_SIZE) + { + // Get a new line from the input file. + std::string line; + std::getline(traceFile, line); + currentLine++; + + // If the line is empty (\n or \r\n) or starts with '#' (comment) the transaction is + // ignored. + if (line.size() <= 1 || line.at(0) == '#') + continue; + + parsedLines++; + parseBuffer->emplace_back(); + Request &content = parseBuffer->back(); + + // Trace files MUST provide timestamp, command and address for every + // transaction. The data information depends on the storage mode + // configuration. + std::string element; + std::istringstream iss; + + iss.str(line); + + // Get the timestamp for the transaction. + iss >> element; + if (element.empty()) + SC_REPORT_FATAL( + "StlPlayer", + ("Malformed trace file line " + std::to_string(currentLine) + ".").c_str()); + + content.delay = playerPeriod * static_cast(std::stoull(element)); + + // Get the optional burst length and command + iss >> element; + if (element.empty()) + SC_REPORT_FATAL( + "StlPlayer", + ("Malformed trace file line " + std::to_string(currentLine) + ".").c_str()); + + if (element.at(0) == '(') + { + element.erase(0, 1); + content.length = std::stoul(element); + iss >> element; + if (element.empty()) + SC_REPORT_FATAL( + "StlPlayer", + ("Malformed trace file line " + std::to_string(currentLine) + ".").c_str()); + } + else + content.length = defaultDataLength; + + if (element == "read") + content.command = Request::Command::Read; + else if (element == "write") + content.command = Request::Command::Write; + else + SC_REPORT_FATAL( + "StlPlayer", + ("Malformed trace file line " + std::to_string(currentLine) + ".").c_str()); + + // Get the address. + iss >> element; + if (element.empty()) + SC_REPORT_FATAL( + "StlPlayer", + ("Malformed trace file line " + std::to_string(currentLine) + ".").c_str()); + content.address = std::stoull(element, nullptr, 16); + + // Get the data if necessary. + if (storageEnabled && content.command == Request::Command::Write) + { + // The input trace file must provide the data to be stored into the memory. + iss >> element; + + // Check if data length in the trace file is correct. + // We need two characters to represent 1 byte in hexadecimal. Offset for 0x prefix. + if (element.length() != (content.length * 2 + 2)) + SC_REPORT_FATAL( + "StlPlayer", + ("Malformed trace file line " + std::to_string(currentLine) + ".").c_str()); + + // Set data + for (unsigned i = 0; i < content.length; i++) + content.data.emplace_back(static_cast( + std::stoi(element.substr(i * 2 + 2, 2), nullptr, 16))); + } + } +} + +std::vector::const_iterator StlPlayer::swapBuffers() +{ + // Wait for parser to finish + if (parserThread.joinable()) + parserThread.join(); + + // Swap buffers + std::swap(readoutBuffer, parseBuffer); + + // Start new parser thread + parserThread = std::thread(&StlPlayer::parseTraceFile, this); + + return readoutBuffer->cbegin(); +} diff --git a/src/simulator/simulator/StlPlayer.h b/src/simulator/simulator/player/StlPlayer.h similarity index 57% rename from src/simulator/simulator/StlPlayer.h rename to src/simulator/simulator/player/StlPlayer.h index 35406468..e9d4b8b1 100644 --- a/src/simulator/simulator/StlPlayer.h +++ b/src/simulator/simulator/player/StlPlayer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Technische Universität Kaiserslautern + * Copyright (c) 2023, Technische Universität Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,65 +38,59 @@ * Derek Christ */ -#ifndef STLPLAYER_H -#define STLPLAYER_H +#pragma once -#include "simulator/TraceSetup.h" -#include "simulator/TrafficInitiator.h" +#include "simulator/request/Request.h" +#include "simulator/request/RequestProducer.h" -#include -#include -#include -#include -#include #include #include -class StlPlayer : public TrafficInitiator +#include +#include +#include +#include + +class StlPlayer : public RequestProducer { public: - StlPlayer(const sc_core::sc_module_name &name, - const Configuration& config, - const std::string &pathToTrace, - const sc_core::sc_time &playerClk, - unsigned int maxPendingReadRequests, - unsigned int maxPendingWriteRequests, - TraceSetup& setup, - bool relative); - - ~StlPlayer() override; - void sendNextPayload() override; - uint64_t getNumberOfLines() const; - -private: - struct LineContent + enum class TraceType { - sc_core::sc_time sendingTime; - unsigned dataLength; - tlm::tlm_command command; - uint64_t address; - std::vector data; + Absolute, + Relative, }; - void parseTraceFile(); - std::vector::const_iterator swapBuffers(); + StlPlayer(std::string_view tracePath, + unsigned int clkMhz, + unsigned int defaultDataLength, + TraceType traceType, + bool storageEnabled); - std::ifstream file; - uint64_t lineCnt = 0; + Request nextRequest() override; + + sc_core::sc_time clkPeriod() override { return playerPeriod; } + uint64_t totalRequests() override { return numberOfLines; } + +private: + void parseTraceFile(); + std::vector::const_iterator swapBuffers(); + + static constexpr std::size_t LINE_BUFFER_SIZE = 10000; + + const TraceType traceType; + const bool storageEnabled; + const sc_core::sc_time playerPeriod; + const unsigned int defaultDataLength; + + std::ifstream traceFile; + uint64_t currentLine = 0; uint64_t numberOfLines = 0; - const sc_core::sc_time playerClk; // May be different from the memory clock! + std::array>, 2> lineBuffers; + std::shared_ptr> parseBuffer; + std::shared_ptr> readoutBuffer; - static constexpr unsigned lineBufferSize = 10000; - - std::vector* currentBuffer; - std::vector* parseBuffer; - std::array, 2> lineContents; - std::vector::const_iterator lineIterator; + std::vector::const_iterator readoutIt; std::thread parserThread; - - const bool relative; }; - -#endif // STLPLAYER_H diff --git a/src/simulator/simulator/request/Request.h b/src/simulator/simulator/request/Request.h new file mode 100644 index 00000000..7ee69d82 --- /dev/null +++ b/src/simulator/simulator/request/Request.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023, 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 + */ + +#pragma once + +#include +#include + +struct Request +{ + enum class Command + { + Read, + Write, + Stop + } command; + uint64_t address; + std::size_t length; + sc_core::sc_time delay; + std::vector data; +}; diff --git a/src/simulator/simulator/request/RequestIssuer.cpp b/src/simulator/simulator/request/RequestIssuer.cpp new file mode 100644 index 00000000..27c76a1b --- /dev/null +++ b/src/simulator/simulator/request/RequestIssuer.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2023, 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 "RequestIssuer.h" + +RequestIssuer::RequestIssuer(sc_core::sc_module_name const &name, + MemoryManager &memoryManager, + std::optional maxPendingReadRequests, + std::optional maxPendingWriteRequests, + std::function nextRequest, + std::function transactionFinished, + std::function terminate) + : sc_module(name), + memoryManager(memoryManager), + maxPendingReadRequests(maxPendingReadRequests), + maxPendingWriteRequests(maxPendingWriteRequests), + nextRequest(std::move(nextRequest)), + transactionFinished(std::move(transactionFinished)), + terminate(std::move(terminate)), + payloadEventQueue(this, &RequestIssuer::peqCallback) +{ + SC_THREAD(sendNextRequest); + iSocket.register_nb_transport_bw(this, &RequestIssuer::nb_transport_bw); +} + +void RequestIssuer::sendNextRequest() +{ + Request request = nextRequest(); + + if (request.command == Request::Command::Stop) + { + finished = true; + return; + } + + tlm::tlm_generic_payload &payload = memoryManager.allocate(request.length); + payload.acquire(); + payload.set_address(request.address); + payload.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + payload.set_dmi_allowed(false); + payload.set_byte_enable_length(0); + payload.set_data_length(request.length); + payload.set_streaming_width(request.length); + payload.set_command(request.command == Request::Command::Read ? tlm::TLM_READ_COMMAND + : tlm::TLM_WRITE_COMMAND); + + tlm::tlm_phase phase = tlm::BEGIN_REQ; + sc_core::sc_time delay = request.delay; + + if (transactionsSent == 0) + delay = sc_core::SC_ZERO_TIME; + + iSocket->nb_transport_fw(payload, phase, delay); + transactionInProgress = true; + + if (request.command == Request::Command::Read) + pendingReadRequests++; + else if (request.command == Request::Command::Write) + pendingWriteRequests++; + + transactionsSent++; +} + +bool RequestIssuer::nextRequestSendable() const +{ + // If either the maxPendingReadRequests or maxPendingWriteRequests + // limit is reached, do not send next payload. + if (maxPendingReadRequests.has_value() && pendingReadRequests >= maxPendingReadRequests.value()) + return false; + + if (maxPendingWriteRequests.has_value() && + pendingWriteRequests >= maxPendingWriteRequests.value()) + return false; + + return true; +} + +void RequestIssuer::peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) +{ + if (phase == tlm::END_REQ) + { + if (nextRequestSendable()) + sendNextRequest(); + else + transactionPostponed = true; + } + else if (phase == tlm::BEGIN_RESP) + { + tlm::tlm_phase phase = tlm::END_RESP; + sc_core::sc_time delay = sc_core::SC_ZERO_TIME; + iSocket->nb_transport_fw(payload, phase, delay); + + payload.release(); + transactionInProgress = false; + + transactionFinished(); + + transactionsReceived++; + + if (payload.get_command() == tlm::TLM_READ_COMMAND) + pendingReadRequests--; + else if (payload.get_command() == tlm::TLM_WRITE_COMMAND) + pendingWriteRequests--; + + // If the initiator wasn't able to send the next payload in the END_REQ phase, do it + // now. + if (transactionPostponed && nextRequestSendable()) + { + sendNextRequest(); + transactionPostponed = false; + } + + // If all answers were received: + if (finished && transactionsSent == transactionsReceived) + terminate(); + } + else + { + SC_REPORT_FATAL("TrafficInitiator", "PEQ was triggered with unknown phase"); + } +} diff --git a/src/simulator/simulator/TrafficInitiator.h b/src/simulator/simulator/request/RequestIssuer.h similarity index 55% rename from src/simulator/simulator/TrafficInitiator.h rename to src/simulator/simulator/request/RequestIssuer.h index ad3b00ca..1d5b3939 100644 --- a/src/simulator/simulator/TrafficInitiator.h +++ b/src/simulator/simulator/request/RequestIssuer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Technische Universität Kaiserslautern + * Copyright (c) 2023, Technische Universität Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,70 +30,68 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: - * Robert Gernhardt - * Matthias Jung - * Éder F. Zulian - * Felipe S. Prado * Derek Christ */ -#ifndef TRAFFICINITIATOR_H -#define TRAFFICINITIATOR_H +#pragma once -#include "simulator/TraceSetup.h" +#include "Request.h" +#include "simulator/MemoryManager.h" -#include "DRAMSys/configuration/Configuration.h" -#include "DRAMSys/common/DebugManager.h" - -#include -#include -#include -#include #include -#include +#include #include +#include -class TrafficInitiator : public sc_core::sc_module +#include + +class RequestIssuer : sc_core::sc_module { public: - tlm_utils::simple_initiator_socket iSocket; - TrafficInitiator(const sc_core::sc_module_name &name, const Configuration& config, TraceSetup& setup, - unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, unsigned int defaultDataLength); - SC_HAS_PROCESS(TrafficInitiator); - virtual void sendNextPayload() = 0; + tlm_utils::simple_initiator_socket iSocket; -protected: - static sc_core::sc_time evaluateGeneratorClk(const DRAMSys::Config::TrafficInitiator &conf); - - tlm_utils::peq_with_cb_and_phase payloadEventQueue; - void terminate(); - TraceSetup& setup; - void sendToTarget(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase, - const sc_core::sc_time &delay); - - uint64_t transactionsReceived = 0; - 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; - const bool storageEnabled; - const bool simulationProgressBar; - - // 0 disables the max value. - static constexpr unsigned int defaultMaxPendingWriteRequests = 0; - static constexpr unsigned int defaultMaxPendingReadRequests = 0; + RequestIssuer(sc_core::sc_module_name const &name, + MemoryManager &memoryManager, + std::optional maxPendingReadRequests, + std::optional maxPendingWriteRequests, + std::function nextRequest, + std::function transactionFinished, + std::function terminate); + SC_HAS_PROCESS(RequestIssuer); private: - tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, - sc_core::sc_time &bwDelay); - void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); - bool nextPayloadSendable() const; -}; + tlm_utils::peq_with_cb_and_phase payloadEventQueue; + MemoryManager &memoryManager; -#endif // TRAFFICINITIATOR_H + bool transactionInProgress = false; + bool transactionPostponed = false; + bool finished = false; + + uint64_t transactionsSent = 0; + uint64_t transactionsReceived = 0; + + unsigned int pendingReadRequests = 0; + unsigned int pendingWriteRequests = 0; + const std::optional maxPendingReadRequests; + const std::optional maxPendingWriteRequests; + + unsigned int activeProducers = 0; + + std::function transactionFinished; + std::function terminate; + std::function nextRequest; + + void sendNextRequest(); + + bool nextRequestSendable() const; + + tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &bwDelay) + { + payloadEventQueue.notify(payload, phase, bwDelay); + return tlm::TLM_ACCEPTED; + } + + void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); +}; diff --git a/src/simulator/simulator/request/RequestProducer.h b/src/simulator/simulator/request/RequestProducer.h new file mode 100644 index 00000000..4a6eee73 --- /dev/null +++ b/src/simulator/simulator/request/RequestProducer.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023, 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 + */ + +#pragma once + +#include "Request.h" + +class RequestProducer +{ +public: + virtual ~RequestProducer() = default; + + virtual Request nextRequest() = 0; + virtual uint64_t totalRequests() = 0; + virtual sc_core::sc_time clkPeriod() = 0; + virtual void reset(){}; +}; diff --git a/src/simulator/simulator/util.cpp b/src/simulator/simulator/util.cpp new file mode 100644 index 00000000..4c04bb32 --- /dev/null +++ b/src/simulator/simulator/util.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023, 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: + * Matthias Jung + * Derek Christ + */ + +#include "util.h" + +#include +#include +#include + +void loadBar(uint64_t x, uint64_t n, unsigned int w, unsigned int granularity) +{ + if ((n < 100) || ((x != n) && (x % (n / 100 * granularity) != 0))) + return; + + float ratio = x / (float)n; + unsigned int c = (ratio * w); + float rest = (ratio * w) - c; + std::cout << std::setw(3) << std::round(ratio * 100) << "% |"; + for (unsigned int x = 0; x < c; x++) + std::cout << "█"; + + if (rest >= 0 && rest < 0.125f && c != w) + std::cout << " "; + if (rest >= 0.125f && rest < 2 * 0.125f) + std::cout << "▏"; + if (rest >= 2 * 0.125f && rest < 3 * 0.125f) + std::cout << "▎"; + if (rest >= 3 * 0.125f && rest < 4 * 0.125f) + std::cout << "▍"; + if (rest >= 4 * 0.125f && rest < 5 * 0.125f) + std::cout << "▌"; + if (rest >= 5 * 0.125f && rest < 6 * 0.125f) + std::cout << "▋"; + if (rest >= 6 * 0.125f && rest < 7 * 0.125f) + std::cout << "▊"; + if (rest >= 7 * 0.125f && rest < 8 * 0.125f) + std::cout << "▉"; + + for (unsigned int x = c; x < (w - 1); x++) + std::cout << " "; + std::cout << "|\r" << std::flush; +} diff --git a/src/simulator/simulator/TraceSetup.h b/src/simulator/simulator/util.h similarity index 58% rename from src/simulator/simulator/TraceSetup.h rename to src/simulator/simulator/util.h index 57913573..160d2367 100644 --- a/src/simulator/simulator/TraceSetup.h +++ b/src/simulator/simulator/util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Technische Universität Kaiserslautern + * Copyright (c) 2023, Technische Universität Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,43 +34,8 @@ * Derek Christ */ -#ifndef TRACESETUP_H -#define TRACESETUP_H +#pragma once -#include "simulator/MemoryManager.h" +#include -#include "DRAMSys/config/DRAMSysConfiguration.h" -#include "DRAMSys/configuration/Configuration.h" - -#include -#include -#include -#include - -class TrafficInitiator; - -class TraceSetup -{ -public: - TraceSetup(const Configuration& config, - const DRAMSys::Config::TraceSetup &traceSetup, - const std::string &pathToResources, - std::vector> &devices); - - void trafficInitiatorTerminates(); - void transactionFinished(); - tlm::tlm_generic_payload& allocatePayload(unsigned dataLength); - tlm::tlm_generic_payload& allocatePayload(); - -private: - unsigned int numberOfTrafficInitiators; - uint64_t totalTransactions = 0; - uint64_t remainingTransactions; - unsigned int finishedTrafficInitiators = 0; - MemoryManager memoryManager; - unsigned defaultDataLength = 64; - - static void loadBar(uint64_t x, uint64_t n, unsigned int w = 50, unsigned int granularity = 1); -}; - -#endif // TRACESETUP_H +void loadBar(uint64_t x, uint64_t n, unsigned int w = 50, unsigned int granularity = 1); diff --git a/src/util/DRAMSys/util/json.h b/src/util/DRAMSys/util/json.h index 94a24cdf..8c09489e 100644 --- a/src/util/DRAMSys/util/json.h +++ b/src/util/DRAMSys/util/json.h @@ -35,6 +35,7 @@ * * Authors: * Thomas Psota + * Derek Christ */ diff --git a/tests/tests_configuration/test_configuration.cpp b/tests/tests_configuration/test_configuration.cpp index 89f0740d..3e81d3ef 100644 --- a/tests/tests_configuration/test_configuration.cpp +++ b/tests/tests_configuration/test_configuration.cpp @@ -60,7 +60,7 @@ protected: static DRAMSys::Config::TracePlayer createTracePlayer(); static DRAMSys::Config::TrafficGenerator createTraceGeneratorOneState(); static DRAMSys::Config::TrafficGeneratorStateMachine createTraceGeneratorMultipleStates(); - static DRAMSys::Config::TraceHammer createTraceHammer(); + static DRAMSys::Config::RowHammer createTraceHammer(); DRAMSys::Config::AddressMapping addressMapping{ {{{0, 1}}, @@ -109,7 +109,7 @@ protected: DRAMSys::Config::TracePlayer tracePlayer; DRAMSys::Config::TrafficGenerator traceGeneratorOneState; DRAMSys::Config::TrafficGeneratorStateMachine traceGeneratorMultipleStates; - DRAMSys::Config::TraceHammer traceHammer; + DRAMSys::Config::RowHammer traceHammer; DRAMSys::Config::TraceSetup traceSetup{{tracePlayer, traceGeneratorOneState, traceGeneratorMultipleStates, traceHammer}}; DRAMSys::Config::Configuration configuration{ @@ -183,7 +183,6 @@ DRAMSys::Config::TrafficGenerator ConfigurationTest::createTraceGeneratorOneStat gen.addressIncrement = {}; gen.minAddress = {}; gen.maxAddress = {}; - gen.clksPerRequest = {}; return gen; } @@ -203,7 +202,6 @@ DRAMSys::Config::TrafficGeneratorStateMachine ConfigurationTest::createTraceGene state0.addressIncrement = 256; state0.minAddress = {}; state0.maxAddress = 1024; - state0.clksPerRequest = {}; state0.id = 0; DRAMSys::Config::TrafficGeneratorActiveState state1; @@ -213,7 +211,6 @@ DRAMSys::Config::TrafficGeneratorStateMachine ConfigurationTest::createTraceGene state1.addressIncrement = 512; state1.minAddress = 1024; state1.maxAddress = 2048; - state1.clksPerRequest = {}; state1.id = 1; gen.states.push_back(state0); @@ -226,9 +223,9 @@ DRAMSys::Config::TrafficGeneratorStateMachine ConfigurationTest::createTraceGene return gen; } -DRAMSys::Config::TraceHammer ConfigurationTest::createTraceHammer() +DRAMSys::Config::RowHammer ConfigurationTest::createTraceHammer() { - DRAMSys::Config::TraceHammer hammer; + DRAMSys::Config::RowHammer hammer; hammer.clkMhz = 100; hammer.name = "MyTestHammer"; From c8e509a120ce4a27f3aada422374d55c902be555 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Thu, 12 Jan 2023 10:54:39 +0100 Subject: [PATCH 03/20] Add EccModule to simulator --- .../DRAMSys/common/dramExtensions.h | 14 ++ .../DRAMSys/controller/Controller.cpp | 5 +- .../DRAMSys/simulation/AddressDecoder.cpp | 40 ++++- .../DRAMSys/simulation/AddressDecoder.h | 6 +- src/libdramsys/DRAMSys/simulation/DRAMSys.cpp | 2 +- src/libdramsys/DRAMSys/simulation/DRAMSys.h | 1 + .../DRAMSys/simulation/DRAMSysRecordable.cpp | 2 +- src/simulator/simulator/player/StlPlayer.cpp | 2 +- tests/tests_dramsys/AddressDecoderConfigs.h | 149 ++++++++++++++++++ tests/tests_dramsys/AddressDecoderTests.cpp | 119 ++++++++++++++ tests/tests_dramsys/Testfile.h | 85 +++++----- tests/tests_dramsys/main.cpp | 1 + 12 files changed, 374 insertions(+), 52 deletions(-) create mode 100644 tests/tests_dramsys/AddressDecoderConfigs.h create mode 100644 tests/tests_dramsys/AddressDecoderTests.cpp diff --git a/src/libdramsys/DRAMSys/common/dramExtensions.h b/src/libdramsys/DRAMSys/common/dramExtensions.h index 7a8a80c1..b920747b 100644 --- a/src/libdramsys/DRAMSys/common/dramExtensions.h +++ b/src/libdramsys/DRAMSys/common/dramExtensions.h @@ -288,4 +288,18 @@ public: static bool notifyChildTransCompletion(tlm::tlm_generic_payload& trans); }; +class EccExtension : public tlm::tlm_extension +{ +public: + tlm_extension_base* clone() const override + { + return new EccExtension; + } + + void copy_from(tlm_extension_base const &ext) override + { + auto const &cpyFrom = static_cast(ext); + } +}; + #endif // DRAMEXTENSIONS_H diff --git a/src/libdramsys/DRAMSys/controller/Controller.cpp b/src/libdramsys/DRAMSys/controller/Controller.cpp index a1262417..09a5a414 100644 --- a/src/libdramsys/DRAMSys/controller/Controller.cpp +++ b/src/libdramsys/DRAMSys/controller/Controller.cpp @@ -515,7 +515,10 @@ void Controller::manageResponses() tlm_generic_payload* nextTransInRespQueue = respQueue->nextPayload(); if (nextTransInRespQueue != nullptr) { - numberOfBeatsServed += ControllerExtension::getBurstLength(*nextTransInRespQueue); + // Ignore ECC requests + if (nextTransInRespQueue->get_extension() == nullptr) + numberOfBeatsServed += ControllerExtension::getBurstLength(*nextTransInRespQueue); + if (ChildExtension::isChildTrans(*nextTransInRespQueue)) { tlm_generic_payload& parentTrans = ChildExtension::getParentTrans(*nextTransInRespQueue); diff --git a/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp b/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp index 2ec633de..7b3de3b2 100644 --- a/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp +++ b/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp @@ -37,13 +37,14 @@ */ #include "AddressDecoder.h" +#include "DRAMSys/configuration/Configuration.h" #include #include #include #include -AddressDecoder::AddressDecoder(const Configuration& config, const DRAMSys::Config::AddressMapping& addressMapping) +AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping &addressMapping, const MemSpec &memSpec) { if (const auto &channelBits = addressMapping.CONGEN.CHANNEL_BIT) { @@ -113,8 +114,6 @@ AddressDecoder::AddressDecoder(const Configuration& config, const DRAMSys::Confi SC_REPORT_FATAL("AddressDecoder", "Not all address bits occur exactly once"); } - const MemSpec& memSpec = *config.memSpec; - unsigned highestByteBit = *std::max_element(vByteBits.begin(), vByteBits.end()); for (unsigned bitPosition = 0; bitPosition <= highestByteBit; bitPosition++) @@ -213,6 +212,41 @@ unsigned AddressDecoder::decodeChannel(uint64_t encAddr) const return channel; } +uint64_t AddressDecoder::encodeAddress(DecodedAddress decodedAddress) const +{ + // Convert absoulte addressing for bank, bankgroup to relative + decodedAddress.bankgroup = decodedAddress.bankgroup % bankgroupsPerRank; + decodedAddress.bank = decodedAddress.bank % banksPerGroup; + + uint64_t address = 0; + + for (unsigned i = 0; i < vChannelBits.size(); i++) + address |= ((decodedAddress.channel >> i) & 0x1) << vChannelBits[i]; + + for (unsigned i = 0; i < vRankBits.size(); i++) + address |= ((decodedAddress.rank >> i) & 0x1) << vRankBits[i]; + + for (unsigned i = 0; i < vBankGroupBits.size(); i++) + address |= ((decodedAddress.bankgroup >> i) & 0x1) << vBankGroupBits[i]; + + for (unsigned i = 0; i < vBankBits.size(); i++) + address |= ((decodedAddress.bank >> i) & 0x1) << vBankBits[i]; + + for (unsigned i = 0; i < vRowBits.size(); i++) + address |= ((decodedAddress.row >> i) & 0x1) << vRowBits[i]; + + for (unsigned i = 0; i < vColumnBits.size(); i++) + address |= ((decodedAddress.column >> i) & 0x1) << vColumnBits[i]; + + for (unsigned i = 0; i < vByteBits.size(); i++) + address |= ((decodedAddress.byte >> i) & 0x1) << vByteBits[i]; + + // TODO: XOR encoding + + return address; +} + + void AddressDecoder::print() const { std::cout << headline << std::endl; diff --git a/src/libdramsys/DRAMSys/simulation/AddressDecoder.h b/src/libdramsys/DRAMSys/simulation/AddressDecoder.h index 57f2f324..42a9f0d3 100644 --- a/src/libdramsys/DRAMSys/simulation/AddressDecoder.h +++ b/src/libdramsys/DRAMSys/simulation/AddressDecoder.h @@ -39,9 +39,8 @@ #ifndef ADDRESSDECODER_H #define ADDRESSDECODER_H -#include "DRAMSys/configuration/Configuration.h" - #include "DRAMSys/config/DRAMSysConfiguration.h" +#include "DRAMSys/configuration/Configuration.h" #include #include @@ -69,9 +68,10 @@ struct DecodedAddress class AddressDecoder { public: - AddressDecoder(const Configuration& config, const DRAMSys::Config::AddressMapping& addressMapping); + AddressDecoder(const DRAMSys::Config::AddressMapping &addressMapping, const MemSpec &memSpec); [[nodiscard]] DecodedAddress decodeAddress(uint64_t encAddr) const; [[nodiscard]] unsigned decodeChannel(uint64_t encAddr) const; + [[nodiscard]] uint64_t encodeAddress(DecodedAddress decodedAddress) const; void print() const; private: diff --git a/src/libdramsys/DRAMSys/simulation/DRAMSys.cpp b/src/libdramsys/DRAMSys/simulation/DRAMSys.cpp index 6e32e0b5..25e23c70 100644 --- a/src/libdramsys/DRAMSys/simulation/DRAMSys.cpp +++ b/src/libdramsys/DRAMSys/simulation/DRAMSys.cpp @@ -157,7 +157,7 @@ void DRAMSys::setupDebugManager(NDEBUG_UNUSED(const std::string& traceName)) con void DRAMSys::instantiateModules(const ::DRAMSys::Config::AddressMapping& addressMapping) { - addressDecoder = std::make_unique(config, addressMapping); + addressDecoder = std::make_unique(addressMapping, *config.memSpec); addressDecoder->print(); // Create arbiter diff --git a/src/libdramsys/DRAMSys/simulation/DRAMSys.h b/src/libdramsys/DRAMSys/simulation/DRAMSys.h index cec3a6d9..84343589 100644 --- a/src/libdramsys/DRAMSys/simulation/DRAMSys.h +++ b/src/libdramsys/DRAMSys/simulation/DRAMSys.h @@ -70,6 +70,7 @@ public: const ::DRAMSys::Config::Configuration& configLib); const Configuration& getConfig() const; + const AddressDecoder &getAddressDecoder() const { return *addressDecoder; } protected: DRAMSys(const sc_core::sc_module_name& name, diff --git a/src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp b/src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp index 719c8bff..2309b838 100644 --- a/src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp +++ b/src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp @@ -120,7 +120,7 @@ void DRAMSysRecordable::setupTlmRecorders(const std::string& traceName, void DRAMSysRecordable::instantiateModules(const std::string& traceName, const ::DRAMSys::Config::Configuration& configLib) { - addressDecoder = std::make_unique(config, configLib.addressmapping); + addressDecoder = std::make_unique(configLib.addressmapping, *config.memSpec); addressDecoder->print(); // Create and properly initialize TLM recorders. diff --git a/src/simulator/simulator/player/StlPlayer.cpp b/src/simulator/simulator/player/StlPlayer.cpp index 2fbda317..2b29d794 100644 --- a/src/simulator/simulator/player/StlPlayer.cpp +++ b/src/simulator/simulator/player/StlPlayer.cpp @@ -102,7 +102,7 @@ Request StlPlayer::nextRequest() delay -= sc_core::sc_time_stamp(); } - Request request(std::move(*readoutIt)); + Request request(*readoutIt); request.delay = delay; readoutIt++; diff --git a/tests/tests_dramsys/AddressDecoderConfigs.h b/tests/tests_dramsys/AddressDecoderConfigs.h new file mode 100644 index 00000000..671c24ef --- /dev/null +++ b/tests/tests_dramsys/AddressDecoderConfigs.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2022, 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 + */ + +#pragma once + +#include + +inline constexpr std::string_view memSpecJsonString = R"( +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 8, + "nbrOfBankGroups": 4, + "nbrOfBanks": 16, + "nbrOfColumns": 1024, + "nbrOfRows": 65536, + "nbrOfRanks": 1, + "nbrOfDevices": 1, + "nbrOfChannels": 1, + "width": 16, + "per2BankOffset": 8 + }, + "memoryId": "JEDEC_1Gbx16_BG_LPDDR5-6400", + "memoryType": "LPDDR5", + "memtimingspec": { + "RCD": 15, + "PPD": 2, + "RPab": 17, + "RPpb": 15, + "RAS": 34, + "RCab": 51, + "RCpb": 48, + "FAW": 16, + "RRD": 4, + "RL": 17, + "WCK2CK": 0, + "WCK2DQO": 1, + "RBTP": 4, + "RPRE": 0, + "RPST": 0, + "WL": 9, + "WCK2DQI": 0, + "WPRE": 0, + "WPST": 0, + "WR": 28, + "WTR_L": 10, + "WTR_S": 5, + "CCDMW": 16, + "REFI": 3124, + "REFIpb": 390, + "RFCab": 224, + "RFCpb": 112, + "RTRS": 1, + "BL_n_min_16": 2, + "BL_n_max_16": 4, + "BL_n_L_16": 4, + "BL_n_S_16": 2, + "BL_n_min_32": 6, + "BL_n_max_32": 8, + "BL_n_L_32": 8, + "BL_n_S_32": 2, + "pbR2act": 6, + "pbR2pbR": 72, + "clkMhz": 800 + } + } +} +)"; + +inline constexpr std::string_view addressMappingJsonString = R"( +{ + "CONGEN": { + "BYTE_BIT": [ + 0 + ], + "COLUMN_BIT": [ + 1, + 2, + 3, + 4, + 9, + 10, + 11, + 12, + 13, + 14 + ], + "BANKGROUP_BIT": [ + 5, + 6 + ], + "BANK_BIT": [ + 7, + 8 + ], + "ROW_BIT": [ + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30 + ] + } +} +)"; diff --git a/tests/tests_dramsys/AddressDecoderTests.cpp b/tests/tests_dramsys/AddressDecoderTests.cpp new file mode 100644 index 00000000..fe9dd24b --- /dev/null +++ b/tests/tests_dramsys/AddressDecoderTests.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2022, 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 "AddressDecoderConfigs.h" + +#include + +#include +#include + +class AddressDecoderFixture : public ::testing::Test +{ +protected: + AddressDecoderFixture() : + addressMappingJson(nlohmann::json::parse(addressMappingJsonString)), + memSpecJson(nlohmann::json::parse(memSpecJsonString).at("memspec")), + addressMappingConfig(addressMappingJson.get()), + memSpec(memSpecConfig), + memSpecConfig(memSpecJson.get()), + addressDecoder(addressMappingConfig, memSpec) + { + } + + nlohmann::json addressMappingJson; + nlohmann::json memSpecJson; + + // Configs + DRAMSys::Config::AddressMapping addressMappingConfig; + DRAMSys::Config::MemSpec memSpecConfig; + + MemSpecLPDDR5 memSpec; + AddressDecoder addressDecoder; +}; + +TEST_F(AddressDecoderFixture, Decoding) +{ + uint64_t address = 0x3A59'1474; + auto decodedAddress = addressDecoder.decodeAddress(address); + + unsigned int channel = decodedAddress.channel; + unsigned int rank = decodedAddress.rank; + unsigned int bankgroup = decodedAddress.bankgroup; + unsigned int bank = decodedAddress.bank; + unsigned int row = decodedAddress.row; + unsigned int column = decodedAddress.column; + unsigned int byte = decodedAddress.byte; + + EXPECT_EQ(channel, 0); + EXPECT_EQ(rank, 0); + EXPECT_EQ(bankgroup, 3); + EXPECT_EQ(bank, 12); + EXPECT_EQ(row, 29874); + EXPECT_EQ(column, 170); + EXPECT_EQ(byte, 0); +} + +TEST_F(AddressDecoderFixture, Encoding) +{ + unsigned int channel = 0; + unsigned int rank = 0; + unsigned int bankgroup = 3; + unsigned int bank = 12; + unsigned int row = 29874; + unsigned int column = 170; + unsigned int byte = 0; + + DecodedAddress decodedAddress(channel, rank, bankgroup, bank, row, column, byte); + + uint64_t address = addressDecoder.encodeAddress(decodedAddress); + EXPECT_EQ(address, 0x3A59'1474); +} + +TEST_F(AddressDecoderFixture, DeEncoding) +{ + std::array testAddresses{std::uint64_t(0x3A59'1474), + std::uint64_t(0x0000'0000), + std::uint64_t(0x2FFA'1231), + std::uint64_t(0x0001'FFFF)}; + + for (auto address: testAddresses) + { + DecodedAddress decodedAddress = addressDecoder.decodeAddress(address); + uint64_t encodedAddress = addressDecoder.encodeAddress(decodedAddress); + + EXPECT_EQ(encodedAddress, address); + } +} \ No newline at end of file diff --git a/tests/tests_dramsys/Testfile.h b/tests/tests_dramsys/Testfile.h index 74835a7d..e381048b 100644 --- a/tests/tests_dramsys/Testfile.h +++ b/tests/tests_dramsys/Testfile.h @@ -1,42 +1,43 @@ -///* -// * Copyright (c) 2019, 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: -// * Lukas Steiner -// */ -// -//#include -//#include "../library/src/controller/Command.h" -// -//TEST(testsuite, test) -//{ -// EXPECT_EQ(commandToString(Command::ACT), "ACT"); -//} +/* + * Copyright (c) 2019, 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: + * Lukas Steiner + */ + +#include + +#include + +TEST(testsuite, test) +{ + EXPECT_EQ(Command(Command::Type::ACT).toString(), "ACT"); +} diff --git a/tests/tests_dramsys/main.cpp b/tests/tests_dramsys/main.cpp index 1c92c82d..42f2dbbe 100644 --- a/tests/tests_dramsys/main.cpp +++ b/tests/tests_dramsys/main.cpp @@ -35,6 +35,7 @@ #include #include +#include "Testfile.h" int sc_main(int argc, char **argv) { From 45e31f5b5ae02fede38186b5792db7006e8c6475 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 23 Jan 2023 15:37:37 +0100 Subject: [PATCH 04/20] First integration of Cache --- src/simulator/simulator/Cache.cpp | 638 +++++++++++++++++++++ src/simulator/simulator/Cache.h | 200 +++++++ src/simulator/simulator/player/DbiPlayer.h | 47 ++ tests/tests_configuration/CMakeLists.txt | 2 +- 4 files changed, 886 insertions(+), 1 deletion(-) create mode 100644 src/simulator/simulator/Cache.cpp create mode 100644 src/simulator/simulator/Cache.h create mode 100644 src/simulator/simulator/player/DbiPlayer.h diff --git a/src/simulator/simulator/Cache.cpp b/src/simulator/simulator/Cache.cpp new file mode 100644 index 00000000..96ff8868 --- /dev/null +++ b/src/simulator/simulator/Cache.cpp @@ -0,0 +1,638 @@ +#include "Cache.h" +#include "MemoryManager.h" + +#include +#include +#include +#include +#include +#include + +using namespace tlm; +using namespace sc_core; + +DECLARE_EXTENDED_PHASE(HIT_HANDLING); +DECLARE_EXTENDED_PHASE(MISS_HANDLING); + +Cache::Cache(const sc_module_name &name, + std::size_t size, + std::size_t associativity, + std::size_t lineSize, + std::size_t mshrDepth, + std::size_t writeBufferDepth, + std::size_t maxTargetListSize, + bool storageEnabled, + sc_core::sc_time cycleTime, + std::size_t hitCycles) : + sc_module(name), + payloadEventQueue(this, &Cache::peqCallback), + storageEnabled(storageEnabled), + cycleTime(cycleTime), + hitLatency(cycleTime * static_cast(hitCycles)), + size(size), + associativity(associativity), + lineSize(lineSize), + numberOfSets(size / (lineSize * associativity)), + indexShifts(static_cast(std::log2(lineSize))), + indexMask(numberOfSets - 1), + tagShifts(indexShifts + static_cast(std::log2(numberOfSets))), + mshrDepth(mshrDepth), + writeBufferDepth(writeBufferDepth), + maxTargetListSize(maxTargetListSize), + memoryManager(storageEnabled) +{ + iSocket.register_nb_transport_bw(this, &Cache::nb_transport_bw); + tSocket.register_nb_transport_fw(this, &Cache::nb_transport_fw); + + lineTable = std::vector>(numberOfSets, std::vector(associativity)); + + if (storageEnabled) + { + dataMemory.reserve(size); + + for (std::size_t set = 0; set < lineTable.size(); set++) + { + for (std::size_t way = 0; way < lineTable[set].size(); way++) + lineTable[set][way].dataPtr = dataMemory.data() + set * associativity * lineSize + way * lineSize; + } + } +} + +tlm_sync_enum Cache::nb_transport_fw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &delay) // core side ---> +{ + if (phase == BEGIN_REQ) + { + if (trans.get_data_length() > lineSize) + { + SC_REPORT_FATAL(name(), "Accesses larger than line size in non-blocking mode not supported!"); + } + + trans.acquire(); + } + + // TODO: early completion would be possible + payloadEventQueue.notify(trans, phase, ceilDelay(delay)); + + return TLM_ACCEPTED; +} + +tlm_sync_enum Cache::nb_transport_bw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &bwDelay) // DRAM side <--- +{ + // TODO: early completion would be possible + payloadEventQueue.notify(trans, phase, ceilDelay(bwDelay)); + + return TLM_ACCEPTED; +} + +void Cache::peqCallback(tlm_generic_payload &trans, const tlm_phase &phase) +{ + if (phase == BEGIN_REQ) // core side ---> + { + assert(!endRequestPending); + fetchLineAndSendEndRequest(trans); + return; + } + else if (phase == END_REQ) // <--- DRAM side + { + lastEndReq = sc_time_stamp(); + clearInitiatorBackpressureAndProcessBuffers(); + return; + } + else if (phase == BEGIN_RESP && &trans == requestInProgress) // <--- DRAM side + { + // Shortcut, 2 phases in one + clearInitiatorBackpressureAndProcessBuffers(); + sendEndResponseAndFillLine(trans); + return; + } + else if (phase == BEGIN_RESP) // <--- DRAM side + { + sendEndResponseAndFillLine(trans); + return; + } + else if (phase == END_RESP) // core side ---> + { + clearTargetBackpressureAndProcessLines(trans); + return; + } + else if (phase == HIT_HANDLING) // direct hit, account for the hit delay + { + index_t index; + tag_t tag; + std::tie(index, tag, std::ignore) = decodeAddress(trans.get_address()); + + hitQueue.emplace_back(index, tag, &trans); + processHitQueue(); + } + else if (phase == MISS_HANDLING) // fetched MSHR entry available, account for the hit delay + { + accessCacheAndSendResponse(trans); + + index_t index; + tag_t tag; + std::tie(index, tag, std::ignore) = decodeAddress(trans.get_address()); + + auto mshrIt = std::find_if(mshrQueue.begin(), mshrQueue.end(), + [index, tag](const Mshr &mshr) { return mshr.index == index && mshr.tag == tag; }); + + assert(mshrIt != mshrQueue.end()); + mshrIt->hitDelayAccounted = true; + + if (mshrIt->requestList.empty()) + { + mshrQueue.erase(mshrIt); + + if (endRequestPending != nullptr && hasBufferSpace()) + { + payloadEventQueue.notify(*endRequestPending, BEGIN_REQ, SC_ZERO_TIME); + endRequestPending = nullptr; + } + } + } + else + { + SC_REPORT_FATAL("Cache", "PEQ was triggered with unknown phase"); + } +} + +/// Handler for begin request from core side. +void Cache::fetchLineAndSendEndRequest(tlm_generic_payload &trans) +{ + if (hasBufferSpace()) + { + index_t index; + tag_t tag; + std::tie(index, tag, std::ignore) = decodeAddress(trans.get_address()); + + auto mshrEntry = + std::find_if(mshrQueue.begin(), mshrQueue.end(), + [index, tag](const Mshr &entry) { return (index == entry.index) && (tag == entry.tag); }); + + if (isHit(index, tag)) + { + numberOfHits++; + + // Handle hit + // Account for the 1 cycle accept delay. + payloadEventQueue.notify(trans, HIT_HANDLING, hitLatency + cycleTime); + } + else if (mshrEntry != mshrQueue.end()) // Miss with outstanding previous Miss, noted in MSHR + { + numberOfSecondaryMisses++; + assert(isAllocated(index, tag)); + + // A fetch for this cache line is already in progress + // Add request to the existing Mshr entry + + if (mshrEntry->requestList.size() == maxTargetListSize) + { + // Insertion into requestList in mshrEntry not possible. + endRequestPending = &trans; + return; + } + + mshrEntry->requestList.emplace_back(&trans); + } + else // Miss without MSHR entry: + { + numberOfPrimaryMisses++; + assert(!isAllocated(index, tag)); + + // Cache miss and no fetch in progress. + // So evict line and allocate empty line. + auto evictedLine = evictLine(index); + if (!evictedLine) + { + // Line eviction not possible. + endRequestPending = &trans; + return; + } + + allocateLine(evictedLine, tag); + mshrQueue.emplace_back(index, tag, &trans); + + processMshrQueue(); + processWriteBuffer(); + } + + tlm_phase bwPhase = END_REQ; + sc_time bwDelay = SC_ZERO_TIME; + tSocket->nb_transport_bw(trans, bwPhase, bwDelay); + } + else + { + endRequestPending = &trans; + } +} + +/// Handler for end request from DRAM side. +void Cache::clearInitiatorBackpressureAndProcessBuffers() +{ + requestInProgress = nullptr; + + processMshrQueue(); + processWriteBuffer(); +} + +/// Handler for begin response from DRAM side. +void Cache::sendEndResponseAndFillLine(tlm_generic_payload &trans) +{ + tlm_phase fwPhase = END_RESP; + sc_time fwDelay = SC_ZERO_TIME; + iSocket->nb_transport_fw(trans, fwPhase, fwDelay); + + if (trans.is_read()) + { + fillLine(trans); + processMshrResponse(); + } + + trans.release(); +} + +/// Handler for end response from core side. +void Cache::clearTargetBackpressureAndProcessLines(tlm_generic_payload &trans) +{ + trans.release(); + tSocketBackpressure = false; + + processHitQueue(); + processMshrResponse(); + + // When the cache currently only handles hits from the hit queue and + // no other requests to the DRAM side are pending, there is a chance + // that a endRequestPending will never be served. + // To circumvent this, pass it into the system again at this point. + if (endRequestPending != nullptr && hasBufferSpace()) + { + payloadEventQueue.notify(*endRequestPending, BEGIN_REQ, SC_ZERO_TIME); + endRequestPending = nullptr; + } +} + +unsigned int Cache::transport_dbg(tlm_generic_payload &trans) +{ + return iSocket->transport_dbg(trans); +} + +bool Cache::isHit(index_t index, tag_t tag) const +{ + return std::find_if(lineTable[index].begin(), lineTable[index].end(), + [tag](const CacheLine &cacheLine) + { return (cacheLine.tag == tag) && cacheLine.valid; }) != lineTable[index].end(); +} + +bool Cache::isHit(uint64_t address) const +{ + index_t index; + tag_t tag; + std::tie(index, tag, std::ignore) = decodeAddress(address); + + return isHit(index, tag); +} + +std::tuple Cache::decodeAddress(uint64_t address) const +{ + return {(address >> indexShifts) & indexMask, address >> tagShifts, address % lineSize}; +} + +uint64_t Cache::encodeAddress(Cache::index_t index, Cache::tag_t tag, Cache::lineOffset_t lineOffset) const +{ + return static_cast(tag << tagShifts) | index << indexShifts | lineOffset; +} + +/// Write data to an available cache line, update flags +void Cache::writeLine( + index_t index, tag_t tag, lineOffset_t lineOffset, unsigned int dataLength, const unsigned char *dataPtr) +{ + // SC_REPORT_ERROR("cache", "Write to Cache not allowed!"); + + CacheLine ¤tLine = *std::find_if(lineTable[index].begin(), lineTable[index].end(), + [tag](const CacheLine &cacheLine) { return cacheLine.tag == tag; }); + + assert(currentLine.valid); + currentLine.lastAccessTime = sc_time_stamp(); + currentLine.dirty = true; + + if (storageEnabled) + std::copy(dataPtr, dataPtr + dataLength, currentLine.dataPtr + lineOffset); +} + +/// Read data from an available cache line, update flags +void Cache::readLine(index_t index, tag_t tag, lineOffset_t lineOffset, unsigned int dataLength, unsigned char *dataPtr) +{ + CacheLine ¤tLine = *std::find_if(lineTable[index].begin(), lineTable[index].end(), + [tag](const CacheLine &cacheLine) { return cacheLine.tag == tag; }); + + assert(currentLine.valid); + currentLine.lastAccessTime = sc_time_stamp(); + + if (storageEnabled) + std::copy(currentLine.dataPtr + lineOffset, currentLine.dataPtr + lineOffset + dataLength, dataPtr); +} + +/// Tries to evict oldest line (insert into write memory) +/// Returns the line or a nullptr if not possible +Cache::CacheLine *Cache::evictLine(Cache::index_t index) +{ + CacheLine &oldestLine = *std::min_element(lineTable[index].begin(), lineTable[index].end(), + [](const CacheLine &lhs, const CacheLine &rhs) + { return lhs.lastAccessTime < rhs.lastAccessTime; }); + + if (oldestLine.allocated && !oldestLine.valid) + { + // oldestline is allocated but not yet valid -> fetch in progress + return nullptr; + } + else if (std::find_if(mshrQueue.begin(), mshrQueue.end(), + [index, oldestLine](const Mshr &entry) + { return (index == entry.index) && (oldestLine.tag == entry.tag); }) != mshrQueue.end()) + { + // TODO: solve this in a more clever way + // There are still entries in mshrQueue to the oldest line -> do not evict it + return nullptr; + } + else if (std::find_if(hitQueue.begin(), hitQueue.end(), + [index, oldestLine](const BufferEntry &entry) + { return (index == entry.index) && (oldestLine.tag == entry.tag); }) != hitQueue.end()) + { + // TODO: solve this in a more clever way + // There are still hits in hitQueue to the oldest line -> do not evict it + return nullptr; + } + else + { + if (oldestLine.valid && oldestLine.dirty) + { + auto &wbTrans = memoryManager.allocate(lineSize); + wbTrans.acquire(); + wbTrans.set_address(encodeAddress(index, oldestLine.tag)); + wbTrans.set_write(); + wbTrans.set_data_length(lineSize); + wbTrans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + + if (storageEnabled) + std::copy(oldestLine.dataPtr, oldestLine.dataPtr + lineSize, wbTrans.get_data_ptr()); + + writeBuffer.emplace_back(index, oldestLine.tag, &wbTrans); + } + + oldestLine.allocated = false; + oldestLine.valid = false; + oldestLine.dirty = false; + + return &oldestLine; + } +} + +/// Align address to cache line size +uint64_t Cache::getAlignedAddress(uint64_t address) const +{ + return address - (address % lineSize); +} + +/// Issue read requests for entries in the MshrQueue to the target +void Cache::processMshrQueue() +{ + if (!requestInProgress && !mshrQueue.empty()) + { + // Get the first entry that wasn't already issued to the target + auto mshrIt = std::find_if(mshrQueue.begin(), mshrQueue.end(), [](const Mshr &entry) { return !entry.issued; }); + + if (mshrIt == mshrQueue.end()) + return; + + // Note: This is the same address for all entries in the requests list + uint64_t alignedAddress = getAlignedAddress(mshrIt->requestList.front()->get_address()); + + index_t index; + tag_t tag; + std::tie(index, tag, std::ignore) = decodeAddress(alignedAddress); + + // Search through the writeBuffer in reverse order to get the most recent entry. + auto writeBufferEntry = std::find_if(writeBuffer.rbegin(), writeBuffer.rbegin(), + [index, tag](const BufferEntry &entry) + { return (index == entry.index) && (tag == entry.tag); }); + + if (writeBufferEntry != writeBuffer.rbegin()) + { + // There is an entry for the required line in the write buffer. + // Snoop into it and get the data from there instead of the dram. + mshrIt->issued = true; + clearInitiatorBackpressureAndProcessBuffers(); + + fillLine(*writeBufferEntry->trans); + processMshrResponse(); + + return; + } + + // Prevents that the cache line will get fetched multiple times from the target + mshrIt->issued = true; + + auto &fetchTrans = memoryManager.allocate(lineSize); + fetchTrans.acquire(); + fetchTrans.set_read(); + fetchTrans.set_data_length(lineSize); + fetchTrans.set_streaming_width(lineSize); + fetchTrans.set_address(alignedAddress); + fetchTrans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + + tlm_phase fwPhase = BEGIN_REQ; + + // Always account for the cycle as either we just received the BEGIN_REQ + // or we cleared the backpressure from another END_REQ. + sc_time fwDelay = cycleTime; + + requestInProgress = &fetchTrans; + tlm_sync_enum returnValue = iSocket->nb_transport_fw(fetchTrans, fwPhase, fwDelay); + + if (returnValue == tlm::TLM_UPDATED) + { + // END_REQ or BEGIN_RESP + payloadEventQueue.notify(fetchTrans, fwPhase, fwDelay); + } + else if (returnValue == tlm::TLM_COMPLETED) + { + clearInitiatorBackpressureAndProcessBuffers(); + + fillLine(fetchTrans); + processMshrResponse(); + + fetchTrans.release(); + } + + if (endRequestPending != nullptr && hasBufferSpace()) + { + payloadEventQueue.notify(*endRequestPending, BEGIN_REQ, SC_ZERO_TIME); + endRequestPending = nullptr; + } + } +} + +/// Processes writeBuffer (dirty cache line evictions) +void Cache::processWriteBuffer() +{ + if (!requestInProgress && !writeBuffer.empty()) + { + tlm_generic_payload &wbTrans = *writeBuffer.front().trans; + + tlm_phase fwPhase = BEGIN_REQ; + sc_time fwDelay = (lastEndReq == sc_time_stamp()) ? cycleTime : SC_ZERO_TIME; + + requestInProgress = &wbTrans; + tlm_sync_enum returnValue = iSocket->nb_transport_fw(wbTrans, fwPhase, fwDelay); + + if (returnValue == tlm::TLM_UPDATED) + { + // END_REQ or BEGIN_RESP + payloadEventQueue.notify(wbTrans, fwPhase, fwDelay); + } + else if (returnValue == tlm::TLM_COMPLETED) + { + clearInitiatorBackpressureAndProcessBuffers(); + wbTrans.release(); + } + + if (endRequestPending != nullptr && hasBufferSpace()) + { + payloadEventQueue.notify(*endRequestPending, BEGIN_REQ, SC_ZERO_TIME); + endRequestPending = nullptr; + } + + writeBuffer.pop_front(); + } +} + +/// Fill allocated cache line with data from memory +void Cache::fillLine(tlm_generic_payload &trans) +{ + index_t index; + tag_t tag; + std::tie(index, tag, std::ignore) = decodeAddress(trans.get_address()); + + CacheLine &allocatedLine = + *std::find_if(lineTable[index].begin(), lineTable[index].end(), + [tag](const CacheLine &cacheLine) { return cacheLine.allocated && cacheLine.tag == tag; }); + + allocatedLine.valid = true; + allocatedLine.dirty = false; + + if (storageEnabled) + std::copy(trans.get_data_ptr(), trans.get_data_ptr() + lineSize, allocatedLine.dataPtr); +} + +/// Make cache access for pending hits +void Cache::processHitQueue() +{ + if (!tSocketBackpressure && !hitQueue.empty()) + { + auto hit = hitQueue.front(); + hitQueue.pop_front(); + + accessCacheAndSendResponse(*hit.trans); + } +} + +/// Access the available cache line and send the response +void Cache::accessCacheAndSendResponse(tlm_generic_payload &trans) +{ + assert(!tSocketBackpressure); + assert(isHit(trans.get_address())); + + auto [index, tag, lineOffset] = decodeAddress(trans.get_address()); + + if (trans.is_read()) + readLine(index, tag, lineOffset, trans.get_data_length(), trans.get_data_ptr()); + else + writeLine(index, tag, lineOffset, trans.get_data_length(), trans.get_data_ptr()); + + tlm_phase bwPhase = BEGIN_RESP; + sc_time bwDelay = SC_ZERO_TIME; + + trans.set_response_status(tlm::TLM_OK_RESPONSE); + + tlm_sync_enum returnValue = tSocket->nb_transport_bw(trans, bwPhase, bwDelay); + if (returnValue == tlm::TLM_UPDATED) // TODO tlm_completed + payloadEventQueue.notify(trans, bwPhase, bwDelay); + + tSocketBackpressure = true; +} + +/// Allocates an empty line for later filling (lastAccessTime = sc_max_time()) +void Cache::allocateLine(CacheLine *line, tag_t tag) +{ + line->allocated = true; + line->tag = tag; + line->lastAccessTime = sc_max_time(); +} + +/// Checks whether a line with the corresponding tag is already allocated (fetch in progress or already valid) +bool Cache::isAllocated(Cache::index_t index, Cache::tag_t tag) const +{ + return std::find_if(lineTable[index].begin(), lineTable[index].end(), + [tag](const CacheLine &cacheLine) + { return (cacheLine.tag == tag) && cacheLine.allocated; }) != lineTable[index].end(); +} + +/// Process oldest hit in mshrQueue, accept pending request from initiator +void Cache::processMshrResponse() +{ + if (!tSocketBackpressure) // TODO: Bedingung eigentlich zu streng, wenn man Hit delay berücksichtigt. + { + const auto hitIt = std::find_if(mshrQueue.begin(), mshrQueue.end(), + [this](const Mshr &entry) { return isHit(entry.index, entry.tag); }); + + // In case there are hits in mshrActive, handle them. Otherwise try again later. + if (hitIt == mshrQueue.end()) + return; + + // Another MSHR target already started the modeling of the hit delay. + // Try again later. + if (hitIt->hitDelayStarted && !hitIt->hitDelayAccounted) + return; + + // Get the first request in the list and respond to it + tlm_generic_payload &returnTrans = *hitIt->requestList.front(); + hitIt->requestList.pop_front(); + + if (hitIt->hitDelayAccounted) + accessCacheAndSendResponse(returnTrans); + else + { + hitIt->hitDelayStarted = true; + payloadEventQueue.notify(returnTrans, MISS_HANDLING, hitLatency + sc_time(1, SC_NS)); + return; + } + + if (hitIt->requestList.empty()) + { + mshrQueue.erase(hitIt); + + if (endRequestPending != nullptr && hasBufferSpace()) + { + payloadEventQueue.notify(*endRequestPending, BEGIN_REQ, SC_ZERO_TIME); + endRequestPending = nullptr; + } + } + } +} + +/// Checks whether both mshrActive and writeBuffer have memory space +bool Cache::hasBufferSpace() const +{ + return mshrQueue.size() < mshrDepth && writeBuffer.size() < writeBufferDepth; +} + +sc_time Cache::ceilTime(const sc_time &inTime) const +{ + return std::ceil(inTime / cycleTime) * cycleTime; +} + +sc_time Cache::ceilDelay(const sc_time &inDelay) const +{ + sc_time inTime = sc_time_stamp() + inDelay; + sc_time outTime = ceilTime(inTime); + sc_time outDelay = outTime - sc_time_stamp(); + return outDelay; +} diff --git a/src/simulator/simulator/Cache.h b/src/simulator/simulator/Cache.h new file mode 100644 index 00000000..7dd9ff5b --- /dev/null +++ b/src/simulator/simulator/Cache.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2022, 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: + * Christian Malek + * Derek Christ + */ + +#pragma once + +#include "MemoryManager.h" + +#include +#include +#include +#include +#include +#include +#include + +class Cache : public sc_core::sc_module +{ +public: + tlm_utils::simple_initiator_socket iSocket; + tlm_utils::simple_target_socket tSocket; + + Cache(const sc_core::sc_module_name &name, + std::size_t size, + std::size_t associativity, + std::size_t lineSize, + std::size_t mshrDepth, + std::size_t writeBufferDepth, + std::size_t maxTargetListSize, + bool storageEnabled, + sc_core::sc_time cycleTime, + std::size_t hitCycles); + SC_HAS_PROCESS(Cache); + +private: + void peqCallback(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase); + + tlm::tlm_sync_enum + nb_transport_fw(tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, sc_core::sc_time &fwDelay); + tlm::tlm_sync_enum + nb_transport_bw(tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, sc_core::sc_time &bwDelay); + unsigned int transport_dbg(tlm::tlm_generic_payload &trans); + + void fetchLineAndSendEndRequest(tlm::tlm_generic_payload &trans); + void clearInitiatorBackpressureAndProcessBuffers(); + void sendEndResponseAndFillLine(tlm::tlm_generic_payload &trans); + void clearTargetBackpressureAndProcessLines(tlm::tlm_generic_payload &trans); + + tlm_utils::peq_with_cb_and_phase payloadEventQueue; + + const bool storageEnabled; + sc_core::sc_time cycleTime; + const sc_core::sc_time hitLatency; + const std::size_t size; + + // Lines per set. + const std::size_t associativity; + + const std::size_t lineSize; + const std::size_t numberOfSets; + const std::size_t indexShifts; + const std::size_t indexMask; + const std::size_t tagShifts; + + const std::size_t mshrDepth; + const std::size_t writeBufferDepth; + const std::size_t maxTargetListSize; + + using index_t = std::uint64_t; + using tag_t = std::uint64_t; + using lineOffset_t = std::uint64_t; + + struct CacheLine + { + tag_t tag = 0; + unsigned char *dataPtr = nullptr; + bool allocated = false; + bool valid = false; + bool dirty = false; + sc_core::sc_time lastAccessTime = sc_core::SC_ZERO_TIME; + }; + + std::vector> lineTable; + std::vector dataMemory; + + bool isHit(index_t index, tag_t tag) const; + bool isHit(std::uint64_t address) const; + void + writeLine(index_t index, tag_t tag, lineOffset_t lineOffset, unsigned int dataLength, const unsigned char *dataPtr); + void readLine(index_t index, tag_t tag, lineOffset_t lineOffset, unsigned int dataLength, unsigned char *dataPtr); + + CacheLine *evictLine(index_t index); + + std::tuple decodeAddress(std::uint64_t address) const; + std::uint64_t encodeAddress(index_t index, tag_t tag, lineOffset_t lineOffset = 0) const; + + struct BufferEntry + { + index_t index; + tag_t tag; + tlm::tlm_generic_payload *trans; + + BufferEntry(index_t index, tag_t tag, tlm::tlm_generic_payload *trans) : index(index), tag(tag), trans(trans) {} + }; + + struct Mshr + { + index_t index; + tag_t tag; + std::list requestList; + + /// Whether the Mshr entry was already issued to the target. + bool issued = false; + + /// Whether the hit delay was already accounted for. + /// Used to determine if the next entry in the request list + /// should be sent out without the hit delay. + bool hitDelayAccounted = false; + + /// Whether the hit delay is being awaited on. + /// Used prevent other MSHR targets to wait on the hit + /// delay when it is already being waited on. + bool hitDelayStarted = false; + + Mshr(index_t index, tag_t tag, tlm::tlm_generic_payload *request) : index(index), tag(tag), requestList{request} + { + } + }; + + std::deque mshrQueue; + std::deque hitQueue; + + using writeBuffer_t = std::list; + writeBuffer_t writeBuffer; + + uint64_t numberOfHits = 0; + uint64_t numberOfPrimaryMisses = 0; + uint64_t numberOfSecondaryMisses = 0; + + std::uint64_t getAlignedAddress(std::uint64_t address) const; + + void processMshrResponse(); + void processWriteBuffer(); + void processHitQueue(); + void processMshrQueue(); + + bool tSocketBackpressure = false; + + // Request to the target + tlm::tlm_generic_payload *requestInProgress = nullptr; + + // Backpressure on initiator + tlm::tlm_generic_payload *endRequestPending = nullptr; + + sc_core::sc_time lastEndReq = sc_core::sc_max_time(); + + void fillLine(tlm::tlm_generic_payload &trans); + void accessCacheAndSendResponse(tlm::tlm_generic_payload &trans); + void allocateLine(CacheLine *line, tag_t tag); + + bool isAllocated(index_t index, tag_t tag) const; + bool hasBufferSpace() const; + + sc_core::sc_time ceilTime(const sc_core::sc_time &inTime) const; + sc_core::sc_time ceilDelay(const sc_core::sc_time &inDelay) const; + + MemoryManager memoryManager; +}; diff --git a/src/simulator/simulator/player/DbiPlayer.h b/src/simulator/simulator/player/DbiPlayer.h new file mode 100644 index 00000000..2eedeeb7 --- /dev/null +++ b/src/simulator/simulator/player/DbiPlayer.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022, 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: + * Lukas Steiner + * Derek Christ + */ + +#pragma once + +#include "request/Request.h" +#include "request/RequestProducer.h" + +class DbiProducer : public RequestProducer +{ + Request nextRequest() override {} + uint64_t totalRequests() override {} + sc_core::sc_time clkPeriod() override {} +}; diff --git a/tests/tests_configuration/CMakeLists.txt b/tests/tests_configuration/CMakeLists.txt index 97ddf6c8..baab76cc 100644 --- a/tests/tests_configuration/CMakeLists.txt +++ b/tests/tests_configuration/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.1.0) -project(test_configuration) +project(tests_configuration) add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/test_configuration.cpp) From a4fe32703cf2b7f659d7b5f5a78d8c70e270a4ac Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Fri, 27 Jan 2023 12:08:51 +0100 Subject: [PATCH 05/20] Set up testing infrastructure for Cache --- src/simulator/CMakeLists.txt | 21 +- src/simulator/{simulator => }/main.cpp | 14 +- src/simulator/simulator/Cache.cpp | 7 +- src/simulator/simulator/Cache.h | 5 +- src/simulator/simulator/EccModule.cpp | 313 ++++++++++++++++++ src/simulator/simulator/EccModule.h | 107 ++++++ tests/CMakeLists.txt | 1 + tests/tests_simulator/CMakeLists.txt | 27 ++ tests/tests_simulator/cache/ListInitiator.cpp | 189 +++++++++++ tests/tests_simulator/cache/ListInitiator.h | 104 ++++++ tests/tests_simulator/cache/TargetMemory.cpp | 231 +++++++++++++ tests/tests_simulator/cache/TargetMemory.h | 83 +++++ tests/tests_simulator/cache/tests_cache.cpp | 93 ++++++ tests/tests_simulator/main.cpp | 43 +++ 14 files changed, 1221 insertions(+), 17 deletions(-) rename src/simulator/{simulator => }/main.cpp (96%) create mode 100644 src/simulator/simulator/EccModule.cpp create mode 100644 src/simulator/simulator/EccModule.h create mode 100644 tests/tests_simulator/CMakeLists.txt create mode 100644 tests/tests_simulator/cache/ListInitiator.cpp create mode 100644 tests/tests_simulator/cache/ListInitiator.h create mode 100644 tests/tests_simulator/cache/TargetMemory.cpp create mode 100644 tests/tests_simulator/cache/TargetMemory.h create mode 100644 tests/tests_simulator/cache/tests_cache.cpp create mode 100644 tests/tests_simulator/main.cpp diff --git a/src/simulator/CMakeLists.txt b/src/simulator/CMakeLists.txt index bae5c739..2db1df94 100644 --- a/src/simulator/CMakeLists.txt +++ b/src/simulator/CMakeLists.txt @@ -43,14 +43,25 @@ project(DRAMSys_Simulator) file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS *.cpp) file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS *.h;*.hpp) -add_executable(DRAMSys ${SOURCE_FILES} ${HEADER_FILES}) -target_include_directories(DRAMSys PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +list(FILTER SOURCE_FILES EXCLUDE REGEX "main.cpp") + +add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES} ${HEADER_FILES}) + +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +target_link_libraries(${PROJECT_NAME} + PUBLIC + Threads::Threads + DRAMSys::libdramsys +) + +add_executable(DRAMSys + main.cpp +) target_link_libraries(DRAMSys PRIVATE - Threads::Threads - SystemC::systemc - DRAMSys::libdramsys + DRAMSys_Simulator ) build_source_group() diff --git a/src/simulator/simulator/main.cpp b/src/simulator/main.cpp similarity index 96% rename from src/simulator/simulator/main.cpp rename to src/simulator/main.cpp index 4c986102..06c26503 100644 --- a/src/simulator/simulator/main.cpp +++ b/src/simulator/main.cpp @@ -33,13 +33,13 @@ * Derek Christ */ -#include "Initiator.h" -#include "MemoryManager.h" -#include "SimpleInitiator.h" -#include "generator/TrafficGenerator.h" -#include "hammer/RowHammer.h" -#include "player/StlPlayer.h" -#include "util.h" +#include "simulator/Initiator.h" +#include "simulator/MemoryManager.h" +#include "simulator/SimpleInitiator.h" +#include "simulator/generator/TrafficGenerator.h" +#include "simulator/hammer/RowHammer.h" +#include "simulator/player/StlPlayer.h" +#include "simulator/util.h" #include diff --git a/src/simulator/simulator/Cache.cpp b/src/simulator/simulator/Cache.cpp index 96ff8868..06739cfe 100644 --- a/src/simulator/simulator/Cache.cpp +++ b/src/simulator/simulator/Cache.cpp @@ -23,7 +23,8 @@ Cache::Cache(const sc_module_name &name, std::size_t maxTargetListSize, bool storageEnabled, sc_core::sc_time cycleTime, - std::size_t hitCycles) : + std::size_t hitCycles, + MemoryManager &memoryManager) : sc_module(name), payloadEventQueue(this, &Cache::peqCallback), storageEnabled(storageEnabled), @@ -39,7 +40,7 @@ Cache::Cache(const sc_module_name &name, mshrDepth(mshrDepth), writeBufferDepth(writeBufferDepth), maxTargetListSize(maxTargetListSize), - memoryManager(storageEnabled) + memoryManager(memoryManager) { iSocket.register_nb_transport_bw(this, &Cache::nb_transport_bw); tSocket.register_nb_transport_fw(this, &Cache::nb_transport_fw); @@ -601,7 +602,7 @@ void Cache::processMshrResponse() else { hitIt->hitDelayStarted = true; - payloadEventQueue.notify(returnTrans, MISS_HANDLING, hitLatency + sc_time(1, SC_NS)); + payloadEventQueue.notify(returnTrans, MISS_HANDLING, hitLatency); return; } diff --git a/src/simulator/simulator/Cache.h b/src/simulator/simulator/Cache.h index 7dd9ff5b..0e64bf67 100644 --- a/src/simulator/simulator/Cache.h +++ b/src/simulator/simulator/Cache.h @@ -61,7 +61,8 @@ public: std::size_t maxTargetListSize, bool storageEnabled, sc_core::sc_time cycleTime, - std::size_t hitCycles); + std::size_t hitCycles, + MemoryManager &memoryManager); SC_HAS_PROCESS(Cache); private: @@ -196,5 +197,5 @@ private: sc_core::sc_time ceilTime(const sc_core::sc_time &inTime) const; sc_core::sc_time ceilDelay(const sc_core::sc_time &inDelay) const; - MemoryManager memoryManager; + MemoryManager &memoryManager; }; diff --git a/src/simulator/simulator/EccModule.cpp b/src/simulator/simulator/EccModule.cpp new file mode 100644 index 00000000..6b3caa4f --- /dev/null +++ b/src/simulator/simulator/EccModule.cpp @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2022, 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: + * Christian Malek + * Derek Christ + */ + +#include "EccModule.h" + +#include "DRAMSys/common/dramExtensions.h" + +#include + +using namespace sc_core; +using namespace tlm; + +EccModule::EccModule(sc_module_name name, AddressDecoder const &addressDecoder) : + sc_core::sc_module(name), + payloadEventQueue(this, &EccModule::peqCallback), + addressDecoder(addressDecoder), + memoryManager(false) +{ + iSocket.register_nb_transport_bw(this, &EccModule::nb_transport_bw); + tSocket.register_nb_transport_fw(this, &EccModule::nb_transport_fw); +} + +tlm::tlm_sync_enum EccModule::nb_transport_fw(tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &fwDelay) +{ + if (phase == BEGIN_REQ) + { + payload.acquire(); + } + + payloadEventQueue.notify(payload, phase, fwDelay); + return TLM_ACCEPTED; +} + +tlm::tlm_sync_enum EccModule::nb_transport_bw(tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &bwDelay) +{ + payloadEventQueue.notify(payload, phase, bwDelay); + return TLM_ACCEPTED; +} + +void EccModule::peqCallback(tlm::tlm_generic_payload &cbPayload, const tlm::tlm_phase &cbPhase) +{ + if (cbPhase == BEGIN_REQ) // from initiator + { + // Put transaction into latency map + payloadMap.emplace(&cbPayload, sc_time_stamp()); + + if (!targetBusy) + { + targetBusy = true; + + tlm_phase tPhase = BEGIN_REQ; + sc_time tDelay = SC_ZERO_TIME; + + DecodedAddress decodedAddress = addressDecoder.decodeAddress(cbPayload.get_address()); + decodedAddress = calculateOffsetAddress(decodedAddress); + + // Update the original address to account for the offsets + cbPayload.set_address(addressDecoder.encodeAddress(decodedAddress)); + + auto currentBlock = alignToBlock(decodedAddress.column); + + // In case there is no entry yet. + activeEccBlocks.try_emplace(decodedAddress.bank); + +#ifdef ECC_ENABLE + if (!activeEccBlock(decodedAddress.bank, decodedAddress.row, currentBlock)) + { + blockedRequest = &cbPayload; + + auto &eccFifo = activeEccBlocks[decodedAddress.bank]; + eccFifo.push_back({currentBlock, decodedAddress.row}); + + // Only hold 4 elements at max. + if (eccFifo.size() >= 4) + eccFifo.pop_front(); + + tlm::tlm_generic_payload *eccPayload = generateEccPayload(decodedAddress); + + iSocket->nb_transport_fw(*eccPayload, tPhase, tDelay); + } + else +#endif + { + iSocket->nb_transport_fw(cbPayload, tPhase, tDelay); + } + } + else + { + pendingRequest = &cbPayload; + } + } + else if (cbPhase == END_REQ) // from target + { + // Send payload to inititator in case it is not an ECC transaction + if (cbPayload.get_extension() == nullptr) + { + tlm_phase tPhase = END_REQ; + sc_time tDelay = SC_ZERO_TIME; + + tSocket->nb_transport_bw(cbPayload, tPhase, tDelay); + } + + if (blockedRequest != nullptr) + { + tlm_generic_payload &tPayload = *blockedRequest; + blockedRequest = nullptr; + + tlm_phase tPhase = BEGIN_REQ; + sc_time tDelay = SC_ZERO_TIME; + + iSocket->nb_transport_fw(tPayload, tPhase, tDelay); + + // Do not attempt to send another pending request and hold targetBusy high + return; + } + + if (pendingRequest != nullptr) + { + tlm_generic_payload &tPayload = *pendingRequest; + + tlm_phase tPhase = BEGIN_REQ; + sc_time tDelay = SC_ZERO_TIME; + + DecodedAddress decodedAddress = addressDecoder.decodeAddress(tPayload.get_address()); + decodedAddress = calculateOffsetAddress(decodedAddress); + auto currentBlock = alignToBlock(decodedAddress.column); +#ifdef ECC_ENABLE + if (!activeEccBlock(decodedAddress.bank, decodedAddress.row, currentBlock)) + { + blockedRequest = pendingRequest; + pendingRequest = nullptr; + + auto &eccFifo = activeEccBlocks[decodedAddress.bank]; + eccFifo.push_back({currentBlock, decodedAddress.row}); + + // Only hold 4 elements at max. + if (eccFifo.size() >= 4) + eccFifo.pop_front(); + + tlm::tlm_generic_payload *eccPayload = generateEccPayload(decodedAddress); + + iSocket->nb_transport_fw(*eccPayload, tPhase, tDelay); + } + else +#endif + { + iSocket->nb_transport_fw(tPayload, tPhase, tDelay); + pendingRequest = nullptr; + } + } + else + { + assert(!pendingRequest); + assert(!blockedRequest); + targetBusy = false; + } + } + else if (cbPhase == BEGIN_RESP) // from memory controller + { + // Send payload to inititator in case it is not an ECC transaction + if (cbPayload.get_extension() == nullptr) + { + tlm_phase tPhase = BEGIN_RESP; + sc_time tDelay = SC_ZERO_TIME; + + tlm_sync_enum returnValue = tSocket->nb_transport_bw(cbPayload, tPhase, tDelay); + + // Early completion from initiator + if (returnValue == TLM_UPDATED) + { + payloadEventQueue.notify(cbPayload, tPhase, tDelay); + } + + Latency latency = sc_time_stamp() - payloadMap.at(&cbPayload); + payloadMap.erase(&cbPayload); + + latency = roundLatency(latency); + latencyMap.try_emplace(latency, 0); + latencyMap.at(latency)++; + } + else + { + // Send END_RESP by ourselfes + tlm_phase tPhase = END_RESP; + sc_time tDelay = SC_ZERO_TIME; + + iSocket->nb_transport_fw(cbPayload, tPhase, tDelay); + } + } + else if (cbPhase == END_RESP) // from initiator + { + { + tlm_phase tPhase = END_RESP; + sc_time tDelay = SC_ZERO_TIME; + + iSocket->nb_transport_fw(cbPayload, tPhase, tDelay); + } + + cbPayload.release(); + } + else + { + SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase"); + } +} + +tlm::tlm_generic_payload *EccModule::generateEccPayload(DecodedAddress decodedAddress) +{ + unsigned int eccAtom = decodedAddress.column / 512; + uint64_t eccColumn = 1792 + eccAtom * 32; + + decodedAddress.column = eccColumn; + uint64_t eccAddress = addressDecoder.encodeAddress(decodedAddress); + + tlm_generic_payload &payload = memoryManager.allocate(32); + payload.acquire(); + payload.set_address(eccAddress); + payload.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + payload.set_dmi_allowed(false); + payload.set_byte_enable_length(0); + payload.set_data_length(32); + payload.set_streaming_width(32); + payload.set_command(tlm::TLM_READ_COMMAND); + payload.set_extension(new EccExtension); + + return &payload; +} + +unsigned int EccModule::alignToBlock(unsigned column) +{ + return column & ~(512 - 1); +} + +DecodedAddress EccModule::calculateOffsetAddress(DecodedAddress decodedAddress) +{ + unsigned int newRow = + std::floor((decodedAddress.row * 256 + decodedAddress.column) / 1792) + decodedAddress.row; + unsigned int newColumn = (decodedAddress.row * 256 + decodedAddress.column) % 1792; + + DecodedAddress offsetAddress(decodedAddress); + offsetAddress.row = newRow; + offsetAddress.column = newColumn; + return offsetAddress; +} + +void EccModule::end_of_simulation() +{ + uint64_t latencies = 0; + uint64_t numberOfLatencies = 0; + + for (auto const &[latency, occurences] : latencyMap) + { + latencies += (latency.to_double() / 1000.0) * occurences; + numberOfLatencies += occurences; + } + + std::cout << "Average latency: " << static_cast(latencies) / numberOfLatencies << std::endl; +} + +sc_time EccModule::roundLatency(sc_time latency) +{ + static const sc_time BUCKET_SIZE = sc_time(1, SC_NS); + latency += BUCKET_SIZE / 2; + latency = latency - (latency % BUCKET_SIZE); + return latency; +} + +bool EccModule::activeEccBlock(Bank bank, Row row, Block block) const +{ + auto eccIt = std::find_if(activeEccBlocks.at(bank).cbegin(), activeEccBlocks.at(bank).cend(), + [block, row](EccIdentifier identifier) { + return (identifier.first == block) && (identifier.second == row); + }); + + return eccIt != activeEccBlocks.at(bank).cend(); +} diff --git a/src/simulator/simulator/EccModule.h b/src/simulator/simulator/EccModule.h new file mode 100644 index 00000000..15817db3 --- /dev/null +++ b/src/simulator/simulator/EccModule.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2022, 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: + * Christian Malek + * Derek Christ + */ + +#ifndef ECCMODULE_H +#define ECCMODULE_H + +#include "simulator/MemoryManager.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +class EccModule : public sc_core::sc_module +{ +public: + tlm_utils::simple_initiator_socket iSocket; + tlm_utils::simple_target_socket tSocket; + + EccModule(sc_core::sc_module_name name, AddressDecoder const &addressDecoder); + SC_HAS_PROCESS(EccModule); + +private: + using Block = uint64_t; + using Row = uint64_t; + using Bank = unsigned int; + using EccIdentifier = std::pair; + using EccQueue = std::deque; + + static DecodedAddress calculateOffsetAddress(DecodedAddress decodedAddress); + static sc_core::sc_time roundLatency(sc_core::sc_time latency); + bool activeEccBlock(Bank bank, Row row, Block block) const; + + void end_of_simulation() override; + + void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); + + tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &fwDelay); + tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &bwDelay); + + tlm::tlm_generic_payload *generateEccPayload(DecodedAddress decodedAddress); + + static unsigned int alignToBlock(unsigned int column); + + tlm_utils::peq_with_cb_and_phase payloadEventQueue; + + tlm::tlm_generic_payload *pendingRequest = nullptr; + tlm::tlm_generic_payload *blockedRequest = nullptr; + bool targetBusy = false; + + const sc_core::sc_time tCK; + MemoryManager memoryManager; + AddressDecoder const &addressDecoder; + + std::unordered_map activeEccBlocks; + + using EccPayload = tlm::tlm_generic_payload *; + using StartTime = sc_core::sc_time; + std::unordered_map payloadMap; + + using Latency = sc_core::sc_time; + std::map latencyMap; +}; + +#endif // ECCMODULE_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4702149b..a89ad8d0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,3 +4,4 @@ add_subdirectory(tests_configuration) add_subdirectory(tests_dramsys) add_subdirectory(tests_regression) add_subdirectory(tests_util) +add_subdirectory(tests_simulator) diff --git a/tests/tests_simulator/CMakeLists.txt b/tests/tests_simulator/CMakeLists.txt new file mode 100644 index 00000000..0383d14b --- /dev/null +++ b/tests/tests_simulator/CMakeLists.txt @@ -0,0 +1,27 @@ +############################################### +### tests_simulator ### +############################################### + +cmake_minimum_required(VERSION 3.1.0) + +project(tests_simulator) + +add_executable(${PROJECT_NAME} + main.cpp + cache/tests_cache.cpp + cache/TargetMemory.cpp + cache/ListInitiator.cpp +) + +set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER tests/simulator) + +target_link_libraries(${PROJECT_NAME} PRIVATE + DRAMSys_Simulator + gtest_main +) + +gtest_discover_tests(${PROJECT_NAME} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + +build_source_group() diff --git a/tests/tests_simulator/cache/ListInitiator.cpp b/tests/tests_simulator/cache/ListInitiator.cpp new file mode 100644 index 00000000..a4e5906a --- /dev/null +++ b/tests/tests_simulator/cache/ListInitiator.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2023, 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 "ListInitiator.h" + +#include +#include +#include +#include +#include +#include +#include + +ListInitiator::ListInitiator(const sc_core::sc_module_name &name, MemoryManager &memoryManager) + : sc_core::sc_module(name), + iSocket("iSocket"), + peq(this, &ListInitiator::peqCallback), + memoryManager(memoryManager) +{ + iSocket.register_nb_transport_bw(this, &ListInitiator::nb_transport_bw); + SC_THREAD(process); +} + +void ListInitiator::process() +{ + for (auto &testTransactionData : testTransactionList) + { + wait(testTransactionData.startTime - sc_core::sc_time_stamp()); + + tlm::tlm_command command = + testTransactionData.command == TestTransactionData::Command::Write + ? tlm::TLM_WRITE_COMMAND + : tlm::TLM_READ_COMMAND; + + auto &trans = memoryManager.allocate(testTransactionData.dataLength); + trans.acquire(); + + TestExtension *ext = new TestExtension(testTransactionData); + trans.set_auto_extension(ext); + + trans.set_command(command); + trans.set_address(testTransactionData.address); + trans.set_data_length(testTransactionData.dataLength); + trans.set_streaming_width(testTransactionData.dataLength); + trans.set_byte_enable_ptr(nullptr); + trans.set_dmi_allowed(false); + trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + + if (trans.is_write()) + std::memcpy(trans.get_data_ptr(), &testTransactionData.data, testTransactionData.dataLength); + + if (requestInProgress != nullptr) + { + wait(endRequest); + } + + requestInProgress = &trans; + tlm::tlm_phase phase = tlm::BEGIN_REQ; + sc_core::sc_time delay = sc_core::SC_ZERO_TIME; + + std::cout << "\033[1;31m(" << name() << ")@" << std::setfill(' ') << std::setw(12) + << sc_core::sc_time_stamp() << ": " << std::setw(12) + << (command == tlm::TLM_WRITE_COMMAND ? "Write to " : "Read from ") + << "Addr = " << std::setfill('0') << std::setw(8) << std::dec + << testTransactionData.address << " Data = " + << "0x" << std::setfill('0') << std::setw(8) << std::hex + << testTransactionData.data << "(nb_transport) \033[0m" << std::endl; + + tlm::tlm_sync_enum status = iSocket->nb_transport_fw(trans, phase, delay); + + if (status == tlm::TLM_UPDATED) + { + peq.notify(trans, phase, delay); + } + else if (status == tlm::TLM_COMPLETED) + { + requestInProgress = nullptr; + checkTransaction(trans); + trans.release(); + } + } +} + +tlm::tlm_sync_enum ListInitiator::nb_transport_bw(tlm::tlm_generic_payload &trans, + tlm::tlm_phase &phase, + sc_core::sc_time &delay) +{ + peq.notify(trans, phase, delay); + return tlm::TLM_ACCEPTED; +} + +void ListInitiator::peqCallback(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase) +{ + if (phase == tlm::END_REQ || (&trans == requestInProgress && phase == tlm::BEGIN_RESP)) + { + requestInProgress = nullptr; + endRequest.notify(); + } + else if (phase == tlm::BEGIN_REQ || phase == tlm::END_RESP) + { + SC_REPORT_FATAL(name(), "Illegal transaction phase received"); + } + + if (phase == tlm::BEGIN_RESP) + { + checkTransaction(trans); + + tlm::tlm_phase fw_phase = tlm::END_RESP; + sc_core::sc_time delay = sc_core::sc_time(1, sc_core::SC_NS); + iSocket->nb_transport_fw(trans, fw_phase, delay); + + trans.release(); + } +} + +void ListInitiator::checkTransaction(tlm::tlm_generic_payload &trans) +{ + if (trans.is_response_error()) + { + SC_REPORT_ERROR(name(), "Transaction returned with error!"); + } + + tlm::tlm_command command = trans.get_command(); + + uint64_t transData{}; + + if (trans.get_data_length() == 1) + transData = *reinterpret_cast(trans.get_data_ptr()); + else if (trans.get_data_length() == 2) + transData = *reinterpret_cast(trans.get_data_ptr()); + else if (trans.get_data_length() == 4) + transData = *reinterpret_cast(trans.get_data_ptr()); + else if (trans.get_data_length() == 8) + transData = *reinterpret_cast(trans.get_data_ptr()); + + TestExtension *ext = nullptr; + trans.get_extension(ext); + TestTransactionData data = ext->getTestData(); + + std::cout << "\033[1;31m(" << name() << ")@" << std::setfill(' ') << std::setw(12) + << sc_core::sc_time_stamp() << ": " << std::setw(12) + << (command == tlm::TLM_WRITE_COMMAND ? "Check Write " : "Check Read ") + << "Addr = " << std::setfill('0') << std::setw(8) << std::dec << data.address + << " Data = " + << "0x" << std::setfill('0') << std::setw(8) << std::hex << transData << "\033[0m" + << std::endl; + + if (data.expectedEndTime != sc_core::sc_time_stamp()) + { + SC_REPORT_FATAL(name(), "NOT EXPECTED TIME"); + } + + if (trans.is_read() && data.data != transData) + { + SC_REPORT_FATAL(name(), "NOT EXPECTED DATA"); + } +} diff --git a/tests/tests_simulator/cache/ListInitiator.h b/tests/tests_simulator/cache/ListInitiator.h new file mode 100644 index 00000000..860975cd --- /dev/null +++ b/tests/tests_simulator/cache/ListInitiator.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2023, 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 "simulator/MemoryManager.h" + +#include +#include + +class ListInitiator : public sc_core::sc_module +{ +public: + tlm_utils::simple_initiator_socket iSocket; + + SC_HAS_PROCESS(ListInitiator); + ListInitiator(const sc_core::sc_module_name &name, MemoryManager &memoryManager); + + struct TestTransactionData + { + sc_core::sc_time startTime; + sc_core::sc_time expectedEndTime; + + enum class Command + { + Read, + Write, + } command; + + uint64_t address; + uint32_t dataLength; + uint64_t data; + }; + + void appendTestTransactionList(const std::vector &testTransactionList) + { + std::copy(testTransactionList.cbegin(), testTransactionList.cend(), std::back_inserter(this->testTransactionList)); + } + +private: + class TestExtension : public tlm::tlm_extension + { + public: + TestExtension(TestTransactionData data) : data(std::move(data)) {} + + tlm_extension_base *clone() const { return new TestExtension(data); } + + void copy_from(const tlm_extension_base &ext) + { + const TestExtension &cpyFrom = static_cast(ext); + data = cpyFrom.getTestData(); + } + + TestTransactionData getTestData() const { return data; } + + private: + TestTransactionData data; + }; + + void process(); + + tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &trans, + tlm::tlm_phase &phase, + sc_core::sc_time &delay); + void peqCallback(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase); + void checkTransaction(tlm::tlm_generic_payload &trans); + + std::vector testTransactionList; + + sc_core::sc_event endRequest; + tlm_utils::peq_with_cb_and_phase peq; + tlm::tlm_generic_payload *requestInProgress = nullptr; + MemoryManager &memoryManager; +}; diff --git a/tests/tests_simulator/cache/TargetMemory.cpp b/tests/tests_simulator/cache/TargetMemory.cpp new file mode 100644 index 00000000..bc1524a6 --- /dev/null +++ b/tests/tests_simulator/cache/TargetMemory.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2023, 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 "TargetMemory.h" + +#include +#include +#include +#include + +DECLARE_EXTENDED_PHASE(INTERNAL); + +TargetMemory::TargetMemory(const sc_core::sc_module_name &name, + sc_core::sc_time acceptDelay, + sc_core::sc_time memoryLatency, + std::size_t bufferSize) + : sc_core::sc_module(name), + tSocket("tSocket"), + bufferSize(bufferSize), + peq(this, &TargetMemory::peqCallback), + acceptDelay(acceptDelay), + memoryLatency(memoryLatency) +{ + tSocket.register_nb_transport_fw(this, &TargetMemory::nb_transport_fw); + + memory.reserve(SIZE); + std::fill(memory.begin(), memory.end(), 0); +} + +tlm::tlm_sync_enum TargetMemory::nb_transport_fw(tlm::tlm_generic_payload &trans, + tlm::tlm_phase &phase, + sc_core::sc_time &delay) +{ + peq.notify(trans, phase, delay); + return tlm::TLM_ACCEPTED; +} + +void TargetMemory::printBuffer(int max, int n) +{ + std::cout << "\033[1;35m(" << name() << ")@" << std::setfill(' ') << std::setw(12) + << sc_core::sc_time_stamp() << " Target Buffer: " + << "["; + for (int i = 0; i < n; i++) + { + std::cout << "█"; + } + for (int i = 0; i < max - n; i++) + { + std::cout << " "; + } + std::cout << "]" + << " (Max:" << max << ") " + << "\033[0m" << std::endl; + std::cout.flush(); +} + +void TargetMemory::peqCallback(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase) +{ + sc_core::sc_time delay; + + if (phase == tlm::BEGIN_REQ) + { + trans.acquire(); + + if (currentTransactions < bufferSize) + { + sendEndRequest(trans); + } + else + { + endRequestPending = &trans; + } + } + else if (phase == tlm::END_RESP) + { + if (!responseInProgress) + { + SC_REPORT_FATAL(name(), "Illegal transaction phase END_RESP received by target"); + } + + currentTransactions--; + printBuffer(bufferSize, currentTransactions); + + responseInProgress = false; + if (!responseQueue.empty()) + { + tlm::tlm_generic_payload *next = responseQueue.front(); + responseQueue.pop(); + sendResponse(*next); + } + + if (endRequestPending != nullptr) + { + sendEndRequest(*endRequestPending); + endRequestPending = nullptr; + } + } + else if (phase == INTERNAL) + { + executeTransaction(trans); + + if (responseInProgress) + { + responseQueue.push(&trans); + } + else + { + sendResponse(trans); + } + } + else // tlm::END_REQ or tlm::BEGIN_RESP + { + SC_REPORT_FATAL(name(), "Illegal transaction phase received"); + } +} + +void TargetMemory::sendEndRequest(tlm::tlm_generic_payload &trans) +{ + tlm::tlm_phase bw_phase; + sc_core::sc_time delay; + + // Queue the acceptance and the response with the appropriate latency + bw_phase = tlm::END_REQ; + delay = acceptDelay; + + tlm::tlm_sync_enum status = tSocket->nb_transport_bw(trans, bw_phase, delay); + + // Queue internal event to mark beginning of response + delay = delay + memoryLatency; // MEMORY Latency + peq.notify(trans, INTERNAL, delay); + + currentTransactions++; + printBuffer(bufferSize, currentTransactions); +} + +void TargetMemory::sendResponse(tlm::tlm_generic_payload &trans) +{ + sc_assert(responseInProgress == false); + + responseInProgress = true; + tlm::tlm_phase bw_phase = tlm::BEGIN_RESP; + sc_core::sc_time delay = sc_core::SC_ZERO_TIME; + tlm::tlm_sync_enum status = tSocket->nb_transport_bw(trans, bw_phase, delay); + + if (status == tlm::TLM_UPDATED) + { + peq.notify(trans, bw_phase, delay); + } + else if (status == tlm::TLM_COMPLETED) + { + SC_REPORT_FATAL(name(), "This transition is deprecated since TLM2.0.1"); + } + + trans.release(); +} + +void TargetMemory::executeTransaction(tlm::tlm_generic_payload &trans) +{ + tlm::tlm_command command = trans.get_command(); + sc_dt::uint64 address = trans.get_address(); + unsigned char *data_ptr = trans.get_data_ptr(); + unsigned int data_length = trans.get_data_length(); + unsigned char *byte_enable_ptr = trans.get_byte_enable_ptr(); + unsigned int streaming_width = trans.get_streaming_width(); + + if (address >= SIZE - 64) + { + trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE); + return; + } + if (byte_enable_ptr != nullptr) + { + trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE); + return; + } + if (data_length > 64 || streaming_width < data_length) + { + trans.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE); + return; + } + + if (command == tlm::TLM_READ_COMMAND) + { + std::memcpy(trans.get_data_ptr(), &memory[trans.get_address()], trans.get_data_length()); + } + else if (command == tlm::TLM_WRITE_COMMAND) + { + memcpy(&memory[trans.get_address()], trans.get_data_ptr(), trans.get_data_length()); + } + + std::cout << "\033[1;32m(" << name() << ")@" << std::setfill(' ') << std::setw(12) + << sc_core::sc_time_stamp() << ": " << std::setw(12) + << (command == tlm::TLM_WRITE_COMMAND ? "Exec. Write " : "Exec. Read ") + << "Addr = " << std::setfill('0') << std::setw(8) << std::dec << address << " Data = " + << "0x" << std::setfill('0') << std::setw(8) << std::hex + << *reinterpret_cast(data_ptr) << "\033[0m" << std::endl; + + trans.set_response_status(tlm::TLM_OK_RESPONSE); +} diff --git a/tests/tests_simulator/cache/TargetMemory.h b/tests/tests_simulator/cache/TargetMemory.h new file mode 100644 index 00000000..5ec280d5 --- /dev/null +++ b/tests/tests_simulator/cache/TargetMemory.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2023, 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 + */ + +#pragma once + +#include +#include +#include +#include + +#include + +class TargetMemory : public sc_core::sc_module +{ +public: + tlm_utils::simple_target_socket tSocket; + SC_HAS_PROCESS(TargetMemory); + TargetMemory(const sc_core::sc_module_name &name, + sc_core::sc_time acceptDelay, + sc_core::sc_time memoryLatency, + std::size_t bufferSize = DEFAULT_BUFFER_SIZE); + +private: + tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans, + tlm::tlm_phase &phase, + sc_core::sc_time &delay); + + void peqCallback(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase); + + void sendEndRequest(tlm::tlm_generic_payload &trans); + void sendResponse(tlm::tlm_generic_payload &trans); + void executeTransaction(tlm::tlm_generic_payload &trans); + + void printBuffer(int max, int n); + + static constexpr std::size_t SIZE = static_cast(64 * 1024); + static constexpr std::size_t DEFAULT_BUFFER_SIZE = 8; + const std::size_t bufferSize; + + const sc_core::sc_time acceptDelay; + const sc_core::sc_time memoryLatency; + + std::vector memory; + + unsigned int currentTransactions = 0; + bool responseInProgress = false; + tlm::tlm_generic_payload *endRequestPending = nullptr; + + tlm_utils::peq_with_cb_and_phase peq; + std::queue responseQueue; +}; diff --git a/tests/tests_simulator/cache/tests_cache.cpp b/tests/tests_simulator/cache/tests_cache.cpp new file mode 100644 index 00000000..c8da5576 --- /dev/null +++ b/tests/tests_simulator/cache/tests_cache.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2023, 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 "ListInitiator.h" +#include "TargetMemory.h" + +#include +#include + +#include + +class SystemCTest : public testing::Test +{ +public: + ~SystemCTest() override { sc_core::sc_get_curr_simcontext()->reset(); } +}; + +class DirectMappedCache : public SystemCTest +{ +protected: + DirectMappedCache() + : memoryManager(true), + initiator("ListInitiator", memoryManager), + target("TargetMemory", + sc_core::sc_time(1, sc_core::SC_NS), + sc_core::sc_time(10, sc_core::SC_NS)), + cache("Cache", + 32768, + 1, + 32, + 8, + 8, + 8, + true, + sc_core::sc_time(1, sc_core::SC_NS), + 5, + memoryManager) + { + initiator.iSocket.bind(cache.tSocket); + cache.iSocket.bind(target.tSocket); + } + + MemoryManager memoryManager; + ListInitiator initiator; + TargetMemory target; + Cache cache; +}; + +TEST_F(DirectMappedCache, Hello) +{ + std::vector list{ + {sc_core::sc_time(1000, sc_core::SC_NS), + sc_core::sc_time(1017, sc_core::SC_NS), + ListInitiator::TestTransactionData::Command::Read, + 0x0, + 4, + 0x0}}; + + initiator.appendTestTransactionList(list); + sc_core::sc_start(); +} diff --git a/tests/tests_simulator/main.cpp b/tests/tests_simulator/main.cpp new file mode 100644 index 00000000..1c92c82d --- /dev/null +++ b/tests/tests_simulator/main.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019, 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: + * Lukas Steiner + */ + +#include +#include + +int sc_main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From b0d7e4a18bb6af5114e91a9c236c24b71c7797a6 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 30 Jan 2023 12:57:13 +0100 Subject: [PATCH 06/20] Add some cache test cases --- src/simulator/simulator/Cache.h | 37 +++++++++++----- tests/tests_simulator/cache/tests_cache.cpp | 49 ++++++++++++++++++--- 2 files changed, 68 insertions(+), 18 deletions(-) diff --git a/src/simulator/simulator/Cache.h b/src/simulator/simulator/Cache.h index 0e64bf67..845986c9 100644 --- a/src/simulator/simulator/Cache.h +++ b/src/simulator/simulator/Cache.h @@ -68,10 +68,12 @@ public: private: void peqCallback(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase); - tlm::tlm_sync_enum - nb_transport_fw(tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, sc_core::sc_time &fwDelay); - tlm::tlm_sync_enum - nb_transport_bw(tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, sc_core::sc_time &bwDelay); + tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans, + tlm::tlm_phase &phase, + sc_core::sc_time &fwDelay); + tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &trans, + tlm::tlm_phase &phase, + sc_core::sc_time &bwDelay); unsigned int transport_dbg(tlm::tlm_generic_payload &trans); void fetchLineAndSendEndRequest(tlm::tlm_generic_payload &trans); @@ -118,9 +120,18 @@ private: bool isHit(index_t index, tag_t tag) const; bool isHit(std::uint64_t address) const; - void - writeLine(index_t index, tag_t tag, lineOffset_t lineOffset, unsigned int dataLength, const unsigned char *dataPtr); - void readLine(index_t index, tag_t tag, lineOffset_t lineOffset, unsigned int dataLength, unsigned char *dataPtr); + + void writeLine(index_t index, + tag_t tag, + lineOffset_t lineOffset, + unsigned int dataLength, + const unsigned char *dataPtr); + + void readLine(index_t index, + tag_t tag, + lineOffset_t lineOffset, + unsigned int dataLength, + unsigned char *dataPtr); CacheLine *evictLine(index_t index); @@ -133,7 +144,10 @@ private: tag_t tag; tlm::tlm_generic_payload *trans; - BufferEntry(index_t index, tag_t tag, tlm::tlm_generic_payload *trans) : index(index), tag(tag), trans(trans) {} + BufferEntry(index_t index, tag_t tag, tlm::tlm_generic_payload *trans) + : index(index), tag(tag), trans(trans) + { + } }; struct Mshr @@ -155,7 +169,8 @@ private: /// delay when it is already being waited on. bool hitDelayStarted = false; - Mshr(index_t index, tag_t tag, tlm::tlm_generic_payload *request) : index(index), tag(tag), requestList{request} + Mshr(index_t index, tag_t tag, tlm::tlm_generic_payload *request) + : index(index), tag(tag), requestList{request} { } }; @@ -163,8 +178,8 @@ private: std::deque mshrQueue; std::deque hitQueue; - using writeBuffer_t = std::list; - writeBuffer_t writeBuffer; + using WriteBuffer = std::list; + WriteBuffer writeBuffer; uint64_t numberOfHits = 0; uint64_t numberOfPrimaryMisses = 0; diff --git a/tests/tests_simulator/cache/tests_cache.cpp b/tests/tests_simulator/cache/tests_cache.cpp index c8da5576..44d59737 100644 --- a/tests/tests_simulator/cache/tests_cache.cpp +++ b/tests/tests_simulator/cache/tests_cache.cpp @@ -78,16 +78,51 @@ protected: Cache cache; }; -TEST_F(DirectMappedCache, Hello) +TEST_F(DirectMappedCache, Basic) { + using sc_core::SC_NS; + using sc_core::sc_time; + using Command = ListInitiator::TestTransactionData::Command; + std::vector list{ - {sc_core::sc_time(1000, sc_core::SC_NS), - sc_core::sc_time(1017, sc_core::SC_NS), - ListInitiator::TestTransactionData::Command::Read, - 0x0, - 4, - 0x0}}; + // Test miss + {sc_time(0, SC_NS), sc_time(17, SC_NS), Command::Read, 0x0, 4, 0x0}, + + // Test secondary miss + {sc_time(1, SC_NS), sc_time(18, SC_NS), Command::Read, 0x0, 4, 0x0}, + + // Test hit + {sc_time(100, SC_NS), sc_time(106, SC_NS), Command::Read, 0x0, 4, 0x0}, + + // Test write hit + {sc_time(200, SC_NS), sc_time(206, SC_NS), Command::Write, 0x0, 4, 0x8}, + + // Test eviction + {sc_time(300, SC_NS), sc_time(317, SC_NS), Command::Write, 1024 * 32, 4, 0x0}}; initiator.appendTestTransactionList(list); sc_core::sc_start(); } + +// Does not work yet +// Unclear if a snoop should even happen when the line eviction fails +// TEST_F(DirectMappedCache, WriteBufferSnooping) +// { +// using sc_core::SC_NS; +// using sc_core::sc_time; +// using Command = ListInitiator::TestTransactionData::Command; + +// std::vector list{ +// // Allocate line +// {sc_time(0, SC_NS), sc_time(17, SC_NS), Command::Write, 0x0, 4, 0x0}, + +// // Evict line +// {sc_time(100, SC_NS), sc_time(117, SC_NS), Command::Read, 1024 * 32, 4, 0x0}, + +// // Snoop from write buffer +// {sc_time(102, SC_NS), sc_time(108, SC_NS), Command::Read, 0x0, 4, 0x0}, +// }; + +// initiator.appendTestTransactionList(list); +// sc_core::sc_start(); +// } From a49afa40eb149b93db6bc6891522fb05d6d2f397 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Fri, 17 Mar 2023 14:01:17 +0100 Subject: [PATCH 07/20] Use key "addressmapping" instead of "CONGEN" in addressmapping configs --- configs/README.md | 2 +- .../am_ddr3_4x4Gbx16_dimm_p2KB_brc.json | 2 +- .../am_ddr3_4x4Gbx16_dimm_p2KB_rbc.json | 2 +- .../am_ddr3_8x1Gbx8_dimm_p1KB_brc.json | 2 +- .../am_ddr3_8x1Gbx8_dimm_p1KB_rbc.json | 2 +- .../am_ddr3_8x2Gbx8_dimm_p1KB_brc.json | 2 +- .../am_ddr3_8x2Gbx8_dimm_p1KB_rbc.json | 2 +- configs/addressmapping/am_ddr3_x16_brc.json | 2 +- configs/addressmapping/am_ddr3_x16_rbc.json | 2 +- .../am_ddr4_8x4Gbx8_dimm_p1KB_brc.json | 2 +- .../am_ddr5_2x2x8x4Gbx4_dimm_p1KB_rbc.json | 2 +- .../am_ddr5_2x4x1Gbx8_dimm_p1KB_rbc.json | 2 +- .../am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json | 2 +- .../am_ddr5_2x8x8x2Gbx4_dimm_p1KB_rbc.json | 2 +- .../addressmapping/am_hbm2_8Gb_pc_brc.json | 2 +- .../addressmapping/am_hbm3_8Gb_pc_brc.json | 2 +- .../am_lpddr4_1Gbx16_baroco.json | 2 +- .../am_lpddr4_1Gbx16_robaco.json | 2 +- .../am_lpddr4_1Gbx16_rocoba.json | 2 +- .../am_lpddr4_512Mbx16_baroco.json | 2 +- .../am_lpddr4_512Mbx16_robaco.json | 2 +- .../am_lpddr4_512Mbx16_rocoba.json | 2 +- .../addressmapping/am_lpddr4_8Gbx16_brc.json | 2 +- .../am_lpddr5_1Gbx16_16B_robaco.json | 2 +- .../am_lpddr5_1Gbx16_16B_rocoba.json | 2 +- .../am_lpddr5_1Gbx16_8B_robaco.json | 2 +- .../am_lpddr5_1Gbx16_8B_rocoba.json | 2 +- .../am_lpddr5_1Gbx16_BG_robacobg.json | 2 +- .../am_lpddr5_1Gbx16_BG_rocobabg.json | 2 +- .../am_lpddr5_512Mbx16_16B_robaco.json | 2 +- .../am_lpddr5_512Mbx16_16B_rocoba.json | 2 +- .../am_lpddr5_512Mbx16_8B_robaco.json | 2 +- .../am_lpddr5_512Mbx16_8B_rocoba.json | 2 +- .../am_lpddr5_512Mbx16_BG_robacobg.json | 2 +- .../am_lpddr5_512Mbx16_BG_rocobabg.json | 2 +- configs/addressmapping/am_ranktest.json | 2 +- .../am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json | 2 +- .../am_wideio2_4x64_4x2Gb_brc.json | 2 +- .../am_wideio2_4x64_4x2Gb_rbc.json | 2 +- .../addressmapping/am_wideio_4x1Gb_brc.json | 2 +- .../addressmapping/am_wideio_4x1Gb_rbc.json | 2 +- .../addressmapping/am_wideio_4x256Mb_brc.json | 2 +- .../addressmapping/am_wideio_4x256Mb_rbc.json | 2 +- .../addressmapping/am_wideio_4x2Gb_brc.json | 2 +- .../addressmapping/am_wideio_4x2Gb_rbc.json | 2 +- .../addressmapping/am_wideio_4x4Gb_brc.json | 2 +- .../addressmapping/am_wideio_4x4Gb_rbc.json | 2 +- .../addressmapping/am_wideio_4x512Mb_brc.json | 2 +- .../addressmapping/am_wideio_4x512Mb_rbc.json | 2 +- configs/addressmapping/am_wideio_thermal.json | 2 +- .../DRAMSys/config/AddressMapping.h | 27 +++--- .../DRAMSys/config/DRAMSysConfiguration.cpp | 22 ++--- src/configuration/DRAMSys/config/McConfig.h | 2 +- src/configuration/DRAMSys/config/SimConfig.h | 2 +- src/configuration/DRAMSys/config/TraceSetup.h | 2 +- .../DRAMSys/config/memspec/MemSpec.h | 2 +- .../DRAMSys/simulation/AddressDecoder.cpp | 16 ++-- tests/tests_configuration/reference.json | 94 +++++++++---------- .../am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json | 2 +- .../test_configuration.cpp | 23 ++--- tests/tests_dramsys/AddressDecoderConfigs.h | 2 +- tests/tests_dramsys/AddressDecoderTests.cpp | 2 +- .../b_transport/configs/no_storage.json | 86 +++++++++-------- .../b_transport/configs/storage.json | 86 +++++++++-------- 64 files changed, 227 insertions(+), 241 deletions(-) diff --git a/configs/README.md b/configs/README.md index 6ed1fbef..279560e9 100644 --- a/configs/README.md +++ b/configs/README.md @@ -182,7 +182,7 @@ Used fields: ```json { - "CONGEN": { + "addressmapping": { "XOR": [ { "FIRST": 13, diff --git a/configs/addressmapping/am_ddr3_4x4Gbx16_dimm_p2KB_brc.json b/configs/addressmapping/am_ddr3_4x4Gbx16_dimm_p2KB_brc.json index 3999c105..5438a40d 100644 --- a/configs/addressmapping/am_ddr3_4x4Gbx16_dimm_p2KB_brc.json +++ b/configs/addressmapping/am_ddr3_4x4Gbx16_dimm_p2KB_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 28, 29, diff --git a/configs/addressmapping/am_ddr3_4x4Gbx16_dimm_p2KB_rbc.json b/configs/addressmapping/am_ddr3_4x4Gbx16_dimm_p2KB_rbc.json index d1bcfe70..91c90fa6 100644 --- a/configs/addressmapping/am_ddr3_4x4Gbx16_dimm_p2KB_rbc.json +++ b/configs/addressmapping/am_ddr3_4x4Gbx16_dimm_p2KB_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 13, 14, diff --git a/configs/addressmapping/am_ddr3_8x1Gbx8_dimm_p1KB_brc.json b/configs/addressmapping/am_ddr3_8x1Gbx8_dimm_p1KB_brc.json index 13ee107d..fca7cfed 100644 --- a/configs/addressmapping/am_ddr3_8x1Gbx8_dimm_p1KB_brc.json +++ b/configs/addressmapping/am_ddr3_8x1Gbx8_dimm_p1KB_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 27, 28, diff --git a/configs/addressmapping/am_ddr3_8x1Gbx8_dimm_p1KB_rbc.json b/configs/addressmapping/am_ddr3_8x1Gbx8_dimm_p1KB_rbc.json index 81ac8ef6..3a4a8044 100644 --- a/configs/addressmapping/am_ddr3_8x1Gbx8_dimm_p1KB_rbc.json +++ b/configs/addressmapping/am_ddr3_8x1Gbx8_dimm_p1KB_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 13, 14, diff --git a/configs/addressmapping/am_ddr3_8x2Gbx8_dimm_p1KB_brc.json b/configs/addressmapping/am_ddr3_8x2Gbx8_dimm_p1KB_brc.json index 3999c105..5438a40d 100644 --- a/configs/addressmapping/am_ddr3_8x2Gbx8_dimm_p1KB_brc.json +++ b/configs/addressmapping/am_ddr3_8x2Gbx8_dimm_p1KB_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 28, 29, diff --git a/configs/addressmapping/am_ddr3_8x2Gbx8_dimm_p1KB_rbc.json b/configs/addressmapping/am_ddr3_8x2Gbx8_dimm_p1KB_rbc.json index d1bcfe70..91c90fa6 100644 --- a/configs/addressmapping/am_ddr3_8x2Gbx8_dimm_p1KB_rbc.json +++ b/configs/addressmapping/am_ddr3_8x2Gbx8_dimm_p1KB_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 13, 14, diff --git a/configs/addressmapping/am_ddr3_x16_brc.json b/configs/addressmapping/am_ddr3_x16_brc.json index dbd6a2d2..73d2c68e 100644 --- a/configs/addressmapping/am_ddr3_x16_brc.json +++ b/configs/addressmapping/am_ddr3_x16_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 26, 27, diff --git a/configs/addressmapping/am_ddr3_x16_rbc.json b/configs/addressmapping/am_ddr3_x16_rbc.json index e7cbcd22..3d841bde 100644 --- a/configs/addressmapping/am_ddr3_x16_rbc.json +++ b/configs/addressmapping/am_ddr3_x16_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 13, 14, diff --git a/configs/addressmapping/am_ddr4_8x4Gbx8_dimm_p1KB_brc.json b/configs/addressmapping/am_ddr4_8x4Gbx8_dimm_p1KB_brc.json index 7b9f8340..689baddf 100644 --- a/configs/addressmapping/am_ddr4_8x4Gbx8_dimm_p1KB_brc.json +++ b/configs/addressmapping/am_ddr4_8x4Gbx8_dimm_p1KB_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANKGROUP_BIT":[ 28, 29 diff --git a/configs/addressmapping/am_ddr5_2x2x8x4Gbx4_dimm_p1KB_rbc.json b/configs/addressmapping/am_ddr5_2x2x8x4Gbx4_dimm_p1KB_rbc.json index 5e42017b..0652961c 100644 --- a/configs/addressmapping/am_ddr5_2x2x8x4Gbx4_dimm_p1KB_rbc.json +++ b/configs/addressmapping/am_ddr5_2x2x8x4Gbx4_dimm_p1KB_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0, 1 diff --git a/configs/addressmapping/am_ddr5_2x4x1Gbx8_dimm_p1KB_rbc.json b/configs/addressmapping/am_ddr5_2x4x1Gbx8_dimm_p1KB_rbc.json index 7e02f877..3f6970d8 100644 --- a/configs/addressmapping/am_ddr5_2x4x1Gbx8_dimm_p1KB_rbc.json +++ b/configs/addressmapping/am_ddr5_2x4x1Gbx8_dimm_p1KB_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0, 1 diff --git a/configs/addressmapping/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json b/configs/addressmapping/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json index bce5038e..143f714a 100644 --- a/configs/addressmapping/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json +++ b/configs/addressmapping/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0, 1 diff --git a/configs/addressmapping/am_ddr5_2x8x8x2Gbx4_dimm_p1KB_rbc.json b/configs/addressmapping/am_ddr5_2x8x8x2Gbx4_dimm_p1KB_rbc.json index 48f1301d..e45fd809 100644 --- a/configs/addressmapping/am_ddr5_2x8x8x2Gbx4_dimm_p1KB_rbc.json +++ b/configs/addressmapping/am_ddr5_2x8x8x2Gbx4_dimm_p1KB_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0, 1 diff --git a/configs/addressmapping/am_hbm2_8Gb_pc_brc.json b/configs/addressmapping/am_hbm2_8Gb_pc_brc.json index 687e35d7..87879fdc 100644 --- a/configs/addressmapping/am_hbm2_8Gb_pc_brc.json +++ b/configs/addressmapping/am_hbm2_8Gb_pc_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "PSEUDOCHANNEL_BIT":[ 29 ], diff --git a/configs/addressmapping/am_hbm3_8Gb_pc_brc.json b/configs/addressmapping/am_hbm3_8Gb_pc_brc.json index 7b7c076f..31812705 100644 --- a/configs/addressmapping/am_hbm3_8Gb_pc_brc.json +++ b/configs/addressmapping/am_hbm3_8Gb_pc_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "PSEUDOCHANNEL_BIT":[ 28 ], diff --git a/configs/addressmapping/am_lpddr4_1Gbx16_baroco.json b/configs/addressmapping/am_lpddr4_1Gbx16_baroco.json index bf827c06..03dc8bd7 100644 --- a/configs/addressmapping/am_lpddr4_1Gbx16_baroco.json +++ b/configs/addressmapping/am_lpddr4_1Gbx16_baroco.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 28, 29, diff --git a/configs/addressmapping/am_lpddr4_1Gbx16_robaco.json b/configs/addressmapping/am_lpddr4_1Gbx16_robaco.json index 9e86d16e..69a9c9b5 100644 --- a/configs/addressmapping/am_lpddr4_1Gbx16_robaco.json +++ b/configs/addressmapping/am_lpddr4_1Gbx16_robaco.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 11, 12, diff --git a/configs/addressmapping/am_lpddr4_1Gbx16_rocoba.json b/configs/addressmapping/am_lpddr4_1Gbx16_rocoba.json index f4091b45..eafa99fe 100644 --- a/configs/addressmapping/am_lpddr4_1Gbx16_rocoba.json +++ b/configs/addressmapping/am_lpddr4_1Gbx16_rocoba.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 5, 6, diff --git a/configs/addressmapping/am_lpddr4_512Mbx16_baroco.json b/configs/addressmapping/am_lpddr4_512Mbx16_baroco.json index e9b3ac9f..8e9948b2 100644 --- a/configs/addressmapping/am_lpddr4_512Mbx16_baroco.json +++ b/configs/addressmapping/am_lpddr4_512Mbx16_baroco.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 27, 28, diff --git a/configs/addressmapping/am_lpddr4_512Mbx16_robaco.json b/configs/addressmapping/am_lpddr4_512Mbx16_robaco.json index f4c2c3dd..baa9dcd2 100644 --- a/configs/addressmapping/am_lpddr4_512Mbx16_robaco.json +++ b/configs/addressmapping/am_lpddr4_512Mbx16_robaco.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 11, 12, diff --git a/configs/addressmapping/am_lpddr4_512Mbx16_rocoba.json b/configs/addressmapping/am_lpddr4_512Mbx16_rocoba.json index a8142937..455ae3a3 100644 --- a/configs/addressmapping/am_lpddr4_512Mbx16_rocoba.json +++ b/configs/addressmapping/am_lpddr4_512Mbx16_rocoba.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 5, 6, diff --git a/configs/addressmapping/am_lpddr4_8Gbx16_brc.json b/configs/addressmapping/am_lpddr4_8Gbx16_brc.json index e9b3ac9f..8e9948b2 100644 --- a/configs/addressmapping/am_lpddr4_8Gbx16_brc.json +++ b/configs/addressmapping/am_lpddr4_8Gbx16_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 27, 28, diff --git a/configs/addressmapping/am_lpddr5_1Gbx16_16B_robaco.json b/configs/addressmapping/am_lpddr5_1Gbx16_16B_robaco.json index a48e5b4f..2c2b96b8 100644 --- a/configs/addressmapping/am_lpddr5_1Gbx16_16B_robaco.json +++ b/configs/addressmapping/am_lpddr5_1Gbx16_16B_robaco.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/configs/addressmapping/am_lpddr5_1Gbx16_16B_rocoba.json b/configs/addressmapping/am_lpddr5_1Gbx16_16B_rocoba.json index 52fde69a..8d78bf4a 100644 --- a/configs/addressmapping/am_lpddr5_1Gbx16_16B_rocoba.json +++ b/configs/addressmapping/am_lpddr5_1Gbx16_16B_rocoba.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/configs/addressmapping/am_lpddr5_1Gbx16_8B_robaco.json b/configs/addressmapping/am_lpddr5_1Gbx16_8B_robaco.json index a131562a..82b756fc 100644 --- a/configs/addressmapping/am_lpddr5_1Gbx16_8B_robaco.json +++ b/configs/addressmapping/am_lpddr5_1Gbx16_8B_robaco.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/configs/addressmapping/am_lpddr5_1Gbx16_8B_rocoba.json b/configs/addressmapping/am_lpddr5_1Gbx16_8B_rocoba.json index aaf6a029..1f5d2cfe 100644 --- a/configs/addressmapping/am_lpddr5_1Gbx16_8B_rocoba.json +++ b/configs/addressmapping/am_lpddr5_1Gbx16_8B_rocoba.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/configs/addressmapping/am_lpddr5_1Gbx16_BG_robacobg.json b/configs/addressmapping/am_lpddr5_1Gbx16_BG_robacobg.json index 0fd3b6c0..bf80d312 100644 --- a/configs/addressmapping/am_lpddr5_1Gbx16_BG_robacobg.json +++ b/configs/addressmapping/am_lpddr5_1Gbx16_BG_robacobg.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/configs/addressmapping/am_lpddr5_1Gbx16_BG_rocobabg.json b/configs/addressmapping/am_lpddr5_1Gbx16_BG_rocobabg.json index 2552ccd3..88629310 100644 --- a/configs/addressmapping/am_lpddr5_1Gbx16_BG_rocobabg.json +++ b/configs/addressmapping/am_lpddr5_1Gbx16_BG_rocobabg.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/configs/addressmapping/am_lpddr5_512Mbx16_16B_robaco.json b/configs/addressmapping/am_lpddr5_512Mbx16_16B_robaco.json index 4f5bfd86..8b91cc1e 100644 --- a/configs/addressmapping/am_lpddr5_512Mbx16_16B_robaco.json +++ b/configs/addressmapping/am_lpddr5_512Mbx16_16B_robaco.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/configs/addressmapping/am_lpddr5_512Mbx16_16B_rocoba.json b/configs/addressmapping/am_lpddr5_512Mbx16_16B_rocoba.json index c5cf4d95..8630b987 100644 --- a/configs/addressmapping/am_lpddr5_512Mbx16_16B_rocoba.json +++ b/configs/addressmapping/am_lpddr5_512Mbx16_16B_rocoba.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/configs/addressmapping/am_lpddr5_512Mbx16_8B_robaco.json b/configs/addressmapping/am_lpddr5_512Mbx16_8B_robaco.json index 1846604c..284f8957 100644 --- a/configs/addressmapping/am_lpddr5_512Mbx16_8B_robaco.json +++ b/configs/addressmapping/am_lpddr5_512Mbx16_8B_robaco.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/configs/addressmapping/am_lpddr5_512Mbx16_8B_rocoba.json b/configs/addressmapping/am_lpddr5_512Mbx16_8B_rocoba.json index 9c00c8d9..35b67ef4 100644 --- a/configs/addressmapping/am_lpddr5_512Mbx16_8B_rocoba.json +++ b/configs/addressmapping/am_lpddr5_512Mbx16_8B_rocoba.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/configs/addressmapping/am_lpddr5_512Mbx16_BG_robacobg.json b/configs/addressmapping/am_lpddr5_512Mbx16_BG_robacobg.json index bf283cd6..94066723 100644 --- a/configs/addressmapping/am_lpddr5_512Mbx16_BG_robacobg.json +++ b/configs/addressmapping/am_lpddr5_512Mbx16_BG_robacobg.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/configs/addressmapping/am_lpddr5_512Mbx16_BG_rocobabg.json b/configs/addressmapping/am_lpddr5_512Mbx16_BG_rocobabg.json index c85e1b7e..3898a373 100644 --- a/configs/addressmapping/am_lpddr5_512Mbx16_BG_rocobabg.json +++ b/configs/addressmapping/am_lpddr5_512Mbx16_BG_rocobabg.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/configs/addressmapping/am_ranktest.json b/configs/addressmapping/am_ranktest.json index 720b214e..accf2165 100644 --- a/configs/addressmapping/am_ranktest.json +++ b/configs/addressmapping/am_ranktest.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "RANK_BIT":[ 30, 31 diff --git a/configs/addressmapping/am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json b/configs/addressmapping/am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json index d1bcfe70..91c90fa6 100644 --- a/configs/addressmapping/am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json +++ b/configs/addressmapping/am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 13, 14, diff --git a/configs/addressmapping/am_wideio2_4x64_4x2Gb_brc.json b/configs/addressmapping/am_wideio2_4x64_4x2Gb_brc.json index 512b8090..e1267bcc 100644 --- a/configs/addressmapping/am_wideio2_4x64_4x2Gb_brc.json +++ b/configs/addressmapping/am_wideio2_4x64_4x2Gb_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 25, 26, diff --git a/configs/addressmapping/am_wideio2_4x64_4x2Gb_rbc.json b/configs/addressmapping/am_wideio2_4x64_4x2Gb_rbc.json index 58bc5ce4..e90f4110 100644 --- a/configs/addressmapping/am_wideio2_4x64_4x2Gb_rbc.json +++ b/configs/addressmapping/am_wideio2_4x64_4x2Gb_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 12, 13, diff --git a/configs/addressmapping/am_wideio_4x1Gb_brc.json b/configs/addressmapping/am_wideio_4x1Gb_brc.json index 7f51385c..6f05d067 100644 --- a/configs/addressmapping/am_wideio_4x1Gb_brc.json +++ b/configs/addressmapping/am_wideio_4x1Gb_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 25, 26 diff --git a/configs/addressmapping/am_wideio_4x1Gb_rbc.json b/configs/addressmapping/am_wideio_4x1Gb_rbc.json index cbe47587..cf088be1 100644 --- a/configs/addressmapping/am_wideio_4x1Gb_rbc.json +++ b/configs/addressmapping/am_wideio_4x1Gb_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 11, 12 diff --git a/configs/addressmapping/am_wideio_4x256Mb_brc.json b/configs/addressmapping/am_wideio_4x256Mb_brc.json index 52d665e5..3d4ae4d6 100644 --- a/configs/addressmapping/am_wideio_4x256Mb_brc.json +++ b/configs/addressmapping/am_wideio_4x256Mb_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 23, 24 diff --git a/configs/addressmapping/am_wideio_4x256Mb_rbc.json b/configs/addressmapping/am_wideio_4x256Mb_rbc.json index fc5f8b2a..d855313d 100644 --- a/configs/addressmapping/am_wideio_4x256Mb_rbc.json +++ b/configs/addressmapping/am_wideio_4x256Mb_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 11, 12 diff --git a/configs/addressmapping/am_wideio_4x2Gb_brc.json b/configs/addressmapping/am_wideio_4x2Gb_brc.json index 3040e90a..961a4a36 100644 --- a/configs/addressmapping/am_wideio_4x2Gb_brc.json +++ b/configs/addressmapping/am_wideio_4x2Gb_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 26, 27 diff --git a/configs/addressmapping/am_wideio_4x2Gb_rbc.json b/configs/addressmapping/am_wideio_4x2Gb_rbc.json index 76a9de62..15ddf749 100644 --- a/configs/addressmapping/am_wideio_4x2Gb_rbc.json +++ b/configs/addressmapping/am_wideio_4x2Gb_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 11, 12 diff --git a/configs/addressmapping/am_wideio_4x4Gb_brc.json b/configs/addressmapping/am_wideio_4x4Gb_brc.json index 8c16b58c..639ba547 100644 --- a/configs/addressmapping/am_wideio_4x4Gb_brc.json +++ b/configs/addressmapping/am_wideio_4x4Gb_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 27, 28 diff --git a/configs/addressmapping/am_wideio_4x4Gb_rbc.json b/configs/addressmapping/am_wideio_4x4Gb_rbc.json index e8d1b1e8..4fa24317 100644 --- a/configs/addressmapping/am_wideio_4x4Gb_rbc.json +++ b/configs/addressmapping/am_wideio_4x4Gb_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 12, 13 diff --git a/configs/addressmapping/am_wideio_4x512Mb_brc.json b/configs/addressmapping/am_wideio_4x512Mb_brc.json index 18ab6414..c07fcc40 100644 --- a/configs/addressmapping/am_wideio_4x512Mb_brc.json +++ b/configs/addressmapping/am_wideio_4x512Mb_brc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 24, 25 diff --git a/configs/addressmapping/am_wideio_4x512Mb_rbc.json b/configs/addressmapping/am_wideio_4x512Mb_rbc.json index 62578383..60cacb06 100644 --- a/configs/addressmapping/am_wideio_4x512Mb_rbc.json +++ b/configs/addressmapping/am_wideio_4x512Mb_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 11, 12 diff --git a/configs/addressmapping/am_wideio_thermal.json b/configs/addressmapping/am_wideio_thermal.json index 96be2a29..c8597163 100644 --- a/configs/addressmapping/am_wideio_thermal.json +++ b/configs/addressmapping/am_wideio_thermal.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BANK_BIT": [ 4, 5 diff --git a/src/configuration/DRAMSys/config/AddressMapping.h b/src/configuration/DRAMSys/config/AddressMapping.h index 0d435bd1..333f6b38 100644 --- a/src/configuration/DRAMSys/config/AddressMapping.h +++ b/src/configuration/DRAMSys/config/AddressMapping.h @@ -54,25 +54,20 @@ NLOHMANN_JSONIFY_ALL_THINGS(XorPair, FIRST, SECOND) struct AddressMapping { static constexpr std::string_view KEY = "addressmapping"; - static constexpr std::string_view INNER_KEY = "CONGEN"; - static constexpr std::string_view PATH = "addressmapping"; + static constexpr std::string_view SUB_DIR = "addressmapping"; - struct ConGen { - std::optional> BYTE_BIT; - std::optional> COLUMN_BIT; - std::optional> ROW_BIT; - std::optional> BANK_BIT; - std::optional> BANKGROUP_BIT; - std::optional> RANK_BIT; - std::optional> PSEUDOCHANNEL_BIT; - std::optional> CHANNEL_BIT; - std::optional> XOR; - } CONGEN; + std::optional> BYTE_BIT; + std::optional> COLUMN_BIT; + std::optional> ROW_BIT; + std::optional> BANK_BIT; + std::optional> BANKGROUP_BIT; + std::optional> RANK_BIT; + std::optional> PSEUDOCHANNEL_BIT; + std::optional> CHANNEL_BIT; + std::optional> XOR; }; -NLOHMANN_JSONIFY_ALL_THINGS(AddressMapping, CONGEN) - -NLOHMANN_JSONIFY_ALL_THINGS(AddressMapping::ConGen, +NLOHMANN_JSONIFY_ALL_THINGS(AddressMapping, BYTE_BIT, COLUMN_BIT, ROW_BIT, diff --git a/src/configuration/DRAMSys/config/DRAMSysConfiguration.cpp b/src/configuration/DRAMSys/config/DRAMSysConfiguration.cpp index 0b6f546c..33d2d81a 100644 --- a/src/configuration/DRAMSys/config/DRAMSysConfiguration.cpp +++ b/src/configuration/DRAMSys/config/DRAMSysConfiguration.cpp @@ -57,6 +57,8 @@ Configuration from_path(std::string_view path, std::string_view resourceDirector Unkown } current_sub_config; + // This custom parser callback is responsible to swap out the paths to the sub-config json files + // with the actual json data. std::function parser_callback; parser_callback = @@ -84,6 +86,8 @@ Configuration from_path(std::string_view path, std::string_view resourceDirector current_sub_config = SubConfig::Unkown; } + // In case we have an value (string) instead of an object, replace the value with the loaded + // json object. if (event == parse_event_t::value && current_sub_config != SubConfig::Unkown) { // Replace name of json file with actual json data auto parse_json = [&parser_callback, @@ -105,23 +109,15 @@ Configuration from_path(std::string_view path, std::string_view resourceDirector }; if (current_sub_config == SubConfig::MemSpec) - parsed = parse_json(MemSpec::PATH, MemSpec::KEY, parsed); + parsed = parse_json(MemSpec::SUB_DIR, MemSpec::KEY, parsed); else if (current_sub_config == SubConfig::AddressMapping) - { - parsed = parse_json(AddressMapping::PATH, AddressMapping::INNER_KEY, parsed); - - if (!parsed.contains(AddressMapping::INNER_KEY)) { - auto temp = parsed; - parsed = json_t(); - parsed[AddressMapping::INNER_KEY] = temp; - } - } + parsed = parse_json(AddressMapping::SUB_DIR, AddressMapping::KEY, parsed); else if (current_sub_config == SubConfig::McConfig) - parsed = parse_json(McConfig::PATH, McConfig::KEY, parsed); + parsed = parse_json(McConfig::SUB_DIR, McConfig::KEY, parsed); else if (current_sub_config == SubConfig::SimConfig) - parsed = parse_json(SimConfig::PATH, SimConfig::KEY, parsed); + parsed = parse_json(SimConfig::SUB_DIR, SimConfig::KEY, parsed); else if (current_sub_config == SubConfig::TraceSetup) - parsed = parse_json(TraceSetupConstants::PATH, TraceSetupConstants::KEY, parsed); + parsed = parse_json(TraceSetupConstants::SUB_DIR, TraceSetupConstants::KEY, parsed); } return true; diff --git a/src/configuration/DRAMSys/config/McConfig.h b/src/configuration/DRAMSys/config/McConfig.h index f7a9336d..361716b6 100644 --- a/src/configuration/DRAMSys/config/McConfig.h +++ b/src/configuration/DRAMSys/config/McConfig.h @@ -150,7 +150,7 @@ NLOHMANN_JSON_SERIALIZE_ENUM(ArbiterType, {{ArbiterType::Invalid, nullptr}, struct McConfig { static constexpr std::string_view KEY = "mcconfig"; - static constexpr std::string_view PATH = "mcconfig"; + static constexpr std::string_view SUB_DIR = "mcconfig"; std::optional PagePolicy; std::optional Scheduler; diff --git a/src/configuration/DRAMSys/config/SimConfig.h b/src/configuration/DRAMSys/config/SimConfig.h index 0c283729..d7d0376b 100644 --- a/src/configuration/DRAMSys/config/SimConfig.h +++ b/src/configuration/DRAMSys/config/SimConfig.h @@ -59,7 +59,7 @@ NLOHMANN_JSON_SERIALIZE_ENUM(StoreModeType, {{StoreModeType::Invalid, nullptr}, struct SimConfig { static constexpr std::string_view KEY = "simconfig"; - static constexpr std::string_view PATH = "simconfig"; + static constexpr std::string_view SUB_DIR = "simconfig"; std::optional AddressOffset; std::optional CheckTLM2Protocol; diff --git a/src/configuration/DRAMSys/config/TraceSetup.h b/src/configuration/DRAMSys/config/TraceSetup.h index af100b30..76c6a29a 100644 --- a/src/configuration/DRAMSys/config/TraceSetup.h +++ b/src/configuration/DRAMSys/config/TraceSetup.h @@ -194,7 +194,7 @@ NLOHMANN_JSONIFY_ALL_THINGS( struct TraceSetupConstants { static constexpr std::string_view KEY = "tracesetup"; - static constexpr std::string_view PATH = "tracesetup"; + static constexpr std::string_view SUB_DIR = "tracesetup"; }; using TraceSetup = std::vector< diff --git a/src/configuration/DRAMSys/config/memspec/MemSpec.h b/src/configuration/DRAMSys/config/memspec/MemSpec.h index 8bc1ba73..4521534b 100644 --- a/src/configuration/DRAMSys/config/memspec/MemSpec.h +++ b/src/configuration/DRAMSys/config/memspec/MemSpec.h @@ -48,7 +48,7 @@ namespace DRAMSys::Config { struct MemSpec { static constexpr std::string_view KEY = "memspec"; - static constexpr std::string_view PATH = "memspec"; + static constexpr std::string_view SUB_DIR = "memspec"; MemArchitectureSpecType memarchitecturespec; std::string memoryId; diff --git a/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp b/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp index 7b3de3b2..83cd8f1c 100644 --- a/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp +++ b/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp @@ -46,27 +46,27 @@ AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping &addressMapping, const MemSpec &memSpec) { - if (const auto &channelBits = addressMapping.CONGEN.CHANNEL_BIT) + if (const auto &channelBits = addressMapping.CHANNEL_BIT) { std::copy(channelBits->begin(), channelBits->end(), std::back_inserter(vChannelBits)); } - if (const auto &rankBits = addressMapping.CONGEN.RANK_BIT) + if (const auto &rankBits = addressMapping.RANK_BIT) { std::copy(rankBits->begin(), rankBits->end(), std::back_inserter(vRankBits)); } - if (const auto& bankGroupBits = addressMapping.CONGEN.BANKGROUP_BIT) + if (const auto& bankGroupBits = addressMapping.BANKGROUP_BIT) { std::copy(bankGroupBits->begin(), bankGroupBits->end(), std::back_inserter(vBankGroupBits)); } - if (const auto &byteBits = addressMapping.CONGEN.BYTE_BIT) + if (const auto &byteBits = addressMapping.BYTE_BIT) { std::copy(byteBits->begin(), byteBits->end(), std::back_inserter(vByteBits)); } - if (const auto &xorBits = addressMapping.CONGEN.XOR) + if (const auto &xorBits = addressMapping.XOR) { for (const auto& xorBit : *xorBits) { @@ -74,17 +74,17 @@ AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping &addressMap } } - if (const auto &bankBits = addressMapping.CONGEN.BANK_BIT) + if (const auto &bankBits = addressMapping.BANK_BIT) { std::copy(bankBits->begin(), bankBits->end(), std::back_inserter(vBankBits)); } - if (const auto &rowBits = addressMapping.CONGEN.ROW_BIT) + if (const auto &rowBits = addressMapping.ROW_BIT) { std::copy(rowBits->begin(), rowBits->end(), std::back_inserter(vRowBits)); } - if (const auto &columnBits = addressMapping.CONGEN.COLUMN_BIT) + if (const auto &columnBits = addressMapping.COLUMN_BIT) { std::copy(columnBits->begin(), columnBits->end(), std::back_inserter(vColumnBits)); } diff --git a/tests/tests_configuration/reference.json b/tests/tests_configuration/reference.json index ac8f4a31..42d01beb 100644 --- a/tests/tests_configuration/reference.json +++ b/tests/tests_configuration/reference.json @@ -1,54 +1,52 @@ { "simulation": { "addressmapping": { - "CONGEN": { - "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 - ] - } + "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 + ] }, "mcconfig": { "Arbiter": "Simple", diff --git a/tests/tests_configuration/resources/addressmapping/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json b/tests/tests_configuration/resources/addressmapping/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json index bce5038e..143f714a 100644 --- a/tests/tests_configuration/resources/addressmapping/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json +++ b/tests/tests_configuration/resources/addressmapping/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json @@ -1,5 +1,5 @@ { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0, 1 diff --git a/tests/tests_configuration/test_configuration.cpp b/tests/tests_configuration/test_configuration.cpp index 3e81d3ef..ca0430cf 100644 --- a/tests/tests_configuration/test_configuration.cpp +++ b/tests/tests_configuration/test_configuration.cpp @@ -63,15 +63,15 @@ protected: 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}}; + {{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, @@ -439,7 +439,7 @@ TEST_F(ConfigurationTest, AddressMapping) { std::string_view addressmapping_string = R"( { - "CONGEN": { + "addressmapping": { "BANKGROUP_BIT": [ 17, 18, @@ -491,7 +491,8 @@ TEST_F(ConfigurationTest, AddressMapping) )"; json_t addressmapping_reference = json_t::parse(addressmapping_string); - json_t addressmapping_test = addressMapping; + json_t addressmapping_test; + addressmapping_test[AddressMapping::KEY] = addressMapping; EXPECT_EQ(addressmapping_test, addressmapping_reference); } diff --git a/tests/tests_dramsys/AddressDecoderConfigs.h b/tests/tests_dramsys/AddressDecoderConfigs.h index 671c24ef..17e18d79 100644 --- a/tests/tests_dramsys/AddressDecoderConfigs.h +++ b/tests/tests_dramsys/AddressDecoderConfigs.h @@ -102,7 +102,7 @@ inline constexpr std::string_view memSpecJsonString = R"( inline constexpr std::string_view addressMappingJsonString = R"( { - "CONGEN": { + "addressmapping": { "BYTE_BIT": [ 0 ], diff --git a/tests/tests_dramsys/AddressDecoderTests.cpp b/tests/tests_dramsys/AddressDecoderTests.cpp index fe9dd24b..b7390555 100644 --- a/tests/tests_dramsys/AddressDecoderTests.cpp +++ b/tests/tests_dramsys/AddressDecoderTests.cpp @@ -44,7 +44,7 @@ class AddressDecoderFixture : public ::testing::Test { protected: AddressDecoderFixture() : - addressMappingJson(nlohmann::json::parse(addressMappingJsonString)), + addressMappingJson(nlohmann::json::parse(addressMappingJsonString).at("addressmapping")), memSpecJson(nlohmann::json::parse(memSpecJsonString).at("memspec")), addressMappingConfig(addressMappingJson.get()), memSpec(memSpecConfig), diff --git a/tests/tests_dramsys/b_transport/configs/no_storage.json b/tests/tests_dramsys/b_transport/configs/no_storage.json index c2950e40..6b3be967 100644 --- a/tests/tests_dramsys/b_transport/configs/no_storage.json +++ b/tests/tests_dramsys/b_transport/configs/no_storage.json @@ -1,50 +1,48 @@ { "simulation": { "addressmapping": { - "CONGEN": { - "BANKGROUP_BIT": [ - 28, - 29 - ], - "BANK_BIT": [ - 30, - 31 - ], - "BYTE_BIT": [ - 0, - 1, - 2 - ], - "COLUMN_BIT": [ - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12 - ], - "ROW_BIT": [ - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27 - ] - } + "BANKGROUP_BIT": [ + 28, + 29 + ], + "BANK_BIT": [ + 30, + 31 + ], + "BYTE_BIT": [ + 0, + 1, + 2 + ], + "COLUMN_BIT": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12 + ], + "ROW_BIT": [ + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27 + ] }, "mcconfig": { "Arbiter": "Simple", diff --git a/tests/tests_dramsys/b_transport/configs/storage.json b/tests/tests_dramsys/b_transport/configs/storage.json index 3535eaeb..788056ec 100644 --- a/tests/tests_dramsys/b_transport/configs/storage.json +++ b/tests/tests_dramsys/b_transport/configs/storage.json @@ -1,50 +1,48 @@ { "simulation": { "addressmapping": { - "CONGEN": { - "BANKGROUP_BIT": [ - 28, - 29 - ], - "BANK_BIT": [ - 30, - 31 - ], - "BYTE_BIT": [ - 0, - 1, - 2 - ], - "COLUMN_BIT": [ - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12 - ], - "ROW_BIT": [ - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27 - ] - } + "BANKGROUP_BIT": [ + 28, + 29 + ], + "BANK_BIT": [ + 30, + 31 + ], + "BYTE_BIT": [ + 0, + 1, + 2 + ], + "COLUMN_BIT": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12 + ], + "ROW_BIT": [ + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27 + ] }, "mcconfig": { "Arbiter": "Simple", From 3d4f73361f33d60a5bebca4e7d9be6544b3b7921 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Fri, 17 Mar 2023 14:50:50 +0100 Subject: [PATCH 08/20] Fix timings in new StlPlayer --- src/simulator/simulator/player/StlPlayer.cpp | 7 ++++++- src/simulator/simulator/request/RequestIssuer.cpp | 8 ++++++++ src/simulator/simulator/request/RequestIssuer.h | 2 +- tests/tests_regression/compare.sh | 12 +++++++----- tests/tests_regression/compare_table.sh | 5 ++++- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/simulator/simulator/player/StlPlayer.cpp b/src/simulator/simulator/player/StlPlayer.cpp index 2b29d794..fb3c2017 100644 --- a/src/simulator/simulator/player/StlPlayer.cpp +++ b/src/simulator/simulator/player/StlPlayer.cpp @@ -95,12 +95,17 @@ Request StlPlayer::nextRequest() } sc_core::sc_time delay = readoutIt->delay; + sc_core::sc_time offset = playerPeriod - (sc_core::sc_time_stamp() % playerPeriod); if (traceType == TraceType::Absolute) { - delay = std::max(sc_core::sc_time_stamp(), delay); + delay = std::max(sc_core::sc_time_stamp() + offset, delay); delay -= sc_core::sc_time_stamp(); } + else // if (traceType == TraceType::Relative) + { + delay = offset + delay; + } Request request(*readoutIt); request.delay = delay; diff --git a/src/simulator/simulator/request/RequestIssuer.cpp b/src/simulator/simulator/request/RequestIssuer.cpp index 27c76a1b..a7371fc6 100644 --- a/src/simulator/simulator/request/RequestIssuer.cpp +++ b/src/simulator/simulator/request/RequestIssuer.cpp @@ -79,6 +79,9 @@ void RequestIssuer::sendNextRequest() tlm::tlm_phase phase = tlm::BEGIN_REQ; sc_core::sc_time delay = request.delay; + if (request.address == 0x4000f000) + int x = 0; + if (transactionsSent == 0) delay = sc_core::SC_ZERO_TIME; @@ -107,6 +110,11 @@ bool RequestIssuer::nextRequestSendable() const return true; } +sc_core::sc_time RequestIssuer::alignToClock(sc_core::sc_time time) const +{ + +} + void RequestIssuer::peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) { if (phase == tlm::END_REQ) diff --git a/src/simulator/simulator/request/RequestIssuer.h b/src/simulator/simulator/request/RequestIssuer.h index 1d5b3939..7c7d8c69 100644 --- a/src/simulator/simulator/request/RequestIssuer.h +++ b/src/simulator/simulator/request/RequestIssuer.h @@ -82,8 +82,8 @@ private: std::function nextRequest; void sendNextRequest(); - bool nextRequestSendable() const; + sc_core::sc_time alignToClock(sc_core::sc_time time) const; tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, diff --git a/tests/tests_regression/compare.sh b/tests/tests_regression/compare.sh index e5262576..859e8044 100755 --- a/tests/tests_regression/compare.sh +++ b/tests/tests_regression/compare.sh @@ -1,7 +1,9 @@ #!/bin/bash -if [[ $(sqldiff ${CMAKE_CURRENT_SOURCE_DIR}/${standard}/expected/${output_filename} ${output_filename}) ]]; then - exit -1 -else - exit 0 -fi +# When comparing the whole database, we do not care if there are differences or not. +# The tables that need to be checked have their own tests. +# The purpose of this script is solely to output the differences of the two databases +# so that they can be inspected easily. + +sqldiff ${CMAKE_CURRENT_SOURCE_DIR}/${standard}/expected/${output_filename} ${output_filename} +exit 0 diff --git a/tests/tests_regression/compare_table.sh b/tests/tests_regression/compare_table.sh index 8978e49d..1e709f07 100755 --- a/tests/tests_regression/compare_table.sh +++ b/tests/tests_regression/compare_table.sh @@ -1,6 +1,9 @@ #!/bin/bash -if [[ $(sqldiff --table ${table} ${CMAKE_CURRENT_SOURCE_DIR}/${standard}/expected/${output_filename} ${output_filename}) ]]; then +stdout=$(sqldiff --table ${table} ${CMAKE_CURRENT_SOURCE_DIR}/${standard}/expected/${output_filename} ${output_filename}) + +if [[ $stdout ]]; then + echo $stdout exit -1 else exit 0 From 03152c0e6182b792bd1ddbb7fef30b77efc6287c Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Fri, 17 Mar 2023 14:55:16 +0100 Subject: [PATCH 09/20] Fix dump of mcconfig and memspec in GeneralInfo table --- src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp b/src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp index 2309b838..6e892378 100644 --- a/src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp +++ b/src/libdramsys/DRAMSys/simulation/DRAMSysRecordable.cpp @@ -110,9 +110,14 @@ void DRAMSysRecordable::setupTlmRecorders(const std::string& traceName, std::string dbName = std::string(name()) + "_" + traceName + "_ch" + std::to_string(i) + ".tdb"; std::string recorderName = "tlmRecorder" + std::to_string(i); + nlohmann::json mcconfig; + nlohmann::json memspec; + mcconfig[Config::McConfig::KEY] = configLib.mcconfig; + memspec[Config::MemSpec::KEY] = configLib.memspec; + tlmRecorders.emplace_back(recorderName, config, dbName); - tlmRecorders.back().recordMcConfig(nlohmann::json(configLib.mcconfig).dump()); - tlmRecorders.back().recordMemspec(nlohmann::json(configLib.memspec).dump()); + tlmRecorders.back().recordMcConfig(mcconfig.dump()); + tlmRecorders.back().recordMemspec(memspec.dump()); tlmRecorders.back().recordTraceNames(config.simulationName); } } From 0914d736e4db5ff07e052340971a3b918bb44f8f Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 20 Mar 2023 12:21:30 +0100 Subject: [PATCH 10/20] Fix resource directory path in new simulator --- src/simulator/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/simulator/main.cpp b/src/simulator/main.cpp index 06c26503..d5521655 100644 --- a/src/simulator/main.cpp +++ b/src/simulator/main.cpp @@ -68,7 +68,8 @@ int sc_main(int argc, char **argv) baseConfig = argv[1]; } - DRAMSys::Config::Configuration configuration = DRAMSys::Config::from_path(baseConfig.c_str()); + DRAMSys::Config::Configuration configuration = + DRAMSys::Config::from_path(baseConfig.c_str(), resourceDirectory.c_str()); if (!configuration.tracesetup.has_value()) SC_REPORT_FATAL("Simulator", "No traffic initiators specified"); From fb174392bb870e0bbecee780289d5bc8a722c607 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 20 Mar 2023 12:40:09 +0100 Subject: [PATCH 11/20] Only use DRAMSysRecorable when recording is enabled --- src/simulator/main.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/simulator/main.cpp b/src/simulator/main.cpp index d5521655..f8b7238d 100644 --- a/src/simulator/main.cpp +++ b/src/simulator/main.cpp @@ -74,7 +74,15 @@ int sc_main(int argc, char **argv) if (!configuration.tracesetup.has_value()) SC_REPORT_FATAL("Simulator", "No traffic initiators specified"); - DRAMSys::DRAMSysRecordable dramSys("DRAMSys", configuration); + std::unique_ptr dramSys; + if (configuration.simconfig.DatabaseRecording) + { + dramSys = std::make_unique("DRAMSys", configuration); + } + else + { + dramSys = std::make_unique("DRAMSys", configuration); + } MemoryManager memoryManager(false); @@ -99,8 +107,8 @@ int sc_main(int argc, char **argv) for (auto const &initiator_config : configuration.tracesetup.value()) { - uint64_t memorySize = dramSys.getConfig().memSpec->getSimMemSizeInBytes(); - unsigned int dataLength = dramSys.getConfig().memSpec->defaultBytesPerBurst; + uint64_t memorySize = dramSys->getConfig().memSpec->getSimMemSizeInBytes(); + unsigned int dataLength = dramSys->getConfig().memSpec->defaultBytesPerBurst; auto initiator = std::visit( [=, &memoryManager](auto &&config) -> std::unique_ptr @@ -163,7 +171,7 @@ int sc_main(int argc, char **argv) totalTransactions += initiator->totalRequests(); - initiator->bind(dramSys.tSocket); + initiator->bind(dramSys->tSocket); initiators.push_back(std::move(initiator)); } From 15075c3be08bd02ef562de72aab4572bba177a19 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Tue, 21 Mar 2023 09:26:58 +0100 Subject: [PATCH 12/20] Use predefined resource directory if none is specified --- src/simulator/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simulator/main.cpp b/src/simulator/main.cpp index f8b7238d..62195066 100644 --- a/src/simulator/main.cpp +++ b/src/simulator/main.cpp @@ -56,7 +56,7 @@ static constexpr std::string_view TRACE_DIRECTORY = "traces"; int sc_main(int argc, char **argv) { - std::filesystem::path resourceDirectory = "configs"; + std::filesystem::path resourceDirectory = DRAMSYS_RESOURCE_DIR; if (argc >= 3) { resourceDirectory = argv[2]; From 3cd639620780711d6da776b1d94918facaee7b60 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Fri, 24 Mar 2023 10:35:29 +0100 Subject: [PATCH 13/20] Add "dataAlignment" field for random traffic generators --- src/configuration/DRAMSys/config/TraceSetup.h | 4 ++ src/simulator/main.cpp | 8 ++-- .../simulator/generator/RandomProducer.cpp | 12 +++-- .../simulator/generator/RandomProducer.h | 4 +- .../simulator/generator/TrafficGenerator.cpp | 16 +++++-- .../simulator/generator/TrafficGenerator.h | 4 +- src/simulator/simulator/player/DbiPlayer.h | 47 ------------------- 7 files changed, 34 insertions(+), 61 deletions(-) delete mode 100644 src/simulator/simulator/player/DbiPlayer.h diff --git a/src/configuration/DRAMSys/config/TraceSetup.h b/src/configuration/DRAMSys/config/TraceSetup.h index 76c6a29a..54c1fd25 100644 --- a/src/configuration/DRAMSys/config/TraceSetup.h +++ b/src/configuration/DRAMSys/config/TraceSetup.h @@ -128,6 +128,7 @@ struct TrafficGenerator std::optional seed; std::optional maxTransactions; std::optional dataLength; + std::optional dataAlignment; uint64_t numRequests; double rwRatio; @@ -145,6 +146,7 @@ NLOHMANN_JSONIFY_ALL_THINGS(TrafficGenerator, seed, maxTransactions, dataLength, + dataAlignment, numRequests, rwRatio, addressDistribution, @@ -162,6 +164,7 @@ struct TrafficGeneratorStateMachine std::optional seed; std::optional maxTransactions; std::optional dataLength; + std::optional dataAlignment; std::vector> states; std::vector transitions; }; @@ -174,6 +177,7 @@ NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorStateMachine, seed, maxTransactions, dataLength, + dataAlignment, states, transitions) diff --git a/src/simulator/main.cpp b/src/simulator/main.cpp index 62195066..e35ddc8f 100644 --- a/src/simulator/main.cpp +++ b/src/simulator/main.cpp @@ -108,7 +108,7 @@ int sc_main(int argc, char **argv) for (auto const &initiator_config : configuration.tracesetup.value()) { uint64_t memorySize = dramSys->getConfig().memSpec->getSimMemSizeInBytes(); - unsigned int dataLength = dramSys->getConfig().memSpec->defaultBytesPerBurst; + unsigned int defaultDataLength = dramSys->getConfig().memSpec->defaultBytesPerBurst; auto initiator = std::visit( [=, &memoryManager](auto &&config) -> std::unique_ptr @@ -120,7 +120,7 @@ int sc_main(int argc, char **argv) return std::make_unique(config, memoryManager, memorySize, - dataLength, + defaultDataLength, transactionFinished, termianteInitiator); } @@ -143,7 +143,7 @@ int sc_main(int argc, char **argv) } StlPlayer player( - tracePath.c_str(), config.clkMhz, dataLength, traceType, false); + tracePath.c_str(), config.clkMhz, defaultDataLength, traceType, false); return std::make_unique>(config.name.c_str(), memoryManager, @@ -156,7 +156,7 @@ int sc_main(int argc, char **argv) else if constexpr (std::is_same_v) { RowHammer hammer( - config.numRequests, config.clkMhz, config.rowIncrement, dataLength); + config.numRequests, config.clkMhz, config.rowIncrement, defaultDataLength); return std::make_unique>(config.name.c_str(), memoryManager, diff --git a/src/simulator/simulator/generator/RandomProducer.cpp b/src/simulator/simulator/generator/RandomProducer.cpp index d9e3fbd9..418f3f68 100644 --- a/src/simulator/simulator/generator/RandomProducer.cpp +++ b/src/simulator/simulator/generator/RandomProducer.cpp @@ -43,15 +43,17 @@ RandomProducer::RandomProducer(uint64_t numRequests, std::optional minAddress, std::optional maxAddress, uint64_t memorySize, - unsigned int dataLength) + unsigned int dataLength, + unsigned int dataAlignment) : numberOfRequests(numRequests), seed(seed.value_or(DEFAULT_SEED)), rwRatio(rwRatio), randomGenerator(this->seed), generatorPeriod(sc_core::sc_time(1.0 / static_cast(clkMhz), sc_core::SC_US)), dataLength(dataLength), + dataAlignment(dataAlignment), randomAddressDistribution(minAddress.value_or(DEFAULT_MIN_ADDRESS), - maxAddress.value_or((memorySize / dataLength) - 1)) + maxAddress.value_or((memorySize) - dataLength)) { if (minAddress > memorySize - 1) SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); @@ -69,7 +71,11 @@ RandomProducer::RandomProducer(uint64_t numRequests, Request RandomProducer::nextRequest() { Request request; - request.address = randomAddressDistribution(randomGenerator) * dataLength; + request.address = randomAddressDistribution(randomGenerator); + + // Align address + request.address = request.address - (request.address % dataAlignment); + request.command = readWriteDistribution(randomGenerator) < rwRatio ? Request::Command::Read : Request::Command::Write; request.length = dataLength; diff --git a/src/simulator/simulator/generator/RandomProducer.h b/src/simulator/simulator/generator/RandomProducer.h index c0f55322..1da6af9b 100644 --- a/src/simulator/simulator/generator/RandomProducer.h +++ b/src/simulator/simulator/generator/RandomProducer.h @@ -50,7 +50,8 @@ public: std::optional minAddress, std::optional maxAddress, uint64_t memorySize, - unsigned int dataLength); + unsigned int dataLength, + unsigned int dataAlignment); Request nextRequest() override; @@ -62,6 +63,7 @@ public: const double rwRatio; const sc_core::sc_time generatorPeriod; const unsigned int dataLength; + const unsigned int dataAlignment; std::default_random_engine randomGenerator; std::uniform_real_distribution readWriteDistribution{0.0, 1.0}; diff --git a/src/simulator/simulator/generator/TrafficGenerator.cpp b/src/simulator/simulator/generator/TrafficGenerator.cpp index 59639860..ac588b63 100644 --- a/src/simulator/simulator/generator/TrafficGenerator.cpp +++ b/src/simulator/simulator/generator/TrafficGenerator.cpp @@ -38,7 +38,7 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine const &config, MemoryManager &memoryManager, uint64_t memorySize, - unsigned int dataLength, + unsigned int defaultDataLength, std::function transactionFinished, std::function terminateInitiator) : consumer( @@ -51,6 +51,9 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine std::move(terminateInitiator)), stateTransistions(config.transitions) { + unsigned int dataLength = config.dataLength.value_or(defaultDataLength); + unsigned int dataAlignment = config.dataAlignment.value_or(dataLength); + for (auto const &state : config.states) { std::visit( @@ -72,7 +75,8 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine activeState.minAddress, activeState.maxAddress, memorySize, - dataLength); + dataLength, + dataAlignment); producers.emplace(activeState.id, std::move(producer)); } @@ -105,7 +109,7 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const &config, MemoryManager &memoryManager, uint64_t memorySize, - unsigned int dataLength, + unsigned int defaultDataLength, std::function transactionFinished, std::function terminateInitiator) : consumer( @@ -117,6 +121,9 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const &conf std::move(transactionFinished), std::move(terminateInitiator)) { + unsigned int dataLength = config.dataLength.value_or(defaultDataLength); + unsigned int dataAlignment = config.dataAlignment.value_or(dataLength); + if (config.addressDistribution == DRAMSys::Config::AddressDistribution::Random) { auto producer = std::make_unique(config.numRequests, @@ -126,7 +133,8 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const &conf config.minAddress, config.maxAddress, memorySize, - dataLength); + dataLength, + dataAlignment); producers.emplace(0, std::move(producer)); } else diff --git a/src/simulator/simulator/generator/TrafficGenerator.h b/src/simulator/simulator/generator/TrafficGenerator.h index 015e31b7..b7c92b93 100644 --- a/src/simulator/simulator/generator/TrafficGenerator.h +++ b/src/simulator/simulator/generator/TrafficGenerator.h @@ -49,14 +49,14 @@ public: TrafficGenerator(DRAMSys::Config::TrafficGenerator const &config, MemoryManager &memoryManager, uint64_t memorySize, - unsigned int dataLength, + unsigned int defaultDataLength, std::function transactionFinished, std::function terminateInitiator); TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine const &config, MemoryManager &memoryManager, uint64_t memorySize, - unsigned int dataLength, + unsigned int defaultDataLength, std::function transactionFinished, std::function terminateInitiator); diff --git a/src/simulator/simulator/player/DbiPlayer.h b/src/simulator/simulator/player/DbiPlayer.h deleted file mode 100644 index 2eedeeb7..00000000 --- a/src/simulator/simulator/player/DbiPlayer.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2022, 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: - * Lukas Steiner - * Derek Christ - */ - -#pragma once - -#include "request/Request.h" -#include "request/RequestProducer.h" - -class DbiProducer : public RequestProducer -{ - Request nextRequest() override {} - uint64_t totalRequests() override {} - sc_core::sc_time clkPeriod() override {} -}; From 56d43ac1d4fa4c62790acf20a1113cb611393b52 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Fri, 24 Mar 2023 12:22:38 +0100 Subject: [PATCH 14/20] Remove dead function in RequestIssuer --- src/simulator/simulator/request/RequestIssuer.cpp | 5 ----- src/simulator/simulator/request/RequestIssuer.h | 1 - 2 files changed, 6 deletions(-) diff --git a/src/simulator/simulator/request/RequestIssuer.cpp b/src/simulator/simulator/request/RequestIssuer.cpp index a7371fc6..5913e54e 100644 --- a/src/simulator/simulator/request/RequestIssuer.cpp +++ b/src/simulator/simulator/request/RequestIssuer.cpp @@ -110,11 +110,6 @@ bool RequestIssuer::nextRequestSendable() const return true; } -sc_core::sc_time RequestIssuer::alignToClock(sc_core::sc_time time) const -{ - -} - void RequestIssuer::peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) { if (phase == tlm::END_REQ) diff --git a/src/simulator/simulator/request/RequestIssuer.h b/src/simulator/simulator/request/RequestIssuer.h index 7c7d8c69..7f712997 100644 --- a/src/simulator/simulator/request/RequestIssuer.h +++ b/src/simulator/simulator/request/RequestIssuer.h @@ -83,7 +83,6 @@ private: void sendNextRequest(); bool nextRequestSendable() const; - sc_core::sc_time alignToClock(sc_core::sc_time time) const; tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, From 1f161b412fc20e5b1826d35ba2c5d898b7fed7ee Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Tue, 28 Mar 2023 13:55:35 +0200 Subject: [PATCH 15/20] Update documentation --- configs/README.md | 53 +++++++++++++++++++++++++++++++++++++---- src/simulator/README.md | 19 +++++++++++++++ 2 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 src/simulator/README.md diff --git a/configs/README.md b/configs/README.md index 279560e9..fdda34af 100644 --- a/configs/README.md +++ b/configs/README.md @@ -19,7 +19,6 @@ The JSON code below shows an example configuration: }, { "clkMhz": 2000, - "type": "generator", "name": "gen0", "numRequests": 2000, "rwRatio": 0.85, @@ -32,7 +31,6 @@ The JSON code below shows an example configuration: }, { "clkMhz": 1000, - "type": "hammer", "name": "ham0", "numRequests": 4000, "rowIncrement": 2097152 @@ -49,11 +47,58 @@ Field Descriptions: - "mcconfig": memory controller configuration file - "tracesetup": The trace setup is only used in standalone mode. In library mode or gem5 mode the trace setup is ignored. Each device should be added as a json object inside the "tracesetup" array. -Each **trace setup** device configuration can be a **trace player** ("type": "player"), a **traffic generator** ("type": "generator") or a **row hammer generator** ("type": "hammer"). By not specifing the **type** parameter, the device will act as a **trace player**. +Each **trace setup** device configuration can be a **trace player**, a **traffic generator** or a **row hammer generator**. The type will be automatically concluded based on the given parameters. All device configurations must define a **clkMhz** (operation frequency of the **traffic initiator**) and a **name** (in case of a trace player this specifies the **trace file** to play; in case of a generator this field is only for identification purposes). The **maxPendingReadRequests** and **maxPendingWriteRequests** parameters define the maximum number of outstanding read/write requests. The current implementation delays all memory accesses if one limit is reached. The default value (0) disables the limit. -A **traffic generator** can be configured to generate **numRequests** requests in total, of which the **rwRatio** field defines the probability of one request being a read request. The length of a request (in bytes) can be specified with the **dataLength** parameter. The **seed** parameter can be used to produce identical results for all simulations. **minAddress** and **maxAddress** specify the address range, by default the whole address range is used. The parameter **addressDistribution** can either be set to **random** or **sequential**. In case of **sequential** the additional **addressIncrement** field must be specified, defining the address increment after each request. +A **traffic generator** can be configured to generate **numRequests** requests in total, of which the **rwRatio** field defines the probability of one request being a read request. The length of a request (in bytes) can be specified with the **dataLength** parameter. The **seed** parameter can be used to produce identical results for all simulations. **minAddress** and **maxAddress** specify the address range, by default the whole address range is used. The parameter **addressDistribution** can either be set to **random** or **sequential**. In case of **sequential** the additional **addressIncrement** field must be specified, defining the address increment after each request. The address alignment of the random generator can be configured using the **dataAlignment** field. By default, the addresses will be naturally aligned at dataLength. + +For more advanced use cases, the traffic generator is capable of acting as a state machine with multiple states that can be configured in the same manner as described earlier. Each state is specified as an element in the **states** array. Each state has to include an unique **id**. The **transitions** field describes all possible transitions from one state to another with their associated **probability**. +In the context of a state machine, there exists another type of generator: the idle generator. In an idle state no requests are issued. The parameter **idleClks** specifies the duration of the idle state. + +An example of a state machine configuration with 3 states is shown below. + +```json +{ + "clkMhz": 100, + "maxPendingReadRequests": 8, + "name": "StateMachine", + "states": [ + { + "addressDistribution": "sequential", + "addressIncrement": 256, + "id": 0, + "maxAddress": 1024, + "numRequests": 1000, + "rwRatio": 0.5 + }, + { + "id": 1, + "idleClks": 1000 + }, + { + "addressDistribution": "random", + "id": 2, + "maxAddress": 2048, + "minAddress": 1024, + "numRequests": 1000, + "rwRatio": 0.75 + } + ], + "transitions": [ + { + "from": 0, + "probability": 1.0, + "to": 1 + }, + { + "from": 1, + "probability": 1.0, + "to": 2 + } + ] +} +``` The **row hammer generator** is a special traffic generator that mimics a row hammer attack. It generates **numRequests** alternating read requests to two different addresses. The first address is 0x0, the second address is specified by the **rowIncrement** parameter and should decode to a different row in the same bank. Since only one outstanding request is allowed, the controller cannot perform any reordering, forcing a row switch (precharge and activate) for each access. That way the number of activations on the target rows are maximized. diff --git a/src/simulator/README.md b/src/simulator/README.md new file mode 100644 index 00000000..8f8712b2 --- /dev/null +++ b/src/simulator/README.md @@ -0,0 +1,19 @@ +# Simulator +The **standalone** simulator features a set of trace players, traffic generators and miscellaneous components that can be coupled with DRAMSys. + +## Concept +Initiators in the simulator are split up into two disctinct components: **RequestProducers** and **RequestIssuers**. + +**RequestProducers** are simple C++ classes that implement the `RequestProducer` interface. Upon calling the `nextRequest()` method of a producer, a new `Request` is either generated on-the-fly or constructed from a trace file. + +**RequestIssuers** are the SystemC modules that connect with DRAMSys. Issuers have no knowledge of where the requests are coming from. They simply call their `nextRequest()` callback that it has been passed in the constructor to obtain the next request to be sent to DRAMSys. Using this concept, the generation and the issuing of request is completely decoupled to make very flexible initiator designs possible. + +**Initiators** implement the `Initiator` interface, which describes how the initiator is bound to DRAMSys. This abstracts over the actual socket type used by the initiator. +Complex initiators may implement the interface directly, but for simple cases, there exists the templated `SimpleInitiator` class. This specialized initiator consists of only one producer and one issuer that operate together. The `StlPlayer` and `RowHammer` issuers make use of the `SimpleInitiator`. +The `TrafficGenerator` is one example of a direct implementation of the `Initiator` interface, as it consists of many producers (which represent the states of the state machine) but of only one issuer. + +**Requests** are an abstraction over the TLM payloads the issuer generates. A request describes whether it is a read or a write access or an internal `Stop` request that tells the initiator to terminate. +The **delay** field specifies the time that should pass between the issuance of the previous and the current request. + +## Configuration +A detailed description on how to configure the traffic generators of the simulator can be found [here](../../configs/README.md). From 8f6e55f9fa610e84f775731dd945de9ba77e9fc6 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Thu, 13 Apr 2023 10:27:01 +0200 Subject: [PATCH 16/20] Enable StoreMode in new simulator and some refactoring --- .../DRAMSys/config/AddressMapping.h | 2 +- .../DRAMSys/config/ConfigUtil.cpp | 47 ------------- src/configuration/DRAMSys/config/ConfigUtil.h | 68 ------------------- .../DRAMSys/config/DRAMSysConfiguration.cpp | 2 - .../DRAMSys/config/DRAMSysConfiguration.h | 7 +- src/configuration/DRAMSys/config/McConfig.h | 2 +- src/configuration/DRAMSys/config/SimConfig.h | 2 +- src/configuration/DRAMSys/config/TraceSetup.h | 2 +- .../config/memspec/MemArchitectureSpec.h | 2 +- .../DRAMSys/config/memspec/MemPowerSpec.h | 2 +- .../DRAMSys/config/memspec/MemSpec.h | 2 +- .../DRAMSys/config/memspec/MemTimingSpec.h | 2 +- src/simulator/main.cpp | 3 +- src/util/DRAMSys/util/json.h | 4 -- 14 files changed, 12 insertions(+), 135 deletions(-) delete mode 100644 src/configuration/DRAMSys/config/ConfigUtil.cpp delete mode 100644 src/configuration/DRAMSys/config/ConfigUtil.h diff --git a/src/configuration/DRAMSys/config/AddressMapping.h b/src/configuration/DRAMSys/config/AddressMapping.h index 333f6b38..53d285ef 100644 --- a/src/configuration/DRAMSys/config/AddressMapping.h +++ b/src/configuration/DRAMSys/config/AddressMapping.h @@ -36,7 +36,7 @@ #ifndef DRAMSYSCONFIGURATION_ADDRESSMAPPING_H #define DRAMSYSCONFIGURATION_ADDRESSMAPPING_H -#include "DRAMSys/config/ConfigUtil.h" +#include "DRAMSys/util/json.h" #include diff --git a/src/configuration/DRAMSys/config/ConfigUtil.cpp b/src/configuration/DRAMSys/config/ConfigUtil.cpp deleted file mode 100644 index 9c57324c..00000000 --- a/src/configuration/DRAMSys/config/ConfigUtil.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 "ConfigUtil.h" - -#include "DRAMSys/config/DRAMSysConfiguration.h" - -#include -#include -#include - -namespace DRAMSys::Config -{ - -} // namespace DRAMSys::Config diff --git a/src/configuration/DRAMSys/config/ConfigUtil.h b/src/configuration/DRAMSys/config/ConfigUtil.h deleted file mode 100644 index 81fe55ea..00000000 --- a/src/configuration/DRAMSys/config/ConfigUtil.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 "DRAMSys/util/json.h" - -#include -#include - -namespace DRAMSys::Config -{ - template - void invalidateEnum(T& value) - { - if (value.has_value() && value.value() == T::value_type::Invalid) - value.reset(); - } - - inline void remove_null_values(json_t& j) - { - std::vector keysToRemove; - - for (const auto& element : j.items()) - { - if (element.value() == nullptr) - keysToRemove.emplace_back(element.key()); - } - - std::for_each(keysToRemove.begin(), keysToRemove.end(), [&](const std::string& key) { j.erase(key); }); - } - -} // namespace DRAMSys::Config - -#endif // DRAMSYSCONFIGURATION_UTIL_H diff --git a/src/configuration/DRAMSys/config/DRAMSysConfiguration.cpp b/src/configuration/DRAMSys/config/DRAMSysConfiguration.cpp index 33d2d81a..324929fd 100644 --- a/src/configuration/DRAMSys/config/DRAMSysConfiguration.cpp +++ b/src/configuration/DRAMSys/config/DRAMSysConfiguration.cpp @@ -35,8 +35,6 @@ #include "DRAMSysConfiguration.h" -#include "ConfigUtil.h" - #include #include diff --git a/src/configuration/DRAMSys/config/DRAMSysConfiguration.h b/src/configuration/DRAMSys/config/DRAMSysConfiguration.h index 18e45805..ada4f444 100644 --- a/src/configuration/DRAMSys/config/DRAMSysConfiguration.h +++ b/src/configuration/DRAMSys/config/DRAMSysConfiguration.h @@ -41,19 +41,16 @@ #include "DRAMSys/config/SimConfig.h" #include "DRAMSys/config/TraceSetup.h" #include "DRAMSys/config/memspec/MemSpec.h" -#include "DRAMSys/config/ConfigUtil.h" #include #include /** - * To support polymorphic configurations, a Json "type" tag is used - * to determine the correct type before further parsing. - * * To support optional values, std::optional is used. The default * values will be provided by DRAMSys itself. * - * To achieve static polymorphism, std::variant is used. + * To achieve static polymorphism, std::variant is used. The concrete + * type is determined by the provided fields automatically. * * To achieve backwards compatibility, this library manipulates the json * data type as it is parsed in to substitute paths to sub-configurations diff --git a/src/configuration/DRAMSys/config/McConfig.h b/src/configuration/DRAMSys/config/McConfig.h index 361716b6..79437024 100644 --- a/src/configuration/DRAMSys/config/McConfig.h +++ b/src/configuration/DRAMSys/config/McConfig.h @@ -36,7 +36,7 @@ #ifndef DRAMSYSCONFIGURATION_MCCONFIG_H #define DRAMSYSCONFIGURATION_MCCONFIG_H -#include "DRAMSys/config/ConfigUtil.h" +#include "DRAMSys/util/json.h" #include #include diff --git a/src/configuration/DRAMSys/config/SimConfig.h b/src/configuration/DRAMSys/config/SimConfig.h index d7d0376b..a05da277 100644 --- a/src/configuration/DRAMSys/config/SimConfig.h +++ b/src/configuration/DRAMSys/config/SimConfig.h @@ -36,7 +36,7 @@ #ifndef DRAMSYSCONFIGURATION_SIMCONFIG_H #define DRAMSYSCONFIGURATION_SIMCONFIG_H -#include "DRAMSys/config/ConfigUtil.h" +#include "DRAMSys/util/json.h" #include diff --git a/src/configuration/DRAMSys/config/TraceSetup.h b/src/configuration/DRAMSys/config/TraceSetup.h index 54c1fd25..1b67c82e 100644 --- a/src/configuration/DRAMSys/config/TraceSetup.h +++ b/src/configuration/DRAMSys/config/TraceSetup.h @@ -36,7 +36,7 @@ #ifndef DRAMSYSCONFIGURATION_TRACESETUP_H #define DRAMSYSCONFIGURATION_TRACESETUP_H -#include "DRAMSys/config/ConfigUtil.h" +#include "DRAMSys/util/json.h" #include #include diff --git a/src/configuration/DRAMSys/config/memspec/MemArchitectureSpec.h b/src/configuration/DRAMSys/config/memspec/MemArchitectureSpec.h index 328140a4..d3424cd8 100644 --- a/src/configuration/DRAMSys/config/memspec/MemArchitectureSpec.h +++ b/src/configuration/DRAMSys/config/memspec/MemArchitectureSpec.h @@ -36,7 +36,7 @@ #ifndef DRAMSYSCONFIGURATION_MEMARCHITECTURESPEC_H #define DRAMSYSCONFIGURATION_MEMARCHITECTURESPEC_H -#include "DRAMSys/config/ConfigUtil.h" +#include "DRAMSys/util/json.h" #include diff --git a/src/configuration/DRAMSys/config/memspec/MemPowerSpec.h b/src/configuration/DRAMSys/config/memspec/MemPowerSpec.h index 1c85879f..4099bc90 100644 --- a/src/configuration/DRAMSys/config/memspec/MemPowerSpec.h +++ b/src/configuration/DRAMSys/config/memspec/MemPowerSpec.h @@ -36,7 +36,7 @@ #ifndef DRAMSYSCONFIGURATION_MEMPOWERSPEC_H #define DRAMSYSCONFIGURATION_MEMPOWERSPEC_H -#include "DRAMSys/config/ConfigUtil.h" +#include "DRAMSys/util/json.h" #include diff --git a/src/configuration/DRAMSys/config/memspec/MemSpec.h b/src/configuration/DRAMSys/config/memspec/MemSpec.h index 4521534b..adb00acf 100644 --- a/src/configuration/DRAMSys/config/memspec/MemSpec.h +++ b/src/configuration/DRAMSys/config/memspec/MemSpec.h @@ -36,7 +36,7 @@ #ifndef DRAMSYSCONFIGURATION_MEMSPEC_H #define DRAMSYSCONFIGURATION_MEMSPEC_H -#include "DRAMSys/config/ConfigUtil.h" +#include "DRAMSys/util/json.h" #include "DRAMSys/config/memspec/MemArchitectureSpec.h" #include "DRAMSys/config/memspec/MemPowerSpec.h" #include "DRAMSys/config/memspec/MemTimingSpec.h" diff --git a/src/configuration/DRAMSys/config/memspec/MemTimingSpec.h b/src/configuration/DRAMSys/config/memspec/MemTimingSpec.h index 4f68bc06..435f3e3a 100644 --- a/src/configuration/DRAMSys/config/memspec/MemTimingSpec.h +++ b/src/configuration/DRAMSys/config/memspec/MemTimingSpec.h @@ -36,7 +36,7 @@ #ifndef DRAMSYSCONFIGURATION_MEMTIMINGSPEC_H #define DRAMSYSCONFIGURATION_MEMTIMINGSPEC_H -#include "DRAMSys/config/ConfigUtil.h" +#include "DRAMSys/util/json.h" #include diff --git a/src/simulator/main.cpp b/src/simulator/main.cpp index e35ddc8f..66fbf903 100644 --- a/src/simulator/main.cpp +++ b/src/simulator/main.cpp @@ -84,7 +84,8 @@ int sc_main(int argc, char **argv) dramSys = std::make_unique("DRAMSys", configuration); } - MemoryManager memoryManager(false); + bool storageEnabled = dramSys->getConfig().storeMode == Configuration::StoreMode::Store; + MemoryManager memoryManager(storageEnabled); std::vector> initiators; diff --git a/src/util/DRAMSys/util/json.h b/src/util/DRAMSys/util/json.h index 8c09489e..ae8c047c 100644 --- a/src/util/DRAMSys/util/json.h +++ b/src/util/DRAMSys/util/json.h @@ -1,9 +1,5 @@ /* -<<<<<<< HEAD * Copyright (c) 2021, Technische Universität Kaiserslautern -======= - * Copyright (c) 2021, Technische Universit�t Kaiserslautern ->>>>>>> 6a800d9a (Refactor SimConfig to use new jsonify macro) * All rights reserved. * * Redistribution and use in source and binary forms, with or without From b343ea821fc750deba380624c7544caf1cfe0964 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Thu, 13 Apr 2023 11:10:03 +0200 Subject: [PATCH 17/20] Refactor Configuration and add warnings when invalid values are provided --- configs/simconfig/example.json | 2 +- .../DRAMSys/configuration/Configuration.cpp | 296 ++++++++++-------- 2 files changed, 164 insertions(+), 134 deletions(-) diff --git a/configs/simconfig/example.json b/configs/simconfig/example.json index 6b65d7d0..205c2125 100644 --- a/configs/simconfig/example.json +++ b/configs/simconfig/example.json @@ -2,7 +2,7 @@ "simconfig": { "AddressOffset": 0, "CheckTLM2Protocol": false, - "DatabaseRecording": true, + "DatabaseRecording": false, "Debug": false, "EnableWindowing": false, "PowerAnalysis": false, diff --git a/src/libdramsys/DRAMSys/configuration/Configuration.cpp b/src/libdramsys/DRAMSys/configuration/Configuration.cpp index e4aa0d80..1661e8ec 100644 --- a/src/libdramsys/DRAMSys/configuration/Configuration.cpp +++ b/src/libdramsys/DRAMSys/configuration/Configuration.cpp @@ -86,165 +86,195 @@ enum sc_time_unit string2TimeUnit(const std::string &s) } void Configuration::loadSimConfig(const DRAMSys::Config::SimConfig &simConfig) -{ - if (const auto& _addressOffset = simConfig.AddressOffset) - addressOffset = *_addressOffset; +{ + addressOffset = simConfig.AddressOffset.value_or(addressOffset); + checkTLM2Protocol = simConfig.CheckTLM2Protocol.value_or(checkTLM2Protocol); + databaseRecording = simConfig.DatabaseRecording.value_or(databaseRecording); + debug = simConfig.Debug.value_or(debug); + enableWindowing = simConfig.EnableWindowing.value_or(enableWindowing); + simulationName = simConfig.SimulationName.value_or(simulationName); + simulationProgressBar = simConfig.SimulationProgressBar.value_or(simulationProgressBar); + useMalloc = simConfig.UseMalloc.value_or(useMalloc); - if (const auto& _checkTLM2Protocol = simConfig.CheckTLM2Protocol) - checkTLM2Protocol = *_checkTLM2Protocol; - - if (const auto& _databaseRecording = simConfig.DatabaseRecording) - databaseRecording = *_databaseRecording; - - if (const auto& _debug = simConfig.Debug) - debug = *_debug; - - if (const auto& _enableWindowing = simConfig.EnableWindowing) - enableWindowing = *_enableWindowing; - - if (const auto& _powerAnalysis = simConfig.PowerAnalysis) - { - powerAnalysis = *_powerAnalysis; -#ifndef DRAMPOWER - if (powerAnalysis) - SC_REPORT_FATAL("Configuration", "Power analysis is only supported with included DRAMPower library!"); -#endif - } - - if (const auto& _simulationName = simConfig.SimulationName) - simulationName = *_simulationName; - - if (const auto& _simulationProgressBar = simConfig.SimulationProgressBar) - simulationProgressBar = *_simulationProgressBar; - - if (const auto& _useMalloc = simConfig.UseMalloc) - useMalloc = *_useMalloc; - - if (const auto& _windowSize = simConfig.WindowSize) - windowSize = *_windowSize; + if (const auto &_storeMode = simConfig.StoreMode) + storeMode = [=] + { + switch (*_storeMode) + { + case DRAMSys::Config::StoreModeType::NoStorage: + return StoreMode::NoStorage; + case DRAMSys::Config::StoreModeType::Store: + return StoreMode::Store; + default: + SC_REPORT_FATAL("Configuration", "Invalid StoreMode"); + return StoreMode::NoStorage; // Silence Warning + } + }(); + windowSize = simConfig.WindowSize.value_or(windowSize); if (windowSize == 0) SC_REPORT_FATAL("Configuration", "Minimum window size is 1"); - if (const auto& _storeMode = simConfig.StoreMode) - storeMode = [=] { - if (_storeMode == DRAMSys::Config::StoreModeType::NoStorage) - return StoreMode::NoStorage; - else // (_storeMode == DRAMSys::Config::StoreMode::Store) - return StoreMode::Store; - }(); + powerAnalysis = simConfig.PowerAnalysis.value_or(powerAnalysis); +#ifndef DRAMPOWER + if (powerAnalysis) + SC_REPORT_FATAL("Configuration", "Power analysis is only supported with included DRAMPower library!"); +#endif } void Configuration::loadMCConfig(const DRAMSys::Config::McConfig &mcConfig) { - if (const auto& _pagePolicy = mcConfig.PagePolicy) - pagePolicy = [=] { - if (_pagePolicy == DRAMSys::Config::PagePolicyType::Open) + if (const auto &_pagePolicy = mcConfig.PagePolicy) + pagePolicy = [=] + { + switch (*_pagePolicy) + { + case DRAMSys::Config::PagePolicyType::Open: return PagePolicy::Open; - else if (_pagePolicy == DRAMSys::Config::PagePolicyType::OpenAdaptive) + case DRAMSys::Config::PagePolicyType::OpenAdaptive: return PagePolicy::OpenAdaptive; - else if (_pagePolicy == DRAMSys::Config::PagePolicyType::Closed) + case DRAMSys::Config::PagePolicyType::Closed: return PagePolicy::Closed; - else + case DRAMSys::Config::PagePolicyType::ClosedAdaptive: return PagePolicy::ClosedAdaptive; + default: + SC_REPORT_FATAL("Configuration", "Invalid PagePolicy"); + return PagePolicy::Open; // Silence Warning + } }(); - if (const auto& _scheduler = mcConfig.Scheduler) - scheduler = [=] { - if (_scheduler == DRAMSys::Config::SchedulerType::Fifo) - return Scheduler::Fifo; - else if (_scheduler == DRAMSys::Config::SchedulerType::FrFcfs) - return Scheduler::FrFcfs; - else if (_scheduler == DRAMSys::Config::SchedulerType::FrFcfsGrp) - return Scheduler::FrFcfsGrp; - else if (_scheduler == DRAMSys::Config::SchedulerType::GrpFrFcfs) - return Scheduler::GrpFrFcfs; - else - return Scheduler::GrpFrFcfsWm; + if (const auto &_scheduler = mcConfig.Scheduler) + scheduler = [=] + { + switch (*_scheduler) + { + case DRAMSys::Config::SchedulerType::Fifo: + return Scheduler::Fifo; + case DRAMSys::Config::SchedulerType::FrFcfs: + return Scheduler::FrFcfs; + case DRAMSys::Config::SchedulerType::FrFcfsGrp: + return Scheduler::FrFcfsGrp; + case DRAMSys::Config::SchedulerType::GrpFrFcfs: + return Scheduler::GrpFrFcfs; + case DRAMSys::Config::SchedulerType::GrpFrFcfsWm: + return Scheduler::GrpFrFcfsWm; + default: + SC_REPORT_FATAL("Configuration", "Invalid Scheduler"); + return Scheduler::Fifo; // Silence Warning + } }(); - if (const auto& _highWatermark = mcConfig.HighWatermark) - highWatermark = *mcConfig.HighWatermark; - - if (const auto& _lowWatermark = mcConfig.LowWatermark) - lowWatermark = *mcConfig.LowWatermark; - - if (const auto& _schedulerBuffer = mcConfig.SchedulerBuffer) - schedulerBuffer = [=] { - if (_schedulerBuffer == DRAMSys::Config::SchedulerBufferType::Bankwise) + if (const auto &_schedulerBuffer = mcConfig.SchedulerBuffer) + schedulerBuffer = [=] + { + switch (*_schedulerBuffer) + { + case DRAMSys::Config::SchedulerBufferType::Bankwise: return SchedulerBuffer::Bankwise; - else if (_schedulerBuffer == DRAMSys::Config::SchedulerBufferType::ReadWrite) + case DRAMSys::Config::SchedulerBufferType::ReadWrite: return SchedulerBuffer::ReadWrite; - else + case DRAMSys::Config::SchedulerBufferType::Shared: return SchedulerBuffer::Shared; + default: + SC_REPORT_FATAL("Configuration", "Invalid SchedulerBuffer"); + return SchedulerBuffer::Bankwise; // Silence Warning + } }(); - if (const auto& _requestBufferSize = mcConfig.RequestBufferSize) - requestBufferSize = *mcConfig.RequestBufferSize; + if (const auto &_cmdMux = mcConfig.CmdMux) + cmdMux = [=] + { + switch (*_cmdMux) + { + case DRAMSys::Config::CmdMuxType::Oldest: + return CmdMux::Oldest; + case DRAMSys::Config::CmdMuxType::Strict: + return CmdMux::Strict; + default: + SC_REPORT_FATAL("Configuration", "Invalid CmdMux"); + return CmdMux::Oldest; // Silence Warning + } + }(); + if (const auto &_respQueue = mcConfig.RespQueue) + respQueue = [=] + { + switch (*_respQueue) + { + case DRAMSys::Config::RespQueueType::Fifo: + return RespQueue::Fifo; + case DRAMSys::Config::RespQueueType::Reorder: + return RespQueue::Reorder; + default: + SC_REPORT_FATAL("Configuration", "Invalid RespQueue"); + return RespQueue::Fifo; // Silence Warning + } + }(); + + if (const auto &_refreshPolicy = mcConfig.RefreshPolicy) + refreshPolicy = [=] + { + switch (*_refreshPolicy) + { + case DRAMSys::Config::RefreshPolicyType::NoRefresh: + return RefreshPolicy::NoRefresh; + case DRAMSys::Config::RefreshPolicyType::AllBank: + return RefreshPolicy::AllBank; + case DRAMSys::Config::RefreshPolicyType::PerBank: + return RefreshPolicy::PerBank; + case DRAMSys::Config::RefreshPolicyType::Per2Bank: + return RefreshPolicy::Per2Bank; + case DRAMSys::Config::RefreshPolicyType::SameBank: + return RefreshPolicy::SameBank; + default: + SC_REPORT_FATAL("Configuration", "Invalid RefreshPolicy"); + return RefreshPolicy::NoRefresh; // Silence Warning + } + }(); + + if (const auto &_powerDownPolicy = mcConfig.PowerDownPolicy) + powerDownPolicy = [=] + { + switch (*_powerDownPolicy) + { + case DRAMSys::Config::PowerDownPolicyType::NoPowerDown: + return PowerDownPolicy::NoPowerDown; + case DRAMSys::Config::PowerDownPolicyType::Staggered: + return PowerDownPolicy::Staggered; + default: + SC_REPORT_FATAL("Configuration", "Invalid PowerDownPolicy"); + return PowerDownPolicy::NoPowerDown; // Silence Warning + } + }(); + + if (const auto &_arbiter = mcConfig.Arbiter) + arbiter = [=] + { + switch (*_arbiter) + { + case DRAMSys::Config::ArbiterType::Simple: + return Arbiter::Simple; + case DRAMSys::Config::ArbiterType::Fifo: + return Arbiter::Fifo; + case DRAMSys::Config::ArbiterType::Reorder: + return Arbiter::Reorder; + default: + SC_REPORT_FATAL("Configuration", "Invalid Arbiter"); + return Arbiter::Simple; // Silence Warning + } + }(); + + refreshMaxPostponed = mcConfig.RefreshMaxPostponed.value_or(refreshMaxPostponed); + refreshMaxPulledin = mcConfig.RefreshMaxPulledin.value_or(refreshMaxPulledin); + highWatermark = mcConfig.HighWatermark.value_or(highWatermark); + lowWatermark = mcConfig.LowWatermark.value_or(lowWatermark); + maxActiveTransactions = mcConfig.MaxActiveTransactions.value_or(maxActiveTransactions); + refreshManagement = mcConfig.RefreshManagement.value_or(refreshManagement); + + requestBufferSize = mcConfig.RequestBufferSize.value_or(requestBufferSize); if (requestBufferSize == 0) SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!"); - if (const auto& _cmdMux = mcConfig.CmdMux) - cmdMux = [=] { - if (_cmdMux == DRAMSys::Config::CmdMuxType::Oldest) - return CmdMux::Oldest; - else - return CmdMux::Strict; - }(); - - if (const auto& _respQueue = mcConfig.RespQueue) - respQueue = [=] { - if (_respQueue == DRAMSys::Config::RespQueueType::Fifo) - return RespQueue::Fifo; - else - return RespQueue::Reorder; - }(); - - if (const auto& _refreshPolicy = mcConfig.RefreshPolicy) - refreshPolicy = [=] { - if (_refreshPolicy == DRAMSys::Config::RefreshPolicyType::NoRefresh) - return RefreshPolicy::NoRefresh; - else if (_refreshPolicy == DRAMSys::Config::RefreshPolicyType::AllBank) - return RefreshPolicy::AllBank; - else if (_refreshPolicy == DRAMSys::Config::RefreshPolicyType::PerBank) - return RefreshPolicy::PerBank; - else if (_refreshPolicy == DRAMSys::Config::RefreshPolicyType::Per2Bank) - return RefreshPolicy::Per2Bank; - else // if (policy == DRAMSys::Config::RefreshPolicy::SameBank) - return RefreshPolicy::SameBank; - }(); - - if (const auto& _refreshMaxPostponed = mcConfig.RefreshMaxPostponed) - refreshMaxPostponed = *_refreshMaxPostponed; - - if (const auto& _refreshMaxPulledin = mcConfig.RefreshMaxPulledin) - refreshMaxPulledin = *_refreshMaxPulledin; - - if (const auto& _powerDownPolicy = mcConfig.PowerDownPolicy) - powerDownPolicy = [=] { - if (_powerDownPolicy == DRAMSys::Config::PowerDownPolicyType::NoPowerDown) - return PowerDownPolicy::NoPowerDown; - else - return PowerDownPolicy::Staggered; - }(); - - if (const auto& _arbiter = mcConfig.Arbiter) - arbiter = [=] { - if (_arbiter == DRAMSys::Config::ArbiterType::Simple) - return Arbiter::Simple; - else if (_arbiter == DRAMSys::Config::ArbiterType::Fifo) - return Arbiter::Fifo; - else - return Arbiter::Reorder; - }(); - - if (const auto& _maxActiveTransactions = mcConfig.MaxActiveTransactions) - maxActiveTransactions = *_maxActiveTransactions; - - if (const auto& _refreshManagement = mcConfig.RefreshManagement) - refreshManagement = *_refreshManagement; - if (const auto& _arbitrationDelayFw = mcConfig.ArbitrationDelayFw) { arbitrationDelayFw = std::round(sc_time(*_arbitrationDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK; From aa07f071aa538ad67ad8aab1ffe43247d3fa0df5 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Thu, 13 Apr 2023 11:34:27 +0200 Subject: [PATCH 18/20] Update AddressDecoderTest --- tests/tests_dramsys/AddressDecoderConfigs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/tests_dramsys/AddressDecoderConfigs.h b/tests/tests_dramsys/AddressDecoderConfigs.h index 17e18d79..1b3585cc 100644 --- a/tests/tests_dramsys/AddressDecoderConfigs.h +++ b/tests/tests_dramsys/AddressDecoderConfigs.h @@ -56,7 +56,8 @@ inline constexpr std::string_view memSpecJsonString = R"( "memoryId": "JEDEC_1Gbx16_BG_LPDDR5-6400", "memoryType": "LPDDR5", "memtimingspec": { - "RCD": 15, + "RCD_L": 15, + "RCD_S": 15, "PPD": 2, "RPab": 17, "RPpb": 15, From ad4277c0eef512d6c3d357fc34a2cb4d09001a4d Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Fri, 14 Apr 2023 11:11:40 +0200 Subject: [PATCH 19/20] Enable DatabaseRecording by default again --- configs/simconfig/example.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/simconfig/example.json b/configs/simconfig/example.json index 205c2125..6b65d7d0 100644 --- a/configs/simconfig/example.json +++ b/configs/simconfig/example.json @@ -2,7 +2,7 @@ "simconfig": { "AddressOffset": 0, "CheckTLM2Protocol": false, - "DatabaseRecording": false, + "DatabaseRecording": true, "Debug": false, "EnableWindowing": false, "PowerAnalysis": false, From f844449d505f563460b23f163597295080d4c1ba Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 14 Apr 2023 11:21:36 +0200 Subject: [PATCH 20/20] Remove empty cpp files. --- .../DRAMSys/config/AddressMapping.cpp | 43 ------------------- .../DRAMSys/config/SimConfig.cpp | 41 ------------------ .../DRAMSys/config/TraceSetup.cpp | 42 ------------------ .../DRAMSys/config/memspec/MemSpec.cpp | 41 ------------------ src/configuration/Notes.txt | 6 --- 5 files changed, 173 deletions(-) delete mode 100644 src/configuration/DRAMSys/config/AddressMapping.cpp delete mode 100644 src/configuration/DRAMSys/config/SimConfig.cpp delete mode 100644 src/configuration/DRAMSys/config/TraceSetup.cpp delete mode 100644 src/configuration/DRAMSys/config/memspec/MemSpec.cpp delete mode 100644 src/configuration/Notes.txt diff --git a/src/configuration/DRAMSys/config/AddressMapping.cpp b/src/configuration/DRAMSys/config/AddressMapping.cpp deleted file mode 100644 index 857683b2..00000000 --- a/src/configuration/DRAMSys/config/AddressMapping.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2021, Technische Universität Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Derek Christ - */ - -#include "AddressMapping.h" - -#include - -namespace DRAMSys::Config -{ - -} // namespace DRAMSys::Config diff --git a/src/configuration/DRAMSys/config/SimConfig.cpp b/src/configuration/DRAMSys/config/SimConfig.cpp deleted file mode 100644 index a8fb685e..00000000 --- a/src/configuration/DRAMSys/config/SimConfig.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 DRAMSys::Config -{ - -} // namespace DRAMSys::Config diff --git a/src/configuration/DRAMSys/config/TraceSetup.cpp b/src/configuration/DRAMSys/config/TraceSetup.cpp deleted file mode 100644 index 0b08777c..00000000 --- a/src/configuration/DRAMSys/config/TraceSetup.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2021, Technische Universität Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Derek Christ - */ - -#include "TraceSetup.h" - -#include - -namespace DRAMSys::Config { - -} // namespace DRAMSys::Config diff --git a/src/configuration/DRAMSys/config/memspec/MemSpec.cpp b/src/configuration/DRAMSys/config/memspec/MemSpec.cpp deleted file mode 100644 index b9aca438..00000000 --- a/src/configuration/DRAMSys/config/memspec/MemSpec.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 DRAMSys::Config -{ - -} // namespace Configuration diff --git a/src/configuration/Notes.txt b/src/configuration/Notes.txt deleted file mode 100644 index 122aab7b..00000000 --- a/src/configuration/Notes.txt +++ /dev/null @@ -1,6 +0,0 @@ -Things to refactor in the configuration format: - - Embed the resource directory directly into the base configuration OR - - Specify the full (relative) path to each sub-configuration - - - Remove diverging sub-config base key names in base config and in the sub-config (i.e. remove the INNER_KEYs in the code) - - Remove redundant CONGEN type from the addressmapping