From 911a6cfe7b5ea2ee984de80fe3e51ebe0db42ed6 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 14 Aug 2020 13:59:46 +0200 Subject: [PATCH 01/50] Add initial memspec for DDR5. --- .../src/configuration/memspec/MemSpecDDR5.cpp | 142 ++++++++++++++++++ .../src/configuration/memspec/MemSpecDDR5.h | 89 +++++++++++ 2 files changed, 231 insertions(+) create mode 100644 DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp create mode 100644 DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp new file mode 100644 index 00000000..dca14f33 --- /dev/null +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2020, 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 "MemSpecDDR5.h" +#include "../Configuration.h" + +using namespace tlm; +using json = nlohmann::json; + +MemSpecDDR5::MemSpecDDR5(json &memspec) + : MemSpec(memspec, + parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), + parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), + parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), + parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups"), + parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks") + / parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups"), + parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks") + * parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), + parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups") + * parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), + parseUint(memspec["memarchitecturespec"]["nbrOfDevicesOnDIMM"],"nbrOfDevicesOnDIMM")), + tCKE (tCK * parseUint(memspec["memtimingspec"]["CKE"], "CKE")), + tPD (tCKE), + tCKESR (tCK * parseUint(memspec["memtimingspec"]["CKESR"], "CKESR")), + tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")), + tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")), + tRC (tCK * parseUint(memspec["memtimingspec"]["RC"], "RC")), + tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")), + tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")), + tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")), + tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")), + tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")), + tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")), + tXS (tCK * parseUint(memspec["memtimingspec"]["XS"], "XS")), + tCCD_S (tCK * parseUint(memspec["memtimingspec"]["CCD_S"], "CCD_S")), + tCCD_L (tCK * parseUint(memspec["memtimingspec"]["CCD_L"], "CCD_L")), + tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")), + tREFI ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 4) ? + (tCK * (parseUint(memspec["memtimingspec"]["REFI"], "REFI") / 4)) : + ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 2) ? + (tCK * (parseUint(memspec["memtimingspec"]["REFI"], "REFI") / 2)) : + (tCK * parseUint(memspec["memtimingspec"]["REFI"], "REFI")))), + tRFC ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 4) ? + (tCK * parseUint(memspec["memtimingspec"]["RFC4"], "RFC4")) : + ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 2) ? + (tCK * parseUint(memspec["memtimingspec"]["RFC2"], "RFC2")) : + (tCK * parseUint(memspec["memtimingspec"]["RFC"], "RFC")))), + tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), + tRRD_S (tCK * parseUint(memspec["memtimingspec"]["RRD_S"], "RRD_S")), + tRRD_L (tCK * parseUint(memspec["memtimingspec"]["RRD_L"], "RRD_L")), + tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")), + tWTR_L (tCK * parseUint(memspec["memtimingspec"]["WTR_L"], "WTR_L")), + tAL (tCK * parseUint(memspec["memtimingspec"]["AL"], "AL")), + tXPDLL (tCK * parseUint(memspec["memtimingspec"]["XPDLL"], "XPDLL")), + tXSDLL (tCK * parseUint(memspec["memtimingspec"]["XSDLL"], "XSDLL")), + tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")), + tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")), + tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")), + tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")) +{} + +sc_time MemSpecDDR5::getRefreshIntervalAB() const +{ + return tREFI; +} + +sc_time MemSpecDDR5::getRefreshIntervalPB() const +{ + SC_REPORT_FATAL("MemSpecDDR5", "Per bank refresh not supported"); + return SC_ZERO_TIME; +} + +// Returns the execution time for commands that have a fixed execution time +sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload &) const +{ + if (command == Command::PRE || command == Command::PREA) + return tRP; + else if (command == Command::ACT) + return tRCD; + else if (command == Command::RD) + return tRL + burstDuration; + else if (command == Command::RDA) + return tRTP + tRP; + else if (command == Command::WR) + return tWL + burstDuration; + else if (command == Command::WRA) + return tWL + burstDuration + tWR + tRP; + else if (command == Command::REFA) + return tRFC; + else + { + SC_REPORT_FATAL("getExecutionTime", + "command not known or command doesn't have a fixed execution time"); + return SC_ZERO_TIME; + } +} + +TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command) const +{ + if (command == Command::RD || command == Command::RDA) + return TimeInterval(sc_time_stamp() + tRL, sc_time_stamp() + tRL + burstDuration); + else if (command == Command::WR || command == Command::WRA) + return TimeInterval(sc_time_stamp() + tWL, sc_time_stamp() + tWL + burstDuration); + else + { + SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument"); + return TimeInterval(); + } +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h new file mode 100644 index 00000000..cc9dcda8 --- /dev/null +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020, 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 + */ + +#ifndef MEMSPECDDR5_H +#define MEMSPECDDR5_H + +#include "MemSpec.h" +#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" + +class MemSpecDDR5 final : public MemSpec +{ +public: + MemSpecDDR5(nlohmann::json &memspec); + + // Memspec Variables: + const sc_time tRCD; + const sc_time tPPD; + const sc_time tRP; + const sc_time tRAS; + const sc_time tRL; + const sc_time tRTP; + const sc_time tRPRE; + const sc_time tRPST; + const sc_time tRDQSOFF; + const sc_time tWL; + const sc_time tWR; + const sc_time tWTR_L; + const sc_time tWTR_S; + const sc_time tWPRE; + const sc_time tWPST; + const sc_time tCCD_L_slr; + const sc_time tCCD_S_slr; + const sc_time tCCD_dlr; + const sc_time tCCD_L_WR_slr; + const sc_time tCCD_S_WR_slr; + const sc_time tCCD_WR_dlr; + const sc_time tCCD_WR_dpr; + const sc_time + const sc_time + const sc_time + const sc_time + const sc_time + const sc_time + const sc_time + const sc_time + + // Currents and Voltages: + // TODO: to be completed + + virtual sc_time getRefreshIntervalPB() const override; + virtual sc_time getRefreshIntervalAB() const override; + + virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command) const override; +}; + +#endif // MEMSPECDDR5_H From d2a90773eb539f9ec5c48988d1411157ddc4965c Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 18 Aug 2020 10:12:19 +0200 Subject: [PATCH 02/50] Add read and write preambles to DDR4. --- .../configs/memspecs/JEDEC_4Gb_DDR4-1866_8bit_A.json | 2 ++ .../configs/memspecs/JEDEC_4Gb_DDR4-2400_8bit_A.json | 2 ++ .../configs/memspecs/MICRON_4Gb_DDR4-1866_8bit_A.json | 2 ++ .../configs/memspecs/MICRON_4Gb_DDR4-2400_8bit_A.json | 2 ++ .../library/src/configuration/memspec/MemSpecDDR4.cpp | 10 ++++++---- .../library/src/configuration/memspec/MemSpecDDR4.h | 2 ++ DRAMSys/library/src/controller/checker/CheckerDDR4.cpp | 6 +++--- .../configs/memspecs/MICRON_4Gb_DDR4-1866_8bit_A.json | 2 ++ 8 files changed, 21 insertions(+), 7 deletions(-) diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_4Gb_DDR4-1866_8bit_A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_4Gb_DDR4-1866_8bit_A.json index f993ede8..229ef834 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_4Gb_DDR4-1866_8bit_A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_4Gb_DDR4-1866_8bit_A.json @@ -49,11 +49,13 @@ "RFC2": 150, "RFC4": 103, "RL": 13, + "RPRE": 1, "RP": 13, "RRD_L": 5, "RRD_S": 4, "RTP": 8, "WL": 12, + "WPRE": 1, "WR": 14, "WTR_L": 7, "WTR_S": 3, diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_4Gb_DDR4-2400_8bit_A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_4Gb_DDR4-2400_8bit_A.json index 4eec52f5..f6ad7862 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_4Gb_DDR4-2400_8bit_A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_4Gb_DDR4-2400_8bit_A.json @@ -49,11 +49,13 @@ "RFC2": 192, "RFC4": 132, "RL": 16, + "RPRE": 1, "RP": 16, "RRD_L": 6, "RRD_S": 4, "RTP": 12, "WL": 16, + "WPRE": 1, "WR": 18, "WTR_L": 9, "WTR_S": 3, diff --git a/DRAMSys/library/resources/configs/memspecs/MICRON_4Gb_DDR4-1866_8bit_A.json b/DRAMSys/library/resources/configs/memspecs/MICRON_4Gb_DDR4-1866_8bit_A.json index cb4e5e7c..159b0b73 100644 --- a/DRAMSys/library/resources/configs/memspecs/MICRON_4Gb_DDR4-1866_8bit_A.json +++ b/DRAMSys/library/resources/configs/memspecs/MICRON_4Gb_DDR4-1866_8bit_A.json @@ -47,11 +47,13 @@ "REFI": 3644, "RFC": 243, "RL": 13, + "RPRE": 1, "RP": 13, "RRD_L": 5, "RRD_S": 4, "RTP": 8, "WL": 12, + "WPRE": 1, "WR": 14, "WTR_L": 7, "WTR_S": 3, diff --git a/DRAMSys/library/resources/configs/memspecs/MICRON_4Gb_DDR4-2400_8bit_A.json b/DRAMSys/library/resources/configs/memspecs/MICRON_4Gb_DDR4-2400_8bit_A.json index 865c7b5b..4973bd10 100644 --- a/DRAMSys/library/resources/configs/memspecs/MICRON_4Gb_DDR4-2400_8bit_A.json +++ b/DRAMSys/library/resources/configs/memspecs/MICRON_4Gb_DDR4-2400_8bit_A.json @@ -47,11 +47,13 @@ "REFI": 4680, "RFC": 313, "RL": 16, + "RPRE": 1, "RP": 16, "RRD_L": 6, "RRD_S": 4, "RTP": 12, "WL": 16, + "WPRE": 1, "WR": 18, "WTR_L": 9, "WTR_S": 3, diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp index d3bd513c..fdb2f843 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp @@ -55,19 +55,17 @@ MemSpecDDR4::MemSpecDDR4(json &memspec) tCKE (tCK * parseUint(memspec["memtimingspec"]["CKE"], "CKE")), tPD (tCKE), tCKESR (tCK * parseUint(memspec["memtimingspec"]["CKESR"], "CKESR")), - tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")), tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")), tRC (tCK * parseUint(memspec["memtimingspec"]["RC"], "RC")), tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")), tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")), + tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")), tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")), tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")), + tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")), tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")), tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")), tXS (tCK * parseUint(memspec["memtimingspec"]["XS"], "XS")), - tCCD_S (tCK * parseUint(memspec["memtimingspec"]["CCD_S"], "CCD_S")), - tCCD_L (tCK * parseUint(memspec["memtimingspec"]["CCD_L"], "CCD_L")), - tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")), tREFI ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 4) ? (tCK * (parseUint(memspec["memtimingspec"]["REFI"], "REFI") / 4)) : ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 2) ? @@ -79,6 +77,10 @@ MemSpecDDR4::MemSpecDDR4(json &memspec) (tCK * parseUint(memspec["memtimingspec"]["RFC2"], "RFC2")) : (tCK * parseUint(memspec["memtimingspec"]["RFC"], "RFC")))), tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), + tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")), + tCCD_S (tCK * parseUint(memspec["memtimingspec"]["CCD_S"], "CCD_S")), + tCCD_L (tCK * parseUint(memspec["memtimingspec"]["CCD_L"], "CCD_L")), + tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")), tRRD_S (tCK * parseUint(memspec["memtimingspec"]["RRD_S"], "RRD_S")), tRRD_L (tCK * parseUint(memspec["memtimingspec"]["RRD_L"], "RRD_L")), tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")), diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h index 9395626c..c702f871 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h @@ -52,8 +52,10 @@ public: const sc_time tRC; const sc_time tRCD; const sc_time tRL; + const sc_time tRPRE; const sc_time tRTP; const sc_time tWL; + const sc_time tWPRE; const sc_time tWR; const sc_time tXP; const sc_time tXS; diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp index a8439903..e2529753 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp @@ -52,11 +52,11 @@ CheckerDDR4::CheckerDDR4() last4Activates = std::vector>(memSpec->numberOfRanks); tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; - tRDWR = memSpec->tRL + tBURST - memSpec->tWL + 2 * memSpec->tCK; - tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; + tRDWR = memSpec->tRL + tBURST + memSpec->tCK - memSpec->tWL + memSpec->tWPRE; + tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL + memSpec->tWPRE; tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S; tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L; - tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL; + tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL + memSpec->tRPRE; tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK; tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR; diff --git a/DRAMSys/tests/DDR4/configs/memspecs/MICRON_4Gb_DDR4-1866_8bit_A.json b/DRAMSys/tests/DDR4/configs/memspecs/MICRON_4Gb_DDR4-1866_8bit_A.json index 35a1dd8c..960db938 100644 --- a/DRAMSys/tests/DDR4/configs/memspecs/MICRON_4Gb_DDR4-1866_8bit_A.json +++ b/DRAMSys/tests/DDR4/configs/memspecs/MICRON_4Gb_DDR4-1866_8bit_A.json @@ -47,11 +47,13 @@ "REFI": 3644, "RFC": 243, "RL": 13, + "RPRE": 1, "RP": 13, "RRD_L": 5, "RRD_S": 4, "RTP": 8, "WL": 12, + "WPRE": 1, "WR": 14, "WTR_L": 7, "WTR_S": 3, From c15434c4fa1e6784701d2775107099df428ff91d Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 19 Aug 2020 09:46:24 +0200 Subject: [PATCH 03/50] Add initial version of DDR5 based on DDR4. --- DRAMSys/library/CMakeLists.txt | 3 + .../am_ddr5_2x4x8Gbx8_dimm_p1KB_rbc.json | 49 ++ .../memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json | 54 ++ .../resources/configs/simulator/ddr5.json | 19 + .../resources/simulations/ddr5-example.json | 16 + .../src/configuration/Configuration.cpp | 3 + .../src/configuration/memspec/MemSpecDDR5.cpp | 32 +- .../src/configuration/memspec/MemSpecDDR5.h | 52 +- DRAMSys/library/src/controller/Controller.cpp | 3 + .../src/controller/checker/CheckerDDR5.cpp | 462 ++++++++++++++++++ .../src/controller/checker/CheckerDDR5.h | 77 +++ DRAMSys/library/src/simulation/DRAMSys.cpp | 3 + .../src/simulation/DRAMSysRecordable.cpp | 7 +- .../library/src/simulation/dram/DramDDR5.cpp | 52 ++ .../library/src/simulation/dram/DramDDR5.h | 50 ++ .../src/simulation/dram/DramRecordable.cpp | 2 + 16 files changed, 845 insertions(+), 39 deletions(-) create mode 100644 DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x4x8Gbx8_dimm_p1KB_rbc.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json create mode 100644 DRAMSys/library/resources/configs/simulator/ddr5.json create mode 100644 DRAMSys/library/resources/simulations/ddr5-example.json create mode 100644 DRAMSys/library/src/controller/checker/CheckerDDR5.cpp create mode 100644 DRAMSys/library/src/controller/checker/CheckerDDR5.h create mode 100644 DRAMSys/library/src/simulation/dram/DramDDR5.cpp create mode 100644 DRAMSys/library/src/simulation/dram/DramDDR5.h diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index 67bf3d92..7871f809 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -99,6 +99,7 @@ add_library(DRAMSysLibrary src/configuration/memspec/MemSpec.cpp src/configuration/memspec/MemSpecDDR3.cpp src/configuration/memspec/MemSpecDDR4.cpp + src/configuration/memspec/MemSpecDDR5.cpp src/configuration/memspec/MemSpecLPDDR4.cpp src/configuration/memspec/MemSpecWideIO.cpp src/configuration/memspec/MemSpecWideIO2.cpp @@ -115,6 +116,7 @@ add_library(DRAMSysLibrary src/controller/checker/CheckerIF.h src/controller/checker/CheckerDDR3.cpp src/controller/checker/CheckerDDR4.cpp + src/controller/checker/CheckerDDR5.cpp src/controller/checker/CheckerLPDDR4.cpp src/controller/checker/CheckerWideIO.cpp src/controller/checker/CheckerWideIO2.cpp @@ -161,6 +163,7 @@ add_library(DRAMSysLibrary src/simulation/dram/Dram.cpp src/simulation/dram/DramDDR3.cpp src/simulation/dram/DramDDR4.cpp + src/simulation/dram/DramDDR5.cpp src/simulation/dram/DramLPDDR4.cpp src/simulation/dram/DramWideIO.cpp src/simulation/dram/DramWideIO2.cpp diff --git a/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x4x8Gbx8_dimm_p1KB_rbc.json b/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x4x8Gbx8_dimm_p1KB_rbc.json new file mode 100644 index 00000000..7e02f877 --- /dev/null +++ b/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x4x8Gbx8_dimm_p1KB_rbc.json @@ -0,0 +1,49 @@ +{ + "CONGEN": { + "BYTE_BIT": [ + 0, + 1 + ], + "COLUMN_BIT": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "BANKGROUP_BIT": [ + 12, + 13, + 14 + ], + "BANK_BIT": [ + 15 + ], + "ROW_BIT": [ + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31 + ], + "CHANNEL_BIT": [ + 32 + ] + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json new file mode 100644 index 00000000..0b580d0d --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json @@ -0,0 +1,54 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfRows": 65536, + "width": 8, + "nbrOfDevicesOnDIMM": 4, + "nbrOfChannels": 2 + }, + "memoryId": "JEDEC_2x8Gb_DDR5-3200A_8bit", + "memoryType": "DDR5", + + "memtimingspec": { + "AL": 0, + "CCD_L": 16, + "CCD_S": 8, + "CKE": 6, + "CKESR": 7, + "DQSCK": 2, + "FAW": 32, + "RAS": 52, + "RC": 74, + "RCD": 22, + "REFM": 1, + "REFI": 6240, + "RFC": 312, + "RL": 22, + "RPRE": 1, + "RP": 22, + "RRD_L": 8, + "RRD_S": 8, + "RTP": 12, + "WL": 20, + "WPRE": 2, + "WR": 48, + "WTR_L": 16, + "WTR_S": 4, + "XP": 12, + "XPDLL": 0, + "XS": 312, + "XSDLL": 1024, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "RTRS": 1, + "clkMhz": 1600 + } + } +} diff --git a/DRAMSys/library/resources/configs/simulator/ddr5.json b/DRAMSys/library/resources/configs/simulator/ddr5.json new file mode 100644 index 00000000..d3987d37 --- /dev/null +++ b/DRAMSys/library/resources/configs/simulator/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/DRAMSys/library/resources/simulations/ddr5-example.json b/DRAMSys/library/resources/simulations/ddr5-example.json new file mode 100644 index 00000000..b0052ec5 --- /dev/null +++ b/DRAMSys/library/resources/simulations/ddr5-example.json @@ -0,0 +1,16 @@ +{ + "simulation": { + "addressmapping": "am_ddr5_2x4x8Gbx8_dimm_p1KB_rbc.json", + "mcconfig": "fr_fcfs.json", + "memspec": "JEDEC_2x8Gb_DDR5-3200A_8bit.json", + "simconfig": "ddr5.json", + "simulationid": "ddr5-example", + "thermalconfig": "config.json", + "tracesetup": [ + { + "clkMhz": 200, + "name": "ddr3_example.stl" + } + ] + } +} diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 4a0b9645..5d1e1aa0 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -43,6 +43,7 @@ #include "Configuration.h" #include "memspec/MemSpecDDR3.h" #include "memspec/MemSpecDDR4.h" +#include "memspec/MemSpecDDR5.h" #include "memspec/MemSpecWideIO.h" #include "memspec/MemSpecLPDDR4.h" #include "memspec/MemSpecWideIO2.h" @@ -291,6 +292,8 @@ void Configuration::loadMemSpec(Configuration &config, std::string memspecUri) memSpec = new MemSpecDDR3(jMemSpec); else if (memoryType == "DDR4") memSpec = new MemSpecDDR4(jMemSpec); + else if (memoryType == "DDR5") + memSpec = new MemSpecDDR5(jMemSpec); else if (memoryType == "LPDDR4") memSpec = new MemSpecLPDDR4(jMemSpec); else if (memoryType == "WIDEIO_SDR") diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp index dca14f33..baf91d70 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp @@ -55,19 +55,17 @@ MemSpecDDR5::MemSpecDDR5(json &memspec) tCKE (tCK * parseUint(memspec["memtimingspec"]["CKE"], "CKE")), tPD (tCKE), tCKESR (tCK * parseUint(memspec["memtimingspec"]["CKESR"], "CKESR")), - tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")), tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")), tRC (tCK * parseUint(memspec["memtimingspec"]["RC"], "RC")), tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")), tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")), + tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")), tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")), tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")), + tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")), tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")), tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")), tXS (tCK * parseUint(memspec["memtimingspec"]["XS"], "XS")), - tCCD_S (tCK * parseUint(memspec["memtimingspec"]["CCD_S"], "CCD_S")), - tCCD_L (tCK * parseUint(memspec["memtimingspec"]["CCD_L"], "CCD_L")), - tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")), tREFI ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 4) ? (tCK * (parseUint(memspec["memtimingspec"]["REFI"], "REFI") / 4)) : ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 2) ? @@ -79,6 +77,10 @@ MemSpecDDR5::MemSpecDDR5(json &memspec) (tCK * parseUint(memspec["memtimingspec"]["RFC2"], "RFC2")) : (tCK * parseUint(memspec["memtimingspec"]["RFC"], "RFC")))), tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), + tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")), + tCCD_S (tCK * parseUint(memspec["memtimingspec"]["CCD_S"], "CCD_S")), + tCCD_L (tCK * parseUint(memspec["memtimingspec"]["CCD_L"], "CCD_L")), + tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")), tRRD_S (tCK * parseUint(memspec["memtimingspec"]["RRD_S"], "RRD_S")), tRRD_L (tCK * parseUint(memspec["memtimingspec"]["RRD_L"], "RRD_L")), tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")), @@ -90,7 +92,13 @@ MemSpecDDR5::MemSpecDDR5(json &memspec) tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")), tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")), tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")) -{} +{ + commandLengthInCycles[Command::ACT] = 2; + commandLengthInCycles[Command::RD] = 2; + commandLengthInCycles[Command::RDA] = 2; + commandLengthInCycles[Command::WR] = 2; + commandLengthInCycles[Command::WRA] = 2; +} sc_time MemSpecDDR5::getRefreshIntervalAB() const { @@ -109,15 +117,15 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload if (command == Command::PRE || command == Command::PREA) return tRP; else if (command == Command::ACT) - return tRCD; + return tRCD + tCK; else if (command == Command::RD) - return tRL + burstDuration; + return tRL + burstDuration + tCK; else if (command == Command::RDA) - return tRTP + tRP; + return tRTP + tRP + tCK; else if (command == Command::WR) - return tWL + burstDuration; + return tWL + burstDuration + tCK; else if (command == Command::WRA) - return tWL + burstDuration + tWR + tRP; + return tWL + burstDuration + tWR + tRP + tCK; else if (command == Command::REFA) return tRFC; else @@ -131,9 +139,9 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command) const { if (command == Command::RD || command == Command::RDA) - return TimeInterval(sc_time_stamp() + tRL, sc_time_stamp() + tRL + burstDuration); + return TimeInterval(sc_time_stamp() + tRL + tCK, sc_time_stamp() + tRL + burstDuration + tCK); else if (command == Command::WR || command == Command::WRA) - return TimeInterval(sc_time_stamp() + tWL, sc_time_stamp() + tWL + burstDuration); + return TimeInterval(sc_time_stamp() + tWL + tCK, sc_time_stamp() + tWL + burstDuration + tCK); else { SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument"); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h index cc9dcda8..e1f02a62 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h @@ -45,36 +45,38 @@ public: MemSpecDDR5(nlohmann::json &memspec); // Memspec Variables: - const sc_time tRCD; - const sc_time tPPD; - const sc_time tRP; + const sc_time tCKE; + const sc_time tPD; + const sc_time tCKESR; const sc_time tRAS; + const sc_time tRC; + const sc_time tRCD; const sc_time tRL; - const sc_time tRTP; const sc_time tRPRE; - const sc_time tRPST; - const sc_time tRDQSOFF; + const sc_time tRTP; const sc_time tWL; - const sc_time tWR; - const sc_time tWTR_L; - const sc_time tWTR_S; const sc_time tWPRE; - const sc_time tWPST; - const sc_time tCCD_L_slr; - const sc_time tCCD_S_slr; - const sc_time tCCD_dlr; - const sc_time tCCD_L_WR_slr; - const sc_time tCCD_S_WR_slr; - const sc_time tCCD_WR_dlr; - const sc_time tCCD_WR_dpr; - const sc_time - const sc_time - const sc_time - const sc_time - const sc_time - const sc_time - const sc_time - const sc_time + const sc_time tWR; + const sc_time tXP; + const sc_time tXS; + const sc_time tREFI; + const sc_time tRFC; + const sc_time tRP; + const sc_time tDQSCK; + const sc_time tCCD_S; + const sc_time tCCD_L; + const sc_time tFAW; + const sc_time tRRD_S; + const sc_time tRRD_L; + const sc_time tWTR_S; + const sc_time tWTR_L; + const sc_time tAL; + const sc_time tXPDLL; + const sc_time tXSDLL; + const sc_time tACTPDEN; + const sc_time tPRPDEN; + const sc_time tREFPDEN; + const sc_time tRTRS; // Currents and Voltages: // TODO: to be completed diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 169e90ae..5a81d6f1 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -39,6 +39,7 @@ #include "Command.h" #include "checker/CheckerDDR3.h" #include "checker/CheckerDDR4.h" +#include "checker/CheckerDDR5.h" #include "checker/CheckerWideIO.h" #include "checker/CheckerLPDDR4.h" #include "checker/CheckerWideIO2.h" @@ -76,6 +77,8 @@ Controller::Controller(sc_module_name name) : checker = new CheckerDDR3(); else if (memSpec->memoryType == "DDR4") checker = new CheckerDDR4(); + else if (memSpec->memoryType == "DDR5") + checker = new CheckerDDR5(); else if (memSpec->memoryType == "WIDEIO_SDR") checker = new CheckerWideIO(); else if (memSpec->memoryType == "LPDDR4") diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp new file mode 100644 index 00000000..ee9e44b6 --- /dev/null +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#include "CheckerDDR5.h" + +CheckerDDR5::CheckerDDR5() +{ + Configuration &config = Configuration::getInstance(); + memSpec = dynamic_cast(config.memSpec); + if (memSpec == nullptr) + SC_REPORT_FATAL("CheckerDDR5", "Wrong MemSpec chosen"); + + lastScheduledByCommandAndBank = std::vector> + (numberOfCommands(), std::vector(memSpec->numberOfBanks)); + lastScheduledByCommandAndBankGroup = std::vector> + (numberOfCommands(), std::vector(memSpec->numberOfBankGroups)); + lastScheduledByCommandAndRank = std::vector> + (numberOfCommands(), std::vector(memSpec->numberOfRanks)); + lastScheduledByCommand = std::vector(numberOfCommands()); + + last4Activates = std::vector>(memSpec->numberOfRanks); + + tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tRDWR = memSpec->tRL + tBURST + memSpec->tCK - memSpec->tWL + memSpec->tWPRE; + tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL + memSpec->tWPRE; + tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S; + tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L; + tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL + memSpec->tRPRE; + tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; + tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK; + tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR; + tWRAPDEN = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR; +} + +sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const +{ + sc_time lastCommandStart; + sc_time earliestTimeToStart = sc_time_stamp(); + + if (command == Command::RD || command == Command::RDA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); + + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + if (command == Command::RDA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP); + } + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S); + + lastCommandStart = lastScheduledByCommand[Command::WR]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S); + + lastCommandStart = lastScheduledByCommand[Command::WRA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL); + } + else if (command == Command::WR || command == Command::WRA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); + + lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); + + lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL); + } + else if (command == Command::ACT) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L); + + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_S); + + lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + + if (last4Activates[rank.ID()].size() >= 4) + earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW); + } + else if (command == Command::PRE) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + + lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + } + else if (command == Command::PREA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + } + else if (command == Command::REFA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::PDEA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + } + else if (command == Command::PDXA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); + } + else if (command == Command::PDEP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::PDXP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); + } + else if (command == Command::SREFEN) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::SREFEX) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR); + } + else + SC_REPORT_FATAL("CheckerDDR5", "Unknown command!"); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK); + + return earliestTimeToStart; +} + +void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank) +{ + PRINTDEBUGMESSAGE("CheckerDDR5", "Changing state on bank " + std::to_string(bank.ID()) + + " command is " + commandToString(command)); + + lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp(); + lastScheduledByCommandAndBankGroup[command][bankgroup.ID()] = sc_time_stamp(); + lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp(); + lastScheduledByCommand[command] = sc_time_stamp(); + lastCommandOnBus = sc_time_stamp(); + + if (command == Command::ACT) + { + if (last4Activates[rank.ID()].size() == 4) + last4Activates[rank.ID()].pop(); + last4Activates[rank.ID()].push(sc_time_stamp()); + } +} diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.h b/DRAMSys/library/src/controller/checker/CheckerDDR5.h new file mode 100644 index 00000000..c2338fa6 --- /dev/null +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#ifndef CHECKERDDR5_H +#define CHECKERDDR5_H + +#include "CheckerIF.h" +#include +#include +#include "../../configuration/memspec/MemSpecDDR5.h" +#include "../../configuration/Configuration.h" + +class CheckerDDR5 final : public CheckerIF +{ +public: + CheckerDDR5(); + virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override; + virtual void insert(Command, Rank, BankGroup, Bank) override; + +private: + const MemSpecDDR5 *memSpec; + + std::vector> lastScheduledByCommandAndBank; + std::vector> lastScheduledByCommandAndBankGroup; + std::vector> lastScheduledByCommandAndRank; + std::vector lastScheduledByCommand; + sc_time lastCommandOnBus; + + // Four activate window + std::vector> last4Activates; + + sc_time tBURST; + sc_time tRDWR; + sc_time tRDWR_R; + sc_time tWRRD_S; + sc_time tWRRD_L; + sc_time tWRRD_R; + sc_time tRDAACT; + sc_time tWRPRE; + sc_time tWRAACT; + sc_time tRDPDEN; + sc_time tWRPDEN; + sc_time tWRAPDEN; +}; + +#endif // CHECKERDDR5_H diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index fca962a1..9140dd6f 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -51,6 +51,7 @@ #include "../error/ecchamming.h" #include "dram/DramDDR3.h" #include "dram/DramDDR4.h" +#include "dram/DramDDR5.h" #include "dram/DramWideIO.h" #include "dram/DramLPDDR4.h" #include "dram/DramWideIO2.h" @@ -216,6 +217,8 @@ void DRAMSys::instantiateModules(const std::string &pathToResources, dram = new DramWideIO(str.c_str()); else if (memoryType == "DDR4") dram = new DramDDR4(str.c_str()); + else if (memoryType == "DDR5") + dram = new DramDDR5(str.c_str()); else if (memoryType == "LPDDR4") dram = new DramLPDDR4(str.c_str()); else if (memoryType == "WIDEIO2") diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp index 93b92a33..70631100 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp @@ -38,6 +38,7 @@ #include "dram/DramRecordable.h" #include "dram/DramDDR3.h" #include "dram/DramDDR4.h" +#include "dram/DramDDR5.h" #include "dram/DramWideIO.h" #include "dram/DramLPDDR4.h" #include "dram/DramWideIO2.h" @@ -152,12 +153,14 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, if (memoryType == "DDR3") dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "WIDEIO_SDR") - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); else if (memoryType == "DDR4") dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == "DDR5") + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); else if (memoryType == "LPDDR4") dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == "WIDEIO_SDR") + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); else if (memoryType == "WIDEIO2") dram = new DramRecordable(str.c_str(), tlmRecorders[i]); else if (memoryType == "HBM2") diff --git a/DRAMSys/library/src/simulation/dram/DramDDR5.cpp b/DRAMSys/library/src/simulation/dram/DramDDR5.cpp new file mode 100644 index 00000000..c794e9c0 --- /dev/null +++ b/DRAMSys/library/src/simulation/dram/DramDDR5.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020, 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 "DramDDR5.h" + +#include "Dram.h" +#include "../../configuration/Configuration.h" +#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h" +#include "../../configuration/memspec/MemSpecDDR5.h" + +using namespace DRAMPower; + +DramDDR5::DramDDR5(sc_module_name name) : Dram(name) +{ + if (storeMode == StorageMode::ErrorModel) + SC_REPORT_FATAL("DramDDR5", "Error Model not supported for DDR5"); + + if (Configuration::getInstance().powerAnalysis) + SC_REPORT_FATAL("DramDDR5", "DRAMPower does not support DDR5"); +} diff --git a/DRAMSys/library/src/simulation/dram/DramDDR5.h b/DRAMSys/library/src/simulation/dram/DramDDR5.h new file mode 100644 index 00000000..14898af1 --- /dev/null +++ b/DRAMSys/library/src/simulation/dram/DramDDR5.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020, 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 + */ + +#ifndef DRAMDDR5_H +#define DRAMDDR5_H + +#include +#include "Dram.h" + +class DramDDR5 : public Dram +{ +public: + DramDDR5(sc_module_name); + SC_HAS_PROCESS(DramDDR5); + virtual ~DramDDR5() {} +}; + +#endif // DRAMDDR5_H diff --git a/DRAMSys/library/src/simulation/dram/DramRecordable.cpp b/DRAMSys/library/src/simulation/dram/DramRecordable.cpp index 3b9215ef..2532bf91 100644 --- a/DRAMSys/library/src/simulation/dram/DramRecordable.cpp +++ b/DRAMSys/library/src/simulation/dram/DramRecordable.cpp @@ -41,6 +41,7 @@ #include "../../common/utils.h" #include "DramDDR3.h" #include "DramDDR4.h" +#include "DramDDR5.h" #include "DramWideIO.h" #include "DramLPDDR4.h" #include "DramWideIO2.h" @@ -147,6 +148,7 @@ void DramRecordable::powerWindow() template class DramRecordable; template class DramRecordable; +template class DramRecordable; template class DramRecordable; template class DramRecordable; template class DramRecordable; From 2c15bb8f79509fa85bf606e6dc8137eadc78c1af Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 25 Aug 2020 10:16:45 +0200 Subject: [PATCH 04/50] Add new DDR5 checker and timings. --- DRAMSys/library/src/common/dramExtensions.cpp | 8 +- .../src/configuration/memspec/MemSpec.h | 30 +- .../src/configuration/memspec/MemSpecDDR5.cpp | 96 ++-- .../src/configuration/memspec/MemSpecDDR5.h | 60 ++- .../src/controller/checker/CheckerDDR5.cpp | 467 ++++++++---------- .../src/controller/checker/CheckerDDR5.h | 36 +- 6 files changed, 354 insertions(+), 343 deletions(-) diff --git a/DRAMSys/library/src/common/dramExtensions.cpp b/DRAMSys/library/src/common/dramExtensions.cpp index abd34d62..279ef518 100644 --- a/DRAMSys/library/src/common/dramExtensions.cpp +++ b/DRAMSys/library/src/common/dramExtensions.cpp @@ -60,9 +60,9 @@ DramExtension::DramExtension(const Thread &thread, const Channel &channel, const DramExtension &DramExtension::getExtension(const tlm_generic_payload *payload) { - DramExtension *result = NULL; + DramExtension *result = nullptr; payload->get_extension(result); - sc_assert(result != NULL); + sc_assert(result != nullptr); return *result; } @@ -234,9 +234,9 @@ void GenerationExtension::copy_from(const tlm_extension_base &ext) GenerationExtension &GenerationExtension::getExtension(const tlm_generic_payload *payload) { - GenerationExtension *result = NULL; + GenerationExtension *result = nullptr; payload->get_extension(result); - sc_assert(result != NULL); + sc_assert(result != nullptr); return *result; } diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index 6f0fa875..3f97dcff 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -48,23 +48,23 @@ class MemSpec { public: - unsigned numberOfChannels; - unsigned numberOfRanks; - unsigned banksPerRank; - unsigned groupsPerRank; - unsigned banksPerGroup; - unsigned numberOfBanks; - unsigned numberOfBankGroups; - unsigned numberOfDevicesOnDIMM; - unsigned numberOfRows; - unsigned numberOfColumns; - unsigned burstLength; - unsigned dataRate; - unsigned bitWidth; + const unsigned numberOfChannels; + const unsigned numberOfRanks; + const unsigned banksPerRank; + const unsigned groupsPerRank; + const unsigned banksPerGroup; + const unsigned numberOfBanks; + const unsigned numberOfBankGroups; + const unsigned numberOfDevicesOnDIMM; + const unsigned numberOfRows; + const unsigned numberOfColumns; + const unsigned burstLength; + const unsigned dataRate; + const unsigned bitWidth; // Clock - double fCKMHz; - sc_time tCK; + const double fCKMHz; + const sc_time tCK; std::string memoryId; std::string memoryType; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp index baf91d70..88f998ff 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp @@ -46,52 +46,60 @@ MemSpecDDR5::MemSpecDDR5(json &memspec) parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks") - / parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups"), + / parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks") - * parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), + * parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups") - * parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), + * parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfDevicesOnDIMM"],"nbrOfDevicesOnDIMM")), - tCKE (tCK * parseUint(memspec["memtimingspec"]["CKE"], "CKE")), - tPD (tCKE), - tCKESR (tCK * parseUint(memspec["memtimingspec"]["CKESR"], "CKESR")), - tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")), - tRC (tCK * parseUint(memspec["memtimingspec"]["RC"], "RC")), - tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")), - tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")), - tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")), - tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")), - tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")), - tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")), - tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")), - tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")), - tXS (tCK * parseUint(memspec["memtimingspec"]["XS"], "XS")), - tREFI ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 4) ? - (tCK * (parseUint(memspec["memtimingspec"]["REFI"], "REFI") / 4)) : - ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 2) ? - (tCK * (parseUint(memspec["memtimingspec"]["REFI"], "REFI") / 2)) : - (tCK * parseUint(memspec["memtimingspec"]["REFI"], "REFI")))), - tRFC ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 4) ? - (tCK * parseUint(memspec["memtimingspec"]["RFC4"], "RFC4")) : - ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 2) ? - (tCK * parseUint(memspec["memtimingspec"]["RFC2"], "RFC2")) : - (tCK * parseUint(memspec["memtimingspec"]["RFC"], "RFC")))), - tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), - tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")), - tCCD_S (tCK * parseUint(memspec["memtimingspec"]["CCD_S"], "CCD_S")), - tCCD_L (tCK * parseUint(memspec["memtimingspec"]["CCD_L"], "CCD_L")), - tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")), - tRRD_S (tCK * parseUint(memspec["memtimingspec"]["RRD_S"], "RRD_S")), - tRRD_L (tCK * parseUint(memspec["memtimingspec"]["RRD_L"], "RRD_L")), - tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")), - tWTR_L (tCK * parseUint(memspec["memtimingspec"]["WTR_L"], "WTR_L")), - tAL (tCK * parseUint(memspec["memtimingspec"]["AL"], "AL")), - tXPDLL (tCK * parseUint(memspec["memtimingspec"]["XPDLL"], "XPDLL")), - tXSDLL (tCK * parseUint(memspec["memtimingspec"]["XSDLL"], "XSDLL")), - tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")), - tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")), - tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")), - tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")) + numberOfDIMMRanks(parseUint(memspec["memarchitecturespec"]["nbrOfDIMMRanks"], "nbrOfDIMMRanks")), + physicalRanksPerDIMMRank(parseUint(memspec["memarchitecturespec"]["nbrOfPhysicalRanks"], "nbrOfPhysicalRanks")), + numberOfPhysicalRanks(physicalRanksPerDIMMRank * numberOfDIMMRanks), + logicalRanksPerPhysicalRank(parseUint(memspec["memarchitecturespec"]["nbrOfLogicalRanks"], "nbrOfLogicalRanks")), + numberOfLogicalRanks(logicalRanksPerPhysicalRank * numberOfPhysicalRanks), + tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")), + tPPD (tCK * parseUint(memspec["memtimingspec"]["PPD"], "PPD")), + tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), + tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")), + tRC (tRAS + tRP), + tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")), + tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")), + tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")), + tRPST (tCK * parseUint(memspec["memtimingspec"]["RPST"], "RPST")), + tRDDQS (tCK * parseUint(memspec["memtimingspec"]["RDDQS"], "RDDQS")), + tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")), + tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")), + tWPST (tCK * parseUint(memspec["memtimingspec"]["WPST"], "WPST")), + tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")), + tCCD_L_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_slr"], "CCD_L_slr")), + tCCD_L_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_WR_slr"], "CCD_L_WR_slr")), + tCCD_S_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_slr"], "CCD_S_slr")), + tCCD_S_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_WR_slr"], "CCD_S_WR_slr")), + tCCD_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_dlr"], "CCD_dlr")), + tCCD_WR_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dlr"], "CCD_WR_dlr")), + tCCD_WR_dpr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dpr"], "CCD_WR_dpr")), + tRRD_L_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_L_slr"], "RRD_L_slr")), + tRRD_S_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_S_slr"], "RRD_S_slr")), + tRRD_dlr (tCK * parseUint(memspec["memtimingspec"]["RRD_dlr"], "RRD_dlr")), + tFAW_slr (tCK * parseUint(memspec["memtimingspec"]["FAW_slr"], "FAW_slr")), + tFAW_dlr (tCK * parseUint(memspec["memtimingspec"]["FAW_dlr"], "FAW_dlr")), + tWTR_L (tCK * parseUint(memspec["memtimingspec"]["WTR_L"], "WTR_L")), + tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")), + tRFC_slr (tCK * parseUint(memspec["memtimingspec"]["RFC_slr"], "RFC_slr")), + tRFC_dlr (tCK * parseUint(memspec["memtimingspec"]["RFC_dlr"], "RFC_dlr")), + tRFC_dpr (tCK * parseUint(memspec["memtimingspec"]["RFC_dpr"], "RFC_dpr")), + tRFCsb_slr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_slr"], "RFCsb_slr")), + tRFCsb_dlr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_dlr"], "RFCsb_dlr")), + tREFI (tCK * parseUint(memspec["memtimingspec"]["REFI"], "REFI")), + tREFSBRD_slr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_slr"], "REFSBRD_slr")), + tREFSBRD_dlr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_dlr"], "REFSBRD_dlr")), + tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")), + tCPDED (tCK * parseUint(memspec["memtimingspec"]["CPDED"], "CPDED")), + tPD (tCK * parseUint(memspec["memtimingspec"]["PD"], "PD")), + tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")), + tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")), + tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")), + tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")) { commandLengthInCycles[Command::ACT] = 2; commandLengthInCycles[Command::RD] = 2; @@ -127,7 +135,7 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload else if (command == Command::WRA) return tWL + burstDuration + tWR + tRP + tCK; else if (command == Command::REFA) - return tRFC; + return tRFC_slr; else { SC_REPORT_FATAL("getExecutionTime", diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h index e1f02a62..f243b1a0 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h @@ -44,39 +44,57 @@ class MemSpecDDR5 final : public MemSpec public: MemSpecDDR5(nlohmann::json &memspec); + const unsigned numberOfDIMMRanks; + const unsigned physicalRanksPerDIMMRank; + const unsigned numberOfPhysicalRanks; + const unsigned logicalRanksPerPhysicalRank; + const unsigned numberOfLogicalRanks; + // Memspec Variables: - const sc_time tCKE; - const sc_time tPD; - const sc_time tCKESR; + const sc_time tRCD; + const sc_time tPPD; + const sc_time tRP; const sc_time tRAS; const sc_time tRC; - const sc_time tRCD; const sc_time tRL; - const sc_time tRPRE; const sc_time tRTP; + const sc_time tRPRE; + const sc_time tRPST; + const sc_time tRDDQS; const sc_time tWL; const sc_time tWPRE; + const sc_time tWPST; const sc_time tWR; - const sc_time tXP; - const sc_time tXS; - const sc_time tREFI; - const sc_time tRFC; - const sc_time tRP; - const sc_time tDQSCK; - const sc_time tCCD_S; - const sc_time tCCD_L; - const sc_time tFAW; - const sc_time tRRD_S; - const sc_time tRRD_L; - const sc_time tWTR_S; + const sc_time tCCD_L_slr; + const sc_time tCCD_L_WR_slr; + const sc_time tCCD_S_slr; + const sc_time tCCD_S_WR_slr; + const sc_time tCCD_dlr; + const sc_time tCCD_WR_dlr; + const sc_time tCCD_WR_dpr; + const sc_time tRRD_L_slr; + const sc_time tRRD_S_slr; + const sc_time tRRD_dlr; + const sc_time tFAW_slr; + const sc_time tFAW_dlr; const sc_time tWTR_L; - const sc_time tAL; - const sc_time tXPDLL; - const sc_time tXSDLL; + const sc_time tWTR_S; + const sc_time tRFC_slr; + const sc_time tRFC_dlr; + const sc_time tRFC_dpr; + const sc_time tRFCsb_slr; + const sc_time tRFCsb_dlr; + const sc_time tREFI; + const sc_time tREFSBRD_slr; + const sc_time tREFSBRD_dlr; + const sc_time tRTRS; + + const sc_time tCPDED; + const sc_time tPD; + const sc_time tXP; const sc_time tACTPDEN; const sc_time tPRPDEN; const sc_time tREFPDEN; - const sc_time tRTRS; // Currents and Voltages: // TODO: to be completed diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index ee9e44b6..68de6a49 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -41,26 +41,45 @@ CheckerDDR5::CheckerDDR5() if (memSpec == nullptr) SC_REPORT_FATAL("CheckerDDR5", "Wrong MemSpec chosen"); - lastScheduledByCommandAndBank = std::vector> - (numberOfCommands(), std::vector(memSpec->numberOfBanks)); + lastScheduledByCommandAndDIMMRank = std::vector> + (numberOfCommands(), std::vector(memSpec->numberOfDIMMRanks)); + lastScheduledByCommandAndPhysicalRank = std::vector> + (numberOfCommands(), std::vector(memSpec->numberOfPhysicalRanks)); + lastScheduledByCommandAndLogicalRank = std::vector> + (numberOfCommands(), std::vector(memSpec->numberOfLogicalRanks)); lastScheduledByCommandAndBankGroup = std::vector> (numberOfCommands(), std::vector(memSpec->numberOfBankGroups)); - lastScheduledByCommandAndRank = std::vector> - (numberOfCommands(), std::vector(memSpec->numberOfRanks)); + lastScheduledByCommandAndBank = std::vector> + (numberOfCommands(), std::vector(memSpec->numberOfBanks)); lastScheduledByCommand = std::vector(numberOfCommands()); - last4Activates = std::vector>(memSpec->numberOfRanks); + last4ActivatesLogical = std::vector>(memSpec->numberOfLogicalRanks); + last4ActivatesPhysical = std::vector>(memSpec->numberOfPhysicalRanks); - tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; - tRDWR = memSpec->tRL + tBURST + memSpec->tCK - memSpec->tWL + memSpec->tWPRE; - tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL + memSpec->tWPRE; - tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S; - tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L; - tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL + memSpec->tRPRE; - tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; - tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK; - tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR; - tWRAPDEN = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR; + tRD_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tWR_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tWTRA = memSpec->tWR - memSpec->tRTP; + tWRRDA = memSpec->tWL + tWR_BURST + tWTRA; + tWRPRE = memSpec->tWL + tWR_BURST + memSpec->tWR; + tRDAACT = memSpec->tRTP + memSpec->tRP; + tWRAACT = tWRPRE + memSpec->tRP; + tCCD_L_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tCCD_S_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tCCD_RTW_dlr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tRDRD_dpr = tRD_BURST + memSpec->tRTRS; + tRDRD_ddr = tRD_BURST + memSpec->tRTRS; + tRDWR_dpr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tRDWR_ddr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tCCD_L_WTR_slr = memSpec->tWL + tWR_BURST + memSpec->tWTR_L; + tCCD_S_WTR_slr = memSpec->tWL + tWR_BURST + memSpec->tWTR_S; + tCCD_WTR_dlr = memSpec->tWL + tWR_BURST + memSpec->tWTR_S; + tWRWR_dpr = std::max(memSpec->tCCD_WR_dpr, tWR_BURST + memSpec->tRTRS); + tWRWR_ddr = tWR_BURST + memSpec->tRTRS; + tWRRD_dpr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE; + tWRRD_ddr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE; + tRDPDEN = memSpec->tRL + tRD_BURST + memSpec->tCK; + tWRPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + memSpec->tCK; + tWRAPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + memSpec->tCK; } sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const @@ -68,128 +87,188 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); + Rank logicalrank = rank; + Rank physicalrank = Rank(logicalrank.ID() / memSpec->logicalRanksPerPhysicalRank); + Rank dimmrank = Rank(physicalrank.ID() / memSpec->physicalRanksPerDIMMRank); + if (command == Command::RD || command == Command::RDA) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); - lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); - lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME; + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); + + if (lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) + { + if (lastScheduledByCommand[Command::RD] == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()]) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); + } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); - lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); - lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME; + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); + + if (lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) + { + if (lastScheduledByCommand[Command::RDA] == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()]) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); + } if (command == Command::RDA) { lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA); } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); - lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr); - lastCommandStart = lastScheduledByCommand[Command::WR]; + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); + + if (lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) + { + if (lastScheduledByCommand[Command::WR] == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()]) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); + } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); - lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr); - lastCommandStart = lastScheduledByCommand[Command::WRA]; + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL); + if (lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) + { + if (lastScheduledByCommand[Command::WRA] == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()]) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); + } } else if (command == Command::WR || command == Command::WRA) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); - lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); - lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); - lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); - lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME; + if (lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) + { + if (lastScheduledByCommand[Command::RD] == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()]) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); + } + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); + + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr); + + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); + + if (lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) + { + if (lastScheduledByCommand[Command::RDA] == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()]) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); + } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr); - lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); - lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME; + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); + + if (lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) + { + if (lastScheduledByCommand[Command::WR] == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()]) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); + } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr); - lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); - lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : SC_ZERO_TIME; + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL); + if (lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) + { + if (lastScheduledByCommand[Command::WRA] == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()]) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); + } } else if (command == Command::ACT) { @@ -199,240 +278,121 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankgroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr); - lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_S); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_S_slr); + + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::ACT][physicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_dlr); lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT); lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT); lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PREA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); - - if (last4Activates[rank.ID()].size() >= 4) - earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr); } else if (command == Command::PRE) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK); lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK); lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PREA][physicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); } else if (command == Command::PREA) { - lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PREA][physicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); } else if (command == Command::REFA) { - lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PRE][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PREA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr); - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFA][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr); - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); - } - else if (command == Command::PDEA) - { - lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN); - - lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); - - lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); - - lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN); - - lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); - } - else if (command == Command::PDXA) - { - lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); - } - else if (command == Command::PDEP) - { - lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); - - lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); - - lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); - - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN); - - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); - } - else if (command == Command::PDXP) - { - lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); - } - else if (command == Command::SREFEN) - { - lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); - - lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP)); - - lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP)); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); - } - else if (command == Command::SREFEX) - { - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr); } else SC_REPORT_FATAL("CheckerDDR5", "Unknown command!"); @@ -447,16 +407,27 @@ void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank b PRINTDEBUGMESSAGE("CheckerDDR5", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); - lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp(); + Rank logicalrank = rank; + Rank physicalrank = Rank(logicalrank.ID() / memSpec->logicalRanksPerPhysicalRank); + Rank dimmrank = Rank(physicalrank.ID() / memSpec->physicalRanksPerDIMMRank); + + lastScheduledByCommandAndDIMMRank[command][dimmrank.ID()] = sc_time_stamp(); + lastScheduledByCommandAndPhysicalRank[command][physicalrank.ID()] = sc_time_stamp(); + lastScheduledByCommandAndLogicalRank[command][logicalrank.ID()] = sc_time_stamp(); lastScheduledByCommandAndBankGroup[command][bankgroup.ID()] = sc_time_stamp(); - lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp(); + lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp(); lastScheduledByCommand[command] = sc_time_stamp(); - lastCommandOnBus = sc_time_stamp(); + + lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK; if (command == Command::ACT) { - if (last4Activates[rank.ID()].size() == 4) - last4Activates[rank.ID()].pop(); - last4Activates[rank.ID()].push(sc_time_stamp()); + if (last4ActivatesLogical[logicalrank.ID()].size() == 4) + last4ActivatesLogical[logicalrank.ID()].pop(); + last4ActivatesLogical[logicalrank.ID()].push(lastCommandOnBus); + + if (last4ActivatesPhysical[physicalrank.ID()].size() == 4) + last4ActivatesPhysical[physicalrank.ID()].pop(); + last4ActivatesPhysical[physicalrank.ID()].push(lastCommandOnBus); } } diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.h b/DRAMSys/library/src/controller/checker/CheckerDDR5.h index c2338fa6..af5cf61f 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.h @@ -51,24 +51,38 @@ public: private: const MemSpecDDR5 *memSpec; - std::vector> lastScheduledByCommandAndBank; + std::vector> lastScheduledByCommandAndDIMMRank; + std::vector> lastScheduledByCommandAndPhysicalRank; + std::vector> lastScheduledByCommandAndLogicalRank; std::vector> lastScheduledByCommandAndBankGroup; - std::vector> lastScheduledByCommandAndRank; + std::vector> lastScheduledByCommandAndBank; std::vector lastScheduledByCommand; sc_time lastCommandOnBus; - // Four activate window - std::vector> last4Activates; + std::vector> last4ActivatesPhysical; + std::vector> last4ActivatesLogical; - sc_time tBURST; - sc_time tRDWR; - sc_time tRDWR_R; - sc_time tWRRD_S; - sc_time tWRRD_L; - sc_time tWRRD_R; - sc_time tRDAACT; + sc_time tRD_BURST; + sc_time tWR_BURST; + sc_time tWTRA; + sc_time tWRRDA; sc_time tWRPRE; + sc_time tRDAACT; sc_time tWRAACT; + sc_time tCCD_L_RTW_slr; + sc_time tCCD_S_RTW_slr; + sc_time tCCD_RTW_dlr; + sc_time tRDRD_dpr; + sc_time tRDRD_ddr; + sc_time tRDWR_dpr; + sc_time tRDWR_ddr; + sc_time tCCD_L_WTR_slr; + sc_time tCCD_S_WTR_slr; + sc_time tCCD_WTR_dlr; + sc_time tWRWR_dpr; + sc_time tWRWR_ddr; + sc_time tWRRD_dpr; + sc_time tWRRD_ddr; sc_time tRDPDEN; sc_time tWRPDEN; sc_time tWRAPDEN; From eb720d5aa61482c96d16876a0878e5a1d6f1838f Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 25 Aug 2020 10:18:10 +0200 Subject: [PATCH 05/50] Add DDR5 example. --- .../am_ddr5_2x8x8x8Gbx4_dimm_p1KB_rbc.json | 55 ++++++++++++++++ .../JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json | 66 +++++++++++++++++++ .../resources/simulations/ddr5-example.json | 6 +- 3 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x8x8x8Gbx4_dimm_p1KB_rbc.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json diff --git a/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x8x8x8Gbx4_dimm_p1KB_rbc.json b/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x8x8x8Gbx4_dimm_p1KB_rbc.json new file mode 100644 index 00000000..48f1301d --- /dev/null +++ b/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x8x8x8Gbx4_dimm_p1KB_rbc.json @@ -0,0 +1,55 @@ +{ + "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 + ], + "RANK_BIT": [ + 33, + 34, + 35 + ], + "CHANNEL_BIT": [ + 36 + ] + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json new file mode 100644 index 00000000..95e2e703 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json @@ -0,0 +1,66 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 2048, + "nbrOfRanks": 8, + "nbrOfDIMMRanks": 2, + "nbrOfPhysicalRanks": 2, + "nbrOfLogicalRanks": 2, + "nbrOfRows": 65536, + "width": 4, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 2 + }, + "memoryId": "JEDEC_2x8x8x8Gbx4_DDR5-3200A_4bit", + "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_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 8, + "CCD_WR_dlr": 8, + "CCD_WR_dpr": 8, + "RRD_L_slr": 8, + "RRD_S_slr": 8, + "RRD_dlr": 4, + "FAW_slr": 32, + "FAW_dlr": 16, + "WTR_L": 16, + "WTR_S": 4, + "RFC_slr": 312, + "RFC_dlr": 104, + "RFC_dpr": 104, + "RFCsb_slr": 184, + "RFCsb_dlr": 62, + "REFI": 6240, + "REFSBRD_slr": 48, + "REFSBRD_dlr": 24, + "RTRS": 2, + "CPDED": 8, + "PD": 12, + "XP": 12, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 1600 + } + } +} diff --git a/DRAMSys/library/resources/simulations/ddr5-example.json b/DRAMSys/library/resources/simulations/ddr5-example.json index b0052ec5..8c36a540 100644 --- a/DRAMSys/library/resources/simulations/ddr5-example.json +++ b/DRAMSys/library/resources/simulations/ddr5-example.json @@ -1,14 +1,14 @@ { "simulation": { - "addressmapping": "am_ddr5_2x4x8Gbx8_dimm_p1KB_rbc.json", + "addressmapping": "am_ddr5_2x8x8x8Gbx4_dimm_p1KB_rbc.json", "mcconfig": "fr_fcfs.json", - "memspec": "JEDEC_2x8Gb_DDR5-3200A_8bit.json", + "memspec": "JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json", "simconfig": "ddr5.json", "simulationid": "ddr5-example", "thermalconfig": "config.json", "tracesetup": [ { - "clkMhz": 200, + "clkMhz": 2000, "name": "ddr3_example.stl" } ] From 79cb57a672c0bd1ed78e73a6a689ae93a4338c22 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 26 Aug 2020 10:20:45 +0200 Subject: [PATCH 06/50] Add number of bankgroups and REFSB command length to trace analyzer. --- .../resources/scripts/createTraceDB.sql | 2 + DRAMSys/library/src/common/TlmRecorder.cpp | 95 ++++++++++--------- .../businessObjects/commandlengths.h | 8 +- .../businessObjects/generalinfo.h | 9 +- .../businessObjects/phases/phase.h | 16 +++- .../businessObjects/phases/phasefactory.cpp | 5 +- DRAMSys/traceAnalyzer/data/tracedb.cpp | 38 ++++---- .../presentation/tracedrawingproperties.h | 7 +- .../traceAnalyzer/presentation/traceplot.cpp | 1 + .../presentation/tracescroller.cpp | 1 + 10 files changed, 105 insertions(+), 77 deletions(-) diff --git a/DRAMSys/library/resources/scripts/createTraceDB.sql b/DRAMSys/library/resources/scripts/createTraceDB.sql index 7a127fac..a8fa60a8 100644 --- a/DRAMSys/library/resources/scripts/createTraceDB.sql +++ b/DRAMSys/library/resources/scripts/createTraceDB.sql @@ -19,6 +19,7 @@ CREATE TABLE GeneralInfo( NumberOfTransactions INTEGER, TraceEnd INTEGER, NumberOfRanks INTEGER, + NumberOfBankgroups INTEGER, NumberOfBanks INTEGER, clk INTEGER, UnitOfTime TEXT, @@ -41,6 +42,7 @@ CREATE TABLE CommandLengths( WRA INTEGER, REFA INTEGER, REFB INTEGER, + REFSB INTEGER, PDEA INTEGER, PDXA INTEGER, PDEP INTEGER, diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index 59805638..24701cb5 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -275,86 +275,86 @@ void TlmRecorder::prepareSqlStatements() insertTransactionString = "INSERT INTO Transactions VALUES (:id,:rangeID,:address,:burstlength,:thread,:channel,:rank," ":bankgroup,:bank,:row,:column,:dataStrobeBegin,:dataStrobeEnd, :timeOfGeneration,:command)"; + insertRangeString = "INSERT INTO Ranges VALUES (:id,:begin,:end)"; + updateRangeString = "UPDATE Ranges SET End = :end WHERE ID = :id"; + updateDataStrobeString = "UPDATE Transactions SET DataStrobeBegin = :begin, DataStrobeEnd = :end WHERE ID = :id"; insertPhaseString = "INSERT INTO Phases (PhaseName,PhaseBegin,PhaseEnd,Transact) VALUES (:name,:begin,:end,:transaction)"; + updatePhaseString = "UPDATE Phases SET PhaseEnd = :end WHERE Transact = :trans AND PhaseName = :name"; + insertGeneralInfoString = "INSERT INTO GeneralInfo VALUES" - "(:numberOfTransactions,:end,:numberOfRanks,:numberOfBanks,:clk,:unitOfTime,:mcconfig,:memspec," + "(:numberOfTransactions,:end,:numberOfRanks,:numberOfBankgroups,:numberOfBanks,:clk,:unitOfTime,:mcconfig,:memspec," ":traces,:windowSize, :flexibleRefresh, :maxRefBurst, :controllerThread)"; + insertCommandLengthsString = "INSERT INTO CommandLengths VALUES" - "(:ACT, :PRE, :PREA, :RD, :RDA, :WR, :WRA, :REFA, :REFB, :PDEA, :PDXA, :PDEP, :PDXP, :SREFEN, :SREFEX)"; + "(:ACT, :PRE, :PREA, :RD, :RDA, :WR, :WRA, :REFA, :REFB, :REFSB, :PDEA, :PDXA, :PDEP, :PDXP, :SREFEN, :SREFEX)"; + insertDebugMessageString = "INSERT INTO DebugMessages (Time,Message) Values (:time,:message)"; + insertPowerString = "INSERT INTO Power VALUES (:time,:averagePower)"; - sqlite3_prepare_v2(db, insertTransactionString.c_str(), -1, - &insertTransactionStatement, 0); + sqlite3_prepare_v2(db, insertTransactionString.c_str(), -1, &insertTransactionStatement, 0); sqlite3_prepare_v2(db, insertRangeString.c_str(), -1, &insertRangeStatement, 0); sqlite3_prepare_v2(db, updateRangeString.c_str(), -1, &updateRangeStatement, 0); sqlite3_prepare_v2(db, insertPhaseString.c_str(), -1, &insertPhaseStatement, 0); sqlite3_prepare_v2(db, updatePhaseString.c_str(), -1, &updatePhaseStatement, 0); - sqlite3_prepare_v2(db, updateDataStrobeString.c_str(), -1, - &updateDataStrobeStatement, 0); - sqlite3_prepare_v2(db, insertGeneralInfoString.c_str(), -1, - &insertGeneralInfoStatement, 0); - sqlite3_prepare_v2(db, insertCommandLengthsString.c_str(), -1, - &insertCommandLengthsStatement, 0); - sqlite3_prepare_v2(db, insertDebugMessageString.c_str(), -1, - &insertDebugMessageStatement, 0); + sqlite3_prepare_v2(db, updateDataStrobeString.c_str(), -1, &updateDataStrobeStatement, 0); + sqlite3_prepare_v2(db, insertGeneralInfoString.c_str(), -1, &insertGeneralInfoStatement, 0); + sqlite3_prepare_v2(db, insertCommandLengthsString.c_str(), -1, &insertCommandLengthsStatement, 0); + sqlite3_prepare_v2(db, insertDebugMessageString.c_str(), -1, &insertDebugMessageStatement, 0); sqlite3_prepare_v2(db, insertPowerString.c_str(), -1, &insertPowerStatement, 0); } void TlmRecorder::insertDebugMessageInDB(std::string message, const sc_time &time) { sqlite3_bind_int64(insertDebugMessageStatement, 1, time.value()); - sqlite3_bind_text(insertDebugMessageStatement, 2, message.c_str(), - message.length(), 0); + sqlite3_bind_text(insertDebugMessageStatement, 2, message.c_str(), message.length(), 0); executeSqlStatement(insertDebugMessageStatement); } void TlmRecorder::insertGeneralInfo() { sqlite3_bind_int64(insertGeneralInfoStatement, 1, totalNumTransactions - 1); - sqlite3_bind_int64(insertGeneralInfoStatement, 2, - simulationTimeCoveredByRecording.value()); - sqlite3_bind_int(insertGeneralInfoStatement, 3, - Configuration::getInstance().memSpec->numberOfRanks); - sqlite3_bind_int(insertGeneralInfoStatement, 4, - Configuration::getInstance().memSpec->numberOfBanks); - sqlite3_bind_int(insertGeneralInfoStatement, 5, - Configuration::getInstance().memSpec->tCK.value()); - sqlite3_bind_text(insertGeneralInfoStatement, 6, "PS", 2, NULL); - sqlite3_bind_text(insertGeneralInfoStatement, 7, mcconfig.c_str(), - mcconfig.length(), NULL); - sqlite3_bind_text(insertGeneralInfoStatement, 8, memspec.c_str(), - memspec.length(), NULL); - sqlite3_bind_text(insertGeneralInfoStatement, 9, traces.c_str(), - traces.length(), NULL); + sqlite3_bind_int64(insertGeneralInfoStatement, 2, simulationTimeCoveredByRecording.value()); + sqlite3_bind_int(insertGeneralInfoStatement, 3, Configuration::getInstance().memSpec->numberOfRanks); + sqlite3_bind_int(insertGeneralInfoStatement, 4, Configuration::getInstance().memSpec->numberOfBankGroups); + sqlite3_bind_int(insertGeneralInfoStatement, 5, Configuration::getInstance().memSpec->numberOfBanks); + sqlite3_bind_int(insertGeneralInfoStatement, 6, Configuration::getInstance().memSpec->tCK.value()); + sqlite3_bind_text(insertGeneralInfoStatement, 7, "PS", 2, NULL); + sqlite3_bind_text(insertGeneralInfoStatement, 8, mcconfig.c_str(), mcconfig.length(), NULL); + sqlite3_bind_text(insertGeneralInfoStatement, 9, memspec.c_str(), memspec.length(), NULL); + sqlite3_bind_text(insertGeneralInfoStatement, 10, traces.c_str(), traces.length(), NULL); if (!Configuration::getInstance().enableWindowing) - sqlite3_bind_int64(insertGeneralInfoStatement, 10, 0); + sqlite3_bind_int64(insertGeneralInfoStatement, 11, 0); else - sqlite3_bind_int64(insertGeneralInfoStatement, 10, - (Configuration::getInstance().memSpec->tCK * - Configuration::getInstance().windowSize).value()); + sqlite3_bind_int64(insertGeneralInfoStatement, 11, + (Configuration::getInstance().memSpec->tCK * + Configuration::getInstance().windowSize).value()); + if ((Configuration::getInstance().refreshMaxPostponed > 0) - || (Configuration::getInstance().refreshMaxPulledin > 0)) { - sqlite3_bind_int(insertGeneralInfoStatement, 11, 1); - sqlite3_bind_int(insertGeneralInfoStatement, 12, - std::max(Configuration::getInstance().refreshMaxPostponed, - Configuration::getInstance().refreshMaxPulledin)); - } else { - sqlite3_bind_int(insertGeneralInfoStatement, 11, 0); + || (Configuration::getInstance().refreshMaxPulledin > 0)) + { + sqlite3_bind_int(insertGeneralInfoStatement, 12, 1); + sqlite3_bind_int(insertGeneralInfoStatement, 13, + std::max(Configuration::getInstance().refreshMaxPostponed, + Configuration::getInstance().refreshMaxPulledin)); + } + else + { sqlite3_bind_int(insertGeneralInfoStatement, 12, 0); + sqlite3_bind_int(insertGeneralInfoStatement, 13, 0); } - sqlite3_bind_int(insertGeneralInfoStatement, 13, UINT_MAX); + sqlite3_bind_int(insertGeneralInfoStatement, 14, UINT_MAX); executeSqlStatement(insertGeneralInfoStatement); } @@ -371,12 +371,13 @@ void TlmRecorder::insertCommandLengths() sqlite3_bind_int(insertCommandLengthsStatement, 7, memSpec->getCommandLength(Command::WRA) / memSpec->tCK); sqlite3_bind_int(insertCommandLengthsStatement, 8, memSpec->getCommandLength(Command::REFA) / memSpec->tCK); sqlite3_bind_int(insertCommandLengthsStatement, 9, memSpec->getCommandLength(Command::REFB) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 10, memSpec->getCommandLength(Command::PDEA) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 11, memSpec->getCommandLength(Command::PDXA) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 12, memSpec->getCommandLength(Command::PDEP) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 13, memSpec->getCommandLength(Command::PDXP) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 14, memSpec->getCommandLength(Command::SREFEN) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 15, memSpec->getCommandLength(Command::SREFEX) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 10, 1); + sqlite3_bind_int(insertCommandLengthsStatement, 11, memSpec->getCommandLength(Command::PDEA) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 12, memSpec->getCommandLength(Command::PDXA) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 13, memSpec->getCommandLength(Command::PDEP) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 14, memSpec->getCommandLength(Command::PDXP) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 15, memSpec->getCommandLength(Command::SREFEN) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 16, memSpec->getCommandLength(Command::SREFEX) / memSpec->tCK); executeSqlStatement(insertCommandLengthsStatement); } diff --git a/DRAMSys/traceAnalyzer/businessObjects/commandlengths.h b/DRAMSys/traceAnalyzer/businessObjects/commandlengths.h index fad3eff2..07b1b2a7 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/commandlengths.h +++ b/DRAMSys/traceAnalyzer/businessObjects/commandlengths.h @@ -47,6 +47,7 @@ struct CommandLengths unsigned WRA; unsigned REFA; unsigned REFB; + unsigned REFSB; unsigned PDEA; unsigned PDXA; unsigned PDEP; @@ -56,10 +57,11 @@ struct CommandLengths CommandLengths(unsigned ACT, unsigned PRE, unsigned PREA, unsigned RD, unsigned RDA, unsigned WR, unsigned WRA, - unsigned REFA, unsigned REFB, unsigned PDEA, unsigned PDXA, - unsigned PDEP, unsigned PDXP, unsigned SREFEN, unsigned SREFEX) : + unsigned REFA, unsigned REFB, unsigned REFSB, + unsigned PDEA, unsigned PDXA, unsigned PDEP, unsigned PDXP, + unsigned SREFEN, unsigned SREFEX) : ACT(ACT), PRE(PRE), PREA(PREA), RD(RD), RDA(RDA), WR(WR), WRA(WRA), - REFA(REFA), REFB(REFB), PDEA(PDEA), PDXA(PDXA), + REFA(REFA), REFB(REFB), REFSB(REFSB), PDEA(PDEA), PDXA(PDXA), PDEP(PDEP), PDXP(PDXP), SREFEN(SREFEN), SREFEX(SREFEX) {} CommandLengths() {} diff --git a/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h b/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h index a86b8d62..8eaa9fd4 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h +++ b/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h @@ -45,6 +45,7 @@ struct GeneralInfo { unsigned int numberOfPhases; Timespan span; unsigned int numberOfRanks; + unsigned int numberOfBankgroups; unsigned int numberOfBanks; QString description; QString unitOfTime; @@ -53,12 +54,12 @@ struct GeneralInfo { unsigned int controllerThread; public: - GeneralInfo(unsigned int numberOfTransactions, unsigned int numberOfPhases, - Timespan span, unsigned int numberOfRanks, unsigned int numberOfBanks, + GeneralInfo(unsigned int numberOfTransactions, unsigned int numberOfPhases, Timespan span, + unsigned int numberOfRanks, unsigned int numberOfBankgroups, unsigned int numberOfBanks, const QString &description, QString unitOfTime, unsigned int clkPeriod, unsigned int windowSize, unsigned int controllerThread) : - numberOfTransactions(numberOfTransactions) , numberOfPhases(numberOfPhases), - span(span), numberOfRanks(numberOfRanks), numberOfBanks(numberOfBanks), + numberOfTransactions(numberOfTransactions) , numberOfPhases(numberOfPhases), span(span), + numberOfRanks(numberOfRanks), numberOfBankgroups(numberOfBankgroups), numberOfBanks(numberOfBanks), description(description), unitOfTime(unitOfTime), clkPeriod(clkPeriod), windowSize(windowSize), controllerThread(controllerThread) {} diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h index ae5cbc3c..eb269c3f 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h @@ -314,8 +314,22 @@ protected: } }; +class REFSB : public AUTO_REFRESH +{ +public: + using AUTO_REFRESH::AUTO_REFRESH; +protected: + virtual QString Name() const override + { + return "REFSB"; + } + virtual bool isBankwise() const override + { + return false; + } +}; -class PRECHARGE_ALL : public Phase +class PREA : public Phase { public: using Phase::Phase; diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp index 9156a5d8..862bf687 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp @@ -68,7 +68,7 @@ shared_ptr PhaseFactory::CreatePhase(ID id, const QString &dbPhaseName, return shared_ptr(new ACT(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.ACT)}, std::shared_ptr())); else if (dbPhaseName == "PREA") - return shared_ptr(new PRECHARGE_ALL(id, span, trans, + return shared_ptr(new PREA(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.PREA)}, std::shared_ptr())); else if (dbPhaseName == "REFA") return shared_ptr(new REFA(id, span, trans, @@ -76,6 +76,9 @@ shared_ptr PhaseFactory::CreatePhase(ID id, const QString &dbPhaseName, else if (dbPhaseName == "REFB") return shared_ptr(new REFB(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.REFB)}, std::shared_ptr())); + else if (dbPhaseName == "REFSB") + return shared_ptr(new REFSB(id, span, trans, + {Timespan(span.Begin(), span.Begin() + clk * cl.REFSB)}, std::shared_ptr())); else if (dbPhaseName == "RD") return shared_ptr(new RD(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RD)}, std::shared_ptr(new Timespan(trans->SpanOnDataStrobe())))); diff --git a/DRAMSys/traceAnalyzer/data/tracedb.cpp b/DRAMSys/traceAnalyzer/data/tracedb.cpp index d8f177ca..4471ce35 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.cpp +++ b/DRAMSys/traceAnalyzer/data/tracedb.cpp @@ -238,7 +238,7 @@ ID TraceDB::getTransactionIDFromPhaseID(ID phaseID) GeneralInfo TraceDB::getGeneralInfoFromDB() { QSqlQuery query(database); - query.prepare("SELECT NumberOfTransactions, TraceEnd, NumberOfRanks, NumberOfBanks, Clk, " + query.prepare("SELECT NumberOfTransactions, TraceEnd, NumberOfRanks, NumberOfBankgroups, NumberOfBanks, Clk, " "UnitOfTime, Traces, Memspec, MCconfig, WindowSize, ControllerThread FROM GeneralInfo"); executeQuery(query); @@ -246,16 +246,17 @@ GeneralInfo TraceDB::getGeneralInfoFromDB() unsigned int numberOfTransactions = query.value(0).toInt(); traceTime traceEnd = query.value(1).toLongLong(); unsigned int numberOfRanks = query.value(2).toInt(); - unsigned int numberOfBanks = query.value(3).toInt(); - unsigned int clkPeriod = query.value(4).toInt(); - QString unitOfTime = query.value(5).toString(); + unsigned int numberOfBankgroups = query.value(3).toInt(); + unsigned int numberOfBanks = query.value(4).toInt(); + unsigned int clkPeriod = query.value(5).toInt(); + QString unitOfTime = query.value(6).toString(); unsigned int numberOfPhases = getNumberOfPhases(); - QString traces = "Traces: " + query.value(6).toString(); - QString memspec = "Memspec: " + query.value(7).toString(); - QString mcconfig = "MCconfig: " + query.value(8).toString(); - unsigned int windowSize = query.value(9).toInt(); - unsigned int controllerThread = query.value(10).toUInt(); + QString traces = "Traces: " + query.value(7).toString(); + QString memspec = "Memspec: " + query.value(8).toString(); + QString mcconfig = "MCconfig: " + query.value(9).toString(); + unsigned int windowSize = query.value(10).toInt(); + unsigned int controllerThread = query.value(11).toUInt(); QString description = (traces + "\n"); description += mcconfig + "\n"; @@ -268,8 +269,8 @@ GeneralInfo TraceDB::getGeneralInfoFromDB() description += "Window size:" + QString::number(windowSize) + "\n"; return GeneralInfo(numberOfTransactions, numberOfPhases, Timespan(0, traceEnd), - numberOfRanks, numberOfBanks, description, unitOfTime, - clkPeriod, windowSize, controllerThread); + numberOfRanks, numberOfBankgroups, numberOfBanks, + description, unitOfTime, clkPeriod, windowSize, controllerThread); } else { throw sqlException("Tracefile corrupted. No general info table", this->pathToDB.toStdString()); @@ -293,14 +294,15 @@ CommandLengths TraceDB::getCommandLengthsFromDB() unsigned WRA = query.value(6).toInt(); unsigned REFA = query.value(7).toInt(); unsigned REFB = query.value(8).toInt(); - unsigned PDEA = query.value(9).toInt(); - unsigned PDXA = query.value(10).toInt(); - unsigned PDEP = query.value(11).toInt(); - unsigned PDXP = query.value(12).toInt(); - unsigned SREFEN = query.value(13).toInt(); - unsigned SREFEX = query.value(14).toInt(); + unsigned REFSB = query.value(9).toInt(); + unsigned PDEA = query.value(10).toInt(); + unsigned PDXA = query.value(11).toInt(); + unsigned PDEP = query.value(12).toInt(); + unsigned PDXP = query.value(13).toInt(); + unsigned SREFEN = query.value(14).toInt(); + unsigned SREFEX = query.value(15).toInt(); - return CommandLengths(ACT, PRE, PREA, RD, RDA, WR, WRA, REFA, REFB, + return CommandLengths(ACT, PRE, PREA, RD, RDA, WR, WRA, REFA, REFB, REFSB, PDEA, PDXA, PDEP, PDXP, SREFEN, SREFEX); } else diff --git a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h index 7f5f7abc..1a763554 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h +++ b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h @@ -54,6 +54,7 @@ struct TraceDrawingProperties { int yValCommandBus; int yValDataBus; unsigned int numberOfRanks; + unsigned int numberOfBankgroups; unsigned int numberOfBanks; unsigned int banksPerRank; @@ -68,8 +69,8 @@ struct TraceDrawingProperties { drawText(drawText), drawBorder(drawBorder), colorGrouping(colorGrouping), yValResponse(yValResponse), yValRequest(yValRequest), yValCommandBus(yValCommandBus), yValDataBus(yValDataBus), - numberOfRanks(numberOfRanks), numberOfBanks(numberOfBanks), - banksPerRank(numberOfBanks / numberOfRanks) {} + numberOfRanks(numberOfRanks), numberOfBankgroups(numberOfBankgroups), + numberOfBanks(numberOfBanks), banksPerRank(numberOfBanks / numberOfRanks) {} QHash getLabels() const { @@ -78,7 +79,7 @@ struct TraceDrawingProperties { result[i] = QString("Bank ") + QString::number(i); } - result[yValCommandBus] = "Cmd Bus"; + result[yValCommandBus] = "Command Bus"; result[yValResponse] = "RESP"; result[yValRequest] = "REQ"; result[yValDataBus] = "Data Bus"; diff --git a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp index 351477ee..fa518ac2 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp +++ b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp @@ -206,6 +206,7 @@ void TracePlot::connectNavigatorQ_SIGNALS() void TracePlot::setUpDrawingProperties() { drawingProperties.numberOfRanks = navigator->GeneralTraceInfo().numberOfRanks; + drawingProperties.numberOfBankgroups = navigator->GeneralTraceInfo().numberOfBankgroups; drawingProperties.numberOfBanks = navigator->GeneralTraceInfo().numberOfBanks; drawingProperties.banksPerRank = drawingProperties.numberOfBanks / drawingProperties.numberOfRanks; drawingProperties.yValResponse = drawingProperties.numberOfBanks; diff --git a/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp b/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp index ddccf75a..5bf8d301 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp @@ -87,6 +87,7 @@ void TraceScroller::setUpTracePlotItem() void TraceScroller::setUpDrawingProperties() { drawingProperties.numberOfRanks = navigator->GeneralTraceInfo().numberOfRanks; + drawingProperties.numberOfBankgroups = navigator->GeneralTraceInfo().numberOfBankgroups; drawingProperties.numberOfBanks = navigator->GeneralTraceInfo().numberOfBanks; drawingProperties.banksPerRank = drawingProperties.numberOfBanks / drawingProperties.numberOfRanks; drawingProperties.yValResponse = drawingProperties.numberOfBanks; From aa7ae09e2b72f7495b8bfbb42af8bfacb0e09751 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 26 Aug 2020 11:36:15 +0200 Subject: [PATCH 07/50] Add rank and bankgroup to drawing. --- .../businessObjects/transaction.h | 2 +- .../presentation/tracedrawingproperties.h | 26 ++++++++++++------- .../traceAnalyzer/presentation/traceplot.cpp | 2 ++ .../presentation/tracescroller.cpp | 2 ++ .../presentation/transactiontreewidget.cpp | 2 +- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/DRAMSys/traceAnalyzer/businessObjects/transaction.h b/DRAMSys/traceAnalyzer/businessObjects/transaction.h index 723cfc8f..b6027df0 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/transaction.h +++ b/DRAMSys/traceAnalyzer/businessObjects/transaction.h @@ -89,7 +89,7 @@ public: { return rank; } - unsigned int BankGroup() const + unsigned int Bankgroup() const { return bankgroup; } diff --git a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h index 1a763554..6fa65695 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h +++ b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h @@ -37,6 +37,7 @@ #ifndef TRACECOLLECTIONDRAWINGPROPERTIES_H #define TRACECOLLECTIONDRAWINGPROPERTIES_H + #include #include #include @@ -57,26 +58,31 @@ struct TraceDrawingProperties { unsigned int numberOfBankgroups; unsigned int numberOfBanks; unsigned int banksPerRank; + unsigned int groupsPerRank; + unsigned int banksPerGroup; TraceDrawingProperties() : drawText(true), drawBorder(true), colorGrouping(ColorGrouping::PhaseType) {} TraceDrawingProperties(bool drawText, bool drawBorder, ColorGrouping colorGrouping) : drawText(drawText), drawBorder(drawBorder), colorGrouping(colorGrouping) {} - TraceDrawingProperties(bool drawText, bool drawBorder, ColorGrouping colorGrouping, - int yValResponse, int yValRequest, int yValCommandBus, int yValDataBus, - unsigned int numberOfRanks, unsigned int numberOfBanks) : - drawText(drawText), drawBorder(drawBorder), colorGrouping(colorGrouping), - yValResponse(yValResponse), yValRequest(yValRequest), - yValCommandBus(yValCommandBus), yValDataBus(yValDataBus), - numberOfRanks(numberOfRanks), numberOfBankgroups(numberOfBankgroups), - numberOfBanks(numberOfBanks), banksPerRank(numberOfBanks / numberOfRanks) {} QHash getLabels() const { QHash result; - for (unsigned int i = 0; i < numberOfBanks; i++) { - result[i] = QString("Bank ") + QString::number(i); + + unsigned i = 0; + for (unsigned rank = 0; rank < numberOfRanks; rank++) + { + for (unsigned group = 0; group < groupsPerRank; group++) + { + for (unsigned bank = 0; bank < banksPerGroup; bank++) + { + result[i++] = QString("RA") + QString::number(rank) + + QString(" BG") + QString::number(group) + + QString(" BA") + QString::number(bank); + } + } } result[yValCommandBus] = "Command Bus"; diff --git a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp index fa518ac2..e54ab395 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp +++ b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp @@ -209,6 +209,8 @@ void TracePlot::setUpDrawingProperties() drawingProperties.numberOfBankgroups = navigator->GeneralTraceInfo().numberOfBankgroups; drawingProperties.numberOfBanks = navigator->GeneralTraceInfo().numberOfBanks; drawingProperties.banksPerRank = drawingProperties.numberOfBanks / drawingProperties.numberOfRanks; + drawingProperties.groupsPerRank = drawingProperties.numberOfBankgroups / drawingProperties.numberOfRanks; + drawingProperties.banksPerGroup = drawingProperties.numberOfBanks / drawingProperties.numberOfBankgroups; drawingProperties.yValResponse = drawingProperties.numberOfBanks; drawingProperties.yValRequest = drawingProperties.numberOfBanks + 1; drawingProperties.yValCommandBus = -3; diff --git a/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp b/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp index 5bf8d301..1090bd45 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp @@ -90,6 +90,8 @@ void TraceScroller::setUpDrawingProperties() drawingProperties.numberOfBankgroups = navigator->GeneralTraceInfo().numberOfBankgroups; drawingProperties.numberOfBanks = navigator->GeneralTraceInfo().numberOfBanks; drawingProperties.banksPerRank = drawingProperties.numberOfBanks / drawingProperties.numberOfRanks; + drawingProperties.groupsPerRank = drawingProperties.numberOfBankgroups / drawingProperties.numberOfRanks; + drawingProperties.banksPerGroup = drawingProperties.numberOfBanks / drawingProperties.numberOfBankgroups; drawingProperties.yValResponse = drawingProperties.numberOfBanks; drawingProperties.yValRequest = drawingProperties.numberOfBanks + 1; drawingProperties.yValCommandBus = -3; diff --git a/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp b/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp index ae672cfa..bd30ad40 100644 --- a/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp +++ b/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp @@ -102,7 +102,7 @@ TransactionTreeWidget::TransactionTreeItem::TransactionTreeItem( this->addChild(new QTreeWidgetItem( {"Channel", QString::number(transaction->Channel())})); this->addChild(new QTreeWidgetItem( {"Rank", QString::number(transaction->Rank())} )); - this->addChild(new QTreeWidgetItem( {"Bankgroup", QString::number(transaction->BankGroup())} )); + this->addChild(new QTreeWidgetItem( {"Bankgroup", QString::number(transaction->Bankgroup())} )); this->addChild(new QTreeWidgetItem( {"Bank", QString::number(transaction->Bank())} )); this->addChild(new QTreeWidgetItem( {"Row", QString::number(transaction->Row())} )); this->addChild(new QTreeWidgetItem( {"Column", QString::number(transaction->Column())} )); From 7b5cbe03e0ee5ab30e63c7a7aec8e11c43c1ad62 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 26 Aug 2020 16:16:16 +0200 Subject: [PATCH 08/50] Change indices in transaction tree widget to relative numbers. --- DRAMSys/tests/DDR4/scripts/createTraceDB.sql | 2 + DRAMSys/tests/HBM2/scripts/createTraceDB.sql | 2 + .../ddr3_multirank/scripts/createTraceDB.sql | 2 + .../tests/lpddr4/scripts/createTraceDB.sql | 2 + .../businessObjects/generalinfo.h | 13 ++-- .../businessObjects/phases/phase.cpp | 8 +-- .../businessObjects/phases/phasefactory.cpp | 8 +-- .../businessObjects/transaction.h | 59 ++----------------- .../presentation/tracenavigator.cpp | 36 +++++------ .../presentation/transactiontreewidget.cpp | 38 ++++++------ .../presentation/transactiontreewidget.h | 2 +- 11 files changed, 69 insertions(+), 103 deletions(-) diff --git a/DRAMSys/tests/DDR4/scripts/createTraceDB.sql b/DRAMSys/tests/DDR4/scripts/createTraceDB.sql index 7a127fac..a8fa60a8 100644 --- a/DRAMSys/tests/DDR4/scripts/createTraceDB.sql +++ b/DRAMSys/tests/DDR4/scripts/createTraceDB.sql @@ -19,6 +19,7 @@ CREATE TABLE GeneralInfo( NumberOfTransactions INTEGER, TraceEnd INTEGER, NumberOfRanks INTEGER, + NumberOfBankgroups INTEGER, NumberOfBanks INTEGER, clk INTEGER, UnitOfTime TEXT, @@ -41,6 +42,7 @@ CREATE TABLE CommandLengths( WRA INTEGER, REFA INTEGER, REFB INTEGER, + REFSB INTEGER, PDEA INTEGER, PDXA INTEGER, PDEP INTEGER, diff --git a/DRAMSys/tests/HBM2/scripts/createTraceDB.sql b/DRAMSys/tests/HBM2/scripts/createTraceDB.sql index 7a127fac..a8fa60a8 100644 --- a/DRAMSys/tests/HBM2/scripts/createTraceDB.sql +++ b/DRAMSys/tests/HBM2/scripts/createTraceDB.sql @@ -19,6 +19,7 @@ CREATE TABLE GeneralInfo( NumberOfTransactions INTEGER, TraceEnd INTEGER, NumberOfRanks INTEGER, + NumberOfBankgroups INTEGER, NumberOfBanks INTEGER, clk INTEGER, UnitOfTime TEXT, @@ -41,6 +42,7 @@ CREATE TABLE CommandLengths( WRA INTEGER, REFA INTEGER, REFB INTEGER, + REFSB INTEGER, PDEA INTEGER, PDXA INTEGER, PDEP INTEGER, diff --git a/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql b/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql index 7a127fac..a8fa60a8 100644 --- a/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql +++ b/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql @@ -19,6 +19,7 @@ CREATE TABLE GeneralInfo( NumberOfTransactions INTEGER, TraceEnd INTEGER, NumberOfRanks INTEGER, + NumberOfBankgroups INTEGER, NumberOfBanks INTEGER, clk INTEGER, UnitOfTime TEXT, @@ -41,6 +42,7 @@ CREATE TABLE CommandLengths( WRA INTEGER, REFA INTEGER, REFB INTEGER, + REFSB INTEGER, PDEA INTEGER, PDXA INTEGER, PDEP INTEGER, diff --git a/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql b/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql index 7a127fac..a8fa60a8 100644 --- a/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql +++ b/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql @@ -19,6 +19,7 @@ CREATE TABLE GeneralInfo( NumberOfTransactions INTEGER, TraceEnd INTEGER, NumberOfRanks INTEGER, + NumberOfBankgroups INTEGER, NumberOfBanks INTEGER, clk INTEGER, UnitOfTime TEXT, @@ -41,6 +42,7 @@ CREATE TABLE CommandLengths( WRA INTEGER, REFA INTEGER, REFB INTEGER, + REFSB INTEGER, PDEA INTEGER, PDXA INTEGER, PDEP INTEGER, diff --git a/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h b/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h index 8eaa9fd4..d201f80d 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h +++ b/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h @@ -40,28 +40,33 @@ #include "timespan.h" #include -struct GeneralInfo { +struct GeneralInfo +{ +public: unsigned int numberOfTransactions; unsigned int numberOfPhases; Timespan span; unsigned int numberOfRanks; unsigned int numberOfBankgroups; unsigned int numberOfBanks; + unsigned int banksPerRank; + unsigned int groupsPerRank; + unsigned int banksPerGroup; QString description; QString unitOfTime; unsigned int clkPeriod; unsigned int windowSize; unsigned int controllerThread; -public: GeneralInfo(unsigned int numberOfTransactions, unsigned int numberOfPhases, Timespan span, unsigned int numberOfRanks, unsigned int numberOfBankgroups, unsigned int numberOfBanks, const QString &description, QString unitOfTime, unsigned int clkPeriod, unsigned int windowSize, unsigned int controllerThread) : numberOfTransactions(numberOfTransactions) , numberOfPhases(numberOfPhases), span(span), numberOfRanks(numberOfRanks), numberOfBankgroups(numberOfBankgroups), numberOfBanks(numberOfBanks), - description(description), unitOfTime(unitOfTime), clkPeriod(clkPeriod), - windowSize(windowSize), controllerThread(controllerThread) {} + banksPerRank(numberOfBanks / numberOfRanks), groupsPerRank(numberOfBankgroups / numberOfRanks), + banksPerGroup(numberOfBanks / numberOfBankgroups), description(description), unitOfTime(unitOfTime), + clkPeriod(clkPeriod), windowSize(windowSize), controllerThread(controllerThread) {} GeneralInfo() {} }; diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp index 1f88cc24..a4393318 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp @@ -113,20 +113,20 @@ QColor Phase::getColor(const TraceDrawingProperties &drawingProperties) const break; case ColorGrouping::Thread: return ColorGenerator::getColor(static_cast - (transaction->Thread())); + (transaction->thread)); break; case ColorGrouping::Transaction: default: - return ColorGenerator::getColor(transaction->Id()); + return ColorGenerator::getColor(transaction->id); } } int Phase::getYVal(const TraceDrawingProperties &drawingProperties) const { if (isBankwise()) - return transaction->Bank(); + return transaction->bank; else - return transaction->Rank() * drawingProperties.banksPerRank; + return transaction->rank * drawingProperties.banksPerRank; } Qt::BrushStyle Phase::getBrushStyle() const diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp index 862bf687..94a6c453 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp @@ -81,16 +81,16 @@ shared_ptr PhaseFactory::CreatePhase(ID id, const QString &dbPhaseName, {Timespan(span.Begin(), span.Begin() + clk * cl.REFSB)}, std::shared_ptr())); else if (dbPhaseName == "RD") return shared_ptr(new RD(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RD)}, - std::shared_ptr(new Timespan(trans->SpanOnDataStrobe())))); + std::shared_ptr(new Timespan(trans->spanOnDataStrobe)))); else if (dbPhaseName == "RDA") return shared_ptr(new RDA(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RDA)}, - std::shared_ptr(new Timespan(trans->SpanOnDataStrobe())))); + std::shared_ptr(new Timespan(trans->spanOnDataStrobe)))); else if (dbPhaseName == "WR") return shared_ptr(new WR(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.WR)}, - std::shared_ptr(new Timespan(trans->SpanOnDataStrobe())))); + std::shared_ptr(new Timespan(trans->spanOnDataStrobe)))); else if (dbPhaseName == "WRA") return shared_ptr(new WRA(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.WRA)}, - std::shared_ptr(new Timespan(trans->SpanOnDataStrobe())))); + std::shared_ptr(new Timespan(trans->spanOnDataStrobe)))); else if (dbPhaseName == "PDNA") return shared_ptr(new PDNA(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.PDEA), Timespan(span.End() - clk * cl.PDXA, span.End())}, std::shared_ptr())); diff --git a/DRAMSys/traceAnalyzer/businessObjects/transaction.h b/DRAMSys/traceAnalyzer/businessObjects/transaction.h index b6027df0..57854bea 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/transaction.h +++ b/DRAMSys/traceAnalyzer/businessObjects/transaction.h @@ -48,14 +48,15 @@ typedef unsigned int ID; class Transaction { private: - unsigned int address, burstlength, thread, channel, rank, - bankgroup, bank, row, column; - Timespan span; - Timespan spanOnDataStrobe; - ID id; std::vector> phases; public: + const unsigned int address, burstlength, thread, channel, rank, + bankgroup, bank, row, column; + const Timespan span; + const Timespan spanOnDataStrobe; + const ID id; + Transaction(ID id, unsigned int address, unsigned int burstlength, unsigned int thread, unsigned int channel, unsigned int rank, unsigned int bankgroup, unsigned int bank, unsigned int row, unsigned int column, @@ -69,54 +70,6 @@ public: bool isSelected(traceTime time, double yVal, const TraceDrawingProperties &drawingproperties) const; - unsigned int Address() const - { - return address; - } - unsigned int Burstlength() const - { - return burstlength; - } - unsigned int Thread() - { - return thread; - } - unsigned int Channel() const - { - return channel; - } - unsigned int Rank() const - { - return rank; - } - unsigned int Bankgroup() const - { - return bankgroup; - } - unsigned int Bank() const - { - return bank; - } - unsigned int Row() const - { - return row; - } - unsigned int Column() const - { - return column; - } - ID Id() const - { - return id; - } - const Timespan &Span() const - { - return span; - } - const Timespan &SpanOnDataStrobe() - { - return spanOnDataStrobe; - } const std::vector> &Phases() const { return phases; diff --git a/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp b/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp index afd59c73..7ff82f87 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp @@ -69,7 +69,7 @@ void TraceNavigator::navigateToTime(traceTime time) void TraceNavigator::navigateToTransaction(ID id) { - navigateToTime(traceFile.getTransactionByID(id)->Span().Begin()); + navigateToTime(traceFile.getTransactionByID(id)->span.Begin()); } @@ -162,25 +162,25 @@ void TraceNavigator::selectTransaction(ID id) void TraceNavigator::selectTransaction(const shared_ptr &transaction) { - selectTransaction(transaction->Id()); + selectTransaction(transaction->id); } void TraceNavigator::selectNextTransaction() { if (selectedTransactions.empty() - || selectedTransactions.front()->Id() == + || selectedTransactions.front()->id == traceFile.getGeneralInfo().numberOfTransactions) selectFirstTransaction(); else - selectTransaction(selectedTransactions.front()->Id() + 1); + selectTransaction(selectedTransactions.front()->id + 1); } void TraceNavigator::selectPreviousTransaction() { - if (selectedTransactions.empty() || selectedTransactions.front()->Id() == 1) + if (selectedTransactions.empty() || selectedTransactions.front()->id == 1) selectLastTransaction(); else - selectTransaction(selectedTransactions.front()->Id() - 1); + selectTransaction(selectedTransactions.front()->id - 1); } void TraceNavigator::selectFirstTransaction() @@ -199,7 +199,7 @@ void TraceNavigator::selectNextRefresh() shared_ptr nextRefresh; if (!SelectedTransactions().empty()) - nextRefresh = traceFile.getNextRefresh(SelectedTransactions().front()->Id()); + nextRefresh = traceFile.getNextRefresh(SelectedTransactions().front()->id); else nextRefresh = traceFile.getNextRefresh(0); @@ -212,7 +212,7 @@ void TraceNavigator::selectNextActivate() shared_ptr nextActivate; if (!SelectedTransactions().empty()) - nextActivate = traceFile.getNextActivate(SelectedTransactions().front()->Id()); + nextActivate = traceFile.getNextActivate(SelectedTransactions().front()->id); else nextActivate = traceFile.getNextActivate(0); @@ -226,7 +226,7 @@ void TraceNavigator::selectNextPrecharge() if (!SelectedTransactions().empty()) nextPrecharge = traceFile.getNextPrecharge( - SelectedTransactions().front()->Id()); + SelectedTransactions().front()->id); else nextPrecharge = traceFile.getNextPrecharge(0); @@ -239,7 +239,7 @@ void TraceNavigator::selectNextActb() shared_ptr nextActb; if (!SelectedTransactions().empty()) - nextActb = traceFile.getNextActb(SelectedTransactions().front()->Id()); + nextActb = traceFile.getNextActb(SelectedTransactions().front()->id); else nextActb = traceFile.getNextActb(0); @@ -253,7 +253,7 @@ void TraceNavigator::selectNextPreb() if (!SelectedTransactions().empty()) nextPreb = traceFile.getNextPreb( - SelectedTransactions().front()->Id()); + SelectedTransactions().front()->id); else nextPreb = traceFile.getNextPreb(0); @@ -266,7 +266,7 @@ void TraceNavigator::selectNextRefb() shared_ptr n; if (!SelectedTransactions().empty()) - n = traceFile.getNextRefb(SelectedTransactions().front()->Id()); + n = traceFile.getNextRefb(SelectedTransactions().front()->id); else n = traceFile.getNextRefb(0); @@ -277,13 +277,13 @@ void TraceNavigator::selectNextRefb() bool TraceNavigator::transactionIsSelected(const shared_ptr &transaction) const { - return transactionIsSelected(transaction->Id()); + return transactionIsSelected(transaction->id); } bool TraceNavigator::transactionIsSelected(ID id) const { for (const auto &transaction : selectedTransactions) { - if (transaction->Id() == id) + if (transaction->id == id) return true; } return false; @@ -307,12 +307,12 @@ Timespan TraceNavigator::getSpanCoveredBySelectedTransaction() if (!hasSelectedTransactions()) return Timespan(0, 0); - traceTime begin = SelectedTransactions().at(0)->Span().Begin(); - traceTime end = SelectedTransactions().at(0)->Span().End(); + traceTime begin = SelectedTransactions().at(0)->span.Begin(); + traceTime end = SelectedTransactions().at(0)->span.End(); for (const auto &transaction : selectedTransactions) { - if (transaction->Span().End() > end) - end = transaction->Span().End(); + if (transaction->span.End() > end) + end = transaction->span.End(); } return Timespan(begin, end); diff --git a/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp b/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp index bd30ad40..af97ff3b 100644 --- a/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp +++ b/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp @@ -66,7 +66,7 @@ void TransactionTreeWidget::AppendTransaction(const shared_ptr &transaction) { QTreeWidgetItem *node = new TransactionTreeItem(this, transaction, - navigator->GeneralTraceInfo().controllerThread); + navigator->GeneralTraceInfo()); addTopLevelItem(node); } @@ -89,33 +89,33 @@ void TransactionTreeWidget::ContextMenuRequested(QPoint point) TransactionTreeWidget::TransactionTreeItem::TransactionTreeItem( QTreeWidget *parent, const shared_ptr &transaction, - unsigned int controllerThread) : QTreeWidgetItem(parent, - transactionTreeItemType) + const GeneralInfo &generalInfo) + : QTreeWidgetItem(parent, transactionTreeItemType) { - this->setText(0, QString::number(transaction->Id())); - this->id = transaction->Id(); + this->setText(0, QString::number(transaction->id)); + this->id = transaction->id; QTreeWidgetItem *time = new QTreeWidgetItem({"Timespan"}); - AppendTimespan(time, transaction->Span()); + AppendTimespan(time, transaction->span); this->addChild(time); - this->addChild(new QTreeWidgetItem( {"Lenght", prettyFormatTime(transaction->Span().timeCovered())})); + this->addChild(new QTreeWidgetItem({"Lenght", prettyFormatTime(transaction->span.timeCovered())})); + this->addChild(new QTreeWidgetItem({"Channel", QString::number(transaction->channel)})); + this->addChild(new QTreeWidgetItem({"Rank", QString::number(transaction->rank)})); + this->addChild(new QTreeWidgetItem({"Bankgroup", QString::number(transaction->bankgroup % generalInfo.groupsPerRank)})); + this->addChild(new QTreeWidgetItem({"Bank", QString::number(transaction->bank % generalInfo.banksPerGroup)})); + this->addChild(new QTreeWidgetItem({"Row", QString::number(transaction->row)})); + this->addChild(new QTreeWidgetItem({"Column", QString::number(transaction->column)})); + this->addChild(new QTreeWidgetItem({"Address", QString("0x") + QString::number(transaction->address, 16)})); - this->addChild(new QTreeWidgetItem( {"Channel", QString::number(transaction->Channel())})); - this->addChild(new QTreeWidgetItem( {"Rank", QString::number(transaction->Rank())} )); - this->addChild(new QTreeWidgetItem( {"Bankgroup", QString::number(transaction->Bankgroup())} )); - this->addChild(new QTreeWidgetItem( {"Bank", QString::number(transaction->Bank())} )); - this->addChild(new QTreeWidgetItem( {"Row", QString::number(transaction->Row())} )); - this->addChild(new QTreeWidgetItem( {"Column", QString::number(transaction->Column())} )); - this->addChild(new QTreeWidgetItem( {"Address", QString("0x") + QString::number(transaction->Address(), 16)} )); - - if (transaction->Thread() != controllerThread) { - this->addChild(new QTreeWidgetItem( {"Burstlength", QString::number(transaction->Burstlength())})); - this->addChild(new QTreeWidgetItem( {"Thread", QString::number(transaction->Thread())})); + if (transaction->thread != generalInfo.controllerThread) + { + this->addChild(new QTreeWidgetItem({"Burstlength", QString::number(transaction->burstlength)})); + this->addChild(new QTreeWidgetItem({"Thread", QString::number(transaction->thread)})); } QTreeWidgetItem *phasesNode = new QTreeWidgetItem(this); phasesNode->setText(0, "Phases"); - phasesNode->addChild(new QTreeWidgetItem( {"", "Begin", "End"} )); + phasesNode->addChild(new QTreeWidgetItem({"", "Begin", "End"})); for (std::shared_ptr phase : transaction->Phases()) { AppendPhase(phasesNode, *phase); diff --git a/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.h b/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.h index a08547ab..5cda6399 100644 --- a/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.h +++ b/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.h @@ -71,7 +71,7 @@ private: public: static constexpr int transactionTreeItemType = 1001; TransactionTreeItem(QTreeWidget *parent, - const std::shared_ptr &trans, unsigned int controllerThread); + const std::shared_ptr &trans, const GeneralInfo &generalInfo); ID Id() { return id; From d9fc7ac49693fc9a6c6aed9b1e7e34c85adeda2b Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 26 Aug 2020 16:27:21 +0200 Subject: [PATCH 09/50] Add PRESB and REFSB commands. --- DRAMSys/library/src/controller/Command.cpp | 27 +++++++--- DRAMSys/library/src/controller/Command.h | 55 +++++++++++--------- DRAMSys/library/src/simulation/dram/Dram.cpp | 2 +- 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/DRAMSys/library/src/controller/Command.cpp b/DRAMSys/library/src/controller/Command.cpp index d1e9f0d4..976f2d28 100644 --- a/DRAMSys/library/src/controller/Command.cpp +++ b/DRAMSys/library/src/controller/Command.cpp @@ -44,7 +44,7 @@ using namespace DRAMPower; std::string commandToString(Command command) { assert(command >= Command::NOP && command <= Command::SREFEX); - static std::array stringOfCommand = + static std::array stringOfCommand = {"NOP", "RD", "WR", @@ -53,6 +53,8 @@ std::string commandToString(Command command) "PRE", "ACT", "REFB", + "PRESB", + "REFSB", "PREA", "REFA", "PDEA", @@ -66,13 +68,13 @@ std::string commandToString(Command command) unsigned numberOfCommands() { - return 16; + return 18; } tlm_phase commandToPhase(Command command) { assert(command >= Command::NOP && command <= Command::SREFEX); - static std::array phaseOfCommand = + static std::array phaseOfCommand = {UNINITIALIZED_PHASE, BEGIN_RD, BEGIN_WR, @@ -81,6 +83,8 @@ tlm_phase commandToPhase(Command command) BEGIN_PRE, BEGIN_ACT, BEGIN_REFB, + BEGIN_PRESB, + BEGIN_REFSB, BEGIN_PREA, BEGIN_REFA, BEGIN_PDNA, @@ -95,7 +99,7 @@ tlm_phase commandToPhase(Command command) Command phaseToCommand(tlm_phase phase) { assert(phase >= BEGIN_RD && phase <= END_SREF); - static std::array commandOfPhase = + static std::array commandOfPhase = {Command::RD, Command::WR, Command::RDA, @@ -103,6 +107,8 @@ Command phaseToCommand(tlm_phase phase) Command::PRE, Command::ACT, Command::REFB, + Command::PRESB, + Command::REFSB, Command::PREA, Command::REFA, Command::PDEA, @@ -116,8 +122,9 @@ Command phaseToCommand(tlm_phase phase) MemCommand::cmds phaseToDRAMPowerCommand(tlm_phase phase) { + // TODO: add correct phases when DRAMPower supports DDR5 same bank refresh assert(phase >= BEGIN_RD && phase <= END_SREF); - static std::array phaseOfCommand = + static std::array phaseOfCommand = {MemCommand::RD, MemCommand::WR, MemCommand::RDA, @@ -125,6 +132,8 @@ MemCommand::cmds phaseToDRAMPowerCommand(tlm_phase phase) MemCommand::PRE, MemCommand::ACT, MemCommand::REFB, + MemCommand::NOP, + MemCommand::NOP, MemCommand::PREA, MemCommand::REF, MemCommand::PDN_S_ACT, @@ -144,7 +153,7 @@ bool phaseNeedsEnd(tlm_phase phase) tlm_phase getEndPhase(tlm_phase phase) { assert(phase >= BEGIN_RD && phase <= BEGIN_REFA); - return (phase + 15); + return (phase + 17); } bool isBankCommand(Command command) @@ -153,6 +162,12 @@ bool isBankCommand(Command command) return (command <= Command::REFB); } +bool isGroupCommand(Command command) +{ + assert(command >= Command::NOP && command <= Command::SREFEX); + return (command >= Command::PRESB && command <= Command::REFSB); +} + bool isRankCommand(Command command) { assert(command >= Command::NOP && command <= Command::SREFEX); diff --git a/DRAMSys/library/src/controller/Command.h b/DRAMSys/library/src/controller/Command.h index 3a511f38..a773fbb1 100644 --- a/DRAMSys/library/src/controller/Command.h +++ b/DRAMSys/library/src/controller/Command.h @@ -43,31 +43,35 @@ #include "../common/third_party/DRAMPower/src/MemCommand.h" // DO NOT CHANGE THE ORDER! -DECLARE_EXTENDED_PHASE(BEGIN_RD); // 5 -DECLARE_EXTENDED_PHASE(BEGIN_WR); // 6 -DECLARE_EXTENDED_PHASE(BEGIN_RDA); // 7 -DECLARE_EXTENDED_PHASE(BEGIN_WRA); // 8 -DECLARE_EXTENDED_PHASE(BEGIN_PRE); // 9 -DECLARE_EXTENDED_PHASE(BEGIN_ACT); // 10 -DECLARE_EXTENDED_PHASE(BEGIN_REFB); // 11 -DECLARE_EXTENDED_PHASE(BEGIN_PREA); // 12 -DECLARE_EXTENDED_PHASE(BEGIN_REFA); // 13 -DECLARE_EXTENDED_PHASE(BEGIN_PDNA); // 14 -DECLARE_EXTENDED_PHASE(END_PDNA); // 15 -DECLARE_EXTENDED_PHASE(BEGIN_PDNP); // 16 -DECLARE_EXTENDED_PHASE(END_PDNP); // 17 -DECLARE_EXTENDED_PHASE(BEGIN_SREF); // 18 -DECLARE_EXTENDED_PHASE(END_SREF); // 19 +DECLARE_EXTENDED_PHASE(BEGIN_RD); // 5 +DECLARE_EXTENDED_PHASE(BEGIN_WR); // 6 +DECLARE_EXTENDED_PHASE(BEGIN_RDA); // 7 +DECLARE_EXTENDED_PHASE(BEGIN_WRA); // 8 +DECLARE_EXTENDED_PHASE(BEGIN_PRE); // 9 +DECLARE_EXTENDED_PHASE(BEGIN_ACT); // 10 +DECLARE_EXTENDED_PHASE(BEGIN_REFB); // 11 +DECLARE_EXTENDED_PHASE(BEGIN_PRESB); // 12 +DECLARE_EXTENDED_PHASE(BEGIN_REFSB); // 13 +DECLARE_EXTENDED_PHASE(BEGIN_PREA); // 14 +DECLARE_EXTENDED_PHASE(BEGIN_REFA); // 15 +DECLARE_EXTENDED_PHASE(BEGIN_PDNA); // 16 +DECLARE_EXTENDED_PHASE(END_PDNA); // 17 +DECLARE_EXTENDED_PHASE(BEGIN_PDNP); // 18 +DECLARE_EXTENDED_PHASE(END_PDNP); // 19 +DECLARE_EXTENDED_PHASE(BEGIN_SREF); // 20 +DECLARE_EXTENDED_PHASE(END_SREF); // 21 -DECLARE_EXTENDED_PHASE(END_RD); // 20 -DECLARE_EXTENDED_PHASE(END_WR); // 21 -DECLARE_EXTENDED_PHASE(END_RDA); // 22 -DECLARE_EXTENDED_PHASE(END_WRA); // 23 -DECLARE_EXTENDED_PHASE(END_PRE); // 24 -DECLARE_EXTENDED_PHASE(END_ACT); // 25 -DECLARE_EXTENDED_PHASE(END_REFB); // 26 -DECLARE_EXTENDED_PHASE(END_PREA); // 27 -DECLARE_EXTENDED_PHASE(END_REFA); // 28 +DECLARE_EXTENDED_PHASE(END_RD); // 22 +DECLARE_EXTENDED_PHASE(END_WR); // 23 +DECLARE_EXTENDED_PHASE(END_RDA); // 24 +DECLARE_EXTENDED_PHASE(END_WRA); // 25 +DECLARE_EXTENDED_PHASE(END_PRE); // 26 +DECLARE_EXTENDED_PHASE(END_ACT); // 27 +DECLARE_EXTENDED_PHASE(END_REFB); // 28 +DECLARE_EXTENDED_PHASE(END_PRESB); // 29 +DECLARE_EXTENDED_PHASE(END_REFSB); // 30 +DECLARE_EXTENDED_PHASE(END_PREA); // 31 +DECLARE_EXTENDED_PHASE(END_REFA); // 32 enum Command { @@ -79,6 +83,8 @@ enum Command PRE, ACT, REFB, + PRESB, + REFSB, PREA, REFA, PDEA, @@ -97,6 +103,7 @@ bool phaseNeedsEnd(tlm::tlm_phase); tlm::tlm_phase getEndPhase(tlm::tlm_phase); unsigned numberOfCommands(); bool isBankCommand(Command); +bool isGroupCommand(Command); bool isRankCommand(Command); bool isCasCommand(Command); bool isRasCommand(Command); diff --git a/DRAMSys/library/src/simulation/dram/Dram.cpp b/DRAMSys/library/src/simulation/dram/Dram.cpp index 8238195c..a18098be 100644 --- a/DRAMSys/library/src/simulation/dram/Dram.cpp +++ b/DRAMSys/library/src/simulation/dram/Dram.cpp @@ -142,7 +142,7 @@ void Dram::reportPower() tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &) { - assert(phase >= 5 && phase <= 19); + assert(phase >= 5 && phase <= 21); if (Configuration::getInstance().powerAnalysis) { From 8ba0180d5741c7b5770bd9d5fc6715aee1ddb792 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 27 Aug 2020 14:31:18 +0200 Subject: [PATCH 10/50] Groupwise commands can be displayed. --- .../businessObjects/phases/phase.cpp | 67 ++++++++++++++----- .../businessObjects/phases/phase.h | 38 ++++++----- 2 files changed, 70 insertions(+), 35 deletions(-) diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp index a4393318..a7d7ef5a 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp @@ -63,23 +63,32 @@ void Phase::draw(QPainter *painter, const QwtScaleMap &xMap, painter->setPen(pen); } - if (!isBankwise()) { + if (getGranularity() == Granularity::Rankwise) + { for (int i = getYVal(drawingProperties); i < (int)(getYVal(drawingProperties) + drawingProperties.banksPerRank); i++) drawPhaseSymbol(span.Begin(), span.End(), i, drawingProperties.drawText, getPhaseSymbol(), painter, xMap, yMap); - } else + } + else if (getGranularity() == Granularity::Groupwise) + { + for (int i = getYVal(drawingProperties); i < (int)(getYVal(drawingProperties) + drawingProperties.banksPerRank); i += drawingProperties.banksPerGroup) + drawPhaseSymbol(span.Begin(), span.End(), i, drawingProperties.drawText, + getPhaseSymbol(), painter, xMap, yMap); + } + else // if (getGranularity() == Granularity::Bankwise) drawPhaseSymbol(span.Begin(), span.End(), getYVal(drawingProperties), drawingProperties.drawText, getPhaseSymbol(), painter, xMap, yMap); - for (Timespan span : spansOnCommandBus) { + for (Timespan span : spansOnCommandBus) + { drawPhaseSymbol(span.Begin(), span.End(), drawingProperties.yValCommandBus, false, PhaseSymbol::Hexagon, painter, xMap, yMap); } - if (spanOnDataBus) { - drawPhaseSymbol(spanOnDataBus->Begin(), spanOnDataBus->End(), - drawingProperties.yValDataBus, false, PhaseSymbol::Hexagon, painter, xMap, - yMap); + if (spanOnDataBus) + { + drawPhaseSymbol(spanOnDataBus->Begin(), spanOnDataBus->End(), drawingProperties.yValDataBus, + false, PhaseSymbol::Hexagon, painter, xMap, yMap); } } @@ -88,7 +97,7 @@ void Phase::drawPhaseSymbol(traceTime begin, traceTime end, double y, const QwtScaleMap &yMap) const { double yVal = yMap.transform(y); - double symbolHeight = yMap.transform(0) - yMap.transform(hexagonHeigth); + double symbolHeight = yMap.transform(0) - yMap.transform(hexagonHeight); if (symbol == PhaseSymbol::Hexagon) { QPoint hexFrom(xMap.transform(begin), yVal); @@ -123,9 +132,12 @@ QColor Phase::getColor(const TraceDrawingProperties &drawingProperties) const int Phase::getYVal(const TraceDrawingProperties &drawingProperties) const { - if (isBankwise()) + if (getGranularity() == Granularity::Bankwise) return transaction->bank; - else + else if (getGranularity() == Granularity::Groupwise) + return transaction->rank * drawingProperties.banksPerRank + + transaction->bank % drawingProperties.banksPerGroup; + else // if (getGranularity() == Granularity::Rankwise) return transaction->rank * drawingProperties.banksPerRank; } @@ -135,18 +147,39 @@ Qt::BrushStyle Phase::getBrushStyle() const } bool Phase::isSelected(traceTime time, double yVal, - const TraceDrawingProperties &drawingproperties) const + const TraceDrawingProperties &drawingProperties) const { - if (span.contains(time) && (!this->isBankwise() - || fabs(yVal - getYVal(drawingproperties)) <= hexagonHeigth)) - return true; - if (spanOnDataBus && spanOnDataBus->contains(time) - && fabs(yVal - drawingproperties.yValDataBus) <= hexagonHeigth) + if (span.contains(time)) + { + if (getGranularity() == Granularity::Bankwise) + { + if (fabs(yVal - getYVal(drawingProperties)) <= hexagonHeight) + return true; + } + else if (getGranularity() == Granularity::Groupwise) + { + for (int offset = 0; offset < drawingProperties.banksPerRank; offset += drawingProperties.banksPerGroup) + { + if (fabs(yVal - (getYVal(drawingProperties) + offset)) <= hexagonHeight) + return true; + } + } + else // if (getGranularity() == Granularity::Rankwise) + { + for (int offset = 0; offset < drawingProperties.banksPerRank; offset++) + { + if (fabs(yVal - (getYVal(drawingProperties) + offset)) <= hexagonHeight) + return true; + } + } + } + + if (spanOnDataBus && spanOnDataBus->contains(time) && fabs(yVal - drawingProperties.yValDataBus) <= hexagonHeight) return true; for (Timespan span : spansOnCommandBus) { if (span.contains(time) - && fabs(yVal - drawingproperties.yValCommandBus) <= hexagonHeigth) + && fabs(yVal - drawingProperties.yValCommandBus) <= hexagonHeight) return true; } diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h index eb269c3f..0b3274bb 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h @@ -58,7 +58,7 @@ public: std::shared_ptr spanOnDataBus): id(id), span(span), transaction(transaction), spansOnCommandBus(spansOnCommandBus), spanOnDataBus(spanOnDataBus), - hexagonHeigth(0.6), captionPosition(TextPositioning::bottomRight) {} + hexagonHeight(0.6), captionPosition(TextPositioning::bottomRight) {} void draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, bool highlight, @@ -74,10 +74,6 @@ public: return id; } virtual QString Name() const = 0; - virtual bool isBankwise() const - { - return true; - } protected: ID id; @@ -85,7 +81,7 @@ protected: std::shared_ptr transaction; std::vector spansOnCommandBus; std::shared_ptr spanOnDataBus; - double hexagonHeigth; + double hexagonHeight; TextPositioning captionPosition; enum PhaseSymbol {Hexagon, Rect}; @@ -98,6 +94,12 @@ protected: bool drawtext, PhaseSymbol symbol, QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap) const; + enum class Granularity {Bankwise, Groupwise, Rankwise}; + + virtual Granularity getGranularity() const + { + return Granularity::Bankwise; + } }; class REQ : public Phase @@ -297,9 +299,9 @@ protected: { return "REFA"; } - virtual bool isBankwise() const override + virtual Granularity getGranularity() const override { - return false; + return Granularity::Rankwise; } }; @@ -323,9 +325,9 @@ protected: { return "REFSB"; } - virtual bool isBankwise() const override + virtual Granularity getGranularity() const override { - return false; + return Granularity::Groupwise; } }; @@ -351,9 +353,9 @@ protected: { return ColorGenerator::getColor(10); } - virtual bool isBankwise() const override + virtual Granularity getGranularity() const override { - return false; + return Granularity::Rankwise; } }; @@ -394,9 +396,9 @@ protected: { return "PDNA"; } - virtual bool isBankwise() const override + virtual Granularity getGranularity() const override { - return false; + return Granularity::Rankwise; } }; @@ -437,9 +439,9 @@ protected: { return "PDNP"; } - virtual bool isBankwise() const override + virtual Granularity getGranularity() const override { - return false; + return Granularity::Rankwise; } }; @@ -480,9 +482,9 @@ protected: { return "SREF"; } - virtual bool isBankwise() const override + virtual Granularity getGranularity() const override { - return false; + return Granularity::Rankwise; } }; From 57f6881ae1d978c45b4d0b4d0e5927a7a89622fe Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 27 Aug 2020 15:33:17 +0200 Subject: [PATCH 11/50] Add new commands and command lengths. --- .../resources/scripts/createTraceDB.sql | 28 ++-- DRAMSys/library/src/common/TlmRecorder.cpp | 36 ++--- DRAMSys/library/src/controller/Command.cpp | 134 +++++++++--------- DRAMSys/library/src/controller/Command.h | 10 +- DRAMSys/tests/DDR4/scripts/createTraceDB.sql | 28 ++-- DRAMSys/tests/HBM2/scripts/createTraceDB.sql | 28 ++-- .../ddr3_multirank/scripts/createTraceDB.sql | 28 ++-- .../tests/lpddr4/scripts/createTraceDB.sql | 28 ++-- .../businessObjects/commandlengths.h | 32 +++-- .../businessObjects/phases/phase.h | 84 +++++++---- .../businessObjects/phases/phasefactory.cpp | 3 + DRAMSys/traceAnalyzer/data/tracedb.cpp | 37 ++--- 12 files changed, 263 insertions(+), 213 deletions(-) diff --git a/DRAMSys/library/resources/scripts/createTraceDB.sql b/DRAMSys/library/resources/scripts/createTraceDB.sql index a8fa60a8..f902d02f 100644 --- a/DRAMSys/library/resources/scripts/createTraceDB.sql +++ b/DRAMSys/library/resources/scripts/createTraceDB.sql @@ -33,20 +33,22 @@ CREATE TABLE GeneralInfo( ); CREATE TABLE CommandLengths( - ACT INTEGER, - PRE INTEGER, - PREA INTEGER, - RD INTEGER, - RDA INTEGER, - WR INTEGER, - WRA INTEGER, - REFA INTEGER, - REFB INTEGER, + NOP INTEGER, + RD INTEGER, + WR INTEGER, + RDA INTEGER, + WRA INTEGER, + ACT INTEGER, + PRE INTEGER, + REFB INTEGER, + PRESB INTEGER, REFSB INTEGER, - PDEA INTEGER, - PDXA INTEGER, - PDEP INTEGER, - PDXP INTEGER, + PREA INTEGER, + REFA INTEGER, + PDEA INTEGER, + PDXA INTEGER, + PDEP INTEGER, + PDXP INTEGER, SREFEN INTEGER, SREFEX INTEGER ); diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index 24701cb5..9d1bf9b9 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -296,7 +296,7 @@ void TlmRecorder::prepareSqlStatements() insertCommandLengthsString = "INSERT INTO CommandLengths VALUES" - "(:ACT, :PRE, :PREA, :RD, :RDA, :WR, :WRA, :REFA, :REFB, :REFSB, :PDEA, :PDXA, :PDEP, :PDXP, :SREFEN, :SREFEX)"; + "(:NOP, :RD, :WR, :RDA, :WRA, :ACT, :PRE, :REFB, :PRESB, :REFSB, :PREA, :REFA, :PDEA, :PDXA, :PDEP, :PDXP, :SREFEN, :SREFEX)"; insertDebugMessageString = "INSERT INTO DebugMessages (Time,Message) Values (:time,:message)"; @@ -362,22 +362,24 @@ void TlmRecorder::insertCommandLengths() { MemSpec *memSpec = Configuration::getInstance().memSpec; - sqlite3_bind_int(insertCommandLengthsStatement, 1, memSpec->getCommandLength(Command::ACT) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 2, memSpec->getCommandLength(Command::PRE) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 3, memSpec->getCommandLength(Command::PREA) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 4, memSpec->getCommandLength(Command::RD) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 5, memSpec->getCommandLength(Command::RDA) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 6, memSpec->getCommandLength(Command::WR) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 7, memSpec->getCommandLength(Command::WRA) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 8, memSpec->getCommandLength(Command::REFA) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 9, memSpec->getCommandLength(Command::REFB) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 10, 1); - sqlite3_bind_int(insertCommandLengthsStatement, 11, memSpec->getCommandLength(Command::PDEA) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 12, memSpec->getCommandLength(Command::PDXA) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 13, memSpec->getCommandLength(Command::PDEP) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 14, memSpec->getCommandLength(Command::PDXP) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 15, memSpec->getCommandLength(Command::SREFEN) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 16, memSpec->getCommandLength(Command::SREFEX) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 1, memSpec->getCommandLength(Command::NOP) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 2, memSpec->getCommandLength(Command::RD) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 3, memSpec->getCommandLength(Command::WR) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 4, memSpec->getCommandLength(Command::RDA) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 5, memSpec->getCommandLength(Command::WRA) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 6, memSpec->getCommandLength(Command::PRE) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 7, memSpec->getCommandLength(Command::ACT) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 8, memSpec->getCommandLength(Command::REFB) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 9, memSpec->getCommandLength(Command::PRESB) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 10, memSpec->getCommandLength(Command::REFSB) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 11, memSpec->getCommandLength(Command::PREA) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 12, memSpec->getCommandLength(Command::REFA) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 13, memSpec->getCommandLength(Command::PDEA) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 14, memSpec->getCommandLength(Command::PDXA) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 15, memSpec->getCommandLength(Command::PDEP) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 16, memSpec->getCommandLength(Command::PDXP) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 17, memSpec->getCommandLength(Command::SREFEN) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 18, memSpec->getCommandLength(Command::SREFEX) / memSpec->tCK); executeSqlStatement(insertCommandLengthsStatement); } diff --git a/DRAMSys/library/src/controller/Command.cpp b/DRAMSys/library/src/controller/Command.cpp index 976f2d28..a5f50101 100644 --- a/DRAMSys/library/src/controller/Command.cpp +++ b/DRAMSys/library/src/controller/Command.cpp @@ -46,23 +46,23 @@ std::string commandToString(Command command) assert(command >= Command::NOP && command <= Command::SREFEX); static std::array stringOfCommand = {"NOP", - "RD", - "WR", - "RDA", - "WRA", - "PRE", - "ACT", - "REFB", - "PRESB", - "REFSB", - "PREA", - "REFA", - "PDEA", - "PDXA", - "PDEP", - "PDXP", - "SREFEN", - "SREFEX"}; + "RD", + "WR", + "RDA", + "WRA", + "ACT", + "PRE", + "REFB", + "PRESB", + "REFSB", + "PREA", + "REFA", + "PDEA", + "PDXA", + "PDEP", + "PDXP", + "SREFEN", + "SREFEX"}; return stringOfCommand[command]; } @@ -76,23 +76,23 @@ tlm_phase commandToPhase(Command command) assert(command >= Command::NOP && command <= Command::SREFEX); static std::array phaseOfCommand = {UNINITIALIZED_PHASE, - BEGIN_RD, - BEGIN_WR, - BEGIN_RDA, - BEGIN_WRA, - BEGIN_PRE, - BEGIN_ACT, - BEGIN_REFB, - BEGIN_PRESB, - BEGIN_REFSB, - BEGIN_PREA, - BEGIN_REFA, - BEGIN_PDNA, - END_PDNA, - BEGIN_PDNP, - END_PDNP, - BEGIN_SREF, - END_SREF}; + BEGIN_RD, + BEGIN_WR, + BEGIN_RDA, + BEGIN_WRA, + BEGIN_ACT, + BEGIN_PRE, + BEGIN_REFB, + BEGIN_PRESB, + BEGIN_REFSB, + BEGIN_PREA, + BEGIN_REFA, + BEGIN_PDNA, + END_PDNA, + BEGIN_PDNP, + END_PDNP, + BEGIN_SREF, + END_SREF}; return phaseOfCommand[command]; } @@ -101,22 +101,22 @@ Command phaseToCommand(tlm_phase phase) assert(phase >= BEGIN_RD && phase <= END_SREF); static std::array commandOfPhase = {Command::RD, - Command::WR, - Command::RDA, - Command::WRA, - Command::PRE, - Command::ACT, - Command::REFB, - Command::PRESB, - Command::REFSB, - Command::PREA, - Command::REFA, - Command::PDEA, - Command::PDXA, - Command::PDEP, - Command::PDXP, - Command::SREFEN, - Command::SREFEX}; + Command::WR, + Command::RDA, + Command::WRA, + Command::ACT, + Command::PRE, + Command::REFB, + Command::PRESB, + Command::REFSB, + Command::PREA, + Command::REFA, + Command::PDEA, + Command::PDXA, + Command::PDEP, + Command::PDXP, + Command::SREFEN, + Command::SREFEX}; return commandOfPhase[phase - BEGIN_RD]; } @@ -126,22 +126,22 @@ MemCommand::cmds phaseToDRAMPowerCommand(tlm_phase phase) assert(phase >= BEGIN_RD && phase <= END_SREF); static std::array phaseOfCommand = {MemCommand::RD, - MemCommand::WR, - MemCommand::RDA, - MemCommand::WRA, - MemCommand::PRE, - MemCommand::ACT, - MemCommand::REFB, - MemCommand::NOP, - MemCommand::NOP, - MemCommand::PREA, - MemCommand::REF, - MemCommand::PDN_S_ACT, - MemCommand::PUP_ACT, - MemCommand::PDN_S_PRE, - MemCommand::PUP_PRE, - MemCommand::SREN, - MemCommand::SREX}; + MemCommand::WR, + MemCommand::RDA, + MemCommand::WRA, + MemCommand::ACT, + MemCommand::PRE, + MemCommand::REFB, + MemCommand::NOP, + MemCommand::NOP, + MemCommand::PREA, + MemCommand::REF, + MemCommand::PDN_S_ACT, + MemCommand::PUP_ACT, + MemCommand::PDN_S_PRE, + MemCommand::PUP_PRE, + MemCommand::SREN, + MemCommand::SREX}; return phaseOfCommand[phase - BEGIN_RD]; } @@ -183,5 +183,5 @@ bool isCasCommand(Command command) bool isRasCommand(Command command) { assert(command >= Command::NOP && command <= Command::SREFEX); - return (command >= Command::PRE); + return (command >= Command::ACT); } diff --git a/DRAMSys/library/src/controller/Command.h b/DRAMSys/library/src/controller/Command.h index a773fbb1..6c9fdee7 100644 --- a/DRAMSys/library/src/controller/Command.h +++ b/DRAMSys/library/src/controller/Command.h @@ -47,8 +47,8 @@ DECLARE_EXTENDED_PHASE(BEGIN_RD); // 5 DECLARE_EXTENDED_PHASE(BEGIN_WR); // 6 DECLARE_EXTENDED_PHASE(BEGIN_RDA); // 7 DECLARE_EXTENDED_PHASE(BEGIN_WRA); // 8 -DECLARE_EXTENDED_PHASE(BEGIN_PRE); // 9 -DECLARE_EXTENDED_PHASE(BEGIN_ACT); // 10 +DECLARE_EXTENDED_PHASE(BEGIN_ACT); // 9 +DECLARE_EXTENDED_PHASE(BEGIN_PRE); // 10 DECLARE_EXTENDED_PHASE(BEGIN_REFB); // 11 DECLARE_EXTENDED_PHASE(BEGIN_PRESB); // 12 DECLARE_EXTENDED_PHASE(BEGIN_REFSB); // 13 @@ -65,8 +65,8 @@ DECLARE_EXTENDED_PHASE(END_RD); // 22 DECLARE_EXTENDED_PHASE(END_WR); // 23 DECLARE_EXTENDED_PHASE(END_RDA); // 24 DECLARE_EXTENDED_PHASE(END_WRA); // 25 -DECLARE_EXTENDED_PHASE(END_PRE); // 26 -DECLARE_EXTENDED_PHASE(END_ACT); // 27 +DECLARE_EXTENDED_PHASE(END_ACT); // 26 +DECLARE_EXTENDED_PHASE(END_PRE); // 27 DECLARE_EXTENDED_PHASE(END_REFB); // 28 DECLARE_EXTENDED_PHASE(END_PRESB); // 29 DECLARE_EXTENDED_PHASE(END_REFSB); // 30 @@ -80,8 +80,8 @@ enum Command WR, RDA, WRA, - PRE, ACT, + PRE, REFB, PRESB, REFSB, diff --git a/DRAMSys/tests/DDR4/scripts/createTraceDB.sql b/DRAMSys/tests/DDR4/scripts/createTraceDB.sql index a8fa60a8..f902d02f 100644 --- a/DRAMSys/tests/DDR4/scripts/createTraceDB.sql +++ b/DRAMSys/tests/DDR4/scripts/createTraceDB.sql @@ -33,20 +33,22 @@ CREATE TABLE GeneralInfo( ); CREATE TABLE CommandLengths( - ACT INTEGER, - PRE INTEGER, - PREA INTEGER, - RD INTEGER, - RDA INTEGER, - WR INTEGER, - WRA INTEGER, - REFA INTEGER, - REFB INTEGER, + NOP INTEGER, + RD INTEGER, + WR INTEGER, + RDA INTEGER, + WRA INTEGER, + ACT INTEGER, + PRE INTEGER, + REFB INTEGER, + PRESB INTEGER, REFSB INTEGER, - PDEA INTEGER, - PDXA INTEGER, - PDEP INTEGER, - PDXP INTEGER, + PREA INTEGER, + REFA INTEGER, + PDEA INTEGER, + PDXA INTEGER, + PDEP INTEGER, + PDXP INTEGER, SREFEN INTEGER, SREFEX INTEGER ); diff --git a/DRAMSys/tests/HBM2/scripts/createTraceDB.sql b/DRAMSys/tests/HBM2/scripts/createTraceDB.sql index a8fa60a8..f902d02f 100644 --- a/DRAMSys/tests/HBM2/scripts/createTraceDB.sql +++ b/DRAMSys/tests/HBM2/scripts/createTraceDB.sql @@ -33,20 +33,22 @@ CREATE TABLE GeneralInfo( ); CREATE TABLE CommandLengths( - ACT INTEGER, - PRE INTEGER, - PREA INTEGER, - RD INTEGER, - RDA INTEGER, - WR INTEGER, - WRA INTEGER, - REFA INTEGER, - REFB INTEGER, + NOP INTEGER, + RD INTEGER, + WR INTEGER, + RDA INTEGER, + WRA INTEGER, + ACT INTEGER, + PRE INTEGER, + REFB INTEGER, + PRESB INTEGER, REFSB INTEGER, - PDEA INTEGER, - PDXA INTEGER, - PDEP INTEGER, - PDXP INTEGER, + PREA INTEGER, + REFA INTEGER, + PDEA INTEGER, + PDXA INTEGER, + PDEP INTEGER, + PDXP INTEGER, SREFEN INTEGER, SREFEX INTEGER ); diff --git a/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql b/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql index a8fa60a8..f902d02f 100644 --- a/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql +++ b/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql @@ -33,20 +33,22 @@ CREATE TABLE GeneralInfo( ); CREATE TABLE CommandLengths( - ACT INTEGER, - PRE INTEGER, - PREA INTEGER, - RD INTEGER, - RDA INTEGER, - WR INTEGER, - WRA INTEGER, - REFA INTEGER, - REFB INTEGER, + NOP INTEGER, + RD INTEGER, + WR INTEGER, + RDA INTEGER, + WRA INTEGER, + ACT INTEGER, + PRE INTEGER, + REFB INTEGER, + PRESB INTEGER, REFSB INTEGER, - PDEA INTEGER, - PDXA INTEGER, - PDEP INTEGER, - PDXP INTEGER, + PREA INTEGER, + REFA INTEGER, + PDEA INTEGER, + PDXA INTEGER, + PDEP INTEGER, + PDXP INTEGER, SREFEN INTEGER, SREFEX INTEGER ); diff --git a/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql b/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql index a8fa60a8..f902d02f 100644 --- a/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql +++ b/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql @@ -33,20 +33,22 @@ CREATE TABLE GeneralInfo( ); CREATE TABLE CommandLengths( - ACT INTEGER, - PRE INTEGER, - PREA INTEGER, - RD INTEGER, - RDA INTEGER, - WR INTEGER, - WRA INTEGER, - REFA INTEGER, - REFB INTEGER, + NOP INTEGER, + RD INTEGER, + WR INTEGER, + RDA INTEGER, + WRA INTEGER, + ACT INTEGER, + PRE INTEGER, + REFB INTEGER, + PRESB INTEGER, REFSB INTEGER, - PDEA INTEGER, - PDXA INTEGER, - PDEP INTEGER, - PDXP INTEGER, + PREA INTEGER, + REFA INTEGER, + PDEA INTEGER, + PDXA INTEGER, + PDEP INTEGER, + PDXP INTEGER, SREFEN INTEGER, SREFEX INTEGER ); diff --git a/DRAMSys/traceAnalyzer/businessObjects/commandlengths.h b/DRAMSys/traceAnalyzer/businessObjects/commandlengths.h index 07b1b2a7..5db48e37 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/commandlengths.h +++ b/DRAMSys/traceAnalyzer/businessObjects/commandlengths.h @@ -38,16 +38,18 @@ struct CommandLengths { + unsigned NOP; + unsigned RD; + unsigned WR; + unsigned RDA; + unsigned WRA; unsigned ACT; unsigned PRE; - unsigned PREA; - unsigned RD; - unsigned RDA; - unsigned WR; - unsigned WRA; - unsigned REFA; unsigned REFB; + unsigned PRESB; unsigned REFSB; + unsigned PREA; + unsigned REFA; unsigned PDEA; unsigned PDXA; unsigned PDEP; @@ -55,14 +57,16 @@ struct CommandLengths unsigned SREFEN; unsigned SREFEX; - CommandLengths(unsigned ACT, unsigned PRE, unsigned PREA, - unsigned RD, unsigned RDA, unsigned WR, unsigned WRA, - unsigned REFA, unsigned REFB, unsigned REFSB, - unsigned PDEA, unsigned PDXA, unsigned PDEP, unsigned PDXP, - unsigned SREFEN, unsigned SREFEX) : - ACT(ACT), PRE(PRE), PREA(PREA), RD(RD), RDA(RDA), WR(WR), WRA(WRA), - REFA(REFA), REFB(REFB), REFSB(REFSB), PDEA(PDEA), PDXA(PDXA), - PDEP(PDEP), PDXP(PDXP), SREFEN(SREFEN), SREFEX(SREFEX) {} + CommandLengths(unsigned NOP, unsigned RD, unsigned WR, + unsigned RDA, unsigned WRA, unsigned ACT, + unsigned PRE, unsigned REFB, unsigned PRESB, + unsigned REFSB, unsigned PREA, unsigned REFA, + unsigned PDEA, unsigned PDXA, unsigned PDEP, + unsigned PDXP, unsigned SREFEN, unsigned SREFEX) : + NOP(NOP), RD(RD), WR(WR), RDA(RDA), WRA(WRA), ACT(ACT), PRE(PRE), + REFB(REFB), PRESB(PRESB), REFSB(REFSB), PREA(PREA), REFA(REFA), + PDEA(PDEA), PDXA(PDXA), PDEP(PDEP), PDXP(PDXP), + SREFEN(SREFEN), SREFEX(SREFEX) {} CommandLengths() {} }; diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h index 0b3274bb..3192aed1 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h @@ -174,6 +174,62 @@ protected: } }; +class PRESB : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QString Name() const override + { + return "PRESB"; + } + virtual std::vector getTimesOnCommandBus() const + { + return {span.Begin()}; + } + virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const + override + { + Q_UNUSED(drawingProperties) return getPhaseColor(); + } + virtual QColor getPhaseColor() const override + { + return ColorGenerator::getColor(1); + } + virtual Granularity getGranularity() const override + { + return Granularity::Groupwise; + } +}; + +class PREA : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QString Name() const override + { + return "PREA"; + } + virtual std::vector getTimesOnCommandBus() const + { + return {span.Begin()}; + } + virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const + override + { + Q_UNUSED(drawingProperties) return getPhaseColor(); + } + virtual QColor getPhaseColor() const override + { + return ColorGenerator::getColor(10); + } + virtual Granularity getGranularity() const override + { + return Granularity::Rankwise; + } +}; + class ACTB : public Phase { public: @@ -331,34 +387,6 @@ protected: } }; -class PREA : public Phase -{ -public: - using Phase::Phase; -protected: - virtual QString Name() const override - { - return "PREA"; - } - virtual std::vector getTimesOnCommandBus() const - { - return {span.Begin()}; - } - virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const - override - { - Q_UNUSED(drawingProperties) return getPhaseColor(); - } - virtual QColor getPhaseColor() const override - { - return ColorGenerator::getColor(10); - } - virtual Granularity getGranularity() const override - { - return Granularity::Rankwise; - } -}; - class PDNAB : public Phase { public: diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp index 94a6c453..8ea561e5 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phasefactory.cpp @@ -76,6 +76,9 @@ shared_ptr PhaseFactory::CreatePhase(ID id, const QString &dbPhaseName, else if (dbPhaseName == "REFB") return shared_ptr(new REFB(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.REFB)}, std::shared_ptr())); + else if (dbPhaseName == "PRESB") + return shared_ptr(new PRESB(id, span, trans, + {Timespan(span.Begin(), span.Begin() + clk * cl.PRESB)}, std::shared_ptr())); else if (dbPhaseName == "REFSB") return shared_ptr(new REFSB(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.REFSB)}, std::shared_ptr())); diff --git a/DRAMSys/traceAnalyzer/data/tracedb.cpp b/DRAMSys/traceAnalyzer/data/tracedb.cpp index 4471ce35..e44f49ef 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.cpp +++ b/DRAMSys/traceAnalyzer/data/tracedb.cpp @@ -285,25 +285,28 @@ CommandLengths TraceDB::getCommandLengthsFromDB() if (query.next()) { - unsigned ACT = query.value(0).toInt(); - unsigned PRE = query.value(1).toInt(); - unsigned PREA = query.value(2).toInt(); - unsigned RD = query.value(3).toInt(); - unsigned RDA = query.value(4).toInt(); - unsigned WR = query.value(5).toInt(); - unsigned WRA = query.value(6).toInt(); - unsigned REFA = query.value(7).toInt(); - unsigned REFB = query.value(8).toInt(); + unsigned NOP = query.value(0).toInt(); + unsigned RD = query.value(1).toInt(); + unsigned WR = query.value(2).toInt(); + unsigned RDA = query.value(3).toInt(); + unsigned WRA = query.value(4).toInt(); + unsigned ACT = query.value(5).toInt(); + unsigned PRE = query.value(6).toInt(); + unsigned REFB = query.value(7).toInt(); + unsigned PRESB = query.value(8).toInt(); unsigned REFSB = query.value(9).toInt(); - unsigned PDEA = query.value(10).toInt(); - unsigned PDXA = query.value(11).toInt(); - unsigned PDEP = query.value(12).toInt(); - unsigned PDXP = query.value(13).toInt(); - unsigned SREFEN = query.value(14).toInt(); - unsigned SREFEX = query.value(15).toInt(); + unsigned PREA = query.value(10).toInt(); + unsigned REFA = query.value(11).toInt(); + unsigned PDEA = query.value(12).toInt(); + unsigned PDXA = query.value(13).toInt(); + unsigned PDEP = query.value(14).toInt(); + unsigned PDXP = query.value(15).toInt(); + unsigned SREFEN = query.value(16).toInt(); + unsigned SREFEX = query.value(17).toInt(); - return CommandLengths(ACT, PRE, PREA, RD, RDA, WR, WRA, REFA, REFB, REFSB, - PDEA, PDXA, PDEP, PDXP, SREFEN, SREFEX); + return CommandLengths(NOP, RD, WR, RDA, WRA, ACT, PRE, REFB, + PRESB, REFSB, PREA, REFA, PDEA, PDXA, + PDEP, PDXP, SREFEN, SREFEX); } else { From e9d206441e752749c020c807d89a92cffc0d8e9f Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 28 Aug 2020 10:05:39 +0200 Subject: [PATCH 12/50] Fix indication error for RDA/WRA commands. --- DRAMSys/library/src/common/TlmRecorder.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index 9d1bf9b9..c1137f5c 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -186,7 +186,11 @@ void TlmRecorder::commitRecordedDataToDB() } sc_time rangeBegin = recordingData.recordedPhases.front().interval.start; - sc_time rangeEnd = recordingData.recordedPhases.back().interval.end; + sc_time rangeEnd = rangeBegin; + for (auto &it : recordingData.recordedPhases) + { + rangeEnd = std::max(rangeEnd, it.interval.end); + } insertRangeInDB(recordingData.id, rangeBegin, rangeEnd); } @@ -261,6 +265,10 @@ void TlmRecorder::setUpTransactionTerminatingPhases() transactionTerminatingPhases.push_back(static_cast (END_REFB)); + // Refresh Same Bank + transactionTerminatingPhases.push_back(static_cast + (END_REFSB)); + // Phases for Power Down transactionTerminatingPhases.push_back(static_cast (END_PDNA)); From ef90bfbb915cc0e0c6473c805bd8a6073e7be872 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 28 Aug 2020 16:17:47 +0200 Subject: [PATCH 13/50] First part of same bank refresh (manager not done). --- DRAMSys/library/CMakeLists.txt | 1 + .../memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json | 1 + .../JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json | 3 +- .../src/configuration/memspec/MemSpec.cpp | 18 ++ .../src/configuration/memspec/MemSpec.h | 5 +- .../src/configuration/memspec/MemSpecDDR3.cpp | 6 - .../src/configuration/memspec/MemSpecDDR3.h | 1 - .../src/configuration/memspec/MemSpecDDR4.cpp | 6 - .../src/configuration/memspec/MemSpecDDR4.h | 1 - .../src/configuration/memspec/MemSpecDDR5.cpp | 6 +- .../src/configuration/memspec/MemSpecDDR5.h | 3 +- .../src/configuration/memspec/MemSpecGDDR5.h | 2 +- .../src/configuration/memspec/MemSpecGDDR5X.h | 2 +- .../src/configuration/memspec/MemSpecGDDR6.h | 2 +- .../src/configuration/memspec/MemSpecHBM2.h | 2 +- .../src/configuration/memspec/MemSpecLPDDR4.h | 2 +- .../configuration/memspec/MemSpecWideIO.cpp | 6 - .../src/configuration/memspec/MemSpecWideIO.h | 1 - .../configuration/memspec/MemSpecWideIO2.h | 2 +- .../library/src/controller/BankMachine.cpp | 4 +- DRAMSys/library/src/controller/Controller.cpp | 48 ++-- .../src/controller/checker/CheckerDDR5.cpp | 141 +++++++++++- .../src/controller/checker/CheckerDDR5.h | 2 + .../refresh/RefreshManagerBankwise.cpp | 9 +- .../refresh/RefreshManagerGroupwise.cpp | 209 ++++++++++++++++++ .../refresh/RefreshManagerGroupwise.h | 80 +++++++ .../refresh/RefreshManagerRankwise.cpp | 4 +- 27 files changed, 508 insertions(+), 59 deletions(-) create mode 100644 DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp create mode 100644 DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.h diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index 7871f809..de833506 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -137,6 +137,7 @@ add_library(DRAMSysLibrary src/controller/refresh/RefreshManagerDummy.cpp src/controller/refresh/RefreshManagerRankwise.cpp src/controller/refresh/RefreshManagerBankwise.cpp + src/controller/refresh/RefreshManagerGroupwise.cpp src/controller/respqueue/RespQueueIF.h src/controller/respqueue/RespQueueFifo.cpp diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json index 0b580d0d..492eea26 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json @@ -28,6 +28,7 @@ "RCD": 22, "REFM": 1, "REFI": 6240, + "REFISB": 1560, "RFC": 312, "RL": 22, "RPRE": 1, diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json index 95e2e703..d8984701 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json @@ -50,7 +50,8 @@ "RFC_dpr": 104, "RFCsb_slr": 184, "RFCsb_dlr": 62, - "REFI": 6240, + "REFI": 6240, + "REFISB": 1560, "REFSBRD_slr": 48, "REFSBRD_dlr": 24, "RTRS": 2, diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp index 39fd1211..ac893709 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp @@ -74,3 +74,21 @@ sc_time MemSpec::getCommandLength(Command command) const { return tCK * commandLengthInCycles[command]; } + +sc_time MemSpec::getRefreshIntervalAB() const +{ + SC_REPORT_FATAL("MemSpec", "All bank refresh not supported"); + return SC_ZERO_TIME; +} + +sc_time MemSpec::getRefreshIntervalPB() const +{ + SC_REPORT_FATAL("MemSpec", "Per bank refresh not supported"); + return SC_ZERO_TIME; +} + +sc_time MemSpec::getRefreshIntervalSB() const +{ + SC_REPORT_FATAL("MemSpec", "Same bank refresh not supported"); + return SC_ZERO_TIME; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index 3f97dcff..1f9687ab 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -71,8 +71,9 @@ public: virtual ~MemSpec() {} - virtual sc_time getRefreshIntervalAB() const = 0; - virtual sc_time getRefreshIntervalPB() const = 0; + virtual sc_time getRefreshIntervalAB() const; + virtual sc_time getRefreshIntervalPB() const; + virtual sc_time getRefreshIntervalSB() const; virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const = 0; virtual TimeInterval getIntervalOnDataStrobe(Command) const = 0; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp index 427c3f85..21a1434a 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp @@ -95,12 +95,6 @@ sc_time MemSpecDDR3::getRefreshIntervalAB() const return tREFI; } -sc_time MemSpecDDR3::getRefreshIntervalPB() const -{ - SC_REPORT_FATAL("MemSpecDDR3", "Per bank refresh not supported"); - return SC_ZERO_TIME; -} - // Returns the execution time for commands that have a fixed execution time sc_time MemSpecDDR3::getExecutionTime(Command command, const tlm_generic_payload &) const { diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h index f8a1d6de..f71cde71 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h @@ -88,7 +88,6 @@ public: const double iDD3P1; virtual sc_time getRefreshIntervalAB() const override; - virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp index fdb2f843..cd9c2624 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp @@ -114,12 +114,6 @@ sc_time MemSpecDDR4::getRefreshIntervalAB() const return tREFI; } -sc_time MemSpecDDR4::getRefreshIntervalPB() const -{ - SC_REPORT_FATAL("MemSpecDDR4", "Per bank refresh not supported"); - return SC_ZERO_TIME; -} - // Returns the execution time for commands that have a fixed execution time sc_time MemSpecDDR4::getExecutionTime(Command command, const tlm_generic_payload &) const { diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h index c702f871..d6da746e 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h @@ -95,7 +95,6 @@ public: const double iDD62; const double vDD2; - virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getRefreshIntervalAB() const override; virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp index 88f998ff..14a3a334 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp @@ -91,6 +91,7 @@ MemSpecDDR5::MemSpecDDR5(json &memspec) tRFCsb_slr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_slr"], "RFCsb_slr")), tRFCsb_dlr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_dlr"], "RFCsb_dlr")), tREFI (tCK * parseUint(memspec["memtimingspec"]["REFI"], "REFI")), + tREFIsb (tCK * parseUint(memspec["memtimingspec"]["REFISB"], "REFISB")), tREFSBRD_slr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_slr"], "REFSBRD_slr")), tREFSBRD_dlr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_dlr"], "REFSBRD_dlr")), tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")), @@ -113,10 +114,9 @@ sc_time MemSpecDDR5::getRefreshIntervalAB() const return tREFI; } -sc_time MemSpecDDR5::getRefreshIntervalPB() const +sc_time MemSpecDDR5::getRefreshIntervalSB() const { - SC_REPORT_FATAL("MemSpecDDR5", "Per bank refresh not supported"); - return SC_ZERO_TIME; + return tREFIsb; } // Returns the execution time for commands that have a fixed execution time diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h index f243b1a0..3103c3cd 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h @@ -85,6 +85,7 @@ public: const sc_time tRFCsb_slr; const sc_time tRFCsb_dlr; const sc_time tREFI; + const sc_time tREFIsb; const sc_time tREFSBRD_slr; const sc_time tREFSBRD_dlr; const sc_time tRTRS; @@ -99,8 +100,8 @@ public: // Currents and Voltages: // TODO: to be completed - virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getRefreshIntervalAB() const override; + virtual sc_time getRefreshIntervalSB() const override; virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h index 84e7113e..690f29b5 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h @@ -85,8 +85,8 @@ public: // Currents and Voltages: // TODO: to be completed - virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getRefreshIntervalAB() const override; + virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h index f5d22239..130606f7 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h @@ -85,8 +85,8 @@ public: // Currents and Voltages: // TODO: to be completed - virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getRefreshIntervalAB() const override; + virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h index a4d2318d..7e2f91c8 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h @@ -87,8 +87,8 @@ public: // Currents and Voltages: // TODO: to be completed - virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getRefreshIntervalAB() const override; + virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h index a6885b49..148be20a 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h @@ -80,8 +80,8 @@ public: // Currents and Voltages: // TODO: to be completed - virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getRefreshIntervalAB() const override; + virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h index 26da297c..d85998a9 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h @@ -80,8 +80,8 @@ public: // Currents and Voltages: // TODO: to be completed - virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getRefreshIntervalAB() const override; + virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp index 0d8b9be6..577c1ca3 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp @@ -101,12 +101,6 @@ sc_time MemSpecWideIO::getRefreshIntervalAB() const return tREFI; } -sc_time MemSpecWideIO::getRefreshIntervalPB() const -{ - SC_REPORT_FATAL("MemSpecWideIO", "Per bank refresh not supported"); - return SC_ZERO_TIME; -} - // Returns the execution time for commands that have a fixed execution time sc_time MemSpecWideIO::getExecutionTime(Command command, const tlm_generic_payload &) const { diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h index 2ce092ff..49d351f7 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h @@ -93,7 +93,6 @@ public: const double iDD62; const double vDD2; - virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getRefreshIntervalAB() const override; virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h index d56f9d30..877f15bd 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h @@ -74,8 +74,8 @@ public: // Currents and Voltages: // TODO: to be completed - virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getRefreshIntervalAB() const override; + virtual sc_time getRefreshIntervalPB() const override; virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index 82259337..115dbf8f 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -57,7 +57,7 @@ void BankMachine::updateState(Command command) currentState = BmState::Activated; currentRow = DramExtension::getRow(currentPayload); break; - case Command::PRE: case Command::PREA: + case Command::PRE: case Command::PREA: case Command::PRESB: currentState = BmState::Precharged; break; case Command::RD: case Command::WR: @@ -70,7 +70,7 @@ void BankMachine::updateState(Command command) case Command::PDEA: case Command::PDEP: case Command::SREFEN: sleeping = true; break; - case Command::REFA: case Command::REFB: + case Command::REFA: case Command::REFB: case Command::REFSB: sleeping = false; blocked = false; break; diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 5a81d6f1..912f990d 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -54,9 +54,10 @@ #include "cmdmux/CmdMuxOldest.h" #include "respqueue/RespQueueFifo.h" #include "respqueue/RespQueueReorder.h" -#include "refresh/RefreshManagerRankwise.h" #include "refresh/RefreshManagerDummy.h" +#include "refresh/RefreshManagerRankwise.h" #include "refresh/RefreshManagerBankwise.h" +#include "refresh/RefreshManagerGroupwise.h" #include "powerdown/PowerDownManagerStaggered.h" #include "powerdown/PowerDownManagerDummy.h" @@ -185,6 +186,15 @@ Controller::Controller(sc_module_name name) : refreshManagers.push_back(manager); } } + else if (config.refreshPolicy == "Groupwise") + { + for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) + { + RefreshManagerIF *manager = new RefreshManagerGroupwise + (bankMachinesOnRank[rankID], powerDownManagers[rankID], Rank(rankID), checker); + refreshManagers.push_back(manager); + } + } else if (config.refreshPolicy == "Bankwise") { for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) @@ -271,28 +281,36 @@ void Controller::controllerMethod() if (!readyCommands.empty()) { commandTuple = cmdMux->selectCommand(readyCommands); - if (std::get<0>(commandTuple) != Command::NOP) // can happen with FIFO strict + Command selectedCommand = std::get<0>(commandTuple); + if (selectedCommand != Command::NOP) // can happen with FIFO strict { - Rank rank = DramExtension::getRank(std::get<1>(commandTuple)); - BankGroup bankgroup = DramExtension::getBankGroup(std::get<1>(commandTuple)); - Bank bank = DramExtension::getBank(std::get<1>(commandTuple)); + tlm_generic_payload *selectedPayload = std::get<1>(commandTuple); + Rank rank = DramExtension::getRank(selectedPayload); + BankGroup bankgroup = DramExtension::getBankGroup(selectedPayload); + Bank bank = DramExtension::getBank(selectedPayload); - if (isRankCommand(std::get<0>(commandTuple))) + if (isRankCommand(selectedCommand)) { for (auto it : bankMachinesOnRank[rank.ID()]) - it->updateState(std::get<0>(commandTuple)); + it->updateState(selectedCommand); + } + else if (isGroupCommand(selectedCommand)) + { + for (unsigned bankID = (bank.ID() % memSpec->banksPerGroup); + bankID < memSpec->banksPerRank; bankID += memSpec->banksPerGroup) + bankMachinesOnRank[rank.ID()][bankID]->updateState(selectedCommand); } else - bankMachines[bank.ID()]->updateState(std::get<0>(commandTuple)); + bankMachines[bank.ID()]->updateState(selectedCommand); - refreshManagers[rank.ID()]->updateState(std::get<0>(commandTuple)); - powerDownManagers[rank.ID()]->updateState(std::get<0>(commandTuple)); - checker->insert(std::get<0>(commandTuple), rank, bankgroup, bank); + refreshManagers[rank.ID()]->updateState(selectedCommand); + powerDownManagers[rank.ID()]->updateState(selectedCommand); + checker->insert(selectedCommand, rank, bankgroup, bank); - if (isCasCommand(std::get<0>(commandTuple))) + if (isCasCommand(selectedCommand)) { - scheduler->removeRequest(std::get<1>(commandTuple)); - respQueue->insertPayload(std::get<1>(commandTuple), memSpec->getIntervalOnDataStrobe(std::get<0>(commandTuple)).end); + scheduler->removeRequest(selectedPayload); + respQueue->insertPayload(selectedPayload, memSpec->getIntervalOnDataStrobe(selectedCommand).end); sc_time triggerTime = respQueue->getTriggerTime(); if (triggerTime != sc_max_time()) @@ -303,7 +321,7 @@ void Controller::controllerMethod() if (ranksNumberOfPayloads[rank.ID()] == 0) powerDownManagers[rank.ID()]->triggerEntry(); - sendToDram(std::get<0>(commandTuple), std::get<1>(commandTuple)); + sendToDram(selectedCommand, selectedPayload); } else readyCmdBlocked = true; diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index 68de6a49..24679491 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -53,6 +53,9 @@ CheckerDDR5::CheckerDDR5() (numberOfCommands(), std::vector(memSpec->numberOfBanks)); lastScheduledByCommand = std::vector(numberOfCommands()); + lastScheduledByCommandAndBankInGroup = std::vector> + (numberOfCommands(), std::vector(memSpec->numberOfRanks * memSpec->banksPerGroup)); + last4ActivatesLogical = std::vector>(memSpec->numberOfLogicalRanks); last4ActivatesPhysical = std::vector>(memSpec->numberOfPhysicalRanks); @@ -80,6 +83,8 @@ CheckerDDR5::CheckerDDR5() tRDPDEN = memSpec->tRL + tRD_BURST + memSpec->tCK; tWRPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + memSpec->tCK; tWRAPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + memSpec->tCK; + + // TODO: tRTP BL 32!!! (check LPDDR4) } sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const @@ -91,6 +96,8 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr Rank physicalrank = Rank(logicalrank.ID() / memSpec->logicalRanksPerPhysicalRank); Rank dimmrank = Rank(physicalrank.ID() / memSpec->physicalRanksPerDIMMRank); + unsigned bankInGroupID = rank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup; + if (command == Command::RD || command == Command::RDA) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; @@ -304,9 +311,37 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK); + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroupID]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK); + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - memSpec->tCK); + + // TODO: No tRFC_dlr and tRFC_dpr between REFA and ACT? + + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::REFSB][bankInGroupID]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - memSpec->tCK); + + // TODO: No tRFCsb_dlr between REFSB and ACT? + + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_slr - memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFSB][physicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_dlr - memSpec->tCK); + + if (last4ActivatesLogical[logicalrank.ID()].size() >= 4) + earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front() + + memSpec->tFAW_slr - memSpec->tCK); + + if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4) + earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front() + + memSpec->tFAW_dlr - memSpec->tCK); } else if (command == Command::PRE) { @@ -329,6 +364,10 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PREA][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRESB][physicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); } else if (command == Command::PREA) { @@ -359,6 +398,40 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PREA][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + // PRESB tPPD + } + else if (command == Command::PRESB) + { + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroupID]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RD][bankInGroupID]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroupID]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WR][bankInGroupID]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroupID]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + // PREA tRP + + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRESB][physicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); } else if (command == Command::REFA) { @@ -393,6 +466,67 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr); + + // REFSB tRFCsb + // PRESB tRP + } + else if (command == Command::REFSB) + { + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroupID]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroupID]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRE][bankInGroupID]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + // PREA tRP + + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroupID]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr); + + // TODO: check this + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFA][physicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr); + + // TODO: check this + lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr); + + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr); + + lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFSB][physicalrank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_dlr); + + if (last4ActivatesLogical[logicalrank.ID()].size() >= 4) + earliestTimeToStart = std::max(earliestTimeToStart, + last4ActivatesLogical[logicalrank.ID()].front() + memSpec->tFAW_slr); + + if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4) + earliestTimeToStart = std::max(earliestTimeToStart, + last4ActivatesPhysical[physicalrank.ID()].front() + memSpec->tFAW_dlr); } else SC_REPORT_FATAL("CheckerDDR5", "Unknown command!"); @@ -420,7 +554,10 @@ void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank b lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK; - if (command == Command::ACT) + lastScheduledByCommandAndBankInGroup[command][rank.ID() * memSpec->banksPerGroup + + bank.ID() % memSpec->banksPerGroup] = sc_time_stamp(); + + if (command == Command::ACT || command == Command::REFSB) { if (last4ActivatesLogical[logicalrank.ID()].size() == 4) last4ActivatesLogical[logicalrank.ID()].pop(); diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.h b/DRAMSys/library/src/controller/checker/CheckerDDR5.h index af5cf61f..54d5c080 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.h @@ -59,6 +59,8 @@ private: std::vector lastScheduledByCommand; sc_time lastCommandOnBus; + std::vector> lastScheduledByCommandAndBankInGroup; + std::vector> last4ActivatesPhysical; std::vector> last4ActivatesLogical; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp index 6acb4e6c..48685335 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp @@ -39,9 +39,9 @@ using namespace tlm; -RefreshManagerBankwise::RefreshManagerBankwise(std::vector &bankMachines, +RefreshManagerBankwise::RefreshManagerBankwise(std::vector &bankMachinesOnRank, PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker) - : bankMachinesOnRank(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker) + : bankMachinesOnRank(bankMachinesOnRank), powerDownManager(powerDownManager), rank(rank), checker(checker) { Configuration &config = Configuration::getInstance(); memSpec = config.memSpec; @@ -50,8 +50,9 @@ RefreshManagerBankwise::RefreshManagerBankwise(std::vector &bankM refreshPayloads = std::vector(memSpec->banksPerRank); for (unsigned bankID = 0; bankID < memSpec->banksPerRank; bankID++) { - setUpDummy(refreshPayloads[bankID], 0, rank, bankMachines[bankID]->getBankGroup(), bankMachines[bankID]->getBank()); - allBankMachines.push_back(bankMachines[bankID]); + setUpDummy(refreshPayloads[bankID], 0, rank, bankMachinesOnRank[bankID]->getBankGroup(), + bankMachinesOnRank[bankID]->getBank()); + allBankMachines.push_back(bankMachinesOnRank[bankID]); } remainingBankMachines = allBankMachines; currentBankMachine = *remainingBankMachines.begin(); diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp new file mode 100644 index 00000000..07bf1d7b --- /dev/null +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#include "RefreshManagerGroupwise.h" +#include "../../configuration/Configuration.h" +#include "../../common/utils.h" +#include "../../common/dramExtensions.h" + +using namespace tlm; + +RefreshManagerGroupwise::RefreshManagerGroupwise(std::vector &bankMachines, + PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker) + : bankMachinesOnRank(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker) +{ + Configuration &config = Configuration::getInstance(); + memSpec = config.memSpec; + timeForNextTrigger = memSpec->getRefreshIntervalPB(); + + refreshPayloads = std::vector(memSpec->banksPerRank); + for (unsigned bankID = 0; bankID < memSpec->banksPerRank; bankID++) + { + setUpDummy(refreshPayloads[bankID], 0, rank, bankMachines[bankID]->getBankGroup(), bankMachines[bankID]->getBank()); + allBankMachines.push_back(bankMachines[bankID]); + } + remainingBankMachines = allBankMachines; + currentBankMachine = *remainingBankMachines.begin(); + + maxPostponed = config.refreshMaxPostponed * memSpec->banksPerRank; + maxPulledin = -(config.refreshMaxPulledin * memSpec->banksPerRank); +} + +std::tuple RefreshManagerGroupwise::getNextCommand() +{ + return std::tuple + (nextCommand, &refreshPayloads[currentBankMachine->getBank().ID() % memSpec->banksPerRank], timeToSchedule); +} + +sc_time RefreshManagerGroupwise::start() +{ + timeToSchedule = sc_max_time(); + nextCommand = Command::NOP; + + if (sc_time_stamp() >= timeForNextTrigger) + { + powerDownManager->triggerInterruption(); + if (sleeping) + return timeToSchedule; + + if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalPB()) + { + timeForNextTrigger += memSpec->getRefreshIntervalPB(); + state = RmState::Regular; + } + + if (state == RmState::Regular) + { + bool forcedRefresh = (flexibilityCounter == maxPostponed); + bool allBanksBusy = true; + + if (!skipSelection) + { + currentIterator = remainingBankMachines.begin(); + currentBankMachine = *remainingBankMachines.begin(); + + for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end(); it++) + { + if ((*it)->isIdle()) + { + currentIterator = it; + currentBankMachine = *it; + allBanksBusy = false; + break; + } + } + } + + if (allBanksBusy && !forcedRefresh) + { + flexibilityCounter++; + timeForNextTrigger += memSpec->getRefreshIntervalPB(); + return timeForNextTrigger; + } + else + { + if (currentBankMachine->getState() == BmState::Activated) + nextCommand = Command::PRE; + else + { + nextCommand = Command::REFB; + + if (forcedRefresh) + { + currentBankMachine->block(); + skipSelection = true; + } + } + + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, + currentBankMachine->getBankGroup(), currentBankMachine->getBank()); + return timeToSchedule; + } + } + else // if (state == RmState::Pulledin) + { + bool allBanksBusy = true; + + for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end(); it++) + { + if ((*it)->isIdle()) + { + currentIterator = it; + currentBankMachine = *it; + allBanksBusy = false; + break; + } + } + + if (allBanksBusy) + { + state = RmState::Regular; + timeForNextTrigger += memSpec->getRefreshIntervalPB(); + return timeForNextTrigger; + } + else + { + if (currentBankMachine->getState() == BmState::Activated) + nextCommand = Command::PRE; + else + nextCommand = Command::REFB; + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, + currentBankMachine->getBankGroup(), currentBankMachine->getBank()); + return timeToSchedule; + } + } + } + else + return timeForNextTrigger; +} + +void RefreshManagerGroupwise::updateState(Command command) +{ + switch (command) + { + case Command::REFB: + skipSelection = false; + remainingBankMachines.erase(currentIterator); + if (remainingBankMachines.empty()) + remainingBankMachines = allBankMachines; + + if (state == RmState::Pulledin) + flexibilityCounter--; + else + state = RmState::Pulledin; + + if (flexibilityCounter == maxPulledin) + { + state = RmState::Regular; + timeForNextTrigger += memSpec->getRefreshIntervalPB(); + } + break; + case Command::REFA: + // Refresh command after SREFEX + state = RmState::Regular; // TODO: check if this assignment is necessary + timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalPB(); + sleeping = false; + break; + case Command::PDEA: case Command::PDEP: + sleeping = true; + break; + case Command::SREFEN: + sleeping = true; + timeForNextTrigger = sc_max_time(); + break; + case Command::PDXA: case Command::PDXP: + sleeping = false; + break; + } +} diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.h b/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.h new file mode 100644 index 00000000..ba7e4dd8 --- /dev/null +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#ifndef REFRESHMANAGERGROUPWISE_H +#define REFRESHMANAGERGROUPWISE_H + +#include "RefreshManagerIF.h" +#include "../../configuration/memspec/MemSpec.h" +#include "../BankMachine.h" +#include "../powerdown/PowerDownManagerIF.h" +#include +#include +#include + +class RefreshManagerGroupwise final : public RefreshManagerIF +{ +public: + RefreshManagerGroupwise(std::vector &, PowerDownManagerIF *, Rank, CheckerIF *); + + virtual std::tuple getNextCommand() override; + virtual sc_time start() override; + virtual void updateState(Command) override; + +private: + enum class RmState {Regular, Pulledin} state = RmState::Regular; + const MemSpec *memSpec; + std::vector &bankMachinesOnRank; + PowerDownManagerIF *powerDownManager; + std::vector refreshPayloads; + sc_time timeForNextTrigger = sc_max_time(); + sc_time timeToSchedule = sc_max_time(); + Rank rank; + CheckerIF *checker; + Command nextCommand = Command::NOP; + + std::list remainingBankMachines; + std::list allBankMachines; + std::list::iterator currentIterator; + BankMachine *currentBankMachine; + + int flexibilityCounter = 0; + int maxPostponed = 0; + int maxPulledin = 0; + + bool sleeping = false; + bool skipSelection = false; +}; + +#endif // REFRESHMANAGERGROUPWISE_H diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.cpp index 40df47e3..af163a2f 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.cpp @@ -39,9 +39,9 @@ using namespace tlm; -RefreshManagerRankwise::RefreshManagerRankwise(std::vector &bankMachines, +RefreshManagerRankwise::RefreshManagerRankwise(std::vector &bankMachinesOnRank, PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker) - : bankMachinesOnRank(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker) + : bankMachinesOnRank(bankMachinesOnRank), powerDownManager(powerDownManager), rank(rank), checker(checker) { Configuration &config = Configuration::getInstance(); memSpec = config.memSpec; From 57d4266a30501a3283b979e726b3ee1a841412cd Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 31 Aug 2020 17:02:38 +0200 Subject: [PATCH 14/50] First working version of same bank refresh implemented. --- .../src/configuration/memspec/MemSpecDDR5.cpp | 4 +- .../refresh/RefreshManagerGroupwise.cpp | 131 ++++++++++++------ .../refresh/RefreshManagerGroupwise.h | 13 +- 3 files changed, 98 insertions(+), 50 deletions(-) diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp index 14a3a334..3529c16b 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp @@ -122,7 +122,7 @@ sc_time MemSpecDDR5::getRefreshIntervalSB() const // Returns the execution time for commands that have a fixed execution time sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload &) const { - if (command == Command::PRE || command == Command::PREA) + if (command == Command::PRE || command == Command::PREA || command == Command::PRESB) return tRP; else if (command == Command::ACT) return tRCD + tCK; @@ -136,6 +136,8 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload return tWL + burstDuration + tWR + tRP + tCK; else if (command == Command::REFA) return tRFC_slr; + else if (command == Command::REFSB) + return tRFCsb_slr; else { SC_REPORT_FATAL("getExecutionTime", diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp index 07bf1d7b..ccaf825c 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp @@ -39,31 +39,46 @@ using namespace tlm; -RefreshManagerGroupwise::RefreshManagerGroupwise(std::vector &bankMachines, +RefreshManagerGroupwise::RefreshManagerGroupwise(std::vector &bankMachinesOnRank, PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker) - : bankMachinesOnRank(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker) + : bankMachinesOnRank(bankMachinesOnRank), powerDownManager(powerDownManager), rank(rank), checker(checker) { Configuration &config = Configuration::getInstance(); memSpec = config.memSpec; - timeForNextTrigger = memSpec->getRefreshIntervalPB(); + timeForNextTrigger = memSpec->getRefreshIntervalSB(); - refreshPayloads = std::vector(memSpec->banksPerRank); - for (unsigned bankID = 0; bankID < memSpec->banksPerRank; bankID++) + refreshPayloads = std::vector(memSpec->banksPerGroup); + for (unsigned bankID = 0; bankID < memSpec->banksPerGroup; bankID++) { - setUpDummy(refreshPayloads[bankID], 0, rank, bankMachines[bankID]->getBankGroup(), bankMachines[bankID]->getBank()); - allBankMachines.push_back(bankMachines[bankID]); + setUpDummy(refreshPayloads[bankID], 0, rank, bankMachinesOnRank[bankID]->getBankGroup(), + bankMachinesOnRank[bankID]->getBank()); + allBankMachines.push_back(std::vector(memSpec->groupsPerRank)); } - remainingBankMachines = allBankMachines; - currentBankMachine = *remainingBankMachines.begin(); - maxPostponed = config.refreshMaxPostponed * memSpec->banksPerRank; - maxPulledin = -(config.refreshMaxPulledin * memSpec->banksPerRank); + std::list>::iterator it = allBankMachines.begin(); + for (unsigned bankID = 0; bankID < memSpec->banksPerGroup; bankID++) + { + for (unsigned groupID = 0; groupID < memSpec->groupsPerRank; groupID++) + (*it)[groupID] = bankMachinesOnRank[groupID * memSpec->banksPerGroup + bankID]; + it++; + } + + remainingBankMachines = allBankMachines; + currentIterator = remainingBankMachines.begin(); + + maxPostponed = config.refreshMaxPostponed * memSpec->banksPerGroup; + maxPulledin = -(config.refreshMaxPulledin * memSpec->banksPerGroup); } std::tuple RefreshManagerGroupwise::getNextCommand() { - return std::tuple - (nextCommand, &refreshPayloads[currentBankMachine->getBank().ID() % memSpec->banksPerRank], timeToSchedule); + unsigned id = currentIterator->front()->getBank().ID() % memSpec->banksPerGroup; + tlm_generic_payload *payload = &refreshPayloads[id]; + return std::tuple(nextCommand, payload, timeToSchedule); + +// return std::tuple +// (nextCommand, &refreshPayloads[currentIterator->front()->getBank().ID() +// % memSpec->banksPerGroup], timeToSchedule); } sc_time RefreshManagerGroupwise::start() @@ -77,9 +92,9 @@ sc_time RefreshManagerGroupwise::start() if (sleeping) return timeToSchedule; - if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalPB()) + if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalSB()) { - timeForNextTrigger += memSpec->getRefreshIntervalPB(); + timeForNextTrigger += memSpec->getRefreshIntervalSB(); state = RmState::Regular; } @@ -91,15 +106,21 @@ sc_time RefreshManagerGroupwise::start() if (!skipSelection) { currentIterator = remainingBankMachines.begin(); - currentBankMachine = *remainingBankMachines.begin(); - - for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end(); it++) + for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++) { - if ((*it)->isIdle()) + bool groupIsBusy = false; + for (auto groupIt : *bankIt) + { + if (!groupIt->isIdle()) + { + groupIsBusy = true; + break; + } + } + if (!groupIsBusy) { - currentIterator = it; - currentBankMachine = *it; allBanksBusy = false; + currentIterator = bankIt; break; } } @@ -108,26 +129,30 @@ sc_time RefreshManagerGroupwise::start() if (allBanksBusy && !forcedRefresh) { flexibilityCounter++; - timeForNextTrigger += memSpec->getRefreshIntervalPB(); + timeForNextTrigger += memSpec->getRefreshIntervalSB(); return timeForNextTrigger; } else - { - if (currentBankMachine->getState() == BmState::Activated) - nextCommand = Command::PRE; - else + { + nextCommand = Command::REFSB; + for (auto it : *currentIterator) { - nextCommand = Command::REFB; - - if (forcedRefresh) + if (it->getState() == BmState::Activated) { - currentBankMachine->block(); - skipSelection = true; + nextCommand = Command::PRESB; + break; } } + if (nextCommand == Command::REFSB && forcedRefresh) + { + for (auto it : *currentIterator) + it->block(); + skipSelection = true; + } + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, - currentBankMachine->getBankGroup(), currentBankMachine->getBank()); + currentIterator->front()->getBankGroup(), currentIterator->front()->getBank()); return timeToSchedule; } } @@ -135,13 +160,22 @@ sc_time RefreshManagerGroupwise::start() { bool allBanksBusy = true; - for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end(); it++) + currentIterator = remainingBankMachines.begin(); + for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++) { - if ((*it)->isIdle()) + bool groupIsBusy = false; + for (auto groupIt : *bankIt) + { + if (!groupIt->isIdle()) + { + groupIsBusy = true; + break; + } + } + if (!groupIsBusy) { - currentIterator = it; - currentBankMachine = *it; allBanksBusy = false; + currentIterator = bankIt; break; } } @@ -149,17 +183,23 @@ sc_time RefreshManagerGroupwise::start() if (allBanksBusy) { state = RmState::Regular; - timeForNextTrigger += memSpec->getRefreshIntervalPB(); + timeForNextTrigger += memSpec->getRefreshIntervalSB(); return timeForNextTrigger; } else { - if (currentBankMachine->getState() == BmState::Activated) - nextCommand = Command::PRE; - else - nextCommand = Command::REFB; + nextCommand = Command::REFSB; + for (auto it : *currentIterator) + { + if (it->getState() == BmState::Activated) + { + nextCommand = Command::PRESB; + break; + } + } + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, - currentBankMachine->getBankGroup(), currentBankMachine->getBank()); + currentIterator->front()->getBankGroup(), currentIterator->front()->getBank()); return timeToSchedule; } } @@ -172,11 +212,12 @@ void RefreshManagerGroupwise::updateState(Command command) { switch (command) { - case Command::REFB: + case Command::REFSB: skipSelection = false; remainingBankMachines.erase(currentIterator); if (remainingBankMachines.empty()) remainingBankMachines = allBankMachines; + currentIterator = remainingBankMachines.begin(); if (state == RmState::Pulledin) flexibilityCounter--; @@ -186,13 +227,13 @@ void RefreshManagerGroupwise::updateState(Command command) if (flexibilityCounter == maxPulledin) { state = RmState::Regular; - timeForNextTrigger += memSpec->getRefreshIntervalPB(); + timeForNextTrigger += memSpec->getRefreshIntervalSB(); } break; case Command::REFA: // Refresh command after SREFEX state = RmState::Regular; // TODO: check if this assignment is necessary - timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalPB(); + timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalSB(); sleeping = false; break; case Command::PDEA: case Command::PDEP: diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.h b/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.h index ba7e4dd8..6b24da11 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.h @@ -64,10 +64,15 @@ private: CheckerIF *checker; Command nextCommand = Command::NOP; - std::list remainingBankMachines; - std::list allBankMachines; - std::list::iterator currentIterator; - BankMachine *currentBankMachine; + //std::list remainingBankMachines; + //std::list allBankMachines; + //std::list::iterator currentIterator; + //BankMachine *currentBankMachines; + + std::list> remainingBankMachines; + std::list> allBankMachines; + std::list>::iterator currentIterator; + //std::vector *currentBankMachines; int flexibilityCounter = 0; int maxPostponed = 0; From 90ccdece6a8e045312fb6ecb85fbcb088651adad Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 3 Sep 2020 16:13:15 +0200 Subject: [PATCH 15/50] Add 2N mode for commands. --- ...n => am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json} | 17 ++--- ...=> am_ddr5_2x8x8x2Gbx4_dimm_p1KB_rbc.json} | 0 .../memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json | 55 --------------- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json | 68 +++++++++++++++++++ ...json => JEDEC_2x8x8x2Gbx4_DDR5-3200A.json} | 3 +- .../resources/simulations/ddr5-example.json | 4 +- DRAMSys/library/src/common/TlmRecorder.cpp | 4 +- .../src/configuration/memspec/MemSpecDDR5.cpp | 59 +++++++++++----- .../src/configuration/memspec/MemSpecDDR5.h | 4 ++ .../src/controller/checker/CheckerDDR5.cpp | 34 +++++----- .../src/controller/checker/CheckerDDR5.h | 2 + .../refresh/RefreshManagerGroupwise.cpp | 10 +-- 12 files changed, 153 insertions(+), 107 deletions(-) rename DRAMSys/library/resources/configs/amconfigs/{am_ddr5_2x4x8Gbx8_dimm_p1KB_rbc.json => am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json} (87%) rename DRAMSys/library/resources/configs/amconfigs/{am_ddr5_2x8x8x8Gbx4_dimm_p1KB_rbc.json => am_ddr5_2x8x8x2Gbx4_dimm_p1KB_rbc.json} (100%) delete mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json rename DRAMSys/library/resources/configs/memspecs/{JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json => JEDEC_2x8x8x2Gbx4_DDR5-3200A.json} (96%) diff --git a/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x4x8Gbx8_dimm_p1KB_rbc.json b/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json similarity index 87% rename from DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x4x8Gbx8_dimm_p1KB_rbc.json rename to DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json index 7e02f877..bce5038e 100644 --- a/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x4x8Gbx8_dimm_p1KB_rbc.json +++ b/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json @@ -14,18 +14,18 @@ 8, 9, 10, - 11 + 11, + 12 ], "BANKGROUP_BIT": [ - 12, 13, - 14 - ], - "BANK_BIT": [ + 14, 15 ], + "BANK_BIT": [ + 16 + ], "ROW_BIT": [ - 16, 17, 18, 19, @@ -40,10 +40,11 @@ 28, 29, 30, - 31 + 31, + 32 ], "CHANNEL_BIT": [ - 32 + 33 ] } } \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x8x8x8Gbx4_dimm_p1KB_rbc.json b/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x8x8x2Gbx4_dimm_p1KB_rbc.json similarity index 100% rename from DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x8x8x8Gbx4_dimm_p1KB_rbc.json rename to DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x8x8x2Gbx4_dimm_p1KB_rbc.json diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json deleted file mode 100644 index 492eea26..00000000 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8Gb_DDR5-3200A_8bit.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "memspec": { - "memarchitecturespec": { - "burstLength": 16, - "dataRate": 2, - "nbrOfBankGroups": 8, - "nbrOfBanks": 16, - "nbrOfColumns": 1024, - "nbrOfRanks": 1, - "nbrOfRows": 65536, - "width": 8, - "nbrOfDevicesOnDIMM": 4, - "nbrOfChannels": 2 - }, - "memoryId": "JEDEC_2x8Gb_DDR5-3200A_8bit", - "memoryType": "DDR5", - - "memtimingspec": { - "AL": 0, - "CCD_L": 16, - "CCD_S": 8, - "CKE": 6, - "CKESR": 7, - "DQSCK": 2, - "FAW": 32, - "RAS": 52, - "RC": 74, - "RCD": 22, - "REFM": 1, - "REFI": 6240, - "REFISB": 1560, - "RFC": 312, - "RL": 22, - "RPRE": 1, - "RP": 22, - "RRD_L": 8, - "RRD_S": 8, - "RTP": 12, - "WL": 20, - "WPRE": 2, - "WR": 48, - "WTR_L": 16, - "WTR_S": 4, - "XP": 12, - "XPDLL": 0, - "XS": 312, - "XSDLL": 1024, - "ACTPDEN": 2, - "PRPDEN": 2, - "REFPDEN": 2, - "RTRS": 1, - "clkMhz": 1600 - } - } -} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json new file mode 100644 index 00000000..3de8ce00 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json @@ -0,0 +1,68 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 2048, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 4, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 2, + "cmdMode": 1 + }, + "memoryId": "JEDEC_2x8x8x8Gbx4_DDR5-3200A_4bit", + "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_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 8, + "CCD_WR_dlr": 8, + "CCD_WR_dpr": 8, + "RRD_L_slr": 8, + "RRD_S_slr": 8, + "RRD_dlr": 4, + "FAW_slr": 32, + "FAW_dlr": 16, + "WTR_L": 16, + "WTR_S": 4, + "RFC_slr": 312, + "RFC_dlr": 104, + "RFC_dpr": 104, + "RFCsb_slr": 184, + "RFCsb_dlr": 62, + "REFI": 6240, + "REFISB": 1560, + "REFSBRD_slr": 48, + "REFSBRD_dlr": 24, + "RTRS": 2, + "CPDED": 8, + "PD": 12, + "XP": 12, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 1600 + } + } +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x2Gbx4_DDR5-3200A.json similarity index 96% rename from DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json rename to DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x2Gbx4_DDR5-3200A.json index d8984701..95886d86 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x2Gbx4_DDR5-3200A.json @@ -13,7 +13,8 @@ "nbrOfRows": 65536, "width": 4, "nbrOfDevicesOnDIMM": 8, - "nbrOfChannels": 2 + "nbrOfChannels": 2, + "cmdMode": 1 }, "memoryId": "JEDEC_2x8x8x8Gbx4_DDR5-3200A_4bit", "memoryType": "DDR5", diff --git a/DRAMSys/library/resources/simulations/ddr5-example.json b/DRAMSys/library/resources/simulations/ddr5-example.json index 8c36a540..e85d1b92 100644 --- a/DRAMSys/library/resources/simulations/ddr5-example.json +++ b/DRAMSys/library/resources/simulations/ddr5-example.json @@ -1,8 +1,8 @@ { "simulation": { - "addressmapping": "am_ddr5_2x8x8x8Gbx4_dimm_p1KB_rbc.json", + "addressmapping": "am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json", "mcconfig": "fr_fcfs.json", - "memspec": "JEDEC_2x8x8x8Gb_DDR5-3200A_4bit.json", + "memspec": "JEDEC_2x8x2Gbx4_DDR5-3200A.json", "simconfig": "ddr5.json", "simulationid": "ddr5-example", "thermalconfig": "config.json", diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index c1137f5c..e7aebdd2 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -375,8 +375,8 @@ void TlmRecorder::insertCommandLengths() sqlite3_bind_int(insertCommandLengthsStatement, 3, memSpec->getCommandLength(Command::WR) / memSpec->tCK); sqlite3_bind_int(insertCommandLengthsStatement, 4, memSpec->getCommandLength(Command::RDA) / memSpec->tCK); sqlite3_bind_int(insertCommandLengthsStatement, 5, memSpec->getCommandLength(Command::WRA) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 6, memSpec->getCommandLength(Command::PRE) / memSpec->tCK); - sqlite3_bind_int(insertCommandLengthsStatement, 7, memSpec->getCommandLength(Command::ACT) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 6, memSpec->getCommandLength(Command::ACT) / memSpec->tCK); + sqlite3_bind_int(insertCommandLengthsStatement, 7, memSpec->getCommandLength(Command::PRE) / memSpec->tCK); sqlite3_bind_int(insertCommandLengthsStatement, 8, memSpec->getCommandLength(Command::REFB) / memSpec->tCK); sqlite3_bind_int(insertCommandLengthsStatement, 9, memSpec->getCommandLength(Command::PRESB) / memSpec->tCK); sqlite3_bind_int(insertCommandLengthsStatement, 10, memSpec->getCommandLength(Command::REFSB) / memSpec->tCK); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp index 3529c16b..19b5e65f 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp @@ -57,6 +57,7 @@ MemSpecDDR5::MemSpecDDR5(json &memspec) numberOfPhysicalRanks(physicalRanksPerDIMMRank * numberOfDIMMRanks), logicalRanksPerPhysicalRank(parseUint(memspec["memarchitecturespec"]["nbrOfLogicalRanks"], "nbrOfLogicalRanks")), numberOfLogicalRanks(logicalRanksPerPhysicalRank * numberOfPhysicalRanks), + cmdMode(parseUint(memspec["memarchitecturespec"]["cmdMode"], "cmdMode")), tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")), tPPD (tCK * parseUint(memspec["memtimingspec"]["PPD"], "PPD")), tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), @@ -100,13 +101,39 @@ MemSpecDDR5::MemSpecDDR5(json &memspec) tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")), tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")), tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")), - tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")) + tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")), + cmdOffset_S (cmdMode == 2 ? 1 * tCK : 0 * tCK), + cmdOffset_L (cmdMode == 2 ? 3 * tCK : 1 * tCK) { - commandLengthInCycles[Command::ACT] = 2; - commandLengthInCycles[Command::RD] = 2; - commandLengthInCycles[Command::RDA] = 2; - commandLengthInCycles[Command::WR] = 2; - commandLengthInCycles[Command::WRA] = 2; + if (cmdMode == 1) + { + commandLengthInCycles[Command::ACT] = 2; + commandLengthInCycles[Command::RD] = 2; + commandLengthInCycles[Command::RDA] = 2; + commandLengthInCycles[Command::WR] = 2; + commandLengthInCycles[Command::WRA] = 2; + } + else if (cmdMode == 2) + { + commandLengthInCycles[Command::ACT] = 4; + commandLengthInCycles[Command::PRE] = 2; + commandLengthInCycles[Command::PREA] = 2; + commandLengthInCycles[Command::PRESB] = 2; + commandLengthInCycles[Command::RD] = 4; + commandLengthInCycles[Command::RDA] = 4; + commandLengthInCycles[Command::WR] = 4; + commandLengthInCycles[Command::WRA] = 4; + commandLengthInCycles[Command::REFA] = 2; + commandLengthInCycles[Command::REFSB] = 2; + commandLengthInCycles[Command::PDEA] = 2; + commandLengthInCycles[Command::PDXA] = 2; + commandLengthInCycles[Command::PDEP] = 2; + commandLengthInCycles[Command::PDXP] = 2; + commandLengthInCycles[Command::SREFEN] = 2; + commandLengthInCycles[Command::SREFEX] = 2; + } + else + SC_REPORT_FATAL("MemSpecDDR5", "Invalid command mode!"); } sc_time MemSpecDDR5::getRefreshIntervalAB() const @@ -123,21 +150,21 @@ sc_time MemSpecDDR5::getRefreshIntervalSB() const sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload &) const { if (command == Command::PRE || command == Command::PREA || command == Command::PRESB) - return tRP; + return tRP + cmdOffset_S; else if (command == Command::ACT) - return tRCD + tCK; + return tRCD + cmdOffset_L; else if (command == Command::RD) - return tRL + burstDuration + tCK; + return tRL + burstDuration + cmdOffset_L; else if (command == Command::RDA) - return tRTP + tRP + tCK; + return tRTP + tRP + cmdOffset_L; else if (command == Command::WR) - return tWL + burstDuration + tCK; + return tWL + burstDuration + cmdOffset_L; else if (command == Command::WRA) - return tWL + burstDuration + tWR + tRP + tCK; + return tWL + burstDuration + tWR + tRP + cmdOffset_L; else if (command == Command::REFA) - return tRFC_slr; + return tRFC_slr + cmdOffset_S; else if (command == Command::REFSB) - return tRFCsb_slr; + return tRFCsb_slr + cmdOffset_S; else { SC_REPORT_FATAL("getExecutionTime", @@ -149,9 +176,9 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command) const { if (command == Command::RD || command == Command::RDA) - return TimeInterval(sc_time_stamp() + tRL + tCK, sc_time_stamp() + tRL + burstDuration + tCK); + return TimeInterval(sc_time_stamp() + tRL + cmdOffset_L, sc_time_stamp() + tRL + burstDuration + cmdOffset_L); else if (command == Command::WR || command == Command::WRA) - return TimeInterval(sc_time_stamp() + tWL + tCK, sc_time_stamp() + tWL + burstDuration + tCK); + return TimeInterval(sc_time_stamp() + tWL + cmdOffset_L, sc_time_stamp() + tWL + burstDuration + cmdOffset_L); else { SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument"); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h index 3103c3cd..e6549d26 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h @@ -49,6 +49,7 @@ public: const unsigned numberOfPhysicalRanks; const unsigned logicalRanksPerPhysicalRank; const unsigned numberOfLogicalRanks; + const unsigned cmdMode; // Memspec Variables: const sc_time tRCD; @@ -97,6 +98,9 @@ public: const sc_time tPRPDEN; const sc_time tREFPDEN; + const sc_time cmdOffset_S; + const sc_time cmdOffset_L; + // Currents and Voltages: // TODO: to be completed diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index 24679491..9bf98143 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -59,6 +59,8 @@ CheckerDDR5::CheckerDDR5() last4ActivatesLogical = std::vector>(memSpec->numberOfLogicalRanks); last4ActivatesPhysical = std::vector>(memSpec->numberOfPhysicalRanks); + cmdOffset = memSpec->cmdMode * memSpec->tCK; + tRD_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; tWR_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; tWTRA = memSpec->tWR - memSpec->tRTP; @@ -80,9 +82,9 @@ CheckerDDR5::CheckerDDR5() tWRWR_ddr = tWR_BURST + memSpec->tRTRS; tWRRD_dpr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE; tWRRD_ddr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE; - tRDPDEN = memSpec->tRL + tRD_BURST + memSpec->tCK; - tWRPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + memSpec->tCK; - tWRAPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + memSpec->tCK; + tRDPDEN = memSpec->tRL + tRD_BURST + cmdOffset; + tWRPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset; + tWRAPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset; // TODO: tRTP BL 32!!! (check LPDDR4) } @@ -305,43 +307,43 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PREA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset); lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroupID]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - cmdOffset); // TODO: No tRFC_dlr and tRFC_dpr between REFA and ACT? lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::REFSB][bankInGroupID]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - cmdOffset); // TODO: No tRFCsb_dlr between REFSB and ACT? lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_slr - memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_slr - cmdOffset); lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFSB][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_dlr - memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_dlr - cmdOffset); if (last4ActivatesLogical[logicalrank.ID()].size() >= 4) earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front() - + memSpec->tFAW_slr - memSpec->tCK); + + memSpec->tFAW_slr - memSpec->cmdOffset_L); if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4) earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front() - + memSpec->tFAW_dlr - memSpec->tCK); + + memSpec->tFAW_dlr - memSpec->cmdOffset_L); } else if (command == Command::PRE) { @@ -521,12 +523,12 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_dlr); if (last4ActivatesLogical[logicalrank.ID()].size() >= 4) - earliestTimeToStart = std::max(earliestTimeToStart, - last4ActivatesLogical[logicalrank.ID()].front() + memSpec->tFAW_slr); + earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front() + + memSpec->tFAW_slr - memSpec->cmdOffset_S); if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4) - earliestTimeToStart = std::max(earliestTimeToStart, - last4ActivatesPhysical[physicalrank.ID()].front() + memSpec->tFAW_dlr); + earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front() + + memSpec->tFAW_dlr - memSpec->cmdOffset_S); } else SC_REPORT_FATAL("CheckerDDR5", "Unknown command!"); diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.h b/DRAMSys/library/src/controller/checker/CheckerDDR5.h index 54d5c080..caf04154 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.h @@ -64,6 +64,8 @@ private: std::vector> last4ActivatesPhysical; std::vector> last4ActivatesLogical; + sc_time cmdOffset; + sc_time tRD_BURST; sc_time tWR_BURST; sc_time tWTRA; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp index ccaf825c..9cc326c4 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp @@ -72,13 +72,9 @@ RefreshManagerGroupwise::RefreshManagerGroupwise(std::vector &ban std::tuple RefreshManagerGroupwise::getNextCommand() { - unsigned id = currentIterator->front()->getBank().ID() % memSpec->banksPerGroup; - tlm_generic_payload *payload = &refreshPayloads[id]; - return std::tuple(nextCommand, payload, timeToSchedule); - -// return std::tuple -// (nextCommand, &refreshPayloads[currentIterator->front()->getBank().ID() -// % memSpec->banksPerGroup], timeToSchedule); + return std::tuple + (nextCommand, &refreshPayloads[currentIterator->front()->getBank().ID() + % memSpec->banksPerGroup], timeToSchedule); } sc_time RefreshManagerGroupwise::start() From 7f049645cab551516df1e6109fc6525151ae749c Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 2 Oct 2020 15:16:42 +0200 Subject: [PATCH 16/50] Add DDR5 memspecs for different speed grades. --- .../am_ddr5_2x4x1Gbx8_dimm_p1KB_rbc.json | 49 +++++++++++++ .../memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json | 68 +++++++++++++++++++ .../memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json | 68 +++++++++++++++++++ .../memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json | 68 +++++++++++++++++++ .../memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json | 68 +++++++++++++++++++ .../memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json | 68 +++++++++++++++++++ .../memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json | 68 +++++++++++++++++++ .../memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json | 68 +++++++++++++++++++ .../memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json | 68 +++++++++++++++++++ .../memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json | 68 +++++++++++++++++++ 10 files changed, 661 insertions(+) create mode 100644 DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x4x1Gbx8_dimm_p1KB_rbc.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json diff --git a/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x4x1Gbx8_dimm_p1KB_rbc.json b/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x4x1Gbx8_dimm_p1KB_rbc.json new file mode 100644 index 00000000..7e02f877 --- /dev/null +++ b/DRAMSys/library/resources/configs/amconfigs/am_ddr5_2x4x1Gbx8_dimm_p1KB_rbc.json @@ -0,0 +1,49 @@ +{ + "CONGEN": { + "BYTE_BIT": [ + 0, + 1 + ], + "COLUMN_BIT": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "BANKGROUP_BIT": [ + 12, + 13, + 14 + ], + "BANK_BIT": [ + 15 + ], + "ROW_BIT": [ + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31 + ], + "CHANNEL_BIT": [ + 32 + ] + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json new file mode 100644 index 00000000..3febbed0 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json @@ -0,0 +1,68 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 8, + "nbrOfDevicesOnDIMM": 4, + "nbrOfChannels": 2, + "cmdMode": 1 + }, + "memoryId": "JEDEC_2x4x1Gbx8_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": 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, + "RFC_slr": 312, + "RFC_dlr": 0, + "RFC_dpr": 0, + "RFCsb_slr": 184, + "RFCsb_dlr": 0, + "REFI": 6240, + "REFISB": 1560, + "REFSBRD_slr": 48, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 8, + "PD": 12, + "XP": 12, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 1600 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json new file mode 100644 index 00000000..90e37faf --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json @@ -0,0 +1,68 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 8, + "nbrOfDevicesOnDIMM": 4, + "nbrOfChannels": 2, + "cmdMode": 1 + }, + "memoryId": "JEDEC_2x4x1Gbx8_DDR5-3600A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 26, + "PPD": 2, + "RP": 26, + "RAS": 58, + "RL": 26, + "RTP": 14, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 24, + "WPRE": 2, + "WPST": 0, + "WR": 54, + "CCD_L_slr": 9, + "CCD_L_WR_slr": 18, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 9, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 18, + "WTR_S": 5, + "RFC_slr": 351, + "RFC_dlr": 0, + "RFC_dpr": 0, + "RFCsb_slr": 207, + "RFCsb_dlr": 0, + "REFI": 7020, + "REFISB": 1755, + "REFSBRD_slr": 54, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 9, + "PD": 14, + "XP": 14, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 1800 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json new file mode 100644 index 00000000..687e6295 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json @@ -0,0 +1,68 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 8, + "nbrOfDevicesOnDIMM": 4, + "nbrOfChannels": 2, + "cmdMode": 1 + }, + "memoryId": "JEDEC_2x4x1Gbx8_DDR5-4000A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 28, + "PPD": 2, + "RP": 28, + "RAS": 64, + "RL": 28, + "RTP": 15, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 26, + "WPRE": 2, + "WPST": 0, + "WR": 60, + "CCD_L_slr": 10, + "CCD_L_WR_slr": 20, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 10, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 20, + "WTR_S": 5, + "RFC_slr": 390, + "RFC_dlr": 0, + "RFC_dpr": 0, + "RFCsb_slr": 230, + "RFCsb_dlr": 0, + "REFI": 7800, + "REFISB": 1950, + "REFSBRD_slr": 60, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 10, + "PD": 15, + "XP": 15, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 2000 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json new file mode 100644 index 00000000..19c05cbf --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json @@ -0,0 +1,68 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 8, + "nbrOfDevicesOnDIMM": 4, + "nbrOfChannels": 2, + "cmdMode": 1 + }, + "memoryId": "JEDEC_2x4x1Gbx8_DDR5-4400A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 32, + "PPD": 2, + "RP": 32, + "RAS": 71, + "RL": 32, + "RTP": 17, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 30, + "WPRE": 2, + "WPST": 0, + "WR": 66, + "CCD_L_slr": 11, + "CCD_L_WR_slr": 22, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 11, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 22, + "WTR_S": 6, + "RFC_slr": 429, + "RFC_dlr": 0, + "RFC_dpr": 0, + "RFCsb_slr": 253, + "RFCsb_dlr": 0, + "REFI": 8580, + "REFISB": 2145, + "REFSBRD_slr": 66, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 11, + "PD": 17, + "XP": 17, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 2200 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json new file mode 100644 index 00000000..56d7a6b3 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json @@ -0,0 +1,68 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 8, + "nbrOfDevicesOnDIMM": 4, + "nbrOfChannels": 2, + "cmdMode": 1 + }, + "memoryId": "JEDEC_2x4x1Gbx8_DDR5-4800A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 34, + "PPD": 2, + "RP": 34, + "RAS": 77, + "RL": 34, + "RTP": 18, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 32, + "WPRE": 2, + "WPST": 0, + "WR": 72, + "CCD_L_slr": 12, + "CCD_L_WR_slr": 24, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 12, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 24, + "WTR_S": 6, + "RFC_slr": 468, + "RFC_dlr": 0, + "RFC_dpr": 0, + "RFCsb_slr": 276, + "RFCsb_dlr": 0, + "REFI": 9360, + "REFISB": 2340, + "REFSBRD_slr": 72, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 12, + "PD": 18, + "XP": 18, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 2400 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json new file mode 100644 index 00000000..40fe0283 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json @@ -0,0 +1,68 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 8, + "nbrOfDevicesOnDIMM": 4, + "nbrOfChannels": 2, + "cmdMode": 1 + }, + "memoryId": "JEDEC_2x4x1Gbx8_DDR5-5200A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 38, + "PPD": 2, + "RP": 38, + "RAS": 84, + "RL": 38, + "RTP": 20, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 36, + "WPRE": 2, + "WPST": 0, + "WR": 78, + "CCD_L_slr": 13, + "CCD_L_WR_slr": 26, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 13, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 26, + "WTR_S": 7, + "RFC_slr": 507, + "RFC_dlr": 0, + "RFC_dpr": 0, + "RFCsb_slr": 299, + "RFCsb_dlr": 0, + "REFI": 10140, + "REFISB": 2535, + "REFSBRD_slr": 78, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 13, + "PD": 20, + "XP": 20, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 2600 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json new file mode 100644 index 00000000..5ed3f965 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json @@ -0,0 +1,68 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 8, + "nbrOfDevicesOnDIMM": 4, + "nbrOfChannels": 2, + "cmdMode": 1 + }, + "memoryId": "JEDEC_2x4x1Gbx8_DDR5-5600A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 40, + "PPD": 2, + "RP": 40, + "RAS": 90, + "RL": 40, + "RTP": 21, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 38, + "WPRE": 2, + "WPST": 0, + "WR": 84, + "CCD_L_slr": 14, + "CCD_L_WR_slr": 28, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 14, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 28, + "WTR_S": 7, + "RFC_slr": 546, + "RFC_dlr": 0, + "RFC_dpr": 0, + "RFCsb_slr": 322, + "RFCsb_dlr": 0, + "REFI": 10920, + "REFISB": 2730, + "REFSBRD_slr": 84, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 14, + "PD": 21, + "XP": 21, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 2800 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json new file mode 100644 index 00000000..878a99ec --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json @@ -0,0 +1,68 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 8, + "nbrOfDevicesOnDIMM": 4, + "nbrOfChannels": 2, + "cmdMode": 1 + }, + "memoryId": "JEDEC_2x4x1Gbx8_DDR5-6000A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 42, + "PPD": 2, + "RP": 42, + "RAS": 96, + "RL": 42, + "RTP": 23, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 40, + "WPRE": 2, + "WPST": 0, + "WR": 90, + "CCD_L_slr": 15, + "CCD_L_WR_slr": 30, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 15, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 30, + "WTR_S": 8, + "RFC_slr": 585, + "RFC_dlr": 0, + "RFC_dpr": 0, + "RFCsb_slr": 345, + "RFCsb_dlr": 0, + "REFI": 11700, + "REFISB": 2925, + "REFSBRD_slr": 90, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 15, + "PD": 23, + "XP": 23, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 3000 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json new file mode 100644 index 00000000..6f291b49 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json @@ -0,0 +1,68 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 8, + "nbrOfDevicesOnDIMM": 4, + "nbrOfChannels": 2, + "cmdMode": 1 + }, + "memoryId": "JEDEC_2x4x1Gbx8_DDR5-6400A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 46, + "PPD": 2, + "RP": 46, + "RAS": 103, + "RL": 46, + "RTP": 24, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 44, + "WPRE": 2, + "WPST": 0, + "WR": 96, + "CCD_L_slr": 16, + "CCD_L_WR_slr": 32, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 16, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 32, + "WTR_S": 8, + "RFC_slr": 624, + "RFC_dlr": 0, + "RFC_dpr": 0, + "RFCsb_slr": 368, + "RFCsb_dlr": 0, + "REFI": 12480, + "REFISB": 3120, + "REFSBRD_slr": 96, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 16, + "PD": 24, + "XP": 24, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 3200 + } + } +} \ No newline at end of file From 6a8ce57d088c74312e5bf85fd605c1466904ca48 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 2 Oct 2020 16:12:14 +0200 Subject: [PATCH 17/50] Add selection of fine granularity refresh mode. --- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json | 15 ++++++++++----- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json | 15 ++++++++++----- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json | 15 ++++++++++----- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json | 15 ++++++++++----- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json | 15 ++++++++++----- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json | 15 ++++++++++----- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json | 15 ++++++++++----- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json | 15 ++++++++++----- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json | 15 ++++++++++----- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json | 15 ++++++++++----- .../memspecs/JEDEC_2x8x8x2Gbx4_DDR5-3200A.json | 15 ++++++++++----- .../resources/simulations/ddr5-example.json | 4 ++-- .../src/configuration/memspec/MemSpecDDR5.cpp | 17 +++++++++++++---- .../src/configuration/memspec/MemSpecDDR5.h | 1 + .../refresh/RefreshManagerGroupwise.cpp | 6 ++++-- 15 files changed, 130 insertions(+), 63 deletions(-) diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json index 3febbed0..8bc5a428 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json @@ -14,7 +14,8 @@ "width": 8, "nbrOfDevicesOnDIMM": 4, "nbrOfChannels": 2, - "cmdMode": 1 + "cmdMode": 1, + "refMode": 1 }, "memoryId": "JEDEC_2x4x1Gbx8_DDR5-3200A", "memoryType": "DDR5", @@ -46,12 +47,16 @@ "FAW_dlr": 0, "WTR_L": 16, "WTR_S": 4, - "RFC_slr": 312, - "RFC_dlr": 0, - "RFC_dpr": 0, + "RFC1_slr": 312, + "RFC2_slr": 208, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, "RFCsb_slr": 184, "RFCsb_dlr": 0, - "REFI": 6240, + "REFI1": 6240, + "REFI2": 3120, "REFISB": 1560, "REFSBRD_slr": 48, "REFSBRD_dlr": 0, diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json index 90e37faf..639c16a9 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json @@ -14,7 +14,8 @@ "width": 8, "nbrOfDevicesOnDIMM": 4, "nbrOfChannels": 2, - "cmdMode": 1 + "cmdMode": 1, + "refMode": 1 }, "memoryId": "JEDEC_2x4x1Gbx8_DDR5-3600A", "memoryType": "DDR5", @@ -46,12 +47,16 @@ "FAW_dlr": 0, "WTR_L": 18, "WTR_S": 5, - "RFC_slr": 351, - "RFC_dlr": 0, - "RFC_dpr": 0, + "RFC1_slr": 351, + "RFC2_slr": 234, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, "RFCsb_slr": 207, "RFCsb_dlr": 0, - "REFI": 7020, + "REFI1": 7020, + "REFI2": 3510, "REFISB": 1755, "REFSBRD_slr": 54, "REFSBRD_dlr": 0, diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json index 687e6295..98d6a123 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json @@ -14,7 +14,8 @@ "width": 8, "nbrOfDevicesOnDIMM": 4, "nbrOfChannels": 2, - "cmdMode": 1 + "cmdMode": 1, + "refMode": 1 }, "memoryId": "JEDEC_2x4x1Gbx8_DDR5-4000A", "memoryType": "DDR5", @@ -46,12 +47,16 @@ "FAW_dlr": 0, "WTR_L": 20, "WTR_S": 5, - "RFC_slr": 390, - "RFC_dlr": 0, - "RFC_dpr": 0, + "RFC1_slr": 390, + "RFC2_slr": 260, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, "RFCsb_slr": 230, "RFCsb_dlr": 0, - "REFI": 7800, + "REFI1": 7800, + "REFI2": 3900, "REFISB": 1950, "REFSBRD_slr": 60, "REFSBRD_dlr": 0, diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json index 19c05cbf..1455cecb 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json @@ -14,7 +14,8 @@ "width": 8, "nbrOfDevicesOnDIMM": 4, "nbrOfChannels": 2, - "cmdMode": 1 + "cmdMode": 1, + "refMode": 1 }, "memoryId": "JEDEC_2x4x1Gbx8_DDR5-4400A", "memoryType": "DDR5", @@ -46,12 +47,16 @@ "FAW_dlr": 0, "WTR_L": 22, "WTR_S": 6, - "RFC_slr": 429, - "RFC_dlr": 0, - "RFC_dpr": 0, + "RFC_slr": 429, + "RFC_slr": 286, + "RFC_dlr": 0, + "RFC_dlr": 0, + "RFC_dpr": 0, + "RFC_dpr": 0, "RFCsb_slr": 253, "RFCsb_dlr": 0, - "REFI": 8580, + "REFI1": 8580, + "REFI2": 4290, "REFISB": 2145, "REFSBRD_slr": 66, "REFSBRD_dlr": 0, diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json index 56d7a6b3..5fef3321 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json @@ -14,7 +14,8 @@ "width": 8, "nbrOfDevicesOnDIMM": 4, "nbrOfChannels": 2, - "cmdMode": 1 + "cmdMode": 1, + "refMode": 1 }, "memoryId": "JEDEC_2x4x1Gbx8_DDR5-4800A", "memoryType": "DDR5", @@ -46,12 +47,16 @@ "FAW_dlr": 0, "WTR_L": 24, "WTR_S": 6, - "RFC_slr": 468, - "RFC_dlr": 0, - "RFC_dpr": 0, + "RFC1_slr": 468, + "RFC2_slr": 312, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, "RFCsb_slr": 276, "RFCsb_dlr": 0, - "REFI": 9360, + "REFI1": 9360, + "REFI2": 4680, "REFISB": 2340, "REFSBRD_slr": 72, "REFSBRD_dlr": 0, diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json index 40fe0283..358643b8 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json @@ -14,7 +14,8 @@ "width": 8, "nbrOfDevicesOnDIMM": 4, "nbrOfChannels": 2, - "cmdMode": 1 + "cmdMode": 1, + "refMode": 1 }, "memoryId": "JEDEC_2x4x1Gbx8_DDR5-5200A", "memoryType": "DDR5", @@ -46,12 +47,16 @@ "FAW_dlr": 0, "WTR_L": 26, "WTR_S": 7, - "RFC_slr": 507, - "RFC_dlr": 0, - "RFC_dpr": 0, + "RFC1_slr": 507, + "RFC2_slr": 338, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, "RFCsb_slr": 299, "RFCsb_dlr": 0, - "REFI": 10140, + "REFI1": 10140, + "REFI2": 5070, "REFISB": 2535, "REFSBRD_slr": 78, "REFSBRD_dlr": 0, diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json index 5ed3f965..766c837c 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json @@ -14,7 +14,8 @@ "width": 8, "nbrOfDevicesOnDIMM": 4, "nbrOfChannels": 2, - "cmdMode": 1 + "cmdMode": 1, + "refMode": 1 }, "memoryId": "JEDEC_2x4x1Gbx8_DDR5-5600A", "memoryType": "DDR5", @@ -46,12 +47,16 @@ "FAW_dlr": 0, "WTR_L": 28, "WTR_S": 7, - "RFC_slr": 546, - "RFC_dlr": 0, - "RFC_dpr": 0, + "RFC1_slr": 546, + "RFC2_slr": 364, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, "RFCsb_slr": 322, "RFCsb_dlr": 0, - "REFI": 10920, + "REFI1": 10920, + "REFI2": 5460, "REFISB": 2730, "REFSBRD_slr": 84, "REFSBRD_dlr": 0, diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json index 878a99ec..9e387dc4 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json @@ -14,7 +14,8 @@ "width": 8, "nbrOfDevicesOnDIMM": 4, "nbrOfChannels": 2, - "cmdMode": 1 + "cmdMode": 1, + "refMode": 1 }, "memoryId": "JEDEC_2x4x1Gbx8_DDR5-6000A", "memoryType": "DDR5", @@ -46,12 +47,16 @@ "FAW_dlr": 0, "WTR_L": 30, "WTR_S": 8, - "RFC_slr": 585, - "RFC_dlr": 0, - "RFC_dpr": 0, + "RFC1_slr": 585, + "RFC2_slr": 390, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, "RFCsb_slr": 345, "RFCsb_dlr": 0, - "REFI": 11700, + "REFI1": 11700, + "REFI2": 5850, "REFISB": 2925, "REFSBRD_slr": 90, "REFSBRD_dlr": 0, diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json index 6f291b49..18caa618 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json @@ -14,7 +14,8 @@ "width": 8, "nbrOfDevicesOnDIMM": 4, "nbrOfChannels": 2, - "cmdMode": 1 + "cmdMode": 1, + "refMode": 1 }, "memoryId": "JEDEC_2x4x1Gbx8_DDR5-6400A", "memoryType": "DDR5", @@ -46,12 +47,16 @@ "FAW_dlr": 0, "WTR_L": 32, "WTR_S": 8, - "RFC_slr": 624, - "RFC_dlr": 0, - "RFC_dpr": 0, + "RFC1_slr": 624, + "RFC2_slr": 416, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, "RFCsb_slr": 368, "RFCsb_dlr": 0, - "REFI": 12480, + "REFI1": 12480, + "REFI2": 6240, "REFISB": 3120, "REFSBRD_slr": 96, "REFSBRD_dlr": 0, diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json index 3de8ce00..d4d61219 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json @@ -14,7 +14,8 @@ "width": 4, "nbrOfDevicesOnDIMM": 8, "nbrOfChannels": 2, - "cmdMode": 1 + "cmdMode": 1, + "refMode": 1 }, "memoryId": "JEDEC_2x8x8x8Gbx4_DDR5-3200A_4bit", "memoryType": "DDR5", @@ -46,12 +47,16 @@ "FAW_dlr": 16, "WTR_L": 16, "WTR_S": 4, - "RFC_slr": 312, - "RFC_dlr": 104, - "RFC_dpr": 104, + "RFC1_slr": 312, + "RFC2_slr": 208, + "RFC1_dlr": 104, + "RFC2_dlr": 70, + "RFC1_dpr": 104, + "RFC2_dpr": 70, "RFCsb_slr": 184, "RFCsb_dlr": 62, - "REFI": 6240, + "REFI1": 6240, + "REFI2": 3120, "REFISB": 1560, "REFSBRD_slr": 48, "REFSBRD_dlr": 24, diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x2Gbx4_DDR5-3200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x2Gbx4_DDR5-3200A.json index 95886d86..315fb976 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x2Gbx4_DDR5-3200A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x2Gbx4_DDR5-3200A.json @@ -14,7 +14,8 @@ "width": 4, "nbrOfDevicesOnDIMM": 8, "nbrOfChannels": 2, - "cmdMode": 1 + "cmdMode": 1, + "refMode": 1 }, "memoryId": "JEDEC_2x8x8x8Gbx4_DDR5-3200A_4bit", "memoryType": "DDR5", @@ -46,12 +47,16 @@ "FAW_dlr": 16, "WTR_L": 16, "WTR_S": 4, - "RFC_slr": 312, - "RFC_dlr": 104, - "RFC_dpr": 104, + "RFC1_slr": 312, + "RFC2_slr": 208, + "RFC1_dlr": 104, + "RFC2_dlr": 70, + "RFC1_dpr": 104, + "RFC2_dpr": 70, "RFCsb_slr": 184, "RFCsb_dlr": 62, - "REFI": 6240, + "REFI1": 6240, + "REFI2": 3120, "REFISB": 1560, "REFSBRD_slr": 48, "REFSBRD_dlr": 24, diff --git a/DRAMSys/library/resources/simulations/ddr5-example.json b/DRAMSys/library/resources/simulations/ddr5-example.json index e85d1b92..8b66eaa6 100644 --- a/DRAMSys/library/resources/simulations/ddr5-example.json +++ b/DRAMSys/library/resources/simulations/ddr5-example.json @@ -1,8 +1,8 @@ { "simulation": { - "addressmapping": "am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json", + "addressmapping": "am_ddr5_2x4x1Gbx8_dimm_p1KB_rbc.json", "mcconfig": "fr_fcfs.json", - "memspec": "JEDEC_2x8x2Gbx4_DDR5-3200A.json", + "memspec": "JEDEC_2x4x1Gbx8_DDR5-3200A.json", "simconfig": "ddr5.json", "simulationid": "ddr5-example", "thermalconfig": "config.json", diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp index 19b5e65f..9a4892cf 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp @@ -58,6 +58,7 @@ MemSpecDDR5::MemSpecDDR5(json &memspec) logicalRanksPerPhysicalRank(parseUint(memspec["memarchitecturespec"]["nbrOfLogicalRanks"], "nbrOfLogicalRanks")), numberOfLogicalRanks(logicalRanksPerPhysicalRank * numberOfPhysicalRanks), cmdMode(parseUint(memspec["memarchitecturespec"]["cmdMode"], "cmdMode")), + refMode(parseUint(memspec["memarchitecturespec"]["refMode"], "refMode")), tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")), tPPD (tCK * parseUint(memspec["memtimingspec"]["PPD"], "PPD")), tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), @@ -86,12 +87,16 @@ MemSpecDDR5::MemSpecDDR5(json &memspec) tFAW_dlr (tCK * parseUint(memspec["memtimingspec"]["FAW_dlr"], "FAW_dlr")), tWTR_L (tCK * parseUint(memspec["memtimingspec"]["WTR_L"], "WTR_L")), tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")), - tRFC_slr (tCK * parseUint(memspec["memtimingspec"]["RFC_slr"], "RFC_slr")), - tRFC_dlr (tCK * parseUint(memspec["memtimingspec"]["RFC_dlr"], "RFC_dlr")), - tRFC_dpr (tCK * parseUint(memspec["memtimingspec"]["RFC_dpr"], "RFC_dpr")), + tRFC_slr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_slr"], "RFC1_slr") + : tCK * parseUint(memspec["memtimingspec"]["RFC2_slr"], "RFC2_slr")), + tRFC_dlr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dlr"], "RFC1_dlr") + : tCK * parseUint(memspec["memtimingspec"]["RFC2_dlr"], "RFC2_dlr")), + tRFC_dpr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dpr"], "RFC1_dpr") + : tCK * parseUint(memspec["memtimingspec"]["RFC2_dpr"], "RFC2_dpr")), tRFCsb_slr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_slr"], "RFCsb_slr")), tRFCsb_dlr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_dlr"], "RFCsb_dlr")), - tREFI (tCK * parseUint(memspec["memtimingspec"]["REFI"], "REFI")), + tREFI ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["REFI1"], "REFI1") + : tCK * parseUint(memspec["memtimingspec"]["REFI2"], "REFI2")), tREFIsb (tCK * parseUint(memspec["memtimingspec"]["REFISB"], "REFISB")), tREFSBRD_slr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_slr"], "REFSBRD_slr")), tREFSBRD_dlr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_dlr"], "REFSBRD_dlr")), @@ -134,6 +139,10 @@ MemSpecDDR5::MemSpecDDR5(json &memspec) } else SC_REPORT_FATAL("MemSpecDDR5", "Invalid command mode!"); + + if (!(refMode == 1 || refMode == 2)) + SC_REPORT_FATAL("MemSpecDDR5", "Invalid refresh mode! " + "Set 1 for normal or 2 for fine granularity refresh mode."); } sc_time MemSpecDDR5::getRefreshIntervalAB() const diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h index e6549d26..187fe07d 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h @@ -50,6 +50,7 @@ public: const unsigned logicalRanksPerPhysicalRank; const unsigned numberOfLogicalRanks; const unsigned cmdMode; + const unsigned refMode; // Memspec Variables: const sc_time tRCD; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp index 9cc326c4..305f9493 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerGroupwise.cpp @@ -66,8 +66,8 @@ RefreshManagerGroupwise::RefreshManagerGroupwise(std::vector &ban remainingBankMachines = allBankMachines; currentIterator = remainingBankMachines.begin(); - maxPostponed = config.refreshMaxPostponed * memSpec->banksPerGroup; - maxPulledin = -(config.refreshMaxPulledin * memSpec->banksPerGroup); + maxPostponed = static_cast(config.refreshMaxPostponed * memSpec->banksPerGroup); + maxPulledin = -static_cast(config.refreshMaxPulledin * memSpec->banksPerGroup); } std::tuple RefreshManagerGroupwise::getNextCommand() @@ -242,5 +242,7 @@ void RefreshManagerGroupwise::updateState(Command command) case Command::PDXA: case Command::PDXP: sleeping = false; break; + default: + break; } } From 280a0b5f662b46ab136139677e2c17c318fea109 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 2 Oct 2020 16:28:05 +0200 Subject: [PATCH 18/50] Set ddr5 example as default. --- DRAMSys/library/resources/simulations/ddr5-example.json | 4 ++-- DRAMSys/simulator/main.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DRAMSys/library/resources/simulations/ddr5-example.json b/DRAMSys/library/resources/simulations/ddr5-example.json index 8b66eaa6..e85d1b92 100644 --- a/DRAMSys/library/resources/simulations/ddr5-example.json +++ b/DRAMSys/library/resources/simulations/ddr5-example.json @@ -1,8 +1,8 @@ { "simulation": { - "addressmapping": "am_ddr5_2x4x1Gbx8_dimm_p1KB_rbc.json", + "addressmapping": "am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json", "mcconfig": "fr_fcfs.json", - "memspec": "JEDEC_2x4x1Gbx8_DDR5-3200A.json", + "memspec": "JEDEC_2x8x2Gbx4_DDR5-3200A.json", "simconfig": "ddr5.json", "simulationid": "ddr5-example", "thermalconfig": "config.json", diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index 7d29c614..f352ce25 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -74,7 +74,7 @@ int sc_main(int argc, char **argv) // Get path of resources: resources = pathOfFile(argv[0]) + std::string("/../../DRAMSys/library/resources/"); - simulationJson = resources + "simulations/ddr3-example.json"; + simulationJson = resources + "simulations/ddr5-example.json"; } // Run with specific config but default resource folders: else if (argc == 2) { From 0e06c54917effc69259778c013025f3c933df6fc Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 5 Oct 2020 14:11:56 +0200 Subject: [PATCH 19/50] Add more DDR5 memspecs. --- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json | 58 +++++++-------- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-3600A.json | 73 +++++++++++++++++++ .../memspecs/JEDEC_2x8x2Gbx4_DDR5-4000A.json | 73 +++++++++++++++++++ .../memspecs/JEDEC_2x8x2Gbx4_DDR5-4400A.json | 73 +++++++++++++++++++ .../memspecs/JEDEC_2x8x2Gbx4_DDR5-4800A.json | 73 +++++++++++++++++++ .../memspecs/JEDEC_2x8x2Gbx4_DDR5-5200A.json | 73 +++++++++++++++++++ .../memspecs/JEDEC_2x8x2Gbx4_DDR5-5600A.json | 73 +++++++++++++++++++ .../memspecs/JEDEC_2x8x2Gbx4_DDR5-6000A.json | 73 +++++++++++++++++++ .../memspecs/JEDEC_2x8x2Gbx4_DDR5-6400A.json | 73 +++++++++++++++++++ 9 files changed, 613 insertions(+), 29 deletions(-) create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3600A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4000A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4400A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4800A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5200A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5600A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6000A.json create mode 100644 DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6400A.json diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json index d4d61219..aa6e82b0 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json @@ -17,7 +17,7 @@ "cmdMode": 1, "refMode": 1 }, - "memoryId": "JEDEC_2x8x8x8Gbx4_DDR5-3200A_4bit", + "memoryId": "JEDEC_2x8x2Gbx4_DDR5-3200A", "memoryType": "DDR5", "memtimingspec": { "RCD": 22, @@ -33,41 +33,41 @@ "WPRE": 2, "WPST": 0, "WR": 48, - "CCD_L_slr": 8, + "CCD_L_slr": 8, "CCD_L_WR_slr": 32, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, - "CCD_dlr": 8, - "CCD_WR_dlr": 8, - "CCD_WR_dpr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, "RRD_L_slr": 8, - "RRD_S_slr": 8, - "RRD_dlr": 4, - "FAW_slr": 32, - "FAW_dlr": 16, - "WTR_L": 16, - "WTR_S": 4, - "RFC1_slr": 312, - "RFC2_slr": 208, - "RFC1_dlr": 104, - "RFC2_dlr": 70, - "RFC1_dpr": 104, - "RFC2_dpr": 70, - "RFCsb_slr": 184, - "RFCsb_dlr": 62, + "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, + "REFI2": 3120, "REFISB": 1560, - "REFSBRD_slr": 48, - "REFSBRD_dlr": 24, - "RTRS": 2, - "CPDED": 8, - "PD": 12, - "XP": 12, - "ACTPDEN": 2, - "PRPDEN": 2, + "REFSBRD_slr": 48, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 8, + "PD": 12, + "XP": 12, + "ACTPDEN": 2, + "PRPDEN": 2, "REFPDEN": 2, "clkMhz": 1600 } } -} +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3600A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3600A.json new file mode 100644 index 00000000..96359874 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3600A.json @@ -0,0 +1,73 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 2048, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 4, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 2, + "cmdMode": 1, + "refMode": 1 + }, + "memoryId": "JEDEC_2x8x2Gbx4_DDR5-3600A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 26, + "PPD": 2, + "RP": 26, + "RAS": 58, + "RL": 26, + "RTP": 14, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 24, + "WPRE": 2, + "WPST": 0, + "WR": 54, + "CCD_L_slr": 9, + "CCD_L_WR_slr": 36, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 9, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 18, + "WTR_S": 5, + "RFC1_slr": 351, + "RFC2_slr": 234, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, + "RFCsb_slr": 207, + "RFCsb_dlr": 0, + "REFI1": 7020, + "REFI2": 3510, + "REFISB": 1755, + "REFSBRD_slr": 54, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 9, + "PD": 14, + "XP": 14, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 1800 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4000A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4000A.json new file mode 100644 index 00000000..bf632566 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4000A.json @@ -0,0 +1,73 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 2048, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 4, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 2, + "cmdMode": 1, + "refMode": 1 + }, + "memoryId": "JEDEC_2x8x2Gbx4_DDR5-4000A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 28, + "PPD": 2, + "RP": 28, + "RAS": 64, + "RL": 28, + "RTP": 15, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 26, + "WPRE": 2, + "WPST": 0, + "WR": 60, + "CCD_L_slr": 10, + "CCD_L_WR_slr": 40, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 10, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 20, + "WTR_S": 5, + "RFC1_slr": 390, + "RFC2_slr": 260, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, + "RFCsb_slr": 230, + "RFCsb_dlr": 0, + "REFI1": 7800, + "REFI2": 3900, + "REFISB": 1950, + "REFSBRD_slr": 60, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 10, + "PD": 15, + "XP": 15, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 2000 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4400A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4400A.json new file mode 100644 index 00000000..a343598b --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4400A.json @@ -0,0 +1,73 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 2048, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 4, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 2, + "cmdMode": 1, + "refMode": 1 + }, + "memoryId": "JEDEC_2x8x2Gbx4_DDR5-4400A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 32, + "PPD": 2, + "RP": 32, + "RAS": 71, + "RL": 32, + "RTP": 17, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 30, + "WPRE": 2, + "WPST": 0, + "WR": 66, + "CCD_L_slr": 11, + "CCD_L_WR_slr": 44, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 11, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 22, + "WTR_S": 6, + "RFC_slr": 429, + "RFC_slr": 286, + "RFC_dlr": 0, + "RFC_dlr": 0, + "RFC_dpr": 0, + "RFC_dpr": 0, + "RFCsb_slr": 253, + "RFCsb_dlr": 0, + "REFI1": 8580, + "REFI2": 4290, + "REFISB": 2145, + "REFSBRD_slr": 66, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 11, + "PD": 17, + "XP": 17, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 2200 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4800A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4800A.json new file mode 100644 index 00000000..46998d40 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4800A.json @@ -0,0 +1,73 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 2048, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 4, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 2, + "cmdMode": 1, + "refMode": 1 + }, + "memoryId": "JEDEC_2x8x2Gbx4_DDR5-4800A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 34, + "PPD": 2, + "RP": 34, + "RAS": 77, + "RL": 34, + "RTP": 18, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 32, + "WPRE": 2, + "WPST": 0, + "WR": 72, + "CCD_L_slr": 12, + "CCD_L_WR_slr": 48, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 12, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 24, + "WTR_S": 6, + "RFC1_slr": 468, + "RFC2_slr": 312, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, + "RFCsb_slr": 276, + "RFCsb_dlr": 0, + "REFI1": 9360, + "REFI2": 4680, + "REFISB": 2340, + "REFSBRD_slr": 72, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 12, + "PD": 18, + "XP": 18, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 2400 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5200A.json new file mode 100644 index 00000000..18e6c093 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5200A.json @@ -0,0 +1,73 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 2048, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 4, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 2, + "cmdMode": 1, + "refMode": 1 + }, + "memoryId": "JEDEC_2x8x2Gbx4_DDR5-5200A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 38, + "PPD": 2, + "RP": 38, + "RAS": 84, + "RL": 38, + "RTP": 20, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 36, + "WPRE": 2, + "WPST": 0, + "WR": 78, + "CCD_L_slr": 13, + "CCD_L_WR_slr": 52, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 13, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 26, + "WTR_S": 7, + "RFC1_slr": 507, + "RFC2_slr": 338, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, + "RFCsb_slr": 299, + "RFCsb_dlr": 0, + "REFI1": 10140, + "REFI2": 5070, + "REFISB": 2535, + "REFSBRD_slr": 78, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 13, + "PD": 20, + "XP": 20, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 2600 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5600A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5600A.json new file mode 100644 index 00000000..4891bb1b --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5600A.json @@ -0,0 +1,73 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 2048, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 4, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 2, + "cmdMode": 1, + "refMode": 1 + }, + "memoryId": "JEDEC_2x8x2Gbx4_DDR5-5600A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 40, + "PPD": 2, + "RP": 40, + "RAS": 90, + "RL": 40, + "RTP": 21, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 38, + "WPRE": 2, + "WPST": 0, + "WR": 84, + "CCD_L_slr": 14, + "CCD_L_WR_slr": 56, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 14, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 28, + "WTR_S": 7, + "RFC1_slr": 546, + "RFC2_slr": 364, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, + "RFCsb_slr": 322, + "RFCsb_dlr": 0, + "REFI1": 10920, + "REFI2": 5460, + "REFISB": 2730, + "REFSBRD_slr": 84, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 14, + "PD": 21, + "XP": 21, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 2800 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6000A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6000A.json new file mode 100644 index 00000000..3e26408e --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6000A.json @@ -0,0 +1,73 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 2048, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 4, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 2, + "cmdMode": 1, + "refMode": 1 + }, + "memoryId": "JEDEC_2x8x2Gbx4_DDR5-6000A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 42, + "PPD": 2, + "RP": 42, + "RAS": 96, + "RL": 42, + "RTP": 23, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 40, + "WPRE": 2, + "WPST": 0, + "WR": 90, + "CCD_L_slr": 15, + "CCD_L_WR_slr": 60, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 15, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 30, + "WTR_S": 8, + "RFC1_slr": 585, + "RFC2_slr": 390, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, + "RFCsb_slr": 345, + "RFCsb_dlr": 0, + "REFI1": 11700, + "REFI2": 5850, + "REFISB": 2925, + "REFSBRD_slr": 90, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 15, + "PD": 23, + "XP": 23, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 3000 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6400A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6400A.json new file mode 100644 index 00000000..ca9eac9b --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6400A.json @@ -0,0 +1,73 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 16, + "dataRate": 2, + "nbrOfBankGroups": 8, + "nbrOfBanks": 16, + "nbrOfColumns": 2048, + "nbrOfRanks": 1, + "nbrOfDIMMRanks": 1, + "nbrOfPhysicalRanks": 1, + "nbrOfLogicalRanks": 1, + "nbrOfRows": 65536, + "width": 4, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 2, + "cmdMode": 1, + "refMode": 1 + }, + "memoryId": "JEDEC_2x8x2Gbx4_DDR5-6400A", + "memoryType": "DDR5", + "memtimingspec": { + "RCD": 46, + "PPD": 2, + "RP": 46, + "RAS": 103, + "RL": 46, + "RTP": 24, + "RPRE": 1, + "RPST": 0, + "RDDQS": 0, + "WL": 44, + "WPRE": 2, + "WPST": 0, + "WR": 96, + "CCD_L_slr": 16, + "CCD_L_WR_slr": 64, + "CCD_S_slr": 8, + "CCD_S_WR_slr": 8, + "CCD_dlr": 0, + "CCD_WR_dlr": 0, + "CCD_WR_dpr": 0, + "RRD_L_slr": 16, + "RRD_S_slr": 8, + "RRD_dlr": 0, + "FAW_slr": 32, + "FAW_dlr": 0, + "WTR_L": 32, + "WTR_S": 8, + "RFC1_slr": 624, + "RFC2_slr": 416, + "RFC1_dlr": 0, + "RFC2_dlr": 0, + "RFC1_dpr": 0, + "RFC2_dpr": 0, + "RFCsb_slr": 368, + "RFCsb_dlr": 0, + "REFI1": 12480, + "REFI2": 6240, + "REFISB": 3120, + "REFSBRD_slr": 96, + "REFSBRD_dlr": 0, + "RTRS": 2, + "CPDED": 16, + "PD": 24, + "XP": 24, + "ACTPDEN": 2, + "PRPDEN": 2, + "REFPDEN": 2, + "clkMhz": 3200 + } + } +} \ No newline at end of file From c79de8ac030634bf0241a737410e41b3b191b6a0 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 5 Oct 2020 16:06:06 +0200 Subject: [PATCH 20/50] Fix wrong DDR5 timing dependencies. --- DRAMSys/library/src/controller/Controller.cpp | 6 ++++ .../src/controller/checker/CheckerDDR5.cpp | 33 ++++++++++--------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 891e8c19..588587ff 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -300,6 +300,12 @@ void Controller::controllerMethod() for (auto it : bankMachinesOnRank[rank.ID()]) it->updateState(command); } + else if (isGroupCommand(command)) + { + for (unsigned bankID = (bank.ID() % memSpec->banksPerGroup); + bankID < memSpec->banksPerRank; bankID += memSpec->banksPerGroup) + bankMachinesOnRank[rank.ID()][bankID]->updateState(command); + } else bankMachines[bank.ID()]->updateState(command); diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index 9bf98143..c51b0a77 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -53,6 +53,7 @@ CheckerDDR5::CheckerDDR5() (numberOfCommands(), std::vector(memSpec->numberOfBanks)); lastScheduledByCommand = std::vector(numberOfCommands()); + // Required for Same Bank Refresh lastScheduledByCommandAndBankInGroup = std::vector> (numberOfCommands(), std::vector(memSpec->numberOfRanks * memSpec->banksPerGroup)); @@ -86,7 +87,7 @@ CheckerDDR5::CheckerDDR5() tWRPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset; tWRAPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset; - // TODO: tRTP BL 32!!! (check LPDDR4) + // TODO: tRTP BL 32 (similar to LPDDR4) } sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const @@ -98,7 +99,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr Rank physicalrank = Rank(logicalrank.ID() / memSpec->logicalRanksPerPhysicalRank); Rank dimmrank = Rank(physicalrank.ID() / memSpec->physicalRanksPerDIMMRank); - unsigned bankInGroupID = rank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup; + Bank bankInGroup = Bank(rank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup); if (command == Command::RD || command == Command::RDA) { @@ -205,7 +206,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr); lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -313,7 +314,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset); - lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroupID]; + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset); @@ -323,7 +324,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr // TODO: No tRFC_dlr and tRFC_dpr between REFA and ACT? - lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::REFSB][bankInGroupID]; + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::REFSB][bankInGroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - cmdOffset); @@ -405,23 +406,23 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr } else if (command == Command::PRESB) { - lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroupID]; + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RD][bankInGroupID]; + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RD][bankInGroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroupID]; + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WR][bankInGroupID]; + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WR][bankInGroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroupID]; + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK); @@ -469,12 +470,12 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr); - // REFSB tRFCsb + // REFSB tRFCsb_slr/dlr // PRESB tRP } else if (command == Command::REFSB) { - lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroupID]; + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK); @@ -482,21 +483,21 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroupID]; + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRE][bankInGroupID]; + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRE][bankInGroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); // PREA tRP - lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroupID]; + lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); From 24b46811c0b6e138d38c0f07f945865a1af7c77e Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 20 Oct 2020 14:29:28 +0200 Subject: [PATCH 21/50] Bugfix rank-to-rank dependencies. --- .../src/controller/checker/CheckerDDR5.cpp | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index c51b0a77..0f57b9a9 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -119,9 +119,10 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); - if (lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) + lastCommandStart = lastScheduledByCommand[Command::RD]; + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) { - if (lastScheduledByCommand[Command::RD] == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()]) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); @@ -139,9 +140,10 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); - if (lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) + lastCommandStart = lastScheduledByCommand[Command::RDA]; + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) { - if (lastScheduledByCommand[Command::RDA] == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()]) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); @@ -166,9 +168,10 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); - if (lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) + lastCommandStart = lastScheduledByCommand[Command::WR]; + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) { - if (lastScheduledByCommand[Command::WR] == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()]) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); @@ -186,9 +189,10 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); - if (lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) + lastCommandStart = lastScheduledByCommand[Command::WRA]; + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) { - if (lastScheduledByCommand[Command::WRA] == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()]) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); @@ -212,9 +216,10 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); - if (lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) + lastCommandStart = lastScheduledByCommand[Command::RD]; + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) { - if (lastScheduledByCommand[Command::RD] == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()]) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); @@ -232,9 +237,10 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); - if (lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) + lastCommandStart = lastScheduledByCommand[Command::RDA]; + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) { - if (lastScheduledByCommand[Command::RDA] == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()]) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); @@ -252,9 +258,10 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); - if (lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) + lastCommandStart = lastScheduledByCommand[Command::WR]; + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) { - if (lastScheduledByCommand[Command::WR] == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()]) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); @@ -272,9 +279,10 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); - if (lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) + lastCommandStart = lastScheduledByCommand[Command::WRA]; + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) { - if (lastScheduledByCommand[Command::WRA] == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()]) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); From 472c810f89cf87bbeac705ceda81fd6d93c7a2c1 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 22 Oct 2020 16:41:49 +0200 Subject: [PATCH 22/50] Add separate scheduler buffers (bankwise, separate read/write). --- DRAMSys/library/CMakeLists.txt | 4 ++ .../src/configuration/Configuration.cpp | 2 + .../library/src/configuration/Configuration.h | 1 + .../controller/scheduler/BufferBankwise.cpp | 58 ++++++++++++++++++ .../src/controller/scheduler/BufferBankwise.h | 56 ++++++++++++++++++ .../src/controller/scheduler/BufferIF.h | 48 +++++++++++++++ .../controller/scheduler/BufferReadWrite.cpp | 59 +++++++++++++++++++ .../controller/scheduler/BufferReadWrite.h | 54 +++++++++++++++++ .../controller/scheduler/SchedulerFifo.cpp | 44 ++++++++------ .../src/controller/scheduler/SchedulerFifo.h | 16 ++--- .../controller/scheduler/SchedulerFrFcfs.cpp | 51 ++++++++-------- .../controller/scheduler/SchedulerFrFcfs.h | 16 ++--- .../scheduler/SchedulerFrFcfsGrp.cpp | 49 ++++++++------- .../controller/scheduler/SchedulerFrFcfsGrp.h | 15 ++--- .../src/controller/scheduler/SchedulerIF.h | 9 +-- 15 files changed, 392 insertions(+), 90 deletions(-) create mode 100644 DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp create mode 100644 DRAMSys/library/src/controller/scheduler/BufferBankwise.h create mode 100644 DRAMSys/library/src/controller/scheduler/BufferIF.h create mode 100644 DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp create mode 100644 DRAMSys/library/src/controller/scheduler/BufferReadWrite.h diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index 5634ba6d..d88637a8 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -135,6 +135,10 @@ add_library(DRAMSysLibrary src/controller/scheduler/SchedulerFifo.cpp src/controller/scheduler/SchedulerFrFcfs.cpp src/controller/scheduler/SchedulerFrFcfsGrp.cpp + + src/controller/scheduler/BufferIF.h + src/controller/scheduler/BufferBankwise.cpp + src/controller/scheduler/BufferReadWrite.cpp src/error/eccbaseclass.cpp src/error/ecchamming.cpp diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 4a0b9645..144d2899 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -84,6 +84,8 @@ void Configuration::setParameter(std::string name, nlohmann::json value) pagePolicy = value; else if (name == "Scheduler") scheduler = value; + else if (name == "SchedulerBuffer") + schedulerBuffer = value; else if (name == "RequestBufferSize") requestBufferSize = value; else if (name == "CmdMux") diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index 75176ae5..fa18b382 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -71,6 +71,7 @@ public: // MCConfig: std::string pagePolicy = "Open"; std::string scheduler = "Fifo"; + std::string schedulerBuffer = "Bankwise"; std::string cmdMux = "Oldest"; std::string respQueue = "Fifo"; unsigned int requestBufferSize = 8; diff --git a/DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp b/DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp new file mode 100644 index 00000000..d73a3a58 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#include "BufferBankwise.h" +#include "../../common/dramExtensions.h" + +BufferBankwise::BufferBankwise(unsigned requestBufferSize, unsigned numberOfBanks) + : requestBufferSize(requestBufferSize) +{ + requestsOnBank = std::vector(numberOfBanks, 0); +} + +bool BufferBankwise::hasBufferSpace() const +{ + return (requestsOnBank[lastBankID] < requestBufferSize); +} + +void BufferBankwise::storeRequest(tlm::tlm_generic_payload *payload) +{ + lastBankID = DramExtension::getBank(payload).ID(); + requestsOnBank[lastBankID]++; +} + +void BufferBankwise::removeRequest(tlm::tlm_generic_payload *payload) +{ + requestsOnBank[DramExtension::getBank(payload).ID()]--; +} diff --git a/DRAMSys/library/src/controller/scheduler/BufferBankwise.h b/DRAMSys/library/src/controller/scheduler/BufferBankwise.h new file mode 100644 index 00000000..3fd63490 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferBankwise.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#ifndef BUFFERBANKWISE_H +#define BUFFERBANKWISE_H + +#include + +#include "BufferIF.h" + +class BufferBankwise : public BufferIF +{ +public: + BufferBankwise(unsigned requestBufferSize, unsigned numberOfBanks); + virtual bool hasBufferSpace() const override; + virtual void storeRequest(tlm::tlm_generic_payload *payload) override; + virtual void removeRequest(tlm::tlm_generic_payload *payload) override; + +private: + const unsigned requestBufferSize; + std::vector requestsOnBank; + unsigned lastBankID; +}; + +#endif // BUFFERBANKWISE_H diff --git a/DRAMSys/library/src/controller/scheduler/BufferIF.h b/DRAMSys/library/src/controller/scheduler/BufferIF.h new file mode 100644 index 00000000..6c8349ae --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferIF.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#ifndef BUFFERIF_H +#define BUFFERIF_H + +#include + +class BufferIF +{ +public: + virtual bool hasBufferSpace() const = 0; + virtual void storeRequest(tlm::tlm_generic_payload *payload) = 0; + virtual void removeRequest(tlm::tlm_generic_payload *payload) = 0; +}; + +#endif // BUFFERIF_H diff --git a/DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp b/DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp new file mode 100644 index 00000000..62fdf772 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#include "BufferReadWrite.h" + +BufferReadWrite::BufferReadWrite(unsigned requestBufferSize) + : requestBufferSize(requestBufferSize) {} + +bool BufferReadWrite::hasBufferSpace() const +{ + return (numberOfReads < requestBufferSize && numberOfWrites < requestBufferSize); +} + +void BufferReadWrite::storeRequest(tlm::tlm_generic_payload *payload) +{ + if (payload->is_read()) + numberOfReads++; + else + numberOfWrites++; +} + +void BufferReadWrite::removeRequest(tlm::tlm_generic_payload *payload) +{ + if (payload->is_read()) + numberOfReads--; + else + numberOfWrites--; +} diff --git a/DRAMSys/library/src/controller/scheduler/BufferReadWrite.h b/DRAMSys/library/src/controller/scheduler/BufferReadWrite.h new file mode 100644 index 00000000..32835c74 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferReadWrite.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#ifndef BUFFERREADWRITE_H +#define BUFFERREADWRITE_H + +#include "BufferIF.h" + +class BufferReadWrite : public BufferIF +{ +public: + BufferReadWrite(unsigned requestBufferSize); + virtual bool hasBufferSpace() const override; + virtual void storeRequest(tlm::tlm_generic_payload *payload) override; + virtual void removeRequest(tlm::tlm_generic_payload *payload) override; + +private: + const unsigned requestBufferSize; + unsigned numberOfReads = 0; + unsigned numberOfWrites = 0; +}; + +#endif // BUFFERREADWRITE_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp index f90c1c95..7b81977b 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp @@ -34,58 +34,64 @@ #include "SchedulerFifo.h" #include "../../configuration/Configuration.h" +#include "BufferBankwise.h" +#include "BufferReadWrite.h" using namespace tlm; SchedulerFifo::SchedulerFifo() { - buffer = std::vector> - (Configuration::getInstance().memSpec->numberOfBanks); - requestBufferSize = Configuration::getInstance().requestBufferSize; + Configuration &config = Configuration::getInstance(); + localBuffer = std::vector>(config.memSpec->numberOfBanks); + + if (config.schedulerBuffer == "Bankwise") + buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); + else if (Configuration::getInstance().schedulerBuffer == "ReadWrite") + buffer = new BufferReadWrite(config.requestBufferSize); + else + SC_REPORT_FATAL("Scheduler", "Unsupported scheduler buffer!"); } -bool SchedulerFifo::hasBufferSpace() +bool SchedulerFifo::hasBufferSpace() const { - if (buffer[lastBankID].size() < requestBufferSize) - return true; - else - return false; + return buffer->hasBufferSpace(); } void SchedulerFifo::storeRequest(tlm_generic_payload *payload) { - lastBankID = DramExtension::getBank(payload).ID(); - buffer[lastBankID].push_back(payload); + localBuffer[DramExtension::getBank(payload).ID()].push_back(payload); + buffer->storeRequest(payload); } void SchedulerFifo::removeRequest(tlm_generic_payload *payload) { - buffer[DramExtension::getBank(payload).ID()].pop_front(); + localBuffer[DramExtension::getBank(payload).ID()].pop_front(); + buffer->removeRequest(payload); } -tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) +tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) const { unsigned bankID = bankMachine->getBank().ID(); - if (!buffer[bankID].empty()) - return buffer[bankID].front(); + if (!localBuffer[bankID].empty()) + return localBuffer[bankID].front(); else return nullptr; } -bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) +bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) const { - if (buffer[bank.ID()].size() >= 2) + if (localBuffer[bank.ID()].size() >= 2) { - tlm_generic_payload *nextRequest = buffer[bank.ID()][1]; + tlm_generic_payload *nextRequest = localBuffer[bank.ID()][1]; if (DramExtension::getRow(nextRequest) == row) return true; } return false; } -bool SchedulerFifo::hasFurtherRequest(Bank bank) +bool SchedulerFifo::hasFurtherRequest(Bank bank) const { - if (buffer[bank.ID()].size() >= 2) + if (localBuffer[bank.ID()].size() >= 2) return true; else return false; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h index aacbb1e8..c34a095a 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h @@ -38,24 +38,26 @@ #include #include #include + #include "SchedulerIF.h" #include "../../common/dramExtensions.h" #include "../BankMachine.h" +#include "BufferIF.h" class SchedulerFifo : public SchedulerIF { public: SchedulerFifo(); - virtual bool hasBufferSpace() override; + virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *) override; virtual void removeRequest(tlm::tlm_generic_payload *) override; - virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) override; - virtual bool hasFurtherRowHit(Bank, Row) override; - virtual bool hasFurtherRequest(Bank) override; + virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; + virtual bool hasFurtherRowHit(Bank, Row) const override; + virtual bool hasFurtherRequest(Bank) const override; + private: - std::vector> buffer; - unsigned requestBufferSize; - unsigned lastBankID; + std::vector> localBuffer; + BufferIF *buffer; }; #endif // SCHEDULERFIFO_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index de91e8b4..e3b11ff0 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -33,72 +33,75 @@ */ #include "SchedulerFrFcfs.h" - #include "../../configuration/Configuration.h" -#include +#include "BufferBankwise.h" +#include "BufferReadWrite.h" using namespace tlm; SchedulerFrFcfs::SchedulerFrFcfs() { - buffer = std::vector> - (Configuration::getInstance().memSpec->numberOfBanks); - requestBufferSize = Configuration::getInstance().requestBufferSize; + Configuration &config = Configuration::getInstance(); + localBuffer = std::vector>(config.memSpec->numberOfBanks); + + if (config.schedulerBuffer == "Bankwise") + buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); + else if (Configuration::getInstance().schedulerBuffer == "ReadWrite") + buffer = new BufferReadWrite(config.requestBufferSize); + else + SC_REPORT_FATAL("Scheduler", "Unsupported scheduler buffer!"); } -bool SchedulerFrFcfs::hasBufferSpace() +bool SchedulerFrFcfs::hasBufferSpace() const { - if (buffer[lastBankID].size() < requestBufferSize) - return true; - else - return false; + return buffer->hasBufferSpace(); } void SchedulerFrFcfs::storeRequest(tlm_generic_payload *payload) { - lastBankID = DramExtension::getBank(payload).ID(); - buffer[lastBankID].push_back(payload); + localBuffer[DramExtension::getBank(payload).ID()].push_back(payload); + buffer->storeRequest(payload); } void SchedulerFrFcfs::removeRequest(tlm_generic_payload *payload) { + buffer->removeRequest(payload); unsigned bankID = DramExtension::getBank(payload).ID(); - for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) + for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) { if (*it == payload) { - buffer[bankID].erase(it); - return; + localBuffer[bankID].erase(it); + break; } } - SC_REPORT_FATAL("SchedulerFrFcfs", "removeRequest failed!"); } -tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) +tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) const { unsigned bankID = bankMachine->getBank().ID(); - if (!buffer[bankID].empty()) + if (!localBuffer[bankID].empty()) { if (bankMachine->getState() == BmState::Activated) { // Search for row hit Row openRow = bankMachine->getOpenRow(); - for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) + for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) { if (DramExtension::getRow(*it) == openRow) return *it; } } // No row hit found or bank precharged - return buffer[bankID].front(); + return localBuffer[bankID].front(); } return nullptr; } -bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) +bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) const { unsigned rowHitCounter = 0; - for (auto it = buffer[bank.ID()].begin(); it != buffer[bank.ID()].end(); it++) + for (auto it = localBuffer[bank.ID()].begin(); it != localBuffer[bank.ID()].end(); it++) { if (DramExtension::getRow(*it) == row) { @@ -110,7 +113,7 @@ bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) return false; } -bool SchedulerFrFcfs::hasFurtherRequest(Bank bank) +bool SchedulerFrFcfs::hasFurtherRequest(Bank bank) const { - return (buffer[bank.ID()].size() >= 2); + return (localBuffer[bank.ID()].size() >= 2); } diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h index 5d5347a4..d8413b2a 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h @@ -38,24 +38,26 @@ #include #include #include + #include "SchedulerIF.h" #include "../../common/dramExtensions.h" #include "../BankMachine.h" +#include "BufferIF.h" class SchedulerFrFcfs : public SchedulerIF { public: SchedulerFrFcfs(); - virtual bool hasBufferSpace() override; + virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *) override; virtual void removeRequest(tlm::tlm_generic_payload *) override; - virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) override; - virtual bool hasFurtherRowHit(Bank, Row) override; - virtual bool hasFurtherRequest(Bank) override; + virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; + virtual bool hasFurtherRowHit(Bank, Row) const override; + virtual bool hasFurtherRequest(Bank) const override; + private: - std::vector> buffer; - unsigned requestBufferSize; - unsigned lastBankID; + std::vector> localBuffer; + BufferIF *buffer; }; #endif // SCHEDULERFRFCFS_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp index 8af96e96..cebaf7fe 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp @@ -34,56 +34,61 @@ #include "SchedulerFrFcfsGrp.h" #include "../../configuration/Configuration.h" +#include "BufferBankwise.h" +#include "BufferReadWrite.h" using namespace tlm; SchedulerFrFcfsGrp::SchedulerFrFcfsGrp() { - buffer = std::vector> - (Configuration::getInstance().memSpec->numberOfBanks); - requestBufferSize = Configuration::getInstance().requestBufferSize; + Configuration &config = Configuration::getInstance(); + localBuffer = std::vector>(config.memSpec->numberOfBanks); + + if (config.schedulerBuffer == "Bankwise") + buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); + else if (Configuration::getInstance().schedulerBuffer == "ReadWrite") + buffer = new BufferReadWrite(config.requestBufferSize); + else + SC_REPORT_FATAL("Scheduler", "Unsupported scheduler buffer!"); } -bool SchedulerFrFcfsGrp::hasBufferSpace() +bool SchedulerFrFcfsGrp::hasBufferSpace() const { - if (buffer[lastBankID].size() < requestBufferSize) - return true; - else - return false; + return buffer->hasBufferSpace(); } void SchedulerFrFcfsGrp::storeRequest(tlm_generic_payload *payload) { - lastBankID = DramExtension::getBank(payload).ID(); - buffer[lastBankID].push_back(payload); + localBuffer[DramExtension::getBank(payload).ID()].push_back(payload); + buffer->storeRequest(payload); } void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload *payload) { + buffer->removeRequest(payload); lastCommand = payload->get_command(); unsigned bankID = DramExtension::getBank(payload).ID(); - for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) + for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) { if (*it == payload) { - buffer[bankID].erase(it); - return; + localBuffer[bankID].erase(it); + break; } } - SC_REPORT_FATAL("SchedulerFrFcfs", "removeRequest failed!"); } -tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine) +tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine) const { unsigned bankID = bankMachine->getBank().ID(); - if (!buffer[bankID].empty()) + if (!localBuffer[bankID].empty()) { if (bankMachine->getState() == BmState::Activated) { // Filter all row hits Row openRow = bankMachine->getOpenRow(); std::list rowHits; - for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) + for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) { if (DramExtension::getRow(*it) == openRow) rowHits.push_back(*it); @@ -113,15 +118,15 @@ tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine } } // No row hit found or bank precharged - return buffer[bankID].front(); + return localBuffer[bankID].front(); } return nullptr; } -bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) +bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) const { unsigned rowHitCounter = 0; - for (auto it = buffer[bank.ID()].begin(); it != buffer[bank.ID()].end(); it++) + for (auto it = localBuffer[bank.ID()].begin(); it != localBuffer[bank.ID()].end(); it++) { if (DramExtension::getRow(*it) == row) { @@ -133,9 +138,9 @@ bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) return false; } -bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank) +bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank) const { - if (buffer[bank.ID()].size() >= 2) + if (localBuffer[bank.ID()].size() >= 2) return true; else return false; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h index 34ca4472..af2e6ad4 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h @@ -42,22 +42,23 @@ #include "SchedulerIF.h" #include "../../common/dramExtensions.h" #include "../BankMachine.h" +#include "BufferIF.h" class SchedulerFrFcfsGrp : public SchedulerIF { public: SchedulerFrFcfsGrp(); - virtual bool hasBufferSpace() override; + virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *) override; virtual void removeRequest(tlm::tlm_generic_payload *) override; - virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) override; - virtual bool hasFurtherRowHit(Bank, Row) override; - virtual bool hasFurtherRequest(Bank) override; + virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; + virtual bool hasFurtherRowHit(Bank, Row) const override; + virtual bool hasFurtherRequest(Bank) const override; + private: - std::vector> buffer; - unsigned requestBufferSize; + std::vector> localBuffer; tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND; - unsigned lastBankID; + BufferIF *buffer; }; #endif // SCHEDULERFRFCFSGRP_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h index c069a5cb..f82ea208 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h @@ -36,6 +36,7 @@ #define SCHEDULERIF_H #include + #include "../../common/dramExtensions.h" #include "../../common/DebugManager.h" @@ -46,12 +47,12 @@ class SchedulerIF { public: virtual ~SchedulerIF() {} - virtual bool hasBufferSpace() = 0; + virtual bool hasBufferSpace() const = 0; virtual void storeRequest(tlm::tlm_generic_payload *) = 0; virtual void removeRequest(tlm::tlm_generic_payload *) = 0; - virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) = 0; - virtual bool hasFurtherRowHit(Bank, Row) = 0; - virtual bool hasFurtherRequest(Bank) = 0; + virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const = 0; + virtual bool hasFurtherRowHit(Bank, Row) const = 0; + virtual bool hasFurtherRequest(Bank) const = 0; }; #endif // SCHEDULERIF_H From 65d148b7a7d3326c9a5c80f0677bfd8bb674c473 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 23 Oct 2020 12:07:30 +0200 Subject: [PATCH 23/50] Improved configuration process. --- .../src/configuration/Configuration.cpp | 139 +++++++++++++----- .../library/src/configuration/Configuration.h | 18 +-- .../src/configuration/memspec/MemSpec.cpp | 4 +- .../src/configuration/memspec/MemSpec.h | 36 ++--- .../src/configuration/memspec/MemSpecDDR3.cpp | 2 +- .../src/configuration/memspec/MemSpecDDR4.cpp | 2 +- .../configuration/memspec/MemSpecGDDR5.cpp | 2 +- .../configuration/memspec/MemSpecGDDR5X.cpp | 2 +- .../configuration/memspec/MemSpecGDDR6.cpp | 2 +- .../src/configuration/memspec/MemSpecHBM2.cpp | 2 +- .../configuration/memspec/MemSpecLPDDR4.cpp | 2 +- .../configuration/memspec/MemSpecWideIO.cpp | 2 +- .../configuration/memspec/MemSpecWideIO2.cpp | 6 +- DRAMSys/library/src/controller/Controller.cpp | 62 ++++---- .../controller/scheduler/SchedulerFifo.cpp | 6 +- .../controller/scheduler/SchedulerFrFcfs.cpp | 6 +- .../scheduler/SchedulerFrFcfsGrp.cpp | 6 +- DRAMSys/library/src/simulation/DRAMSys.cpp | 49 +++--- .../src/simulation/DRAMSysRecordable.cpp | 52 ++++--- DRAMSys/library/src/simulation/dram/Dram.cpp | 23 +-- DRAMSys/library/src/simulation/dram/Dram.h | 2 +- .../library/src/simulation/dram/DramDDR3.cpp | 4 +- .../library/src/simulation/dram/DramDDR4.cpp | 4 +- .../library/src/simulation/dram/DramGDDR5.cpp | 2 +- .../src/simulation/dram/DramGDDR5X.cpp | 2 +- .../library/src/simulation/dram/DramGDDR6.cpp | 2 +- .../library/src/simulation/dram/DramHBM2.cpp | 2 +- .../src/simulation/dram/DramLPDDR4.cpp | 2 +- .../src/simulation/dram/DramWideIO.cpp | 10 +- .../src/simulation/dram/DramWideIO2.cpp | 2 +- DRAMSys/simulator/MemoryManager.cpp | 2 +- DRAMSys/simulator/TracePlayer.cpp | 2 +- 32 files changed, 247 insertions(+), 212 deletions(-) diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 144d2899..7e67a9f9 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -81,25 +81,86 @@ void Configuration::setParameter(std::string name, nlohmann::json value) { // MCConfig if (name == "PagePolicy") - pagePolicy = value; + { + if (value == "Open") + pagePolicy = PagePolicy::Open; + else if (value == "Closed") + pagePolicy = PagePolicy::Closed; + else if (value == "OpenAdaptive") + pagePolicy = PagePolicy::OpenAdaptive; + else if (value == "ClosedAdaptive") + pagePolicy = PagePolicy::ClosedAdaptive; + else + SC_REPORT_FATAL("Configuration", "Unsupported page policy!"); + } else if (name == "Scheduler") - scheduler = value; + { + if (value == "Fifo") + scheduler = Scheduler::Fifo; + else if (value == "FrFcfs") + scheduler = Scheduler::FrFcfs; + else if (value == "FrFcfsGrp") + scheduler = Scheduler::FrFcfsGrp; + else + SC_REPORT_FATAL("Configuration", "Unsupported scheduler!"); + } else if (name == "SchedulerBuffer") - schedulerBuffer = value; + { + if (value == "Bankwise") + schedulerBuffer = SchedulerBuffer::Bankwise; + else if (value == "ReadWrite") + schedulerBuffer = SchedulerBuffer::ReadWrite; + else + SC_REPORT_FATAL("Configuration", "Unsupported scheduler buffer!"); + } else if (name == "RequestBufferSize") + { requestBufferSize = value; + if (requestBufferSize == 0) + SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!"); + } else if (name == "CmdMux") - cmdMux = value; + { + if (value == "Oldest") + cmdMux = CmdMux::Oldest; + else if (value == "Strict") + cmdMux = CmdMux::Strict; + else + SC_REPORT_FATAL("Configuration", "Unsupported cmd mux!"); + } else if (name == "RespQueue") - respQueue = value; + { + if (value == "Fifo") + respQueue = RespQueue::Fifo; + else if (value == "Reorder") + respQueue = RespQueue::Reorder; + else + SC_REPORT_FATAL("Configuration", "Unsupported response queue!"); + } else if (name == "RefreshPolicy") - refreshPolicy = value; + { + if (value == "NoRefresh") + refreshPolicy = RefreshPolicy::NoRefresh; + else if (value == "Rankwise") + refreshPolicy = RefreshPolicy::Rankwise; + else if (value == "Bankwise") + refreshPolicy = RefreshPolicy::Bankwise; + else + SC_REPORT_FATAL("Configuration", "Unsupported refresh policy!"); + } else if (name == "RefreshMaxPostponed") refreshMaxPostponed = value; else if (name == "RefreshMaxPulledin") refreshMaxPulledin = value; else if (name == "PowerDownPolicy") - powerDownPolicy = value; + { + if (value == "NoPowerDown") + powerDownPolicy = PowerDownPolicy::NoPowerDown; + else if (value == "Staggered") + powerDownPolicy = PowerDownPolicy::Staggered; + else + SC_REPORT_FATAL("Configuration", "Unsupported power down policy!"); + } else if (name == "PowerDownTimeout") powerDownTimeout = value; //SimConfig------------------------------------------------ @@ -115,9 +176,7 @@ void Configuration::setParameter(std::string name, nlohmann::json value) { windowSize = value; if (windowSize == 0) - SC_REPORT_FATAL("Configuration", - ("Invalid value for parameter " + name + - ". This parameter must be at least one.").c_str()); + SC_REPORT_FATAL("Configuration", "Minimum window size is 1"); } else if (name == "Debug") debug = value; @@ -126,26 +185,37 @@ void Configuration::setParameter(std::string name, nlohmann::json value) else if (name == "SimulationProgressBar") simulationProgressBar = value; else if (name == "AddressOffset") - { -#ifdef DRAMSYS_GEM5 addressOffset = value; -#else - addressOffset = 0; -#endif - } else if (name == "UseMalloc") useMalloc = value; else if (name == "CheckTLM2Protocol") checkTLM2Protocol = value; else if (name == "ECCControllerMode") - ECCMode = value; + { + if (value == "Disabled") + eccMode = ECCMode::Disabled; + else if (value == "Hamming") + eccMode = ECCMode::Hamming; + else + SC_REPORT_FATAL("Configuration", "Unsupported ECC mode!"); + } // Specification for ErrorChipSeed, ErrorCSVFile path and StoreMode else if (name == "ErrorChipSeed") errorChipSeed = value; else if (name == "ErrorCSVFile") errorCSVFile = value; else if (name == "StoreMode") - storeMode = value; + { + if (value == "NoStorage") + storeMode = StoreMode::NoStorage; + else if (value == "Store") + storeMode = StoreMode::Store; + else if (value == "ErrorModel") + storeMode = StoreMode::ErrorModel; + else + SC_REPORT_FATAL("Configuration", "Unsupported store mode!"); + } + // Temperature Simulation related else if (name == "TemperatureScale") { @@ -192,7 +262,7 @@ void Configuration::setPathToResources(std::string path) std::uint64_t Configuration::getSimMemSizeInBytes() { // 1. Get number of banks, rows, columns and data width in bits for one die (or chip) - std::string type = memSpec->memoryType; + //std::string type = memSpec->memoryType; std::uint64_t ranks = memSpec->numberOfRanks; std::uint64_t bankgroups = memSpec->numberOfBankGroups; std::uint64_t banks = memSpec->numberOfBanks; @@ -209,7 +279,7 @@ std::uint64_t Configuration::getSimMemSizeInBytes() std::cout << headline << std::endl; std::cout << "Per Channel Configuration:" << std::endl << std::endl; - std::cout << " Memory type: " << type << std::endl; + std::cout << " Memory type: " << "dummy" << std::endl; std::cout << " Memory size in bytes: " << memorySize << std::endl; std::cout << " Number of ranks: " << ranks << std::endl; std::cout << " Number of bankgroups: " << bankgroups << std::endl; @@ -245,18 +315,13 @@ unsigned int Configuration::getBytesPerBurst() unsigned int Configuration::adjustNumBytesAfterECC(unsigned nBytes) { // Manipulate the number of bytes only if there is an ECC Controller selected - if (ECCMode == "Disabled") + if (eccMode == ECCMode::Disabled) return nBytes; - else if (ECCMode == "Hamming") + else // if (eccMode == ECCMode::Hamming) { assert(pECC != nullptr); return pECC->AllocationSize(nBytes); } - else - { - SC_REPORT_FATAL("Configuration", ("ECC mode " + ECCMode + " unsupported").c_str()); - return 0; - } } void Configuration::loadSimConfig(Configuration &config, std::string simconfigUri) @@ -287,25 +352,25 @@ void Configuration::loadMemSpec(Configuration &config, std::string memspecUri) json doc = parseJSON(memspecUri); json jMemSpec = doc["memspec"]; - std::string memoryType = jMemSpec["memoryType"]; + std::string stringMemoryType = jMemSpec["memoryType"]; - if (memoryType == "DDR3") + if (stringMemoryType == "DDR3") memSpec = new MemSpecDDR3(jMemSpec); - else if (memoryType == "DDR4") + else if (stringMemoryType == "DDR4") memSpec = new MemSpecDDR4(jMemSpec); - else if (memoryType == "LPDDR4") + else if (stringMemoryType == "LPDDR4") memSpec = new MemSpecLPDDR4(jMemSpec); - else if (memoryType == "WIDEIO_SDR") + else if (stringMemoryType == "WIDEIO_SDR") memSpec = new MemSpecWideIO(jMemSpec); - else if (memoryType == "WIDEIO2") + else if (stringMemoryType == "WIDEIO2") memSpec = new MemSpecWideIO2(jMemSpec); - else if (memoryType == "HBM2") + else if (stringMemoryType == "HBM2") memSpec = new MemSpecHBM2(jMemSpec); - else if (memoryType == "GDDR5") + else if (stringMemoryType == "GDDR5") memSpec = new MemSpecGDDR5(jMemSpec); - else if (memoryType == "GDDR5X") + else if (stringMemoryType == "GDDR5X") memSpec = new MemSpecGDDR5X(jMemSpec); - else if (memoryType == "GDDR6") + else if (stringMemoryType == "GDDR6") memSpec = new MemSpecGDDR6(jMemSpec); else SC_REPORT_FATAL("Configuration", "Unsupported DRAM type"); diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index fa18b382..e8521ec2 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -69,16 +69,16 @@ public: std::string pathToResources; // MCConfig: - std::string pagePolicy = "Open"; - std::string scheduler = "Fifo"; - std::string schedulerBuffer = "Bankwise"; - std::string cmdMux = "Oldest"; - std::string respQueue = "Fifo"; + enum class PagePolicy {Open, Closed, OpenAdaptive, ClosedAdaptive} pagePolicy; + enum class Scheduler {Fifo, FrFcfs, FrFcfsGrp} scheduler; + enum class SchedulerBuffer {Bankwise, ReadWrite} schedulerBuffer; + enum class CmdMux {Oldest, Strict} cmdMux; + enum class RespQueue {Fifo, Reorder} respQueue; unsigned int requestBufferSize = 8; - std::string refreshPolicy = "Rankwise"; + enum class RefreshPolicy {NoRefresh, Rankwise, Bankwise} refreshPolicy; unsigned int refreshMaxPostponed = 0; unsigned int refreshMaxPulledin = 0; - std::string powerDownPolicy = "NoPowerDown"; + enum class PowerDownPolicy {NoPowerDown, Staggered} powerDownPolicy; unsigned int powerDownTimeout = 3; // SimConfig @@ -91,7 +91,7 @@ public: bool thermalSimulation = false; bool simulationProgressBar = false; bool checkTLM2Protocol = false; - std::string ECCMode = "Disabled"; + enum class ECCMode {Disabled, Hamming} eccMode; ECCBaseClass *pECC = nullptr; bool gem5 = false; bool useMalloc = false; @@ -105,7 +105,7 @@ public: //Configs for Seed, csv file and StorageMode unsigned int errorChipSeed; std::string errorCSVFile = "not defined."; - std::string storeMode; + enum class StoreMode {NoStorage, Store, ErrorModel} storeMode; // Temperature Simulation related TemperatureSimConfig temperatureSim; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp index 39fd1211..4e0be58f 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp @@ -43,7 +43,7 @@ using namespace tlm; using json = nlohmann::json; -MemSpec::MemSpec(json &memspec, unsigned numberOfChannels, +MemSpec::MemSpec(json &memspec, MemoryType memoryType, unsigned numberOfChannels, unsigned numberOfRanks, unsigned banksPerRank, unsigned groupsPerRank, unsigned banksPerGroup, unsigned numberOfBanks, unsigned numberOfBankGroups, @@ -64,7 +64,7 @@ MemSpec::MemSpec(json &memspec, unsigned numberOfChannels, fCKMHz(parseUdouble(memspec["memtimingspec"]["clkMhz"], "clkMhz")), tCK(sc_time(1.0 / fCKMHz, SC_US)), memoryId(parseString(memspec["memoryId"], "memoryId")), - memoryType(parseString(memspec["memoryType"], "memoryType")), + memoryType(memoryType), burstDuration(tCK * (burstLength / dataRate)) { commandLengthInCycles = std::vector(numberOfCommands(), 1); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index 6f0fa875..76d7f19f 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -48,26 +48,26 @@ class MemSpec { public: - unsigned numberOfChannels; - unsigned numberOfRanks; - unsigned banksPerRank; - unsigned groupsPerRank; - unsigned banksPerGroup; - unsigned numberOfBanks; - unsigned numberOfBankGroups; - unsigned numberOfDevicesOnDIMM; - unsigned numberOfRows; - unsigned numberOfColumns; - unsigned burstLength; - unsigned dataRate; - unsigned bitWidth; + const unsigned numberOfChannels; + const unsigned numberOfRanks; + const unsigned banksPerRank; + const unsigned groupsPerRank; + const unsigned banksPerGroup; + const unsigned numberOfBanks; + const unsigned numberOfBankGroups; + const unsigned numberOfDevicesOnDIMM; + const unsigned numberOfRows; + const unsigned numberOfColumns; + const unsigned burstLength; + const unsigned dataRate; + const unsigned bitWidth; // Clock - double fCKMHz; - sc_time tCK; + const double fCKMHz; + const sc_time tCK; - std::string memoryId; - std::string memoryType; + const std::string memoryId; + const enum class MemoryType {DDR3, DDR4, LPDDR4, WideIO, WideIO2, GDDR5, GDDR5X, GDDR6, HBM2} memoryType; virtual ~MemSpec() {} @@ -80,7 +80,7 @@ public: sc_time getCommandLength(Command) const; protected: - MemSpec(nlohmann::json &memspec, unsigned numberOfChannels, + MemSpec(nlohmann::json &memspec, MemoryType memoryType, unsigned numberOfChannels, unsigned numberOfRanks, unsigned banksPerRank, unsigned groupsPerRank, unsigned banksPerGroup, unsigned numberOfBanks, unsigned numberOfBankGroups, diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp index 427c3f85..ecd04ec8 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecDDR3::MemSpecDDR3(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::DDR3, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp index d3bd513c..33d76ac9 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp @@ -40,7 +40,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecDDR4::MemSpecDDR4(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::DDR4, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp index 3ca42b65..fde667d4 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecGDDR5::MemSpecGDDR5(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::GDDR5, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp index e2fd9855..7d24eef8 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecGDDR5X::MemSpecGDDR5X(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::GDDR5X, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp index a1b6e4e3..493fb3d2 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecGDDR6::MemSpecGDDR6(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::GDDR6, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp index 784b4f99..4f0adcdc 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecHBM2::MemSpecHBM2(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::HBM2, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp index 915c14c4..801d8dbb 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecLPDDR4::MemSpecLPDDR4(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::LPDDR4, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp index 0d8b9be6..2f8e71cd 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecWideIO::MemSpecWideIO(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::WideIO, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp index b74129ba..addae394 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecWideIO2::MemSpecWideIO2(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::WideIO2, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), @@ -69,9 +69,9 @@ MemSpecWideIO2::MemSpecWideIO2(json &memspec) tWTR (tCK * parseUint(memspec["memtimingspec"]["WTR"], "WTR")), tRRD (tCK * parseUint(memspec["memtimingspec"]["RRD"], "RRD")), tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")), - tREFI (tCK * (unsigned)(parseUint(memspec["memtimingspec"]["REFI"], "REFI") + tREFI (tCK * static_cast(parseUint(memspec["memtimingspec"]["REFI"], "REFI") * parseUdouble(memspec["memtimingspec"]["REFM"], "REFM"))), - tREFIpb (tCK * (unsigned)(parseUint(memspec["memtimingspec"]["REFIPB"], "REFIPB") + tREFIpb (tCK * static_cast(parseUint(memspec["memtimingspec"]["REFIPB"], "REFIPB") * parseUdouble(memspec["memtimingspec"]["REFM"], "REFM"))), tRFCab (tCK * parseUint(memspec["memtimingspec"]["RFCAB"], "RFCAB")), tRFCpb (tCK * parseUint(memspec["memtimingspec"]["RFCPB"], "RFCPB")), diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 4176929e..ece6abce 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -75,74 +75,64 @@ Controller::Controller(sc_module_name name) : readyCommands.reserve(memSpec->numberOfBanks); // instantiate timing checker - if (memSpec->memoryType == "DDR3") + if (memSpec->memoryType == MemSpec::MemoryType::DDR3) checker = new CheckerDDR3(); - else if (memSpec->memoryType == "DDR4") + else if (memSpec->memoryType == MemSpec::MemoryType::DDR4) checker = new CheckerDDR4(); - else if (memSpec->memoryType == "WIDEIO_SDR") + else if (memSpec->memoryType == MemSpec::MemoryType::WideIO) checker = new CheckerWideIO(); - else if (memSpec->memoryType == "LPDDR4") + else if (memSpec->memoryType == MemSpec::MemoryType::LPDDR4) checker = new CheckerLPDDR4(); - else if (memSpec->memoryType == "WIDEIO2") + else if (memSpec->memoryType == MemSpec::MemoryType::WideIO2) checker = new CheckerWideIO2(); - else if (memSpec->memoryType == "HBM2") + else if (memSpec->memoryType == MemSpec::MemoryType::HBM2) checker = new CheckerHBM2(); - else if (memSpec->memoryType == "GDDR5") + else if (memSpec->memoryType == MemSpec::MemoryType::GDDR5) checker = new CheckerGDDR5(); - else if (memSpec->memoryType == "GDDR5X") + else if (memSpec->memoryType == MemSpec::MemoryType::GDDR5X) checker = new CheckerGDDR5X(); - else if (memSpec->memoryType == "GDDR6") + else if (memSpec->memoryType == MemSpec::MemoryType::GDDR6) checker = new CheckerGDDR6(); - else - SC_REPORT_FATAL("Controller", "Unsupported DRAM type!"); // instantiate scheduler and command mux - if (config.scheduler == "Fifo") + if (config.scheduler == Configuration::Scheduler::Fifo) scheduler = new SchedulerFifo(); - else if (config.scheduler == "FrFcfs") + else if (config.scheduler == Configuration::Scheduler::FrFcfs) scheduler = new SchedulerFrFcfs(); - else if (config.scheduler == "FrFcfsGrp") + else if (config.scheduler == Configuration::Scheduler::FrFcfsGrp) scheduler = new SchedulerFrFcfsGrp(); - else - SC_REPORT_FATAL("Controller", "Selected scheduler not supported!"); - if (config.cmdMux == "Oldest") + if (config.cmdMux == Configuration::CmdMux::Oldest) cmdMux = new CmdMuxOldest(); - else if (config.cmdMux == "Strict") + else if (config.cmdMux == Configuration::CmdMux::Strict) cmdMux = new CmdMuxStrict(); - else - SC_REPORT_FATAL("Controller", "Selected cmdmux not supported!"); - if (config.respQueue == "Fifo") + if (config.respQueue == Configuration::RespQueue::Fifo) respQueue = new RespQueueFifo(); - else if (config.respQueue == "Reorder") + else if (config.respQueue == Configuration::RespQueue::Reorder) respQueue = new RespQueueReorder(); - else - SC_REPORT_FATAL("Controller", "Selected respqueue not supported!"); // instantiate bank machines (one per bank) - if (config.pagePolicy == "Open") + if (config.pagePolicy == Configuration::PagePolicy::Open) { for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++) bankMachines.push_back(new BankMachineOpen(scheduler, checker, Bank(bankID))); } - else if (config.pagePolicy == "OpenAdaptive") + else if (config.pagePolicy == Configuration::PagePolicy::OpenAdaptive) { for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++) bankMachines.push_back(new BankMachineOpenAdaptive(scheduler, checker, Bank(bankID))); } - else if (config.pagePolicy == "Closed") + else if (config.pagePolicy == Configuration::PagePolicy::Closed) { for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++) bankMachines.push_back(new BankMachineClosed(scheduler, checker, Bank(bankID))); } - else if (config.pagePolicy == "ClosedAdaptive") + else if (config.pagePolicy == Configuration::PagePolicy::ClosedAdaptive) { for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++) bankMachines.push_back(new BankMachineClosedAdaptive(scheduler, checker, Bank(bankID))); } - else - SC_REPORT_FATAL("Controller", "Selected page policy not supported!"); for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { @@ -151,7 +141,7 @@ Controller::Controller(sc_module_name name) : } // instantiate power-down managers (one per rank) - if (config.powerDownPolicy == "NoPowerDown") + if (config.powerDownPolicy == Configuration::PowerDownPolicy::NoPowerDown) { for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { @@ -159,7 +149,7 @@ Controller::Controller(sc_module_name name) : powerDownManagers.push_back(manager); } } - else if (config.powerDownPolicy == "Staggered") + else if (config.powerDownPolicy == Configuration::PowerDownPolicy::Staggered) { for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { @@ -167,16 +157,14 @@ Controller::Controller(sc_module_name name) : powerDownManagers.push_back(manager); } } - else - SC_REPORT_FATAL("Controller", "Selected power-down mode not supported!"); // instantiate refresh managers (one per rank) - if (config.refreshPolicy == "NoRefresh") + if (config.refreshPolicy == Configuration::RefreshPolicy::NoRefresh) { for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) refreshManagers.push_back(new RefreshManagerDummy()); } - else if (config.refreshPolicy == "Rankwise") + else if (config.refreshPolicy == Configuration::RefreshPolicy::Rankwise) { for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { @@ -185,7 +173,7 @@ Controller::Controller(sc_module_name name) : refreshManagers.push_back(manager); } } - else if (config.refreshPolicy == "Bankwise") + else if (config.refreshPolicy == Configuration::RefreshPolicy::Bankwise) { for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp index 7b81977b..ab9fa81e 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp @@ -44,12 +44,10 @@ SchedulerFifo::SchedulerFifo() Configuration &config = Configuration::getInstance(); localBuffer = std::vector>(config.memSpec->numberOfBanks); - if (config.schedulerBuffer == "Bankwise") + if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); - else if (Configuration::getInstance().schedulerBuffer == "ReadWrite") + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) buffer = new BufferReadWrite(config.requestBufferSize); - else - SC_REPORT_FATAL("Scheduler", "Unsupported scheduler buffer!"); } bool SchedulerFifo::hasBufferSpace() const diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index e3b11ff0..8c0b02c8 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -44,12 +44,10 @@ SchedulerFrFcfs::SchedulerFrFcfs() Configuration &config = Configuration::getInstance(); localBuffer = std::vector>(config.memSpec->numberOfBanks); - if (config.schedulerBuffer == "Bankwise") + if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); - else if (Configuration::getInstance().schedulerBuffer == "ReadWrite") + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) buffer = new BufferReadWrite(config.requestBufferSize); - else - SC_REPORT_FATAL("Scheduler", "Unsupported scheduler buffer!"); } bool SchedulerFrFcfs::hasBufferSpace() const diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp index cebaf7fe..b9cb739d 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp @@ -44,12 +44,10 @@ SchedulerFrFcfsGrp::SchedulerFrFcfsGrp() Configuration &config = Configuration::getInstance(); localBuffer = std::vector>(config.memSpec->numberOfBanks); - if (config.schedulerBuffer == "Bankwise") + if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); - else if (Configuration::getInstance().schedulerBuffer == "ReadWrite") + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) buffer = new BufferReadWrite(config.requestBufferSize); - else - SC_REPORT_FATAL("Scheduler", "Unsupported scheduler buffer!"); } bool SchedulerFrFcfsGrp::hasBufferSpace() const diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index f890734f..86a5a90c 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -183,24 +183,23 @@ void DRAMSys::instantiateModules(const std::string &pathToResources, // The first call to getInstance() creates the Temperature Controller. // The same instance will be accessed by all other modules. TemperatureController::getInstance(); + Configuration &config = Configuration::getInstance(); // Create new ECC Controller - if (Configuration::getInstance().ECCMode == "Hamming") + if (config.eccMode == Configuration::ECCMode::Hamming) ecc = new ECCHamming("ECCHamming"); - else if (Configuration::getInstance().ECCMode == "Disabled") + else if (config.eccMode == Configuration::ECCMode::Disabled) ecc = nullptr; - else - SC_REPORT_FATAL("DRAMSys", "Unsupported ECC mode"); // Save ECC Controller into the configuration struct to adjust it dynamically - Configuration::getInstance().pECC = ecc; + config.pECC = ecc; // Create arbiter arbiter = new Arbiter("arbiter", pathToResources + "configs/amconfigs/" + amconfig); // Create controllers and DRAMs - std::string memoryType = Configuration::getInstance().memSpec->memoryType; - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) + MemSpec::MemoryType memoryType = config.memSpec->memoryType; + for (size_t i = 0; i < config.memSpec->numberOfChannels; i++) { std::string str = "controller" + std::to_string(i); @@ -210,26 +209,24 @@ void DRAMSys::instantiateModules(const std::string &pathToResources, str = "dram" + std::to_string(i); Dram *dram; - if (memoryType == "DDR3") + if (memoryType == MemSpec::MemoryType::DDR3) dram = new DramDDR3(str.c_str()); - else if (memoryType == "WIDEIO_SDR") - dram = new DramWideIO(str.c_str()); - else if (memoryType == "DDR4") + else if (memoryType == MemSpec::MemoryType::DDR4) dram = new DramDDR4(str.c_str()); - else if (memoryType == "LPDDR4") + else if (memoryType == MemSpec::MemoryType::WideIO) + dram = new DramWideIO(str.c_str()); + else if (memoryType == MemSpec::MemoryType::LPDDR4) dram = new DramLPDDR4(str.c_str()); - else if (memoryType == "WIDEIO2") + else if (memoryType == MemSpec::MemoryType::WideIO2) dram = new DramWideIO2(str.c_str()); - else if (memoryType == "HBM2") + else if (memoryType == MemSpec::MemoryType::HBM2) dram = new DramHBM2(str.c_str()); - else if (memoryType == "GDDR5") + else if (memoryType == MemSpec::MemoryType::GDDR5) dram = new DramGDDR5(str.c_str()); - else if (memoryType == "GDDR5X") + else if (memoryType == MemSpec::MemoryType::GDDR5X) dram = new DramGDDR5X(str.c_str()); - else if (memoryType == "GDDR6") + else if (memoryType == MemSpec::MemoryType::GDDR6) dram = new DramGDDR6(str.c_str()); - else - SC_REPORT_FATAL("DRAMSys", "Unsupported DRAM type"); drams.push_back(dram); @@ -245,21 +242,21 @@ void DRAMSys::instantiateModules(const std::string &pathToResources, void DRAMSys::bindSockets() { + Configuration &config = Configuration::getInstance(); + // If ECC Controller enabled, put it between Trace and arbiter - if (Configuration::getInstance().ECCMode == "Hamming") + if (config.eccMode == Configuration::ECCMode::Hamming) { assert(ecc != nullptr); tSocket.bind(ecc->t_socket); ecc->i_socket.bind(arbiter->tSocket); } - else if (Configuration::getInstance().ECCMode == "Disabled") + else if (config.eccMode == Configuration::ECCMode::Disabled) tSocket.bind(arbiter->tSocket); - else - SC_REPORT_FATAL("DRAMSys", "Unsupported ECC mode"); - if (Configuration::getInstance().checkTLM2Protocol) + if (config.checkTLM2Protocol) { - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) + for (size_t i = 0; i < config.memSpec->numberOfChannels; i++) { arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); controllersTlmCheckers[i]->initiator_socket.bind(controllers[i]->tSocket); @@ -268,7 +265,7 @@ void DRAMSys::bindSockets() } else { - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) + for (size_t i = 0; i < config.memSpec->numberOfChannels; i++) { arbiter->iSocket.bind(controllers[i]->tSocket); controllers[i]->iSocket.bind(drams[i]->tSocket); diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp index 93b92a33..57a97ff3 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp @@ -120,27 +120,27 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, // The same instance will be accessed by all other modules. TemperatureController::getInstance(); + Configuration &config = Configuration::getInstance(); + // Create and properly initialize TLM recorders. // They need to be ready before creating some modules. setupTlmRecorders(traceName, pathToResources); // Create new ECC Controller - if (Configuration::getInstance().ECCMode == "Hamming") + if (config.eccMode == Configuration::ECCMode::Hamming) ecc = new ECCHamming("ECCHamming"); - else if (Configuration::getInstance().ECCMode == "Disabled") + else if (config.eccMode == Configuration::ECCMode::Disabled) ecc = nullptr; - else - SC_REPORT_FATAL("DRAMSys", "Unsupported ECC mode"); // Save ECC Controller into the configuration struct to adjust it dynamically - Configuration::getInstance().pECC = ecc; + config.pECC = ecc; // Create arbiter arbiter = new Arbiter("arbiter", pathToResources + "configs/amconfigs/" + amconfig); // Create controllers and DRAMs - std::string memoryType = Configuration::getInstance().memSpec->memoryType; - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) + MemSpec::MemoryType memoryType = config.memSpec->memoryType; + for (size_t i = 0; i < config.memSpec->numberOfChannels; i++) { std::string str = "controller" + std::to_string(i); @@ -150,30 +150,28 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, str = "dram" + std::to_string(i); Dram *dram; - if (memoryType == "DDR3") + if (memoryType == MemSpec::MemoryType::DDR3) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "WIDEIO_SDR") - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "DDR4") + else if (memoryType == MemSpec::MemoryType::DDR4) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "LPDDR4") + else if (memoryType == MemSpec::MemoryType::WideIO) + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == MemSpec::MemoryType::LPDDR4) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "WIDEIO2") + else if (memoryType == MemSpec::MemoryType::WideIO2) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "HBM2") + else if (memoryType == MemSpec::MemoryType::HBM2) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "GDDR5") + else if (memoryType == MemSpec::MemoryType::GDDR5) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "GDDR5X") + else if (memoryType == MemSpec::MemoryType::GDDR5X) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "GDDR6") + else if (memoryType == MemSpec::MemoryType::GDDR6) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else - SC_REPORT_FATAL("DRAMSys", "Unsupported DRAM type"); drams.push_back(dram); - if (Configuration::getInstance().checkTLM2Protocol) + if (config.checkTLM2Protocol) { str = "TLMCheckerController" + std::to_string(i); tlm_utils::tlm2_base_protocol_checker<> *controllerTlmChecker = @@ -185,21 +183,21 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, void DRAMSysRecordable::bindSockets() { + Configuration &config = Configuration::getInstance(); + // If ECC Controller enabled, put it between Trace and arbiter - if (Configuration::getInstance().ECCMode == "Hamming") + if (config.eccMode == Configuration::ECCMode::Hamming) { assert(ecc != nullptr); tSocket.bind(ecc->t_socket); ecc->i_socket.bind(arbiter->tSocket); } - else if (Configuration::getInstance().ECCMode == "Disabled") + else if (config.eccMode == Configuration::ECCMode::Disabled) tSocket.bind(arbiter->tSocket); - else - SC_REPORT_FATAL("DRAMSys", "Unsupported ECC mode"); - if (Configuration::getInstance().checkTLM2Protocol) + if (config.checkTLM2Protocol) { - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) + for (size_t i = 0; i < config.memSpec->numberOfChannels; i++) { arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); controllersTlmCheckers[i]->initiator_socket.bind(controllers[i]->tSocket); @@ -208,7 +206,7 @@ void DRAMSysRecordable::bindSockets() } else { - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) + for (size_t i = 0; i < config.memSpec->numberOfChannels; i++) { arbiter->iSocket.bind(controllers[i]->tSocket); controllers[i]->iSocket.bind(drams[i]->tSocket); diff --git a/DRAMSys/library/src/simulation/dram/Dram.cpp b/DRAMSys/library/src/simulation/dram/Dram.cpp index 8238195c..9164745a 100644 --- a/DRAMSys/library/src/simulation/dram/Dram.cpp +++ b/DRAMSys/library/src/simulation/dram/Dram.cpp @@ -69,19 +69,12 @@ Dram::Dram(sc_module_name name) : sc_module(name), tSocket("socket") // Adjust number of bytes per burst dynamically to the selected ecc controller bytesPerBurst = config.adjustNumBytesAfterECC(bytesPerBurst); - if (config.storeMode == "NoStorage") - storeMode = StorageMode::NoStorage; - else if (config.storeMode == "Store") - storeMode = StorageMode::Store; - else if (config.storeMode == "ErrorModel") - storeMode = StorageMode::ErrorModel; - else - SC_REPORT_FATAL(this->name(), "Unsupported storage mode"); + storeMode = config.storeMode; - uint64_t memorySize = Configuration::getInstance().getSimMemSizeInBytes(); - if (storeMode == StorageMode::Store) + uint64_t memorySize = config.getSimMemSizeInBytes(); + if (storeMode == Configuration::StoreMode::Store) { - if (Configuration::getInstance().useMalloc) + if (config.useMalloc) { memory = (unsigned char *)malloc(memorySize); if (!memory) @@ -151,7 +144,7 @@ tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload &payload, DRAMPower->doCommand(phaseToDRAMPowerCommand(phase), bank, cycle); } - if (storeMode == StorageMode::Store) + if (storeMode == Configuration::StoreMode::Store) { if (phase == BEGIN_RD || phase == BEGIN_RDA) { @@ -173,7 +166,7 @@ unsigned int Dram::transport_dbg(tlm_generic_payload &trans) PRINTDEBUGMESSAGE(name(), "transport_dgb"); // TODO: This part is not tested yet, neither with traceplayers nor with GEM5 coupling - if (storeMode == StorageMode::NoStorage) + if (storeMode == Configuration::StoreMode::NoStorage) { SC_REPORT_FATAL("DRAM", "Debug Transport is used in combination with NoStorage"); @@ -190,7 +183,7 @@ unsigned int Dram::transport_dbg(tlm_generic_payload &trans) if (cmd == TLM_READ_COMMAND) { - if (storeMode == StorageMode::Store) + if (storeMode == Configuration::StoreMode::Store) { // Use Storage unsigned char *phyAddr = memory + trans.get_address(); memcpy(ptr, phyAddr, trans.get_data_length()); @@ -203,7 +196,7 @@ unsigned int Dram::transport_dbg(tlm_generic_payload &trans) } else if (cmd == TLM_WRITE_COMMAND) { - if (storeMode == StorageMode::Store) + if (storeMode == Configuration::StoreMode::Store) { // Use Storage unsigned char *phyAddr = memory + trans.get_address(); memcpy(phyAddr, ptr, trans.get_data_length()); diff --git a/DRAMSys/library/src/simulation/dram/Dram.h b/DRAMSys/library/src/simulation/dram/Dram.h index d39d07b6..5716c667 100644 --- a/DRAMSys/library/src/simulation/dram/Dram.h +++ b/DRAMSys/library/src/simulation/dram/Dram.h @@ -60,7 +60,7 @@ protected: MemSpec *memSpec = Configuration::getInstance().memSpec; // Data Storage: - enum class StorageMode {NoStorage, Store, ErrorModel} storeMode; + Configuration::StoreMode storeMode; unsigned char *memory; diff --git a/DRAMSys/library/src/simulation/dram/DramDDR3.cpp b/DRAMSys/library/src/simulation/dram/DramDDR3.cpp index da039524..66e491df 100644 --- a/DRAMSys/library/src/simulation/dram/DramDDR3.cpp +++ b/DRAMSys/library/src/simulation/dram/DramDDR3.cpp @@ -44,7 +44,7 @@ using namespace DRAMPower; DramDDR3::DramDDR3(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramDDR3", "Error Model not supported for DDR3"); if (Configuration::getInstance().powerAnalysis) @@ -134,7 +134,7 @@ DramDDR3::DramDDR3(sc_module_name name) : Dram(name) MemorySpecification powerSpec; powerSpec.id = memSpec->memoryId; - powerSpec.memoryType = memSpec->memoryType; + powerSpec.memoryType = MemoryType::DDR3; powerSpec.memTimingSpec = memTimingSpec; powerSpec.memPowerSpec = memPowerSpec; powerSpec.memArchSpec = memArchSpec; diff --git a/DRAMSys/library/src/simulation/dram/DramDDR4.cpp b/DRAMSys/library/src/simulation/dram/DramDDR4.cpp index 751f4e30..82255616 100644 --- a/DRAMSys/library/src/simulation/dram/DramDDR4.cpp +++ b/DRAMSys/library/src/simulation/dram/DramDDR4.cpp @@ -44,7 +44,7 @@ using namespace DRAMPower; DramDDR4::DramDDR4(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramDDR4", "Error Model not supported for DDR4"); if (Configuration::getInstance().powerAnalysis) @@ -134,7 +134,7 @@ DramDDR4::DramDDR4(sc_module_name name) : Dram(name) MemorySpecification powerSpec; powerSpec.id = memSpec->memoryId; - powerSpec.memoryType = memSpec->memoryType; + powerSpec.memoryType = MemoryType::DDR4; powerSpec.memTimingSpec = memTimingSpec; powerSpec.memPowerSpec = memPowerSpec; powerSpec.memArchSpec = memArchSpec; diff --git a/DRAMSys/library/src/simulation/dram/DramGDDR5.cpp b/DRAMSys/library/src/simulation/dram/DramGDDR5.cpp index 552ff81d..e3fe6014 100644 --- a/DRAMSys/library/src/simulation/dram/DramGDDR5.cpp +++ b/DRAMSys/library/src/simulation/dram/DramGDDR5.cpp @@ -42,7 +42,7 @@ DramGDDR5::DramGDDR5(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramGDDR5", "Error Model not supported for GDDR5"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/library/src/simulation/dram/DramGDDR5X.cpp b/DRAMSys/library/src/simulation/dram/DramGDDR5X.cpp index 7db5f265..3c767638 100644 --- a/DRAMSys/library/src/simulation/dram/DramGDDR5X.cpp +++ b/DRAMSys/library/src/simulation/dram/DramGDDR5X.cpp @@ -42,7 +42,7 @@ DramGDDR5X::DramGDDR5X(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramGDDR5X", "Error Model not supported for GDDR5X"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/library/src/simulation/dram/DramGDDR6.cpp b/DRAMSys/library/src/simulation/dram/DramGDDR6.cpp index a144c211..24fbed6f 100644 --- a/DRAMSys/library/src/simulation/dram/DramGDDR6.cpp +++ b/DRAMSys/library/src/simulation/dram/DramGDDR6.cpp @@ -42,7 +42,7 @@ DramGDDR6::DramGDDR6(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramGDDR6", "Error Model not supported for GDDR6"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/library/src/simulation/dram/DramHBM2.cpp b/DRAMSys/library/src/simulation/dram/DramHBM2.cpp index a803d1a6..1dec6977 100644 --- a/DRAMSys/library/src/simulation/dram/DramHBM2.cpp +++ b/DRAMSys/library/src/simulation/dram/DramHBM2.cpp @@ -42,7 +42,7 @@ DramHBM2::DramHBM2(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramHBM2", "Error Model not supported for HBM2"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/library/src/simulation/dram/DramLPDDR4.cpp b/DRAMSys/library/src/simulation/dram/DramLPDDR4.cpp index de60b0da..503d2774 100644 --- a/DRAMSys/library/src/simulation/dram/DramLPDDR4.cpp +++ b/DRAMSys/library/src/simulation/dram/DramLPDDR4.cpp @@ -42,7 +42,7 @@ DramLPDDR4::DramLPDDR4(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramLPDDR4", "Error Model not supported for LPDDR4"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/library/src/simulation/dram/DramWideIO.cpp b/DRAMSys/library/src/simulation/dram/DramWideIO.cpp index eeb78d01..1f9b7a79 100644 --- a/DRAMSys/library/src/simulation/dram/DramWideIO.cpp +++ b/DRAMSys/library/src/simulation/dram/DramWideIO.cpp @@ -135,7 +135,7 @@ DramWideIO::DramWideIO(sc_module_name name) : Dram(name) MemorySpecification powerSpec; powerSpec.id = memSpec->memoryId; - powerSpec.memoryType = memSpec->memoryType; + powerSpec.memoryType = MemoryType::WIDEIO_SDR; powerSpec.memTimingSpec = memTimingSpec; powerSpec.memPowerSpec = memPowerSpec; powerSpec.memArchSpec = memArchSpec; @@ -143,7 +143,7 @@ DramWideIO::DramWideIO(sc_module_name name) : Dram(name) DRAMPower = new libDRAMPower(powerSpec, 0); // For each bank in a channel a error Model is created: - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) { for (unsigned i = 0; i < memSpec->numberOfBanks; i++) { @@ -156,7 +156,7 @@ DramWideIO::DramWideIO(sc_module_name name) : Dram(name) } else { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) { for (unsigned i = 0; i < memSpec->numberOfBanks; i++) { @@ -188,7 +188,7 @@ tlm_sync_enum DramWideIO::nb_transport_fw(tlm_generic_payload &payload, DRAMPower->doCommand(phaseToDRAMPowerCommand(phase), bank, cycle); } - if (storeMode == StorageMode::Store) + if (storeMode == Configuration::StoreMode::Store) { if (phase == BEGIN_RD || phase == BEGIN_RDA) { @@ -201,7 +201,7 @@ tlm_sync_enum DramWideIO::nb_transport_fw(tlm_generic_payload &payload, memcpy(phyAddr, payload.get_data_ptr(), payload.get_data_length()); } } - else if (storeMode == StorageMode::ErrorModel) + else if (storeMode == Configuration::StoreMode::ErrorModel) { unsigned bank = DramExtension::getExtension(payload).getBank().ID(); diff --git a/DRAMSys/library/src/simulation/dram/DramWideIO2.cpp b/DRAMSys/library/src/simulation/dram/DramWideIO2.cpp index aba04086..2dbce0cc 100644 --- a/DRAMSys/library/src/simulation/dram/DramWideIO2.cpp +++ b/DRAMSys/library/src/simulation/dram/DramWideIO2.cpp @@ -42,7 +42,7 @@ DramWideIO2::DramWideIO2(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramWideIO2", "Error Model not supported for WideIO2"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/simulator/MemoryManager.cpp b/DRAMSys/simulator/MemoryManager.cpp index 361b3f68..694dfc9c 100644 --- a/DRAMSys/simulator/MemoryManager.cpp +++ b/DRAMSys/simulator/MemoryManager.cpp @@ -44,7 +44,7 @@ using namespace tlm; MemoryManager::MemoryManager() : numberOfAllocations(0), numberOfFrees(0) { - if (Configuration::getInstance().storeMode == "NoStorage") + if (Configuration::getInstance().storeMode == Configuration::StoreMode::NoStorage) storageEnabled = false; else storageEnabled = true; diff --git a/DRAMSys/simulator/TracePlayer.cpp b/DRAMSys/simulator/TracePlayer.cpp index 69e8b16a..dfdcf848 100644 --- a/DRAMSys/simulator/TracePlayer.cpp +++ b/DRAMSys/simulator/TracePlayer.cpp @@ -49,7 +49,7 @@ TracePlayer::TracePlayer(sc_module_name name, TraceSetup *setup) : SC_METHOD(nextPayload); iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw); - if (Configuration::getInstance().storeMode == "NoStorage") + if (Configuration::getInstance().storeMode == Configuration::StoreMode::NoStorage) storageEnabled = false; else storageEnabled = true; From bfb5f16563fe0402a57e79efb604cb09b4447e57 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 23 Oct 2020 14:24:32 +0200 Subject: [PATCH 24/50] Move getSimMemSizeInBytes to memspec. --- .../src/configuration/Configuration.cpp | 38 ------------------- .../library/src/configuration/Configuration.h | 1 - .../src/configuration/memspec/MemSpec.cpp | 3 +- .../src/configuration/memspec/MemSpec.h | 5 ++- .../src/configuration/memspec/MemSpecDDR3.cpp | 24 ++++++++++++ .../src/configuration/memspec/MemSpecDDR3.h | 2 + .../src/configuration/memspec/MemSpecDDR4.cpp | 25 ++++++++++++ .../src/configuration/memspec/MemSpecDDR4.h | 2 + .../configuration/memspec/MemSpecGDDR5.cpp | 24 ++++++++++++ .../src/configuration/memspec/MemSpecGDDR5.h | 2 + .../configuration/memspec/MemSpecGDDR5X.cpp | 24 ++++++++++++ .../src/configuration/memspec/MemSpecGDDR5X.h | 2 + .../configuration/memspec/MemSpecGDDR6.cpp | 24 ++++++++++++ .../src/configuration/memspec/MemSpecGDDR6.h | 2 + .../src/configuration/memspec/MemSpecHBM2.cpp | 24 ++++++++++++ .../src/configuration/memspec/MemSpecHBM2.h | 2 + .../configuration/memspec/MemSpecLPDDR4.cpp | 23 +++++++++++ .../src/configuration/memspec/MemSpecLPDDR4.h | 2 + .../configuration/memspec/MemSpecWideIO.cpp | 23 +++++++++++ .../src/configuration/memspec/MemSpecWideIO.h | 2 + .../configuration/memspec/MemSpecWideIO2.cpp | 23 +++++++++++ .../configuration/memspec/MemSpecWideIO2.h | 2 + DRAMSys/library/src/simulation/dram/Dram.cpp | 2 +- 23 files changed, 239 insertions(+), 42 deletions(-) diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 7e67a9f9..4e91e4bc 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -258,44 +258,6 @@ void Configuration::setPathToResources(std::string path) temperatureSim.setPathToResources(path); } -// Returns the total memory size in bytes -std::uint64_t Configuration::getSimMemSizeInBytes() -{ - // 1. Get number of banks, rows, columns and data width in bits for one die (or chip) - //std::string type = memSpec->memoryType; - std::uint64_t ranks = memSpec->numberOfRanks; - std::uint64_t bankgroups = memSpec->numberOfBankGroups; - std::uint64_t banks = memSpec->numberOfBanks; - std::uint64_t rows = memSpec->numberOfRows; - std::uint64_t columns = memSpec->numberOfColumns; - std::uint64_t bitWidth = memSpec->bitWidth; - std::uint64_t devicesOnDIMM = memSpec->numberOfDevicesOnDIMM; - // 2. Calculate size of one DRAM chip in bits - std::uint64_t chipBitSize = banks * rows * columns * bitWidth; - // 3. Calculate size of one DRAM chip in bytes - std::uint64_t chipSize = chipBitSize / 8; - // 4. Total memory size in Bytes of one DIMM (with only support of 1 rank on a DIMM) - std::uint64_t memorySize = chipSize * memSpec->numberOfDevicesOnDIMM; - - std::cout << headline << std::endl; - std::cout << "Per Channel Configuration:" << std::endl << std::endl; - std::cout << " Memory type: " << "dummy" << std::endl; - std::cout << " Memory size in bytes: " << memorySize << std::endl; - std::cout << " Number of ranks: " << ranks << std::endl; - std::cout << " Number of bankgroups: " << bankgroups << std::endl; - std::cout << " Number of banks: " << banks << std::endl; - std::cout << " Number of rows: " << rows << std::endl; - std::cout << " Number of columns: " << columns << std::endl; - std::cout << " Chip data bus width: " << bitWidth << std::endl; - std::cout << " Chip size in bits: " << chipBitSize << std::endl; - std::cout << " Chip Size in bytes: " << chipSize << std::endl; - std::cout << " Devices/Chips on DIMM: " << devicesOnDIMM << std::endl; - std::cout << std::endl; - - assert(memorySize > 0); - return memorySize; -} - // Returns the width of the data bus. // All DRAM chips on a DIMM operate in lockstep, // which constituing aggregate data bus width = chip's bus width * # locksteep-operated chips diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index e8521ec2..cb490c68 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -110,7 +110,6 @@ public: // Temperature Simulation related TemperatureSimConfig temperatureSim; - std::uint64_t getSimMemSizeInBytes(); unsigned int getDataBusWidth(); unsigned int getBytesPerBurst(); unsigned int adjustNumBytesAfterECC(unsigned bytes); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp index 4e0be58f..eeb3c3ca 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp @@ -43,7 +43,8 @@ using namespace tlm; using json = nlohmann::json; -MemSpec::MemSpec(json &memspec, MemoryType memoryType, unsigned numberOfChannels, +MemSpec::MemSpec(json &memspec, MemoryType memoryType, + unsigned numberOfChannels, unsigned numberOfRanks, unsigned banksPerRank, unsigned groupsPerRank, unsigned banksPerGroup, unsigned numberOfBanks, unsigned numberOfBankGroups, diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index 76d7f19f..e90bfd79 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -79,8 +79,11 @@ public: sc_time getCommandLength(Command) const; + virtual uint64_t getSimMemSizeInBytes() const = 0; + protected: - MemSpec(nlohmann::json &memspec, MemoryType memoryType, unsigned numberOfChannels, + MemSpec(nlohmann::json &memspec, MemoryType memoryType, + unsigned numberOfChannels, unsigned numberOfRanks, unsigned banksPerRank, unsigned groupsPerRank, unsigned banksPerGroup, unsigned numberOfBanks, unsigned numberOfBankGroups, diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp index ecd04ec8..7986bf89 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp @@ -138,3 +138,27 @@ TimeInterval MemSpecDDR3::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecDDR3::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfDevicesOnDIMM * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "DDR3" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << " Devices on DIMM: " << numberOfDevicesOnDIMM << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h index f8a1d6de..618b65e8 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h @@ -92,6 +92,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECDDR3_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp index 33d76ac9..1912db8b 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp @@ -155,3 +155,28 @@ TimeInterval MemSpecDDR4::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecDDR4::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfDevicesOnDIMM * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "DDR4" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Bank groups per rank: " << groupsPerRank << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << " Devices on DIMM: " << numberOfDevicesOnDIMM << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h index 9395626c..1c3cd405 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h @@ -98,6 +98,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECDDR4_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp index fde667d4..f99ce411 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp @@ -142,3 +142,27 @@ TimeInterval MemSpecGDDR5::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecGDDR5::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "GDDR5" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Bank groups per rank: " << groupsPerRank << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h index 84e7113e..649eef2a 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h @@ -90,6 +90,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECGDDR5_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp index 7d24eef8..84f581fa 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp @@ -142,3 +142,27 @@ TimeInterval MemSpecGDDR5X::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecGDDR5X::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "GDDR5X" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Bank groups per rank: " << groupsPerRank << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h index f5d22239..77b3ca83 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h @@ -90,6 +90,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECGDDR5X_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp index 493fb3d2..4cde4e10 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp @@ -144,3 +144,27 @@ TimeInterval MemSpecGDDR6::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecGDDR6::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "GDDR6" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Bank groups per rank: " << groupsPerRank << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h index a4d2318d..c01326d1 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h @@ -92,6 +92,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECGDDR6_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp index 4f0adcdc..3f61973b 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp @@ -139,3 +139,27 @@ TimeInterval MemSpecHBM2::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecHBM2::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "HBM2" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Bank groups per rank: " << groupsPerRank << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h index a6885b49..50f49428 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h @@ -85,6 +85,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECHBM2_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp index 801d8dbb..ca0a2fc1 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp @@ -147,3 +147,26 @@ TimeInterval MemSpecLPDDR4::getIntervalOnDataStrobe(Command command) const } } +uint64_t MemSpecLPDDR4::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "GDDR5" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} + diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h index 26da297c..e4a3d1ec 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h @@ -85,6 +85,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECLPDDR4_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp index 2f8e71cd..fc52661d 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp @@ -146,3 +146,26 @@ TimeInterval MemSpecWideIO::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecWideIO::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "GDDR5" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h index 2ce092ff..e9d64690 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h @@ -98,6 +98,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECWIDEIO_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp index addae394..97006423 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp @@ -131,3 +131,26 @@ TimeInterval MemSpecWideIO2::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecWideIO2::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "GDDR5" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h index d56f9d30..3fb39da2 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h @@ -79,6 +79,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECWIDEIO2_H diff --git a/DRAMSys/library/src/simulation/dram/Dram.cpp b/DRAMSys/library/src/simulation/dram/Dram.cpp index 9164745a..f2b931b8 100644 --- a/DRAMSys/library/src/simulation/dram/Dram.cpp +++ b/DRAMSys/library/src/simulation/dram/Dram.cpp @@ -71,7 +71,7 @@ Dram::Dram(sc_module_name name) : sc_module(name), tSocket("socket") storeMode = config.storeMode; - uint64_t memorySize = config.getSimMemSizeInBytes(); + uint64_t memorySize = config.memSpec->getSimMemSizeInBytes(); if (storeMode == Configuration::StoreMode::Store) { if (config.useMalloc) From 7bab23f80e96551d10aa4c18addabd1949b662ce Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 23 Oct 2020 15:00:49 +0200 Subject: [PATCH 25/50] Move methods from config to memspec. --- DRAMSys/library/CMakeLists.txt | 2 +- .../library/src/configuration/Configuration.cpp | 15 --------------- DRAMSys/library/src/configuration/Configuration.h | 2 -- .../library/src/configuration/memspec/MemSpec.cpp | 2 ++ .../library/src/configuration/memspec/MemSpec.h | 5 +++-- DRAMSys/library/src/error/errormodel.cpp | 4 ++-- DRAMSys/library/src/error/errormodel.h | 2 +- .../src/{common => simulation}/AddressDecoder.cpp | 2 +- .../src/{common => simulation}/AddressDecoder.h | 0 DRAMSys/library/src/simulation/Arbiter.cpp | 2 +- DRAMSys/library/src/simulation/Arbiter.h | 2 +- DRAMSys/library/src/simulation/dram/Dram.h | 2 +- DRAMSys/simulator/MemoryManager.cpp | 2 +- DRAMSys/simulator/StlPlayer.cpp | 2 +- 14 files changed, 15 insertions(+), 29 deletions(-) rename DRAMSys/library/src/{common => simulation}/AddressDecoder.cpp (99%) rename DRAMSys/library/src/{common => simulation}/AddressDecoder.h (100%) diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index d88637a8..52fb81f1 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -78,7 +78,6 @@ if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src/common/third_party/sqlite-amalgamation) endif() add_library(DRAMSysLibrary - src/common/AddressDecoder.cpp src/common/DebugManager.cpp src/common/dramExtensions.cpp src/common/tlm2_base_protocol_checker.h @@ -149,6 +148,7 @@ add_library(DRAMSysLibrary src/error/ECC/Word.cpp src/simulation/Arbiter.cpp + src/simulation/AddressDecoder.cpp src/simulation/DRAMSys.cpp src/simulation/ReorderBuffer.h src/simulation/TemperatureController.cpp diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 4e91e4bc..c88f8def 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -258,21 +258,6 @@ void Configuration::setPathToResources(std::string path) temperatureSim.setPathToResources(path); } -// Returns the width of the data bus. -// All DRAM chips on a DIMM operate in lockstep, -// which constituing aggregate data bus width = chip's bus width * # locksteep-operated chips -// The bus width is given in bits, e.g., 64-bit data bus, 128-bit data bus, etc. -unsigned int Configuration::getDataBusWidth() -{ - return memSpec->bitWidth * memSpec->numberOfDevicesOnDIMM; -} - -// Returns the number of bytes transfered in a burst -unsigned int Configuration::getBytesPerBurst() -{ - return (memSpec->burstLength * getDataBusWidth()) / 8; -} - // Changes the number of bytes depeding on the ECC Controller. This function is needed for modules which get data directly or indirectly from the ECC Controller unsigned int Configuration::adjustNumBytesAfterECC(unsigned nBytes) { diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index cb490c68..a77a9fa1 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -110,8 +110,6 @@ public: // Temperature Simulation related TemperatureSimConfig temperatureSim; - unsigned int getDataBusWidth(); - unsigned int getBytesPerBurst(); unsigned int adjustNumBytesAfterECC(unsigned bytes); void setPathToResources(std::string path); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp index eeb3c3ca..9794a1ee 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp @@ -62,6 +62,8 @@ MemSpec::MemSpec(json &memspec, MemoryType memoryType, burstLength(parseUint(memspec["memarchitecturespec"]["burstLength"],"burstLength")), dataRate(parseUint(memspec["memarchitecturespec"]["dataRate"],"dataRate")), bitWidth(parseUint(memspec["memarchitecturespec"]["width"],"width")), + dataBusWidth(bitWidth * numberOfDevicesOnDIMM), + bytesPerBurst((burstLength * dataBusWidth) / 8), fCKMHz(parseUdouble(memspec["memtimingspec"]["clkMhz"], "clkMhz")), tCK(sc_time(1.0 / fCKMHz, SC_US)), memoryId(parseString(memspec["memoryId"], "memoryId")), diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index e90bfd79..3b3a2677 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -61,6 +61,8 @@ public: const unsigned burstLength; const unsigned dataRate; const unsigned bitWidth; + const unsigned dataBusWidth; + const unsigned bytesPerBurst; // Clock const double fCKMHz; @@ -78,8 +80,7 @@ public: virtual TimeInterval getIntervalOnDataStrobe(Command) const = 0; sc_time getCommandLength(Command) const; - - virtual uint64_t getSimMemSizeInBytes() const = 0; + virtual uint64_t getSimMemSizeInBytes() const = 0; protected: MemSpec(nlohmann::json &memspec, MemoryType memoryType, diff --git a/DRAMSys/library/src/error/errormodel.cpp b/DRAMSys/library/src/error/errormodel.cpp index 42e1d0d1..0195f194 100644 --- a/DRAMSys/library/src/error/errormodel.cpp +++ b/DRAMSys/library/src/error/errormodel.cpp @@ -36,7 +36,7 @@ #include "errormodel.h" #include "../common/DebugManager.h" #include "../simulation/TemperatureController.h" -#include "../common/AddressDecoder.h" +#include "../simulation/AddressDecoder.h" #include "../common/dramExtensions.h" #include @@ -51,7 +51,7 @@ void errorModel::init() // Get Configuration parameters: burstLenght = Configuration::getInstance().memSpec->burstLength; numberOfColumns = Configuration::getInstance().memSpec->numberOfColumns; - bytesPerColumn = std::log2(Configuration::getInstance().getDataBusWidth()); + bytesPerColumn = std::log2(Configuration::getInstance().memSpec->dataBusWidth); // Adjust number of bytes per column dynamically to the selected ecc controller bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC( diff --git a/DRAMSys/library/src/error/errormodel.h b/DRAMSys/library/src/error/errormodel.h index 99598d9c..99fdd034 100644 --- a/DRAMSys/library/src/error/errormodel.h +++ b/DRAMSys/library/src/error/errormodel.h @@ -40,7 +40,7 @@ #include #include #include "../configuration/Configuration.h" -#include "../common/AddressDecoder.h" +#include "../simulation/AddressDecoder.h" #include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h" class errorModel : public sc_module diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/simulation/AddressDecoder.cpp similarity index 99% rename from DRAMSys/library/src/common/AddressDecoder.cpp rename to DRAMSys/library/src/simulation/AddressDecoder.cpp index b6c9cdd4..f4bf0400 100644 --- a/DRAMSys/library/src/common/AddressDecoder.cpp +++ b/DRAMSys/library/src/simulation/AddressDecoder.cpp @@ -39,7 +39,7 @@ #include #include "AddressDecoder.h" -#include "utils.h" +#include "../common/utils.h" #include "../configuration/Configuration.h" using json = nlohmann::json; diff --git a/DRAMSys/library/src/common/AddressDecoder.h b/DRAMSys/library/src/simulation/AddressDecoder.h similarity index 100% rename from DRAMSys/library/src/common/AddressDecoder.h rename to DRAMSys/library/src/simulation/AddressDecoder.h diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 8ed91d8e..c95212cd 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -36,7 +36,7 @@ */ #include "Arbiter.h" -#include "../common/AddressDecoder.h" +#include "AddressDecoder.h" #include "../configuration/Configuration.h" using namespace tlm; diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index c2c83222..0919f9a9 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -47,7 +47,7 @@ #include #include #include -#include "../common/AddressDecoder.h" +#include "AddressDecoder.h" #include "../common/dramExtensions.h" class Arbiter : public sc_module diff --git a/DRAMSys/library/src/simulation/dram/Dram.h b/DRAMSys/library/src/simulation/dram/Dram.h index 5716c667..1d346e7a 100644 --- a/DRAMSys/library/src/simulation/dram/Dram.h +++ b/DRAMSys/library/src/simulation/dram/Dram.h @@ -50,7 +50,7 @@ class Dram : public sc_module { private: - unsigned int bytesPerBurst = Configuration::getInstance().getBytesPerBurst(); + unsigned int bytesPerBurst = Configuration::getInstance().memSpec->bytesPerBurst; bool powerReported = false; protected: diff --git a/DRAMSys/simulator/MemoryManager.cpp b/DRAMSys/simulator/MemoryManager.cpp index 694dfc9c..bfb64e82 100644 --- a/DRAMSys/simulator/MemoryManager.cpp +++ b/DRAMSys/simulator/MemoryManager.cpp @@ -80,7 +80,7 @@ tlm_generic_payload *MemoryManager::allocate() if (storageEnabled) { // Allocate a data buffer and initialize it with zeroes: - unsigned int dataLength = Configuration::getInstance().getBytesPerBurst(); + unsigned int dataLength = Configuration::getInstance().memSpec->bytesPerBurst; unsigned char *data = new unsigned char[dataLength]; std::fill(data, data + dataLength, 0); payload->set_data_ptr(data); diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index 4aa918ec..24fb7227 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -56,7 +56,7 @@ StlPlayer::StlPlayer(sc_module_name name, this->playerClk = playerClk; burstlength = Configuration::getInstance().memSpec->burstLength; - dataLength = Configuration::getInstance().getBytesPerBurst(); + dataLength = Configuration::getInstance().memSpec->bytesPerBurst; lineCnt = 0; currentBuffer->reserve(lineBufferSize); From e26a438d0624a6eb6f2ce9287dd97ca39bcac8da Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 23 Oct 2020 15:04:40 +0200 Subject: [PATCH 26/50] Code formatting. --- .../src/configuration/Configuration.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index c88f8def..3f6739dd 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -299,25 +299,25 @@ void Configuration::loadMemSpec(Configuration &config, std::string memspecUri) json doc = parseJSON(memspecUri); json jMemSpec = doc["memspec"]; - std::string stringMemoryType = jMemSpec["memoryType"]; + std::string memoryType = jMemSpec["memoryType"]; - if (stringMemoryType == "DDR3") + if (memoryType == "DDR3") memSpec = new MemSpecDDR3(jMemSpec); - else if (stringMemoryType == "DDR4") + else if (memoryType == "DDR4") memSpec = new MemSpecDDR4(jMemSpec); - else if (stringMemoryType == "LPDDR4") + else if (memoryType == "LPDDR4") memSpec = new MemSpecLPDDR4(jMemSpec); - else if (stringMemoryType == "WIDEIO_SDR") + else if (memoryType == "WIDEIO_SDR") memSpec = new MemSpecWideIO(jMemSpec); - else if (stringMemoryType == "WIDEIO2") + else if (memoryType == "WIDEIO2") memSpec = new MemSpecWideIO2(jMemSpec); - else if (stringMemoryType == "HBM2") + else if (memoryType == "HBM2") memSpec = new MemSpecHBM2(jMemSpec); - else if (stringMemoryType == "GDDR5") + else if (memoryType == "GDDR5") memSpec = new MemSpecGDDR5(jMemSpec); - else if (stringMemoryType == "GDDR5X") + else if (memoryType == "GDDR5X") memSpec = new MemSpecGDDR5X(jMemSpec); - else if (stringMemoryType == "GDDR6") + else if (memoryType == "GDDR6") memSpec = new MemSpecGDDR6(jMemSpec); else SC_REPORT_FATAL("Configuration", "Unsupported DRAM type"); From ffca62be7002ca67a94befe830d02321563d791b Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 26 Oct 2020 09:05:50 +0100 Subject: [PATCH 27/50] Renaming scheduler buffer to buffer counter. --- ...Bankwise.cpp => BufferCounterBankwise.cpp} | 10 +++--- ...fferBankwise.h => BufferCounterBankwise.h} | 12 +++---- .../{BufferIF.h => BufferCounterIF.h} | 8 ++--- ...adWrite.cpp => BufferCounterReadWrite.cpp} | 10 +++--- ...erReadWrite.h => BufferCounterReadWrite.h} | 12 +++---- .../controller/scheduler/SchedulerFifo.cpp | 30 ++++++++--------- .../src/controller/scheduler/SchedulerFifo.h | 6 ++-- .../controller/scheduler/SchedulerFrFcfs.cpp | 32 +++++++++---------- .../controller/scheduler/SchedulerFrFcfs.h | 6 ++-- .../scheduler/SchedulerFrFcfsGrp.cpp | 32 +++++++++---------- .../controller/scheduler/SchedulerFrFcfsGrp.h | 6 ++-- 11 files changed, 82 insertions(+), 82 deletions(-) rename DRAMSys/library/src/controller/scheduler/{BufferBankwise.cpp => BufferCounterBankwise.cpp} (85%) rename DRAMSys/library/src/controller/scheduler/{BufferBankwise.h => BufferCounterBankwise.h} (88%) rename DRAMSys/library/src/controller/scheduler/{BufferIF.h => BufferCounterIF.h} (94%) rename DRAMSys/library/src/controller/scheduler/{BufferReadWrite.cpp => BufferCounterReadWrite.cpp} (86%) rename DRAMSys/library/src/controller/scheduler/{BufferReadWrite.h => BufferCounterReadWrite.h} (89%) diff --git a/DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.cpp similarity index 85% rename from DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp rename to DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.cpp index d73a3a58..43648c19 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.cpp @@ -32,27 +32,27 @@ * Author: Lukas Steiner */ -#include "BufferBankwise.h" +#include "BufferCounterBankwise.h" #include "../../common/dramExtensions.h" -BufferBankwise::BufferBankwise(unsigned requestBufferSize, unsigned numberOfBanks) +BufferCounterBankwise::BufferCounterBankwise(unsigned requestBufferSize, unsigned numberOfBanks) : requestBufferSize(requestBufferSize) { requestsOnBank = std::vector(numberOfBanks, 0); } -bool BufferBankwise::hasBufferSpace() const +bool BufferCounterBankwise::hasBufferSpace() const { return (requestsOnBank[lastBankID] < requestBufferSize); } -void BufferBankwise::storeRequest(tlm::tlm_generic_payload *payload) +void BufferCounterBankwise::storeRequest(tlm::tlm_generic_payload *payload) { lastBankID = DramExtension::getBank(payload).ID(); requestsOnBank[lastBankID]++; } -void BufferBankwise::removeRequest(tlm::tlm_generic_payload *payload) +void BufferCounterBankwise::removeRequest(tlm::tlm_generic_payload *payload) { requestsOnBank[DramExtension::getBank(payload).ID()]--; } diff --git a/DRAMSys/library/src/controller/scheduler/BufferBankwise.h b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h similarity index 88% rename from DRAMSys/library/src/controller/scheduler/BufferBankwise.h rename to DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h index 3fd63490..4c351fee 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferBankwise.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h @@ -32,17 +32,17 @@ * Author: Lukas Steiner */ -#ifndef BUFFERBANKWISE_H -#define BUFFERBANKWISE_H +#ifndef BUFFERCOUNTERBANKWISE_H +#define BUFFERCOUNTERBANKWISE_H #include -#include "BufferIF.h" +#include "BufferCounterIF.h" -class BufferBankwise : public BufferIF +class BufferCounterBankwise : public BufferCounterIF { public: - BufferBankwise(unsigned requestBufferSize, unsigned numberOfBanks); + BufferCounterBankwise(unsigned requestBufferSize, unsigned numberOfBanks); virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *payload) override; virtual void removeRequest(tlm::tlm_generic_payload *payload) override; @@ -53,4 +53,4 @@ private: unsigned lastBankID; }; -#endif // BUFFERBANKWISE_H +#endif // BUFFERCOUNTERBANKWISE_H diff --git a/DRAMSys/library/src/controller/scheduler/BufferIF.h b/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h similarity index 94% rename from DRAMSys/library/src/controller/scheduler/BufferIF.h rename to DRAMSys/library/src/controller/scheduler/BufferCounterIF.h index 6c8349ae..2e76bed2 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferIF.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h @@ -32,12 +32,12 @@ * Author: Lukas Steiner */ -#ifndef BUFFERIF_H -#define BUFFERIF_H +#ifndef BUFFERCOUNTERIF_H +#define BUFFERCOUNTERIF_H #include -class BufferIF +class BufferCounterIF { public: virtual bool hasBufferSpace() const = 0; @@ -45,4 +45,4 @@ public: virtual void removeRequest(tlm::tlm_generic_payload *payload) = 0; }; -#endif // BUFFERIF_H +#endif // BUFFERCOUNTERIF_H diff --git a/DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.cpp similarity index 86% rename from DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp rename to DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.cpp index 62fdf772..efdf89db 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.cpp @@ -32,17 +32,17 @@ * Author: Lukas Steiner */ -#include "BufferReadWrite.h" +#include "BufferCounterReadWrite.h" -BufferReadWrite::BufferReadWrite(unsigned requestBufferSize) +BufferCounterReadWrite::BufferCounterReadWrite(unsigned requestBufferSize) : requestBufferSize(requestBufferSize) {} -bool BufferReadWrite::hasBufferSpace() const +bool BufferCounterReadWrite::hasBufferSpace() const { return (numberOfReads < requestBufferSize && numberOfWrites < requestBufferSize); } -void BufferReadWrite::storeRequest(tlm::tlm_generic_payload *payload) +void BufferCounterReadWrite::storeRequest(tlm::tlm_generic_payload *payload) { if (payload->is_read()) numberOfReads++; @@ -50,7 +50,7 @@ void BufferReadWrite::storeRequest(tlm::tlm_generic_payload *payload) numberOfWrites++; } -void BufferReadWrite::removeRequest(tlm::tlm_generic_payload *payload) +void BufferCounterReadWrite::removeRequest(tlm::tlm_generic_payload *payload) { if (payload->is_read()) numberOfReads--; diff --git a/DRAMSys/library/src/controller/scheduler/BufferReadWrite.h b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h similarity index 89% rename from DRAMSys/library/src/controller/scheduler/BufferReadWrite.h rename to DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h index 32835c74..3a27b7b8 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferReadWrite.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h @@ -32,15 +32,15 @@ * Author: Lukas Steiner */ -#ifndef BUFFERREADWRITE_H -#define BUFFERREADWRITE_H +#ifndef BUFFERCOUNTERREADWRITE_H +#define BUFFERCOUNTERREADWRITE_H -#include "BufferIF.h" +#include "BufferCounterIF.h" -class BufferReadWrite : public BufferIF +class BufferCounterReadWrite : public BufferCounterIF { public: - BufferReadWrite(unsigned requestBufferSize); + BufferCounterReadWrite(unsigned requestBufferSize); virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *payload) override; virtual void removeRequest(tlm::tlm_generic_payload *payload) override; @@ -51,4 +51,4 @@ private: unsigned numberOfWrites = 0; }; -#endif // BUFFERREADWRITE_H +#endif // BUFFERCOUNTERREADWRITE_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp index ab9fa81e..2a95b40c 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp @@ -34,53 +34,53 @@ #include "SchedulerFifo.h" #include "../../configuration/Configuration.h" -#include "BufferBankwise.h" -#include "BufferReadWrite.h" +#include "BufferCounterBankwise.h" +#include "BufferCounterReadWrite.h" using namespace tlm; SchedulerFifo::SchedulerFifo() { Configuration &config = Configuration::getInstance(); - localBuffer = std::vector>(config.memSpec->numberOfBanks); + buffer = std::vector>(config.memSpec->numberOfBanks); if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) - buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); + bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) - buffer = new BufferReadWrite(config.requestBufferSize); + bufferCounter = new BufferCounterReadWrite(config.requestBufferSize); } bool SchedulerFifo::hasBufferSpace() const { - return buffer->hasBufferSpace(); + return bufferCounter->hasBufferSpace(); } void SchedulerFifo::storeRequest(tlm_generic_payload *payload) { - localBuffer[DramExtension::getBank(payload).ID()].push_back(payload); - buffer->storeRequest(payload); + buffer[DramExtension::getBank(payload).ID()].push_back(payload); + bufferCounter->storeRequest(payload); } void SchedulerFifo::removeRequest(tlm_generic_payload *payload) { - localBuffer[DramExtension::getBank(payload).ID()].pop_front(); - buffer->removeRequest(payload); + buffer[DramExtension::getBank(payload).ID()].pop_front(); + bufferCounter->removeRequest(payload); } tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) const { unsigned bankID = bankMachine->getBank().ID(); - if (!localBuffer[bankID].empty()) - return localBuffer[bankID].front(); + if (!buffer[bankID].empty()) + return buffer[bankID].front(); else return nullptr; } bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) const { - if (localBuffer[bank.ID()].size() >= 2) + if (buffer[bank.ID()].size() >= 2) { - tlm_generic_payload *nextRequest = localBuffer[bank.ID()][1]; + tlm_generic_payload *nextRequest = buffer[bank.ID()][1]; if (DramExtension::getRow(nextRequest) == row) return true; } @@ -89,7 +89,7 @@ bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) const bool SchedulerFifo::hasFurtherRequest(Bank bank) const { - if (localBuffer[bank.ID()].size() >= 2) + if (buffer[bank.ID()].size() >= 2) return true; else return false; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h index c34a095a..7db8cfbd 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h @@ -42,7 +42,7 @@ #include "SchedulerIF.h" #include "../../common/dramExtensions.h" #include "../BankMachine.h" -#include "BufferIF.h" +#include "BufferCounterIF.h" class SchedulerFifo : public SchedulerIF { @@ -56,8 +56,8 @@ public: virtual bool hasFurtherRequest(Bank) const override; private: - std::vector> localBuffer; - BufferIF *buffer; + std::vector> buffer; + BufferCounterIF *bufferCounter; }; #endif // SCHEDULERFIFO_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index 8c0b02c8..0a46a016 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -34,42 +34,42 @@ #include "SchedulerFrFcfs.h" #include "../../configuration/Configuration.h" -#include "BufferBankwise.h" -#include "BufferReadWrite.h" +#include "BufferCounterBankwise.h" +#include "BufferCounterReadWrite.h" using namespace tlm; SchedulerFrFcfs::SchedulerFrFcfs() { Configuration &config = Configuration::getInstance(); - localBuffer = std::vector>(config.memSpec->numberOfBanks); + buffer = std::vector>(config.memSpec->numberOfBanks); if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) - buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); + bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) - buffer = new BufferReadWrite(config.requestBufferSize); + bufferCounter = new BufferCounterReadWrite(config.requestBufferSize); } bool SchedulerFrFcfs::hasBufferSpace() const { - return buffer->hasBufferSpace(); + return bufferCounter->hasBufferSpace(); } void SchedulerFrFcfs::storeRequest(tlm_generic_payload *payload) { - localBuffer[DramExtension::getBank(payload).ID()].push_back(payload); - buffer->storeRequest(payload); + buffer[DramExtension::getBank(payload).ID()].push_back(payload); + bufferCounter->storeRequest(payload); } void SchedulerFrFcfs::removeRequest(tlm_generic_payload *payload) { - buffer->removeRequest(payload); + bufferCounter->removeRequest(payload); unsigned bankID = DramExtension::getBank(payload).ID(); - for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) + for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) { if (*it == payload) { - localBuffer[bankID].erase(it); + buffer[bankID].erase(it); break; } } @@ -78,20 +78,20 @@ void SchedulerFrFcfs::removeRequest(tlm_generic_payload *payload) tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) const { unsigned bankID = bankMachine->getBank().ID(); - if (!localBuffer[bankID].empty()) + if (!buffer[bankID].empty()) { if (bankMachine->getState() == BmState::Activated) { // Search for row hit Row openRow = bankMachine->getOpenRow(); - for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) + for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) { if (DramExtension::getRow(*it) == openRow) return *it; } } // No row hit found or bank precharged - return localBuffer[bankID].front(); + return buffer[bankID].front(); } return nullptr; } @@ -99,7 +99,7 @@ tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) c bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) const { unsigned rowHitCounter = 0; - for (auto it = localBuffer[bank.ID()].begin(); it != localBuffer[bank.ID()].end(); it++) + for (auto it = buffer[bank.ID()].begin(); it != buffer[bank.ID()].end(); it++) { if (DramExtension::getRow(*it) == row) { @@ -113,5 +113,5 @@ bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) const bool SchedulerFrFcfs::hasFurtherRequest(Bank bank) const { - return (localBuffer[bank.ID()].size() >= 2); + return (buffer[bank.ID()].size() >= 2); } diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h index d8413b2a..d2dc6ac3 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h @@ -42,7 +42,7 @@ #include "SchedulerIF.h" #include "../../common/dramExtensions.h" #include "../BankMachine.h" -#include "BufferIF.h" +#include "BufferCounterIF.h" class SchedulerFrFcfs : public SchedulerIF { @@ -56,8 +56,8 @@ public: virtual bool hasFurtherRequest(Bank) const override; private: - std::vector> localBuffer; - BufferIF *buffer; + std::vector> buffer; + BufferCounterIF *bufferCounter; }; #endif // SCHEDULERFRFCFS_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp index b9cb739d..fe6901a4 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp @@ -34,43 +34,43 @@ #include "SchedulerFrFcfsGrp.h" #include "../../configuration/Configuration.h" -#include "BufferBankwise.h" -#include "BufferReadWrite.h" +#include "BufferCounterBankwise.h" +#include "BufferCounterReadWrite.h" using namespace tlm; SchedulerFrFcfsGrp::SchedulerFrFcfsGrp() { Configuration &config = Configuration::getInstance(); - localBuffer = std::vector>(config.memSpec->numberOfBanks); + buffer = std::vector>(config.memSpec->numberOfBanks); if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) - buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); + bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) - buffer = new BufferReadWrite(config.requestBufferSize); + bufferCounter = new BufferCounterReadWrite(config.requestBufferSize); } bool SchedulerFrFcfsGrp::hasBufferSpace() const { - return buffer->hasBufferSpace(); + return bufferCounter->hasBufferSpace(); } void SchedulerFrFcfsGrp::storeRequest(tlm_generic_payload *payload) { - localBuffer[DramExtension::getBank(payload).ID()].push_back(payload); - buffer->storeRequest(payload); + buffer[DramExtension::getBank(payload).ID()].push_back(payload); + bufferCounter->storeRequest(payload); } void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload *payload) { - buffer->removeRequest(payload); + bufferCounter->removeRequest(payload); lastCommand = payload->get_command(); unsigned bankID = DramExtension::getBank(payload).ID(); - for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) + for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) { if (*it == payload) { - localBuffer[bankID].erase(it); + buffer[bankID].erase(it); break; } } @@ -79,14 +79,14 @@ void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload *payload) tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine) const { unsigned bankID = bankMachine->getBank().ID(); - if (!localBuffer[bankID].empty()) + if (!buffer[bankID].empty()) { if (bankMachine->getState() == BmState::Activated) { // Filter all row hits Row openRow = bankMachine->getOpenRow(); std::list rowHits; - for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) + for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) { if (DramExtension::getRow(*it) == openRow) rowHits.push_back(*it); @@ -116,7 +116,7 @@ tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine } } // No row hit found or bank precharged - return localBuffer[bankID].front(); + return buffer[bankID].front(); } return nullptr; } @@ -124,7 +124,7 @@ tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) const { unsigned rowHitCounter = 0; - for (auto it = localBuffer[bank.ID()].begin(); it != localBuffer[bank.ID()].end(); it++) + for (auto it = buffer[bank.ID()].begin(); it != buffer[bank.ID()].end(); it++) { if (DramExtension::getRow(*it) == row) { @@ -138,7 +138,7 @@ bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) const bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank) const { - if (localBuffer[bank.ID()].size() >= 2) + if (buffer[bank.ID()].size() >= 2) return true; else return false; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h index af2e6ad4..670ccdf8 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h @@ -42,7 +42,7 @@ #include "SchedulerIF.h" #include "../../common/dramExtensions.h" #include "../BankMachine.h" -#include "BufferIF.h" +#include "BufferCounterIF.h" class SchedulerFrFcfsGrp : public SchedulerIF { @@ -56,9 +56,9 @@ public: virtual bool hasFurtherRequest(Bank) const override; private: - std::vector> localBuffer; + std::vector> buffer; tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND; - BufferIF *buffer; + BufferCounterIF *bufferCounter; }; #endif // SCHEDULERFRFCFSGRP_H From 3af9159b445e578261d34194f129fcd4aff4164a Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 26 Oct 2020 09:10:35 +0100 Subject: [PATCH 28/50] Missing cmake changes. --- DRAMSys/library/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index 52fb81f1..6c4e39f8 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -135,9 +135,9 @@ add_library(DRAMSysLibrary src/controller/scheduler/SchedulerFrFcfs.cpp src/controller/scheduler/SchedulerFrFcfsGrp.cpp - src/controller/scheduler/BufferIF.h - src/controller/scheduler/BufferBankwise.cpp - src/controller/scheduler/BufferReadWrite.cpp + src/controller/scheduler/BufferCounterIF.h + src/controller/scheduler/BufferCounterBankwise.cpp + src/controller/scheduler/BufferCounterReadWrite.cpp src/error/eccbaseclass.cpp src/error/ecchamming.cpp From b70c3351d3d5291e9b0ee24038496373d324ad8b Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 26 Oct 2020 13:54:11 +0100 Subject: [PATCH 29/50] Prepare arbiter for reorder buffer. --- DRAMSys/library/src/simulation/Arbiter.cpp | 62 ++++++++++------------ DRAMSys/library/src/simulation/Arbiter.h | 3 +- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index c95212cd..5bea2929 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -51,7 +51,7 @@ Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) : for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; ++i) { - channelIsFree.push_back(true); + channelIsBusy.push_back(false); pendingRequests.push_back(std::queue()); nextPayloadID.push_back(0); } @@ -89,7 +89,7 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, } else if (phase == END_RESP) { - // TODO: why one additional cycle??? + // TODO: why one additional cycle? notDelay += Configuration::getInstance().memSpec->tCK; } @@ -135,14 +135,14 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) // Phases initiated by the intiator side from arbiter's point of view (devices performing memory requests to the arbiter) if (phase == BEGIN_REQ) { - if (channelIsFree[channelId]) + if (!channelIsBusy[channelId]) { - // This channel was available. Forward the new transaction to the memory controller. - channelIsFree[channelId] = false; tlm_phase tPhase = BEGIN_REQ; sc_time tDelay = SC_ZERO_TIME; iSocket[static_cast(channelId)]->nb_transport_fw(payload, tPhase, tDelay); - // TODO: early completion of channel controller!!! + + // This channel was available. Forward the new transaction to the memory controller. + channelIsBusy[channelId] = true; } else { @@ -153,12 +153,12 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) // Phases initiated by the target side from arbiter's point of view (memory side) else if (phase == END_REQ) { - channelIsFree[channelId] = true; - // The arbiter receives a transaction which phase is END_REQ from memory controller and forwards it to the requester device. - tlm_phase tPhase = END_REQ; - sc_time tDelay = SC_ZERO_TIME; - tlm_sync_enum response = tSocket[static_cast(threadId)]->nb_transport_bw(payload, tPhase, tDelay); + { + tlm_phase tPhase = END_REQ; + sc_time tDelay = SC_ZERO_TIME; + tSocket[static_cast(threadId)]->nb_transport_bw(payload, tPhase, tDelay); + } // This channel is now free! Dispatch a new transaction (phase is BEGIN_REQ) from the queue, if any. Send it to the memory controller. if (!pendingRequests[channelId].empty()) @@ -169,31 +169,27 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) tlm_phase tPhase = BEGIN_REQ; sc_time tDelay = SC_ZERO_TIME; iSocket[static_cast(channelId)]->nb_transport_fw(payloadToSend, tPhase, tDelay); - // TODO: early completion of channel controller - // Mark the channel as busy again. - channelIsFree[channelId] = false; } - } + else + { + channelIsBusy[channelId] = false; + } + } else if (phase == BEGIN_RESP) { - // The arbiter receives a transaction in BEGIN_RESP phase - // (that came from the memory side) and forwards it to the requester - // device - if (pendingResponses[threadId].empty()) + if (!threadIsBusy[threadId]) { tlm_phase tPhase = BEGIN_RESP; sc_time tDelay = SC_ZERO_TIME; tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(payload, tPhase, tDelay); - if (returnValue != TLM_ACCEPTED) - { - tPhase = END_RESP; + if (returnValue == TLM_UPDATED) payloadEventQueue.notify(payload, tPhase, tDelay); - } + threadIsBusy[threadId] = true; + } + else + { + pendingResponses[threadId].push(&payload); } - - // Enqueue the transaction in BEGIN_RESP phase until the initiator - // device acknowledges it (phase changes to END_RESP). - pendingResponses[threadId].push(&payload); } else if (phase == END_RESP) { @@ -204,7 +200,6 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) iSocket[static_cast(channelId)]->nb_transport_fw(payload, tPhase, tDelay); } // Drop one element of the queue of BEGIN_RESP from memory to this device - pendingResponses[threadId].pop(); payload.release(); // Check if there are queued transactoins with phase BEGIN_RESP from memory to this device @@ -212,15 +207,16 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) { // The queue is not empty. tlm_generic_payload &payloadToSend = *pendingResponses[threadId].front(); - // Send ONE extra BEGIN_RESP to the device + pendingResponses[threadId].pop(); tlm_phase tPhase = BEGIN_RESP; sc_time tDelay = SC_ZERO_TIME; tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(payloadToSend, tPhase, tDelay); - if (returnValue != TLM_ACCEPTED) - { - tPhase = END_RESP; + if (returnValue == TLM_UPDATED) payloadEventQueue.notify(payloadToSend, tPhase, tDelay); - } + } + else + { + threadIsBusy[threadId] = false; } } else diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 0919f9a9..45aa2c28 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -64,7 +64,7 @@ private: tlm_utils::peq_with_cb_and_phase payloadEventQueue; - std::vector channelIsFree; + std::vector channelIsBusy; // used to account for the request_accept_delay in the dram controllers // This is a queue of new transactions. The phase of a new request is BEGIN_REQ. @@ -72,6 +72,7 @@ private: // used to account for the response_accept_delay in the initiators (traceplayer, core etc.) // This is a queue of responses comming from the memory side. The phase of these transactions is BEGIN_RESP. std::unordered_map> pendingResponses; + std::unordered_map threadIsBusy; // Initiated by initiator side // This function is called when an arbiter's target socket receives a transaction from a device From baf2440a4d123d6eb55921c7e410181a3a9d2e17 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 26 Oct 2020 14:15:06 +0100 Subject: [PATCH 30/50] Change payloadID to channelPayloadID. --- DRAMSys/library/src/common/dramExtensions.cpp | 34 +++++++++---------- DRAMSys/library/src/common/dramExtensions.h | 16 ++++----- DRAMSys/library/src/common/utils.cpp | 4 +-- DRAMSys/library/src/common/utils.h | 3 +- DRAMSys/library/src/controller/Controller.cpp | 4 +-- .../src/controller/ControllerRecordable.cpp | 2 +- .../src/controller/cmdmux/CmdMuxOldest.cpp | 2 +- .../src/controller/cmdmux/CmdMuxStrict.cpp | 2 +- .../controller/respqueue/RespQueueReorder.cpp | 2 +- 9 files changed, 35 insertions(+), 34 deletions(-) diff --git a/DRAMSys/library/src/common/dramExtensions.cpp b/DRAMSys/library/src/common/dramExtensions.cpp index 93a9bbad..14a977c5 100644 --- a/DRAMSys/library/src/common/dramExtensions.cpp +++ b/DRAMSys/library/src/common/dramExtensions.cpp @@ -44,24 +44,24 @@ using namespace tlm; DramExtension::DramExtension() : thread(0), channel(0), rank(0), bankgroup(0), bank(0), - row(0), column(0), burstlength(0), payloadID(0) {} + row(0), column(0), burstlength(0), channelPayloadID(0) {} DramExtension::DramExtension(Thread thread, Rank rank, BankGroup bankgroup, Bank bank, Row row, Column column, - unsigned int burstlength, uint64_t payloadID) : + unsigned int burstlength, uint64_t channelPayloadID) : thread(thread), channel(0), rank(rank), bankgroup(bankgroup), bank(bank), - row(row), column(column), burstlength(burstlength), payloadID(payloadID) {} + row(row), column(column), burstlength(burstlength), channelPayloadID(channelPayloadID) {} DramExtension::DramExtension(Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, uint64_t payloadID) : + Column column, unsigned int burstlength, uint64_t channelPayloadID) : thread(thread), channel(channel), rank(rank), bankgroup(bankgroup), bank(bank), - row(row), column(column), burstlength(burstlength), payloadID(payloadID) {} + row(row), column(column), burstlength(burstlength), channelPayloadID(channelPayloadID) {} void DramExtension::setExtension(tlm::tlm_generic_payload *payload, Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, uint64_t payloadID) + Column column, unsigned int burstlength, uint64_t channelPayloadID) { DramExtension *extension = nullptr; payload->get_extension(extension); @@ -76,12 +76,12 @@ void DramExtension::setExtension(tlm::tlm_generic_payload *payload, extension->row = row; extension->column = column; extension->burstlength = burstlength; - extension->payloadID = payloadID; + extension->channelPayloadID = channelPayloadID; } else { extension = new DramExtension(thread, channel, rank, bankgroup, - bank, row, column, burstlength, payloadID); + bank, row, column, burstlength, channelPayloadID); payload->set_auto_extension(extension); } } @@ -89,10 +89,10 @@ void DramExtension::setExtension(tlm::tlm_generic_payload *payload, void DramExtension::setExtension(tlm::tlm_generic_payload &payload, Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, uint64_t payloadID) + Column column, unsigned int burstlength, uint64_t channelPayloadID) { setExtension(&payload, thread, channel, rank, bankgroup, - bank, row, column, burstlength, payloadID); + bank, row, column, burstlength, channelPayloadID); } DramExtension &DramExtension::getExtension(const tlm_generic_payload *payload) @@ -179,19 +179,19 @@ Column DramExtension::getColumn(const tlm_generic_payload &payload) return DramExtension::getColumn(&payload); } -uint64_t DramExtension::getPayloadID(const tlm_generic_payload *payload) +uint64_t DramExtension::getChannelPayloadID(const tlm_generic_payload *payload) { - return DramExtension::getExtension(payload).getPayloadID(); + return DramExtension::getExtension(payload).getChannelPayloadID(); } -uint64_t DramExtension::getPayloadID(const tlm_generic_payload &payload) +uint64_t DramExtension::getChannelPayloadID(const tlm_generic_payload &payload) { - return DramExtension::getPayloadID(&payload); + return DramExtension::getChannelPayloadID(&payload); } tlm_extension_base *DramExtension::clone() const { - return new DramExtension(thread, channel, rank, bankgroup, bank, row, column, burstlength, payloadID); + return new DramExtension(thread, channel, rank, bankgroup, bank, row, column, burstlength, channelPayloadID); } void DramExtension::copy_from(const tlm_extension_base &ext) @@ -247,9 +247,9 @@ unsigned int DramExtension::getBurstlength() const return burstlength; } -uint64_t DramExtension::getPayloadID() const +uint64_t DramExtension::getChannelPayloadID() const { - return payloadID; + return channelPayloadID; } void DramExtension::incrementRow() diff --git a/DRAMSys/library/src/common/dramExtensions.h b/DRAMSys/library/src/common/dramExtensions.h index 1c33454d..0a4c8249 100644 --- a/DRAMSys/library/src/common/dramExtensions.h +++ b/DRAMSys/library/src/common/dramExtensions.h @@ -165,10 +165,10 @@ public: DramExtension(); DramExtension(Thread thread, Rank rank, BankGroup bankgroup, Bank bank, Row row, Column column, - unsigned int burstlength, uint64_t payloadID); + unsigned int burstlength, uint64_t channelPayloadID); DramExtension(Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, uint64_t payloadID); + Column column, unsigned int burstlength, uint64_t channelPayloadID); virtual tlm::tlm_extension_base *clone() const; virtual void copy_from(const tlm::tlm_extension_base &ext); @@ -176,11 +176,11 @@ public: static void setExtension(tlm::tlm_generic_payload *payload, Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, uint64_t payloadID); + Column column, unsigned int burstlength, uint64_t channelPayloadID); static void setExtension(tlm::tlm_generic_payload &payload, Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, uint64_t payloadID); + Column column, unsigned int burstlength, uint64_t channelPayloadID); static DramExtension &getExtension(const tlm::tlm_generic_payload *payload); static DramExtension &getExtension(const tlm::tlm_generic_payload &payload); @@ -200,8 +200,8 @@ public: static Row getRow(const tlm::tlm_generic_payload &payload); static Column getColumn(const tlm::tlm_generic_payload *payload); static Column getColumn(const tlm::tlm_generic_payload &payload); - static uint64_t getPayloadID(const tlm::tlm_generic_payload *payload); - static uint64_t getPayloadID(const tlm::tlm_generic_payload &payload); + static uint64_t getChannelPayloadID(const tlm::tlm_generic_payload *payload); + static uint64_t getChannelPayloadID(const tlm::tlm_generic_payload &payload); Thread getThread() const; Channel getChannel() const; @@ -212,7 +212,7 @@ public: Column getColumn() const; unsigned int getBurstlength() const; - uint64_t getPayloadID() const; + uint64_t getChannelPayloadID() const; void incrementRow(); private: @@ -224,7 +224,7 @@ private: Row row; Column column; unsigned int burstlength; - uint64_t payloadID; + uint64_t channelPayloadID; }; diff --git a/DRAMSys/library/src/common/utils.cpp b/DRAMSys/library/src/common/utils.cpp index 76237841..57accf8c 100644 --- a/DRAMSys/library/src/common/utils.cpp +++ b/DRAMSys/library/src/common/utils.cpp @@ -140,7 +140,7 @@ std::string parseString(json &obj, std::string name) SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str()); } -void setUpDummy(tlm_generic_payload &payload, uint64_t payloadID, Rank rank, BankGroup bankgroup, Bank bank) +void setUpDummy(tlm_generic_payload &payload, uint64_t channelPayloadID, Rank rank, BankGroup bankgroup, Bank bank) { payload.set_address(bank.getStartAddress()); payload.set_command(TLM_READ_COMMAND); @@ -150,5 +150,5 @@ void setUpDummy(tlm_generic_payload &payload, uint64_t payloadID, Rank rank, Ban payload.set_byte_enable_length(0); payload.set_streaming_width(0); payload.set_extension(new DramExtension(Thread(UINT_MAX), rank, bankgroup, - bank, Row(0), Column(0), 0, payloadID)); + bank, Row(0), Column(0), 0, channelPayloadID)); } diff --git a/DRAMSys/library/src/common/utils.h b/DRAMSys/library/src/common/utils.h index 6a073c81..6d539506 100644 --- a/DRAMSys/library/src/common/utils.h +++ b/DRAMSys/library/src/common/utils.h @@ -110,7 +110,8 @@ unsigned int parseUint(nlohmann::json &obj, std::string name); double parseUdouble(nlohmann::json &obj, std::string name); std::string parseString(nlohmann::json &obj, std::string name); -void setUpDummy(tlm::tlm_generic_payload &payload, uint64_t payloadID, Rank rank = Rank(0), BankGroup bankgroup = BankGroup(0), Bank bank = Bank(0)); +void setUpDummy(tlm::tlm_generic_payload &payload, uint64_t channelPayloadID, + Rank rank = Rank(0), BankGroup bankgroup = BankGroup(0), Bank bank = Bank(0)); #endif // UTILS_H diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index ece6abce..bc99b197 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -356,7 +356,7 @@ void Controller::finishBeginReq() { if (transToAcquire.payload != nullptr && transToAcquire.time <= sc_time_stamp()) { - NDEBUG_UNUSED(uint64_t id) = DramExtension::getPayloadID(transToAcquire.payload); + NDEBUG_UNUSED(uint64_t id) = DramExtension::getChannelPayloadID(transToAcquire.payload); PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system."); if (totalNumberOfPayloads == 0) @@ -417,7 +417,7 @@ void Controller::finishEndResp() { if (transToRelease.payload != nullptr && transToRelease.time <= sc_time_stamp()) { - NDEBUG_UNUSED(uint64_t id) = DramExtension::getPayloadID(transToRelease.payload); + NDEBUG_UNUSED(uint64_t id) = DramExtension::getChannelPayloadID(transToRelease.payload); PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system."); transToRelease.payload->release(); diff --git a/DRAMSys/library/src/controller/ControllerRecordable.cpp b/DRAMSys/library/src/controller/ControllerRecordable.cpp index 8ca3f8c2..37c33594 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.cpp +++ b/DRAMSys/library/src/controller/ControllerRecordable.cpp @@ -78,7 +78,7 @@ void ControllerRecordable::recordPhase(tlm_generic_payload &trans, tlm_phase pha NDEBUG_UNUSED(unsigned bank) = DramExtension::getExtension(trans).getBank().ID(); NDEBUG_UNUSED(unsigned row) = DramExtension::getExtension(trans).getRow().ID(); NDEBUG_UNUSED(unsigned col) = DramExtension::getExtension(trans).getColumn().ID(); - NDEBUG_UNUSED(uint64_t id) = DramExtension::getExtension(trans).getPayloadID(); + NDEBUG_UNUSED(uint64_t id) = DramExtension::getExtension(trans).getChannelPayloadID(); PRINTDEBUGMESSAGE(name(), "Recording " + getPhaseName(phase) + " thread " + std::to_string(thr) + " channel " + std::to_string(ch) + " bank group " + std::to_string( diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp index 769427d6..819db5c4 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp @@ -49,7 +49,7 @@ CommandTuple::Type CmdMuxOldest::selectCommand(ReadyCommands &readyCommands) { if (std::get(*it) == sc_time_stamp()) { - newPayloadID = DramExtension::getPayloadID(std::get(*it)); + newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); if (newPayloadID < lastPayloadID) { lastPayloadID = newPayloadID; diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp index f00f072a..e88b6dd2 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp @@ -49,7 +49,7 @@ CommandTuple::Type CmdMuxStrict::selectCommand(ReadyCommands &readyCommands) { if (std::get(*it) == sc_time_stamp()) { - newPayloadID = DramExtension::getPayloadID(std::get(*it)); + newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); if (isCasCommand(std::get(*it))) { if ((newPayloadID < lastPayloadID) && (newPayloadID == nextPayloadID)) diff --git a/DRAMSys/library/src/controller/respqueue/RespQueueReorder.cpp b/DRAMSys/library/src/controller/respqueue/RespQueueReorder.cpp index d2bf06d2..77118c2f 100644 --- a/DRAMSys/library/src/controller/respqueue/RespQueueReorder.cpp +++ b/DRAMSys/library/src/controller/respqueue/RespQueueReorder.cpp @@ -39,7 +39,7 @@ using namespace tlm; void RespQueueReorder::insertPayload(tlm_generic_payload *payload, sc_time strobeEnd) { - buffer[DramExtension::getPayloadID(payload)] = {payload, strobeEnd}; + buffer[DramExtension::getChannelPayloadID(payload)] = {payload, strobeEnd}; } tlm_generic_payload *RespQueueReorder::nextPayload() From 2c7f5551729e8e0a0364fe41d6daa84209cadc1f Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 26 Oct 2020 14:36:35 +0100 Subject: [PATCH 31/50] Add threadPayloadID. --- DRAMSys/library/src/common/dramExtensions.cpp | 46 +++++++++++++------ DRAMSys/library/src/common/dramExtensions.h | 16 ++++--- DRAMSys/library/src/common/utils.cpp | 4 +- DRAMSys/library/src/simulation/Arbiter.cpp | 7 +-- DRAMSys/library/src/simulation/Arbiter.h | 3 +- 5 files changed, 50 insertions(+), 26 deletions(-) diff --git a/DRAMSys/library/src/common/dramExtensions.cpp b/DRAMSys/library/src/common/dramExtensions.cpp index 14a977c5..6048d138 100644 --- a/DRAMSys/library/src/common/dramExtensions.cpp +++ b/DRAMSys/library/src/common/dramExtensions.cpp @@ -44,24 +44,22 @@ using namespace tlm; DramExtension::DramExtension() : thread(0), channel(0), rank(0), bankgroup(0), bank(0), - row(0), column(0), burstlength(0), channelPayloadID(0) {} - -DramExtension::DramExtension(Thread thread, Rank rank, BankGroup bankgroup, - Bank bank, Row row, Column column, - unsigned int burstlength, uint64_t channelPayloadID) : - thread(thread), channel(0), rank(rank), bankgroup(bankgroup), bank(bank), - row(row), column(column), burstlength(burstlength), channelPayloadID(channelPayloadID) {} + row(0), column(0), burstlength(0), + threadPayloadID(0), channelPayloadID(0) {} DramExtension::DramExtension(Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, uint64_t channelPayloadID) : + Column column, unsigned int burstlength, + uint64_t threadPayloadID, uint64_t channelPayloadID) : thread(thread), channel(channel), rank(rank), bankgroup(bankgroup), bank(bank), - row(row), column(column), burstlength(burstlength), channelPayloadID(channelPayloadID) {} + row(row), column(column), burstlength(burstlength), + threadPayloadID(threadPayloadID), channelPayloadID(channelPayloadID) {} void DramExtension::setExtension(tlm::tlm_generic_payload *payload, Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, uint64_t channelPayloadID) + Column column, unsigned int burstlength, + uint64_t threadPayloadID, uint64_t channelPayloadID) { DramExtension *extension = nullptr; payload->get_extension(extension); @@ -76,12 +74,14 @@ void DramExtension::setExtension(tlm::tlm_generic_payload *payload, extension->row = row; extension->column = column; extension->burstlength = burstlength; + extension->threadPayloadID = threadPayloadID; extension->channelPayloadID = channelPayloadID; } else { extension = new DramExtension(thread, channel, rank, bankgroup, - bank, row, column, burstlength, channelPayloadID); + bank, row, column, burstlength, + threadPayloadID, channelPayloadID); payload->set_auto_extension(extension); } } @@ -89,10 +89,12 @@ void DramExtension::setExtension(tlm::tlm_generic_payload *payload, void DramExtension::setExtension(tlm::tlm_generic_payload &payload, Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, uint64_t channelPayloadID) + Column column, unsigned int burstlength, + uint64_t threadPayloadID, uint64_t channelPayloadID) { setExtension(&payload, thread, channel, rank, bankgroup, - bank, row, column, burstlength, channelPayloadID); + bank, row, column, burstlength, + threadPayloadID, channelPayloadID); } DramExtension &DramExtension::getExtension(const tlm_generic_payload *payload) @@ -179,6 +181,16 @@ Column DramExtension::getColumn(const tlm_generic_payload &payload) return DramExtension::getColumn(&payload); } +uint64_t DramExtension::getThreadPayloadID(const tlm_generic_payload *payload) +{ + return DramExtension::getExtension(payload).getThreadPayloadID(); +} + +uint64_t DramExtension::getThreadPayloadID(const tlm_generic_payload &payload) +{ + return DramExtension::getThreadPayloadID(&payload); +} + uint64_t DramExtension::getChannelPayloadID(const tlm_generic_payload *payload) { return DramExtension::getExtension(payload).getChannelPayloadID(); @@ -191,7 +203,8 @@ uint64_t DramExtension::getChannelPayloadID(const tlm_generic_payload &payload) tlm_extension_base *DramExtension::clone() const { - return new DramExtension(thread, channel, rank, bankgroup, bank, row, column, burstlength, channelPayloadID); + return new DramExtension(thread, channel, rank, bankgroup, bank, row, column, + burstlength, threadPayloadID, channelPayloadID); } void DramExtension::copy_from(const tlm_extension_base &ext) @@ -247,6 +260,11 @@ unsigned int DramExtension::getBurstlength() const return burstlength; } +uint64_t DramExtension::getThreadPayloadID() const +{ + return threadPayloadID; +} + uint64_t DramExtension::getChannelPayloadID() const { return channelPayloadID; diff --git a/DRAMSys/library/src/common/dramExtensions.h b/DRAMSys/library/src/common/dramExtensions.h index 0a4c8249..3b5f75b7 100644 --- a/DRAMSys/library/src/common/dramExtensions.h +++ b/DRAMSys/library/src/common/dramExtensions.h @@ -163,12 +163,10 @@ class DramExtension : public tlm::tlm_extension { public: DramExtension(); - DramExtension(Thread thread, Rank rank, BankGroup bankgroup, - Bank bank, Row row, Column column, - unsigned int burstlength, uint64_t channelPayloadID); DramExtension(Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, uint64_t channelPayloadID); + Column column, unsigned int burstlength, + uint64_t threadPayloadID, uint64_t channelPayloadID); virtual tlm::tlm_extension_base *clone() const; virtual void copy_from(const tlm::tlm_extension_base &ext); @@ -176,11 +174,13 @@ public: static void setExtension(tlm::tlm_generic_payload *payload, Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, uint64_t channelPayloadID); + Column column, unsigned int burstlength, + uint64_t threadPayloadID, uint64_t channelPayloadID); static void setExtension(tlm::tlm_generic_payload &payload, Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, uint64_t channelPayloadID); + Column column, unsigned int burstlength, + uint64_t threadPayloadID, uint64_t channelPayloadID); static DramExtension &getExtension(const tlm::tlm_generic_payload *payload); static DramExtension &getExtension(const tlm::tlm_generic_payload &payload); @@ -200,6 +200,8 @@ public: static Row getRow(const tlm::tlm_generic_payload &payload); static Column getColumn(const tlm::tlm_generic_payload *payload); static Column getColumn(const tlm::tlm_generic_payload &payload); + static uint64_t getThreadPayloadID(const tlm::tlm_generic_payload *payload); + static uint64_t getThreadPayloadID(const tlm::tlm_generic_payload &payload); static uint64_t getChannelPayloadID(const tlm::tlm_generic_payload *payload); static uint64_t getChannelPayloadID(const tlm::tlm_generic_payload &payload); @@ -212,6 +214,7 @@ public: Column getColumn() const; unsigned int getBurstlength() const; + uint64_t getThreadPayloadID() const; uint64_t getChannelPayloadID() const; void incrementRow(); @@ -224,6 +227,7 @@ private: Row row; Column column; unsigned int burstlength; + uint64_t threadPayloadID; uint64_t channelPayloadID; }; diff --git a/DRAMSys/library/src/common/utils.cpp b/DRAMSys/library/src/common/utils.cpp index 57accf8c..369bd889 100644 --- a/DRAMSys/library/src/common/utils.cpp +++ b/DRAMSys/library/src/common/utils.cpp @@ -149,6 +149,6 @@ void setUpDummy(tlm_generic_payload &payload, uint64_t channelPayloadID, Rank ra payload.set_dmi_allowed(false); payload.set_byte_enable_length(0); payload.set_streaming_width(0); - payload.set_extension(new DramExtension(Thread(UINT_MAX), rank, bankgroup, - bank, Row(0), Column(0), 0, channelPayloadID)); + payload.set_extension(new DramExtension(Thread(UINT_MAX), Channel(0), rank, bankgroup, + bank, Row(0), Column(0), 0, 0, channelPayloadID)); } diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 5bea2929..88fc03c6 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -53,7 +53,7 @@ Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) : { channelIsBusy.push_back(false); pendingRequests.push_back(std::queue()); - nextPayloadID.push_back(0); + nextChannelPayloadID.push_back(0); } // One or more devices can accesss all the memory units through the arbiter. @@ -231,9 +231,10 @@ void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload, sc unsigned int burstlength = payload.get_streaming_width(); DecodedAddress decodedAddress = addressDecoder->decodeAddress(payload.get_address()); - DramExtension::setExtension(payload, Thread(static_cast(socketId)), + DramExtension::setExtension(payload, Thread(static_cast(socketId)), Channel(decodedAddress.channel), Rank(decodedAddress.rank), BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank), Row(decodedAddress.row), Column(decodedAddress.column), - burstlength, nextPayloadID[decodedAddress.channel]++); + burstlength, nextThreadPayloadID[static_cast(socketId)]++, + nextChannelPayloadID[decodedAddress.channel]++); } diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 45aa2c28..8a7266aa 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -89,7 +89,8 @@ private: void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); void appendDramExtension(int socketId, tlm::tlm_generic_payload &payload, sc_time delay); - std::vector nextPayloadID; + std::vector nextChannelPayloadID; + std::unordered_map nextThreadPayloadID; }; #endif // ARBITER_H From 5d6042a16abd25cb6097b1375cbe6f29bb3d3c05 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 27 Oct 2020 09:57:48 +0100 Subject: [PATCH 32/50] Renaming of payload IDs in arbiter. --- DRAMSys/library/src/simulation/Arbiter.cpp | 15 ++++----------- DRAMSys/library/src/simulation/Arbiter.h | 6 +++--- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 88fc03c6..c472f0be 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -53,7 +53,7 @@ Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) : { channelIsBusy.push_back(false); pendingRequests.push_back(std::queue()); - nextChannelPayloadID.push_back(0); + nextChannelPayloadIDToAppend.push_back(0); } // One or more devices can accesss all the memory units through the arbiter. @@ -101,12 +101,9 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, // Initiated by dram side // This function is called when an arbiter's initiator socket receives a transaction from a memory controller -tlm_sync_enum Arbiter::nb_transport_bw(int channelId, tlm_generic_payload &payload, +tlm_sync_enum Arbiter::nb_transport_bw(int, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) { - // Check channel ID - assert(static_cast(channelId) == DramExtension::getExtension(payload).getChannel().ID()); - PRINTDEBUGMESSAGE(name(), "[bw] " + getPhaseName(phase) + " notification in " + bwDelay.to_string()); payloadEventQueue.notify(payload, phase, bwDelay); @@ -128,10 +125,6 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) unsigned int threadId = DramExtension::getExtension(payload).getThread().ID(); unsigned int channelId = DramExtension::getExtension(payload).getChannel().ID(); - // Check the valid range of thread ID and channel Id - // TODO: thread ID not checked - assert(channelId < Configuration::getInstance().memSpec->numberOfChannels); - // Phases initiated by the intiator side from arbiter's point of view (devices performing memory requests to the arbiter) if (phase == BEGIN_REQ) { @@ -235,6 +228,6 @@ void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload, sc Channel(decodedAddress.channel), Rank(decodedAddress.rank), BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank), Row(decodedAddress.row), Column(decodedAddress.column), - burstlength, nextThreadPayloadID[static_cast(socketId)]++, - nextChannelPayloadID[decodedAddress.channel]++); + burstlength, nextThreadPayloadIDToAppend[static_cast(socketId)]++, + nextChannelPayloadIDToAppend[decodedAddress.channel]++); } diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 8a7266aa..43201b25 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -81,7 +81,7 @@ private: // Initiated by dram side // This function is called when an arbiter's initiator socket receives a transaction from a memory controller - tlm::tlm_sync_enum nb_transport_bw(int channelId, tlm::tlm_generic_payload &payload, + tlm::tlm_sync_enum nb_transport_bw(int, tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_time &bwDelay); unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans); @@ -89,8 +89,8 @@ private: void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); void appendDramExtension(int socketId, tlm::tlm_generic_payload &payload, sc_time delay); - std::vector nextChannelPayloadID; - std::unordered_map nextThreadPayloadID; + std::vector nextChannelPayloadIDToAppend; + std::unordered_map nextThreadPayloadIDToAppend; }; #endif // ARBITER_H From f6752cb09ad573d6495c31e3eebf6058c0c51a0a Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 27 Oct 2020 16:02:11 +0100 Subject: [PATCH 33/50] Improved arbiter with thread and channel queues. --- .../src/configuration/Configuration.cpp | 2 + .../library/src/configuration/Configuration.h | 1 + DRAMSys/library/src/controller/Controller.cpp | 12 +- DRAMSys/library/src/controller/Controller.h | 4 +- .../src/controller/ControllerRecordable.cpp | 5 +- DRAMSys/library/src/simulation/Arbiter.cpp | 182 ++++++++++-------- DRAMSys/library/src/simulation/Arbiter.h | 52 ++--- 7 files changed, 147 insertions(+), 111 deletions(-) diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 3f6739dd..b4fb45b9 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -163,6 +163,8 @@ void Configuration::setParameter(std::string name, nlohmann::json value) } else if (name == "PowerDownTimeout") powerDownTimeout = value; + else if (name == "MaxActiveTransactions") + maxActiveTransactions = value; //SimConfig------------------------------------------------ else if (name == "SimulationName") simulationName = value; diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index a77a9fa1..cad71c04 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -80,6 +80,7 @@ public: unsigned int refreshMaxPulledin = 0; enum class PowerDownPolicy {NoPowerDown, Staggered} powerDownPolicy; unsigned int powerDownTimeout = 3; + unsigned int maxActiveTransactions = 64; // SimConfig std::string simulationName = "default"; diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index bc99b197..f27a1511 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -318,24 +318,22 @@ void Controller::controllerMethod() tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &delay) { - sc_time notificationDelay = delay + Configuration::getInstance().memSpec->tCK; - if (phase == BEGIN_REQ) { transToAcquire.payload = &trans; - transToAcquire.time = sc_time_stamp() + notificationDelay; - beginReqEvent.notify(notificationDelay); + transToAcquire.time = sc_time_stamp() + delay; + beginReqEvent.notify(delay); } else if (phase == END_RESP) { - transToRelease.time = sc_time_stamp() + notificationDelay; - endRespEvent.notify(notificationDelay); + transToRelease.time = sc_time_stamp() + delay; + endRespEvent.notify(delay); } else SC_REPORT_FATAL("Controller", "nb_transport_fw in controller was triggered with unknown phase"); PRINTDEBUGMESSAGE(name(), "[fw] " + getPhaseName(phase) + " notification in " + - notificationDelay.to_string()); + delay.to_string()); return TLM_ACCEPTED; } diff --git a/DRAMSys/library/src/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h index 4fef0c65..7bcd2eee 100644 --- a/DRAMSys/library/src/controller/Controller.h +++ b/DRAMSys/library/src/controller/Controller.h @@ -72,13 +72,13 @@ protected: virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase); virtual void sendToDram(Command, tlm::tlm_generic_payload *); + MemSpec *memSpec; + private: unsigned totalNumberOfPayloads = 0; std::vector ranksNumberOfPayloads; ReadyCommands readyCommands; - MemSpec *memSpec; - std::vector bankMachines; std::vector> bankMachinesOnRank; CmdMuxIF *cmdMux; diff --git a/DRAMSys/library/src/controller/ControllerRecordable.cpp b/DRAMSys/library/src/controller/ControllerRecordable.cpp index 37c33594..5d3264bf 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.cpp +++ b/DRAMSys/library/src/controller/ControllerRecordable.cpp @@ -65,7 +65,10 @@ void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payl TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command); tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, *payload); } - Controller::sendToDram(command, payload); + sc_time delay = SC_ZERO_TIME; + tlm_phase phase = commandToPhase(command); + + iSocket->nb_transport_fw(*payload, phase, delay); } void ControllerRecordable::recordPhase(tlm_generic_payload &trans, tlm_phase phase, sc_time delay) diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index c472f0be..6c50b9be 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -42,38 +42,47 @@ using namespace tlm; Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) : - sc_module(name), payloadEventQueue(this, &Arbiter::peqCallback) + sc_module(name), payloadEventQueue(this, &Arbiter::peqCallback), + maxActiveTransactions(Configuration::getInstance().maxActiveTransactions), + tCK(Configuration::getInstance().memSpec->tCK) { - // The arbiter communicates with one or more memory unity through one or more sockets (one or more memory channels). - // Each of the arbiter's initiator sockets is bound to a memory controller's target socket. - // Anytime an transaction comes from a memory unity to the arbiter the "bw" callback is called. iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw); - - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; ++i) - { - channelIsBusy.push_back(false); - pendingRequests.push_back(std::queue()); - nextChannelPayloadIDToAppend.push_back(0); - } - - // One or more devices can accesss all the memory units through the arbiter. - // Devices' initiator sockets are bound to arbiter's target sockets. - // As soon the arbiter receives a request in any of its target sockets it should treat and forward it to the proper memory channel. tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw); - tSocket.register_transport_dbg(this, &Arbiter::transport_dbg); addressDecoder = new AddressDecoder(pathToAddressMapping); addressDecoder->print(); } -// Initiated by initiator side -// This function is called when an arbiter's target socket receives a transaction from a device +Arbiter::~Arbiter() +{ + delete addressDecoder; +} + +void Arbiter::end_of_elaboration() +{ + for (unsigned i = 0; i < tSocket.size(); i++) // initiator side + { + threadIsBusy.push_back(false); + pendingResponses.push_back(std::queue()); + nextThreadPayloadIDToAppend.push_back(0); + activeTransactions.push_back(0); + outstandingEndReq.push_back(nullptr); + } + + for (unsigned i = 0; i < iSocket.size(); i++) // channel side + { + channelIsBusy.push_back(false); + pendingRequests.push_back(std::queue()); + nextChannelPayloadIDToAppend.push_back(0); + } +} + tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, tlm_phase &phase, sc_time &fwDelay) { - sc_time notDelay = std::ceil((sc_time_stamp() + fwDelay) / Configuration::getInstance().memSpec->tCK) - * Configuration::getInstance().memSpec->tCK - sc_time_stamp(); + sc_time notDelay = std::ceil((sc_time_stamp() + fwDelay) / tCK) + * tCK - sc_time_stamp(); if (phase == BEGIN_REQ) { @@ -82,16 +91,9 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, payload.set_address(payload.get_address() - Configuration::getInstance().addressOffset); - // In the begin request phase the socket ID is appended to the payload. - // It will extracted from the payload and used later. appendDramExtension(id, payload, fwDelay); payload.acquire(); } - else if (phase == END_RESP) - { - // TODO: why one additional cycle? - notDelay += Configuration::getInstance().memSpec->tCK; - } PRINTDEBUGMESSAGE(name(), "[fw] " + getPhaseName(phase) + " notification in " + notDelay.to_string()); @@ -99,8 +101,6 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, return TLM_ACCEPTED; } -// Initiated by dram side -// This function is called when an arbiter's initiator socket receives a transaction from a memory controller tlm_sync_enum Arbiter::nb_transport_bw(int, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) { @@ -112,7 +112,6 @@ tlm_sync_enum Arbiter::nb_transport_bw(int, tlm_generic_payload &payload, unsigned int Arbiter::transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) { - // adjust address offset: trans.set_address(trans.get_address() - Configuration::getInstance().addressOffset); @@ -125,87 +124,120 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) unsigned int threadId = DramExtension::getExtension(payload).getThread().ID(); unsigned int channelId = DramExtension::getExtension(payload).getChannel().ID(); - // Phases initiated by the intiator side from arbiter's point of view (devices performing memory requests to the arbiter) - if (phase == BEGIN_REQ) + if (phase == BEGIN_REQ) // from initiator { - if (!channelIsBusy[channelId]) - { - tlm_phase tPhase = BEGIN_REQ; - sc_time tDelay = SC_ZERO_TIME; - iSocket[static_cast(channelId)]->nb_transport_fw(payload, tPhase, tDelay); + activeTransactions[threadId]++; - // This channel was available. Forward the new transaction to the memory controller. - channelIsBusy[channelId] = true; - } - else - { - // This channel is busy. Enqueue the new transaction which phase is BEGIN_REQ. - pendingRequests[channelId].push(&payload); - } - } - // Phases initiated by the target side from arbiter's point of view (memory side) - else if (phase == END_REQ) - { - // The arbiter receives a transaction which phase is END_REQ from memory controller and forwards it to the requester device. + if (activeTransactions[threadId] < maxActiveTransactions) { tlm_phase tPhase = END_REQ; sc_time tDelay = SC_ZERO_TIME; tSocket[static_cast(threadId)]->nb_transport_bw(payload, tPhase, tDelay); } + else + { + outstandingEndReq[threadId] = &payload; + } - // This channel is now free! Dispatch a new transaction (phase is BEGIN_REQ) from the queue, if any. Send it to the memory controller. + if (!channelIsBusy[channelId]) + { + channelIsBusy[channelId] = true; + + tlm_phase tPhase = BEGIN_REQ; + sc_time tDelay = tCK; + + if (pendingRequests[channelId].empty()) + { + iSocket[static_cast(channelId)]->nb_transport_fw(payload, tPhase, tDelay); + } + else + { + tlm_generic_payload &tPayload = *pendingRequests[channelId].front(); + pendingRequests[channelId].pop(); + pendingRequests[channelId].push(&payload); + iSocket[static_cast(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay); + } + } + else + { + pendingRequests[channelId].push(&payload); + } + } + else if (phase == END_REQ) // from memory controller + { if (!pendingRequests[channelId].empty()) { - // Send ONE of the enqueued new transactions (phase is BEGIN_REQ) through this channel. - tlm_generic_payload &payloadToSend = *pendingRequests[channelId].front(); + tlm_generic_payload &tPayload = *pendingRequests[channelId].front(); pendingRequests[channelId].pop(); tlm_phase tPhase = BEGIN_REQ; - sc_time tDelay = SC_ZERO_TIME; - iSocket[static_cast(channelId)]->nb_transport_fw(payloadToSend, tPhase, tDelay); + sc_time tDelay = tCK; + iSocket[static_cast(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay); } else { channelIsBusy[channelId] = false; } } - else if (phase == BEGIN_RESP) + else if (phase == BEGIN_RESP) // from memory controller { + // TODO: use early completion + { + tlm_phase tPhase = END_RESP; + sc_time tDelay = SC_ZERO_TIME; + iSocket[static_cast(channelId)]->nb_transport_fw(payload, tPhase, tDelay); + } + if (!threadIsBusy[threadId]) { - tlm_phase tPhase = BEGIN_RESP; - sc_time tDelay = SC_ZERO_TIME; - tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(payload, tPhase, tDelay); - if (returnValue == TLM_UPDATED) - payloadEventQueue.notify(payload, tPhase, tDelay); threadIsBusy[threadId] = true; + + tlm_phase tPhase = BEGIN_RESP; + sc_time tDelay = tCK; + + if (pendingResponses[threadId].empty()) + { + tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(payload, tPhase, tDelay); + if (returnValue == TLM_UPDATED) + payloadEventQueue.notify(payload, tPhase, tDelay); + } + else + { + tlm_generic_payload &tPayload = *pendingResponses[threadId].front(); + pendingResponses[threadId].pop(); + pendingResponses[threadId].push(&payload); + tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay); + if (returnValue == TLM_UPDATED) + payloadEventQueue.notify(tPayload, tPhase, tDelay); + } } else { pendingResponses[threadId].push(&payload); } } - else if (phase == END_RESP) + else if (phase == END_RESP) // from initiator { - // Send the END_RESP message to the memory - { - tlm_phase tPhase = END_RESP; - sc_time tDelay = SC_ZERO_TIME; - iSocket[static_cast(channelId)]->nb_transport_fw(payload, tPhase, tDelay); - } - // Drop one element of the queue of BEGIN_RESP from memory to this device payload.release(); - // Check if there are queued transactoins with phase BEGIN_RESP from memory to this device + if (activeTransactions[threadId] == maxActiveTransactions) + { + tlm_phase tPhase = END_REQ; + sc_time tDelay = SC_ZERO_TIME; + tlm_generic_payload &tPayload = *outstandingEndReq[threadId]; + tSocket[static_cast(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay); + } + + activeTransactions[threadId]--; + if (!pendingResponses[threadId].empty()) { - // The queue is not empty. - tlm_generic_payload &payloadToSend = *pendingResponses[threadId].front(); + tlm_generic_payload &tPayload = *pendingResponses[threadId].front(); pendingResponses[threadId].pop(); tlm_phase tPhase = BEGIN_RESP; - sc_time tDelay = SC_ZERO_TIME; - tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(payloadToSend, tPhase, tDelay); + sc_time tDelay = tCK; + tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay); if (returnValue == TLM_UPDATED) - payloadEventQueue.notify(payloadToSend, tPhase, tDelay); + payloadEventQueue.notify(tPayload, tPhase, tDelay); } else { diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 43201b25..61b26a06 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -59,38 +58,39 @@ public: Arbiter(sc_module_name, std::string); SC_HAS_PROCESS(Arbiter); + virtual ~Arbiter(); + private: + virtual void end_of_elaboration() override; + AddressDecoder *addressDecoder; tlm_utils::peq_with_cb_and_phase payloadEventQueue; - - std::vector channelIsBusy; - - // used to account for the request_accept_delay in the dram controllers - // This is a queue of new transactions. The phase of a new request is BEGIN_REQ. - std::vector> pendingRequests; - // used to account for the response_accept_delay in the initiators (traceplayer, core etc.) - // This is a queue of responses comming from the memory side. The phase of these transactions is BEGIN_RESP. - std::unordered_map> pendingResponses; - std::unordered_map threadIsBusy; - - // Initiated by initiator side - // This function is called when an arbiter's target socket receives a transaction from a device - tlm::tlm_sync_enum nb_transport_fw(int id, tlm::tlm_generic_payload &payload, - tlm::tlm_phase &phase, sc_time &fwDelay); - - // Initiated by dram side - // This function is called when an arbiter's initiator socket receives a transaction from a memory controller - tlm::tlm_sync_enum nb_transport_bw(int, tlm::tlm_generic_payload &payload, - tlm::tlm_phase &phase, sc_time &bwDelay); - - unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans); - void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); - void appendDramExtension(int socketId, tlm::tlm_generic_payload &payload, sc_time delay); + std::vector threadIsBusy; + std::vector channelIsBusy; + + std::vector> pendingResponses; + std::vector> pendingRequests; + + std::vector nextThreadPayloadIDToAppend; std::vector nextChannelPayloadIDToAppend; - std::unordered_map nextThreadPayloadIDToAppend; + + std::vector activeTransactions; + const unsigned maxActiveTransactions; + + std::vector outstandingEndReq; + + tlm::tlm_sync_enum nb_transport_fw(int id, tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, sc_time &fwDelay); + tlm::tlm_sync_enum nb_transport_bw(int, tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, sc_time &bwDelay); + unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans); + + void appendDramExtension(int socketId, tlm::tlm_generic_payload &payload, sc_time delay); + + sc_time tCK; }; #endif // ARBITER_H From 2d507fb32769ea39e18659b1baff370aa9745ccf Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 27 Oct 2020 16:16:48 +0100 Subject: [PATCH 34/50] Decrement active transactions after BEGIN_RESP. --- DRAMSys/library/src/simulation/Arbiter.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 6c50b9be..5ef44350 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -209,6 +209,16 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) if (returnValue == TLM_UPDATED) payloadEventQueue.notify(tPayload, tPhase, tDelay); } + + if (activeTransactions[threadId] == maxActiveTransactions) + { + tlm_phase tPhase = END_REQ; + sc_time tDelay = SC_ZERO_TIME; + tlm_generic_payload &tPayload = *outstandingEndReq[threadId]; + tSocket[static_cast(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay); + } + + activeTransactions[threadId]--; } else { @@ -219,16 +229,6 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) { payload.release(); - if (activeTransactions[threadId] == maxActiveTransactions) - { - tlm_phase tPhase = END_REQ; - sc_time tDelay = SC_ZERO_TIME; - tlm_generic_payload &tPayload = *outstandingEndReq[threadId]; - tSocket[static_cast(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay); - } - - activeTransactions[threadId]--; - if (!pendingResponses[threadId].empty()) { tlm_generic_payload &tPayload = *pendingResponses[threadId].front(); From fe1d8eafdd7ae57e891b9ed50e5fb499f61fbeb8 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 27 Oct 2020 16:41:00 +0100 Subject: [PATCH 35/50] Code cleanup. --- .../library/src/controller/BankMachine.cpp | 40 +++++++++---------- DRAMSys/library/src/controller/BankMachine.h | 14 +++---- .../powerdown/PowerDownManagerStaggered.cpp | 30 +++++++------- .../powerdown/PowerDownManagerStaggered.h | 2 +- .../refresh/RefreshManagerBankwise.cpp | 18 ++++----- .../refresh/RefreshManagerBankwise.h | 2 +- .../refresh/RefreshManagerRankwise.cpp | 14 +++---- .../refresh/RefreshManagerRankwise.h | 2 +- .../controller/scheduler/SchedulerFrFcfs.cpp | 2 +- .../scheduler/SchedulerFrFcfsGrp.cpp | 2 +- .../src/controller/scheduler/SchedulerIF.h | 1 - DRAMSys/library/src/simulation/Arbiter.h | 2 +- 12 files changed, 62 insertions(+), 67 deletions(-) diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index fb7e3e8c..5ddbdcd8 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -55,17 +55,17 @@ void BankMachine::updateState(Command command) switch (command) { case Command::ACT: - currentState = BmState::Activated; - currentRow = DramExtension::getRow(currentPayload); + state = State::Activated; + openRow = DramExtension::getRow(currentPayload); break; case Command::PRE: case Command::PREA: - currentState = BmState::Precharged; + state = State::Precharged; break; case Command::RD: case Command::WR: currentPayload = nullptr; break; case Command::RDA: case Command::WRA: - currentState = BmState::Precharged; + state = State::Precharged; currentPayload = nullptr; break; case Command::PDEA: case Command::PDEP: case Command::SREFEN: @@ -105,12 +105,12 @@ Bank BankMachine::getBank() Row BankMachine::getOpenRow() { - return currentRow; + return openRow; } -BmState BankMachine::getState() +BankMachine::State BankMachine::getState() { - return currentState; + return state; } bool BankMachine::isIdle() @@ -133,14 +133,14 @@ sc_time BankMachineOpen::start() if (currentPayload == nullptr) return timeToSchedule; - if (currentState == BmState::Precharged && !blocked) // row miss + if (state == State::Precharged && !blocked) // row miss { nextCommand = Command::ACT; timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } - else if (currentState == BmState::Activated) + else if (state == State::Activated) { - if (DramExtension::getRow(currentPayload) == currentRow) // row hit + if (DramExtension::getRow(currentPayload) == openRow) // row hit { if (currentPayload->get_command() == TLM_READ_COMMAND) nextCommand = Command::RD; @@ -175,12 +175,12 @@ sc_time BankMachineClosed::start() if (currentPayload == nullptr) return timeToSchedule; - if (currentState == BmState::Precharged && !blocked) // row miss + if (state == State::Precharged && !blocked) // row miss { nextCommand = Command::ACT; timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } - else if (currentState == BmState::Activated) + else if (state == State::Activated) { if (currentPayload->get_command() == TLM_READ_COMMAND) nextCommand = Command::RDA; @@ -209,16 +209,16 @@ sc_time BankMachineOpenAdaptive::start() if (currentPayload == nullptr) return timeToSchedule; - if (currentState == BmState::Precharged && !blocked) // row miss + if (state == State::Precharged && !blocked) // row miss { nextCommand = Command::ACT; timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } - else if (currentState == BmState::Activated) + else if (state == State::Activated) { - if (DramExtension::getRow(currentPayload) == currentRow) // row hit + if (DramExtension::getRow(currentPayload) == openRow) // row hit { - if (scheduler->hasFurtherRequest(bank) && !scheduler->hasFurtherRowHit(bank, currentRow)) + if (scheduler->hasFurtherRequest(bank) && !scheduler->hasFurtherRowHit(bank, openRow)) { if (currentPayload->get_command() == TLM_READ_COMMAND) nextCommand = Command::RDA; @@ -262,16 +262,16 @@ sc_time BankMachineClosedAdaptive::start() if (currentPayload == nullptr) return timeToSchedule; - if (currentState == BmState::Precharged && !blocked) // row miss + if (state == State::Precharged && !blocked) // row miss { nextCommand = Command::ACT; timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } - else if (currentState == BmState::Activated) + else if (state == State::Activated) { - if (DramExtension::getRow(currentPayload) == currentRow) // row hit + if (DramExtension::getRow(currentPayload) == openRow) // row hit { - if (scheduler->hasFurtherRowHit(bank, currentRow)) + if (scheduler->hasFurtherRowHit(bank, openRow)) { if (currentPayload->get_command() == TLM_READ_COMMAND) nextCommand = Command::RD; diff --git a/DRAMSys/library/src/controller/BankMachine.h b/DRAMSys/library/src/controller/BankMachine.h index 9fec70a2..508ed46d 100644 --- a/DRAMSys/library/src/controller/BankMachine.h +++ b/DRAMSys/library/src/controller/BankMachine.h @@ -43,12 +43,6 @@ #include "scheduler/SchedulerIF.h" #include "checker/CheckerIF.h" -enum class BmState -{ - Precharged, - Activated -}; - class BankMachine { public: @@ -58,11 +52,13 @@ public: void updateState(Command); void block(); + enum class State {Precharged, Activated}; + Rank getRank(); BankGroup getBankGroup(); Bank getBank(); Row getOpenRow(); - BmState getState(); + State getState(); bool isIdle(); protected: @@ -71,8 +67,8 @@ protected: SchedulerIF *scheduler; CheckerIF *checker; Command nextCommand = Command::NOP; - BmState currentState = BmState::Precharged; - Row currentRow; + State state = State::Precharged; + Row openRow; sc_time timeToSchedule = sc_max_time(); Rank rank = Rank(0); BankGroup bankgroup = BankGroup(0); diff --git a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp index f299beef..77615452 100644 --- a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp +++ b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp @@ -47,7 +47,7 @@ void PowerDownManagerStaggered::triggerEntry() { controllerIdle = true; - if (state == PdmState::Idle) + if (state == State::Idle) entryTriggered = true; } @@ -57,7 +57,7 @@ void PowerDownManagerStaggered::triggerExit() enterSelfRefresh = false; entryTriggered = false; - if (state != PdmState::Idle) + if (state != State::Idle) exitTriggered = true; } @@ -65,7 +65,7 @@ void PowerDownManagerStaggered::triggerInterruption() { entryTriggered = false; - if (state != PdmState::Idle) + if (state != State::Idle) exitTriggered = true; } @@ -81,13 +81,13 @@ sc_time PowerDownManagerStaggered::start() if (exitTriggered) { - if (state == PdmState::ActivePdn) + if (state == State::ActivePdn) nextCommand = Command::PDXA; - else if (state == PdmState::PrechargePdn) + else if (state == State::PrechargePdn) nextCommand = Command::PDXP; - else if (state == PdmState::SelfRefresh) + else if (state == State::SelfRefresh) nextCommand = Command::SREFEX; - else if (state == PdmState::ExtraRefresh) + else if (state == State::ExtraRefresh) nextCommand = Command::REFA; timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0)); @@ -124,35 +124,35 @@ void PowerDownManagerStaggered::updateState(Command command) activatedBanks = 0; break; case Command::PDEA: - state = PdmState::ActivePdn; + state = State::ActivePdn; entryTriggered = false; break; case Command::PDEP: - state = PdmState::PrechargePdn; + state = State::PrechargePdn; entryTriggered = false; break; case Command::SREFEN: - state = PdmState::SelfRefresh; + state = State::SelfRefresh; entryTriggered = false; enterSelfRefresh = false; break; case Command::PDXA: - state = PdmState::Idle; + state = State::Idle; exitTriggered = false; break; case Command::PDXP: - state = PdmState::Idle; + state = State::Idle; exitTriggered = false; if (controllerIdle) enterSelfRefresh = true; break; case Command::SREFEX: - state = PdmState::ExtraRefresh; + state = State::ExtraRefresh; break; case Command::REFA: - if (state == PdmState::ExtraRefresh) + if (state == State::ExtraRefresh) { - state = PdmState::Idle; + state = State::Idle; exitTriggered = false; } else if (controllerIdle) diff --git a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.h b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.h index fb5795da..eaa6cf77 100644 --- a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.h +++ b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.h @@ -53,7 +53,7 @@ public: virtual sc_time start() override; private: - enum class PdmState {Idle, ActivePdn, PrechargePdn, SelfRefresh, ExtraRefresh} state = PdmState::Idle; + enum class State {Idle, ActivePdn, PrechargePdn, SelfRefresh, ExtraRefresh} state = State::Idle; tlm::tlm_generic_payload powerDownPayload; Rank rank; CheckerIF *checker; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp index c31a73c7..3a184ea1 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp @@ -80,10 +80,10 @@ sc_time RefreshManagerBankwise::start() if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalPB()) { timeForNextTrigger += memSpec->getRefreshIntervalPB(); - state = RmState::Regular; + state = State::Regular; } - if (state == RmState::Regular) + if (state == State::Regular) { bool forcedRefresh = (flexibilityCounter == maxPostponed); bool allBanksBusy = true; @@ -113,7 +113,7 @@ sc_time RefreshManagerBankwise::start() } else { - if (currentBankMachine->getState() == BmState::Activated) + if (currentBankMachine->getState() == BankMachine::State::Activated) nextCommand = Command::PRE; else { @@ -148,13 +148,13 @@ sc_time RefreshManagerBankwise::start() if (allBanksBusy) { - state = RmState::Regular; + state = State::Regular; timeForNextTrigger += memSpec->getRefreshIntervalPB(); return timeForNextTrigger; } else { - if (currentBankMachine->getState() == BmState::Activated) + if (currentBankMachine->getState() == BankMachine::State::Activated) nextCommand = Command::PRE; else nextCommand = Command::REFB; @@ -178,20 +178,20 @@ void RefreshManagerBankwise::updateState(Command command) if (remainingBankMachines.empty()) remainingBankMachines = allBankMachines; - if (state == RmState::Pulledin) + if (state == State::Pulledin) flexibilityCounter--; else - state = RmState::Pulledin; + state = State::Pulledin; if (flexibilityCounter == maxPulledin) { - state = RmState::Regular; + state = State::Regular; timeForNextTrigger += memSpec->getRefreshIntervalPB(); } break; case Command::REFA: // Refresh command after SREFEX - state = RmState::Regular; // TODO: check if this assignment is necessary + state = State::Regular; // TODO: check if this assignment is necessary timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalPB(); sleeping = false; break; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h index ba976fc3..ea96c86d 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h @@ -53,7 +53,7 @@ public: virtual void updateState(Command) override; private: - enum class RmState {Regular, Pulledin} state = RmState::Regular; + enum class State {Regular, Pulledin} state = State::Regular; const MemSpec *memSpec; std::vector &bankMachinesOnRank; PowerDownManagerIF *powerDownManager; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.cpp index dd68bb2b..83d711cc 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.cpp @@ -71,10 +71,10 @@ sc_time RefreshManagerRankwise::start() if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalAB()) { timeForNextTrigger += memSpec->getRefreshIntervalAB(); - state = RmState::Regular; + state = State::Regular; } - if (state == RmState::Regular) + if (state == State::Regular) { if (flexibilityCounter == maxPostponed) // forced refresh { @@ -122,7 +122,7 @@ sc_time RefreshManagerRankwise::start() if (controllerBusy) { - state = RmState::Regular; + state = State::Regular; timeForNextTrigger += memSpec->getRefreshIntervalAB(); return timeForNextTrigger; } @@ -155,20 +155,20 @@ void RefreshManagerRankwise::updateState(Command command) if (sleeping) { // Refresh command after SREFEX - state = RmState::Regular; // TODO: check if this assignment is necessary + state = State::Regular; // TODO: check if this assignment is necessary timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalAB(); sleeping = false; } else { - if (state == RmState::Pulledin) + if (state == State::Pulledin) flexibilityCounter--; else - state = RmState::Pulledin; + state = State::Pulledin; if (flexibilityCounter == maxPulledin) { - state = RmState::Regular; + state = State::Regular; timeForNextTrigger += memSpec->getRefreshIntervalAB(); } } diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.h b/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.h index d1dec3fc..f7e7b859 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.h @@ -51,7 +51,7 @@ public: virtual void updateState(Command) override; private: - enum class RmState {Regular, Pulledin} state = RmState::Regular; + enum class State {Regular, Pulledin} state = State::Regular; const MemSpec *memSpec; std::vector &bankMachinesOnRank; PowerDownManagerIF *powerDownManager; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index 0a46a016..3ba640e1 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -80,7 +80,7 @@ tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) c unsigned bankID = bankMachine->getBank().ID(); if (!buffer[bankID].empty()) { - if (bankMachine->getState() == BmState::Activated) + if (bankMachine->getState() == BankMachine::State::Activated) { // Search for row hit Row openRow = bankMachine->getOpenRow(); diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp index fe6901a4..1e7b538a 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp @@ -81,7 +81,7 @@ tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine unsigned bankID = bankMachine->getBank().ID(); if (!buffer[bankID].empty()) { - if (bankMachine->getState() == BmState::Activated) + if (bankMachine->getState() == BankMachine::State::Activated) { // Filter all row hits Row openRow = bankMachine->getOpenRow(); diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h index f82ea208..3c695c76 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h @@ -40,7 +40,6 @@ #include "../../common/dramExtensions.h" #include "../../common/DebugManager.h" -enum class BmState; class BankMachine; class SchedulerIF diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 61b26a06..faee82da 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -58,7 +58,7 @@ public: Arbiter(sc_module_name, std::string); SC_HAS_PROCESS(Arbiter); - virtual ~Arbiter(); + virtual ~Arbiter() override; private: virtual void end_of_elaboration() override; From c744c43ab264ef4f545b9f8916d0a010ec49b4f7 Mon Sep 17 00:00:00 2001 From: Matthias Jung Date: Tue, 27 Oct 2020 21:29:39 +0100 Subject: [PATCH 36/50] Added first latency analysis --- .../resources/configs/simulator/ddr3.json | 4 +- DRAMSys/traceAnalyzer/data/tracedb.cpp | 5 + DRAMSys/traceAnalyzer/data/tracedb.h | 2 + DRAMSys/traceAnalyzer/scripts/plots.py | 39 +++++++ DRAMSys/traceAnalyzer/tracefiletab.cpp | 88 ++++++++++++++- DRAMSys/traceAnalyzer/tracefiletab.h | 3 + DRAMSys/traceAnalyzer/tracefiletab.ui | 102 ++++++++++++------ 7 files changed, 210 insertions(+), 33 deletions(-) diff --git a/DRAMSys/library/resources/configs/simulator/ddr3.json b/DRAMSys/library/resources/configs/simulator/ddr3.json index 99ccdb45..3f8bf627 100644 --- a/DRAMSys/library/resources/configs/simulator/ddr3.json +++ b/DRAMSys/library/resources/configs/simulator/ddr3.json @@ -5,10 +5,10 @@ "DatabaseRecording": true, "Debug": false, "ECCControllerMode": "Disabled", - "EnableWindowing": false, + "EnableWindowing": true, "ErrorCSVFile": "", "ErrorChipSeed": 42, - "PowerAnalysis": false, + "PowerAnalysis": true, "SimulationName": "ddr3", "SimulationProgressBar": true, "StoreMode": "NoStorage", diff --git a/DRAMSys/traceAnalyzer/data/tracedb.cpp b/DRAMSys/traceAnalyzer/data/tracedb.cpp index d8f177ca..8e80d978 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.cpp +++ b/DRAMSys/traceAnalyzer/data/tracedb.cpp @@ -348,6 +348,11 @@ vector TraceDB::getDebugMessagesInTimespan(const Timespan &span, return parseCommentsFromQuery(selectDebugMessagesByTimespanWithLimit); } +QSqlDatabase TraceDB::getDatabase() const +{ + return database; +} + /* Helpers * * diff --git a/DRAMSys/traceAnalyzer/data/tracedb.h b/DRAMSys/traceAnalyzer/data/tracedb.h index 57a87055..d4c185a0 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.h +++ b/DRAMSys/traceAnalyzer/data/tracedb.h @@ -102,6 +102,8 @@ public: std::vector getDebugMessagesInTimespan(const Timespan &span, unsigned int limit); + QSqlDatabase getDatabase() const; + private: QString pathToDB; QSqlDatabase database; diff --git a/DRAMSys/traceAnalyzer/scripts/plots.py b/DRAMSys/traceAnalyzer/scripts/plots.py index aefb1235..990ba912 100755 --- a/DRAMSys/traceAnalyzer/scripts/plots.py +++ b/DRAMSys/traceAnalyzer/scripts/plots.py @@ -252,6 +252,45 @@ def power_window(connection, tracePath, steps): return outputFile +@plot +def latency_analysis(connection, tracePath, steps): + from collections import Counter + query = """ SELECT ((p2.PhaseEnd - p1.PhaseBegin)/1000), t.id + FROM Transactions t, Phases p1, Phases p2 + WHERE t.id = p1.Transact + AND t.id = p2.Transact + AND p1.PhaseName = "REQ" + AND p2.PhaseName = "RESP" """ + cursor = connection.cursor() + cursor.execute(query) + results = [] + while True: + result = cursor.fetchone() + if (result is not None): + results.append([result[0], result[1]]) + else: + break + + # Create histogram for analysis: + hist = {} + transactions = {} + for i in results: + hist[i[0]] = hist.get(i[0], 0) + 1 + if i[0] in transactions: + transactions[i[0]].append(i[1]) + else: + transactions[i[0]] = [] + + # Find N highest bins + N = 3 + k = Counter(hist) + high = k.most_common(3) + + for i in high: + print(i[0]," :",i[1]," ") + print(transactions[i[0]]) + + return "none\n" @plot def latency_histogram(connection, tracePath, steps): diff --git a/DRAMSys/traceAnalyzer/tracefiletab.cpp b/DRAMSys/traceAnalyzer/tracefiletab.cpp index ca88744c..3acbf409 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.cpp +++ b/DRAMSys/traceAnalyzer/tracefiletab.cpp @@ -41,6 +41,9 @@ #include "QFileInfo" #include "qmessagebox.h" #include +#include +#include +#include TraceFileTab::TraceFileTab(QWidget *parent, const QString &path) : QWidget(parent), ui(new Ui::TraceFileTab), savingChangesToDB(false) @@ -82,7 +85,6 @@ void TraceFileTab::initNavigatorAndItsDependentWidgets(QString path) ui->selectedTransactionTree->init(navigator); //ui->debugMessages->init(navigator,ui->traceplot); ui->commentTree->init(navigator); - } void TraceFileTab::setUpFileWatcher(QString path) @@ -110,3 +112,87 @@ void TraceFileTab::tracefileChanged() navigator->refreshData(); } +class ItemDelegate: public QItemDelegate +{ +public: + ItemDelegate(QObject* parent = nullptr): QItemDelegate(parent) + { + } + + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const + { + if (index.column() == 1) { + double progress = index.data().toDouble(); + QStyleOptionProgressBar opt; + opt.rect = option.rect; + opt.minimum = 0; + opt.maximum = 100; + opt.progress = static_cast(progress); + opt.text = QString::number(progress, 'f', 2)+" %"; + opt.textVisible = true; + QApplication::style()->drawControl(QStyle::CE_ProgressBar, &opt, painter, nullptr); + } else { + QItemDelegate::paint(painter, option, index); + } + } +}; + +void TraceFileTab::on_tabWidget_currentChanged(int index) +{ + if(index == 1) // Changed to latency tab: + { + // Create Database Setup and Query: + QString sql = "SELECT ((p2.PhaseEnd - p1.PhaseBegin)/1000) as latency, t.id " + "FROM Transactions t, Phases p1, Phases p2 " + "WHERE t.id = p1.Transact " + "AND t.id = p2.Transact " + "AND p1.PhaseName = \"REQ\" " + "AND p2.PhaseName = \"RESP\" ORDER BY latency;"; + + QSqlDatabase db = navigator->TraceFile().getDatabase(); + QSqlQuery query(db); + query.exec(sql); + + // Creatoe model and fill it from Database: + QStandardItemModel* model = new QStandardItemModel(); + + int currentLatency = 0; + QStandardItem* currentLatencyItem = nullptr; + int counter = 0; + while (query.next()) { + if(query.value(0) != currentLatency) { + currentLatencyItem = new QStandardItem(QString::number(query.value(0).toInt())+" ns"); + currentLatency = query.value(0).toInt(); + QList row; + row.append(currentLatencyItem); + row.append(new QStandardItem()); + model->appendRow(row); + } + QStandardItem * id = new QStandardItem(query.value(1).toString()); + currentLatencyItem->appendRow(id); + counter++; + } + QStringList header = {"Latency","Occurences"}; + model->setHorizontalHeaderLabels(header); + + // Generate Histrogram: + for(int i = 0; i < model->rowCount(); i++) { + int numberOfChilds = model->item(i)->rowCount(); + double percentage = 100*((double(numberOfChilds))/(double(counter))); + model->item(i,1)->setText(QString::number(percentage)); + } + ui->latencyTreeView->setItemDelegate(new ItemDelegate(ui->latencyTreeView)); + ui->latencyTreeView->setModel(model); + } +} + +void TraceFileTab::on_latencyTreeView_doubleClicked(const QModelIndex &index) +{ + // Get onlye the leaf: + if(index.column() == 0 && index.model()->hasChildren(index) == false) { + unsigned int id = index.data().toUInt(); + if(id!=0) { + navigator->selectTransaction(id); + } + } +} diff --git a/DRAMSys/traceAnalyzer/tracefiletab.h b/DRAMSys/traceAnalyzer/tracefiletab.h index ddc912cc..a802e5b8 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.h +++ b/DRAMSys/traceAnalyzer/tracefiletab.h @@ -79,6 +79,9 @@ public Q_SLOTS: Q_SIGNALS: void statusChanged(QString message, bool saveChangesEnable = false); void colorGroupingChanged(ColorGrouping colorgrouping); +private Q_SLOTS: + void on_tabWidget_currentChanged(int index); + void on_latencyTreeView_doubleClicked(const QModelIndex &index); }; #endif // TRACEFILETAB_H diff --git a/DRAMSys/traceAnalyzer/tracefiletab.ui b/DRAMSys/traceAnalyzer/tracefiletab.ui index d6951f1b..77e62437 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.ui +++ b/DRAMSys/traceAnalyzer/tracefiletab.ui @@ -58,46 +58,88 @@ - - - - 3 - 3 - - + - 300 - 0 + 0 + 500 - - - 16777215 - 16777215 - - - - true - - - false - - - false - - + 0 - - true - + + + Selected Transaction + + + + + + + + + 3 + 3 + + + + + 300 + 0 + + + + + 16777215 + 16777215 + + + + true + + + false + + + false + + + 0 + + + true + + + + + + + + + + Latency Analysis + + + + + + + + QAbstractItemView::NoEditTriggers + + + + + + + - + 2 1 @@ -105,7 +147,7 @@ 300 - 0 + 200 From d2878c62f29cc12a7b317a36ca548bbb1c45aece Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 28 Oct 2020 11:18:13 +0100 Subject: [PATCH 37/50] Add reorder arbiter. --- .../src/configuration/Configuration.cpp | 9 + .../library/src/configuration/Configuration.h | 1 + DRAMSys/library/src/simulation/Arbiter.cpp | 263 +++++++++++++----- DRAMSys/library/src/simulation/Arbiter.h | 47 +++- DRAMSys/library/src/simulation/DRAMSys.cpp | 5 +- .../src/simulation/DRAMSysRecordable.cpp | 5 +- 6 files changed, 261 insertions(+), 69 deletions(-) diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index b4fb45b9..d41307b6 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -137,6 +137,15 @@ void Configuration::setParameter(std::string name, nlohmann::json value) else SC_REPORT_FATAL("Configuration", "Unsupported response queue!"); } + else if (name == "Arbiter") + { + if (value == "Fifo") + arbiter = Arbiter::Fifo; + else if (value == "Reorder") + arbiter = Arbiter::Reorder; + else + SC_REPORT_FATAL("Configuration", "Unsupported arbiter!"); + } else if (name == "RefreshPolicy") { if (value == "NoRefresh") diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index cad71c04..003a8748 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -74,6 +74,7 @@ public: enum class SchedulerBuffer {Bankwise, ReadWrite} schedulerBuffer; enum class CmdMux {Oldest, Strict} cmdMux; enum class RespQueue {Fifo, Reorder} respQueue; + enum class Arbiter {Fifo, Reorder} arbiter; unsigned int requestBufferSize = 8; enum class RefreshPolicy {NoRefresh, Rankwise, Bankwise} refreshPolicy; unsigned int refreshMaxPostponed = 0; diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 5ef44350..fd38aa75 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -33,6 +33,7 @@ * Robert Gernhardt * Matthias Jung * Eder F. Zulian + * Lukas Steiner */ #include "Arbiter.h" @@ -54,6 +55,12 @@ Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) : addressDecoder->print(); } +ArbiterFifo::ArbiterFifo(sc_module_name name, std::string pathToAddressMapping) : + Arbiter(name, pathToAddressMapping) {} + +ArbiterReorder::ArbiterReorder(sc_module_name name, std::string pathToAddressMapping) : + Arbiter(name, pathToAddressMapping) {} + Arbiter::~Arbiter() { delete addressDecoder; @@ -64,7 +71,6 @@ void Arbiter::end_of_elaboration() for (unsigned i = 0; i < tSocket.size(); i++) // initiator side { threadIsBusy.push_back(false); - pendingResponses.push_back(std::queue()); nextThreadPayloadIDToAppend.push_back(0); activeTransactions.push_back(0); outstandingEndReq.push_back(nullptr); @@ -78,6 +84,40 @@ void Arbiter::end_of_elaboration() } } +void ArbiterFifo::end_of_elaboration() +{ + Arbiter::end_of_elaboration(); + + for (unsigned i = 0; i < tSocket.size(); i++) // initiator side + pendingResponses.push_back(std::queue()); +} + +void ArbiterReorder::end_of_elaboration() +{ + Arbiter::end_of_elaboration(); + + for (unsigned i = 0; i < tSocket.size(); i++) // initiator side + { + pendingResponses.push_back(std::set()); + nextThreadPayloadIDToReturn.push_back(0); + } +} + +void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload, sc_time delay) +{ + // Set Generation Extension and DRAM Extension + GenerationExtension::setExtension(&payload, sc_time_stamp() + delay); + + unsigned int burstlength = payload.get_streaming_width(); + DecodedAddress decodedAddress = addressDecoder->decodeAddress(payload.get_address()); + DramExtension::setExtension(payload, Thread(static_cast(socketId)), + Channel(decodedAddress.channel), Rank(decodedAddress.rank), + BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank), + Row(decodedAddress.row), Column(decodedAddress.column), + burstlength, nextThreadPayloadIDToAppend[static_cast(socketId)]++, + nextChannelPayloadIDToAppend[decodedAddress.channel]++); +} + tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, tlm_phase &phase, sc_time &fwDelay) { @@ -119,12 +159,12 @@ unsigned int Arbiter::transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) return iSocket[static_cast(decodedAddress.channel)]->transport_dbg(trans); } -void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) +void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &cbPhase) { - unsigned int threadId = DramExtension::getExtension(payload).getThread().ID(); - unsigned int channelId = DramExtension::getExtension(payload).getChannel().ID(); + unsigned int threadId = DramExtension::getExtension(cbPayload).getThread().ID(); + unsigned int channelId = DramExtension::getExtension(cbPayload).getChannel().ID(); - if (phase == BEGIN_REQ) // from initiator + if (cbPhase == BEGIN_REQ) // from initiator { activeTransactions[threadId]++; @@ -132,38 +172,28 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) { tlm_phase tPhase = END_REQ; sc_time tDelay = SC_ZERO_TIME; - tSocket[static_cast(threadId)]->nb_transport_bw(payload, tPhase, tDelay); + tSocket[static_cast(threadId)]->nb_transport_bw(cbPayload, tPhase, tDelay); } else { - outstandingEndReq[threadId] = &payload; + outstandingEndReq[threadId] = &cbPayload; } + pendingRequests[channelId].push(&cbPayload); + if (!channelIsBusy[channelId]) { channelIsBusy[channelId] = true; + tlm_generic_payload *tPayload = pendingRequests[channelId].front(); + pendingRequests[channelId].pop(); tlm_phase tPhase = BEGIN_REQ; sc_time tDelay = tCK; - if (pendingRequests[channelId].empty()) - { - iSocket[static_cast(channelId)]->nb_transport_fw(payload, tPhase, tDelay); - } - else - { - tlm_generic_payload &tPayload = *pendingRequests[channelId].front(); - pendingRequests[channelId].pop(); - pendingRequests[channelId].push(&payload); - iSocket[static_cast(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay); - } - } - else - { - pendingRequests[channelId].push(&payload); + iSocket[static_cast(channelId)]->nb_transport_fw(*tPayload, tPhase, tDelay); } } - else if (phase == END_REQ) // from memory controller + else if (cbPhase == END_REQ) // from memory controller { if (!pendingRequests[channelId].empty()) { @@ -178,66 +208,64 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) channelIsBusy[channelId] = false; } } - else if (phase == BEGIN_RESP) // from memory controller + else if (cbPhase == BEGIN_RESP) // from memory controller { // TODO: use early completion { tlm_phase tPhase = END_RESP; sc_time tDelay = SC_ZERO_TIME; - iSocket[static_cast(channelId)]->nb_transport_fw(payload, tPhase, tDelay); + iSocket[static_cast(channelId)]->nb_transport_fw(cbPayload, tPhase, tDelay); } + pendingResponses[threadId].push(&cbPayload); + if (!threadIsBusy[threadId]) { threadIsBusy[threadId] = true; + tlm_generic_payload *tPayload = pendingResponses[threadId].front(); + pendingResponses[threadId].pop(); tlm_phase tPhase = BEGIN_RESP; sc_time tDelay = tCK; - if (pendingResponses[threadId].empty()) - { - tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(payload, tPhase, tDelay); - if (returnValue == TLM_UPDATED) - payloadEventQueue.notify(payload, tPhase, tDelay); - } - else - { - tlm_generic_payload &tPayload = *pendingResponses[threadId].front(); - pendingResponses[threadId].pop(); - pendingResponses[threadId].push(&payload); - tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay); - if (returnValue == TLM_UPDATED) - payloadEventQueue.notify(tPayload, tPhase, tDelay); - } + tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(*tPayload, tPhase, tDelay); + if (returnValue == TLM_UPDATED) + payloadEventQueue.notify(*tPayload, tPhase, tDelay); if (activeTransactions[threadId] == maxActiveTransactions) { tlm_phase tPhase = END_REQ; sc_time tDelay = SC_ZERO_TIME; - tlm_generic_payload &tPayload = *outstandingEndReq[threadId]; - tSocket[static_cast(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay); + tPayload = outstandingEndReq[threadId]; + tSocket[static_cast(threadId)]->nb_transport_bw(*tPayload, tPhase, tDelay); } activeTransactions[threadId]--; } - else - { - pendingResponses[threadId].push(&payload); - } } - else if (phase == END_RESP) // from initiator + else if (cbPhase == END_RESP) // from initiator { - payload.release(); + cbPayload.release(); if (!pendingResponses[threadId].empty()) { - tlm_generic_payload &tPayload = *pendingResponses[threadId].front(); + tlm_generic_payload *tPayload = pendingResponses[threadId].front(); pendingResponses[threadId].pop(); tlm_phase tPhase = BEGIN_RESP; sc_time tDelay = tCK; - tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay); + tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(*tPayload, tPhase, tDelay); if (returnValue == TLM_UPDATED) - payloadEventQueue.notify(tPayload, tPhase, tDelay); + payloadEventQueue.notify(*tPayload, tPhase, tDelay); + + if (activeTransactions[threadId] == maxActiveTransactions) + { + tlm_phase tPhase = END_REQ; + sc_time tDelay = SC_ZERO_TIME; + tPayload = outstandingEndReq[threadId]; + tSocket[static_cast(threadId)]->nb_transport_bw(*tPayload, tPhase, tDelay); + } + + activeTransactions[threadId]--; } else { @@ -249,17 +277,128 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) "Payload event queue in arbiter was triggered with unknown phase"); } -void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload, sc_time delay) +void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &cbPhase) { - // Set Generation Extension and DRAM Extension - GenerationExtension::setExtension(&payload, sc_time_stamp() + delay); + unsigned int threadId = DramExtension::getExtension(cbPayload).getThread().ID(); + unsigned int channelId = DramExtension::getExtension(cbPayload).getChannel().ID(); - unsigned int burstlength = payload.get_streaming_width(); - DecodedAddress decodedAddress = addressDecoder->decodeAddress(payload.get_address()); - DramExtension::setExtension(payload, Thread(static_cast(socketId)), - Channel(decodedAddress.channel), Rank(decodedAddress.rank), - BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank), - Row(decodedAddress.row), Column(decodedAddress.column), - burstlength, nextThreadPayloadIDToAppend[static_cast(socketId)]++, - nextChannelPayloadIDToAppend[decodedAddress.channel]++); + if (cbPhase == BEGIN_REQ) // from initiator + { + activeTransactions[threadId]++; + + if (activeTransactions[threadId] < maxActiveTransactions) + { + tlm_phase tPhase = END_REQ; + sc_time tDelay = SC_ZERO_TIME; + tSocket[static_cast(threadId)]->nb_transport_bw(cbPayload, tPhase, tDelay); + } + else + { + outstandingEndReq[threadId] = &cbPayload; + } + + pendingRequests[channelId].push(&cbPayload); + + if (!channelIsBusy[channelId]) + { + channelIsBusy[channelId] = true; + + tlm_generic_payload *tPayload = pendingRequests[channelId].front(); + pendingRequests[channelId].pop(); + tlm_phase tPhase = BEGIN_REQ; + sc_time tDelay = tCK; + + iSocket[static_cast(channelId)]->nb_transport_fw(*tPayload, tPhase, tDelay); + } + } + else if (cbPhase == END_REQ) // from memory controller + { + if (!pendingRequests[channelId].empty()) + { + tlm_generic_payload &tPayload = *pendingRequests[channelId].front(); + pendingRequests[channelId].pop(); + tlm_phase tPhase = BEGIN_REQ; + sc_time tDelay = tCK; + iSocket[static_cast(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay); + } + else + { + channelIsBusy[channelId] = false; + } + } + else if (cbPhase == BEGIN_RESP) // from memory controller + { + // TODO: use early completion + { + tlm_phase tPhase = END_RESP; + sc_time tDelay = SC_ZERO_TIME; + iSocket[static_cast(channelId)]->nb_transport_fw(cbPayload, tPhase, tDelay); + } + + pendingResponses[threadId].insert(&cbPayload); + + if (!threadIsBusy[threadId]) + { + tlm_generic_payload *tPayload = *pendingResponses[threadId].begin(); + + if (DramExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[threadId]) + { + nextThreadPayloadIDToReturn[threadId]++; + pendingResponses[threadId].erase(pendingResponses[threadId].begin()); + threadIsBusy[threadId] = true; + + tlm_phase tPhase = BEGIN_RESP; + sc_time tDelay = tCK; + tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(*tPayload, tPhase, tDelay); + if (returnValue == TLM_UPDATED) + payloadEventQueue.notify(*tPayload, tPhase, tDelay); + + if (activeTransactions[threadId] == maxActiveTransactions) + { + tlm_phase tPhase = END_REQ; + sc_time tDelay = SC_ZERO_TIME; + tPayload = outstandingEndReq[threadId]; + tSocket[static_cast(threadId)]->nb_transport_bw(*tPayload, tPhase, tDelay); + } + + activeTransactions[threadId]--; + } + } + } + else if (cbPhase == END_RESP) // from initiator + { + cbPayload.release(); + + tlm_generic_payload *tPayload = *pendingResponses[threadId].begin(); + + if (!pendingResponses[threadId].empty() && + DramExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[threadId]) + { + nextThreadPayloadIDToReturn[threadId]++; + pendingResponses[threadId].erase(pendingResponses[threadId].begin()); + + tlm_phase tPhase = BEGIN_RESP; + sc_time tDelay = tCK; + tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(*tPayload, tPhase, tDelay); + if (returnValue == TLM_UPDATED) + payloadEventQueue.notify(*tPayload, tPhase, tDelay); + + if (activeTransactions[threadId] == maxActiveTransactions) + { + tlm_phase tPhase = END_REQ; + sc_time tDelay = SC_ZERO_TIME; + tPayload = outstandingEndReq[threadId]; + tSocket[static_cast(threadId)]->nb_transport_bw(*tPayload, tPhase, tDelay); + } + + activeTransactions[threadId]--; + } + else + { + threadIsBusy[threadId] = false; + } + } + else + SC_REPORT_FATAL(0, + "Payload event queue in arbiter was triggered with unknown phase"); } diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index faee82da..42a64ef6 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -33,6 +33,7 @@ * Robert Gernhardt * Matthias Jung * Eder F. Zulian + * Lukas Steiner */ #ifndef ARBITER_H @@ -43,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -55,23 +57,22 @@ public: tlm_utils::multi_passthrough_initiator_socket iSocket; tlm_utils::multi_passthrough_target_socket tSocket; + virtual ~Arbiter() override; + +protected: Arbiter(sc_module_name, std::string); SC_HAS_PROCESS(Arbiter); - virtual ~Arbiter() override; - -private: virtual void end_of_elaboration() override; AddressDecoder *addressDecoder; tlm_utils::peq_with_cb_and_phase payloadEventQueue; - void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); + virtual void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) = 0; std::vector threadIsBusy; std::vector channelIsBusy; - std::vector> pendingResponses; std::vector> pendingRequests; std::vector nextThreadPayloadIDToAppend; @@ -93,4 +94,40 @@ private: sc_time tCK; }; +class ArbiterFifo final : public Arbiter +{ +public: + ArbiterFifo(sc_module_name, std::string); + SC_HAS_PROCESS(ArbiterFifo); + virtual ~ArbiterFifo() override {} + +private: + virtual void end_of_elaboration() override; + virtual void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) override; + std::vector> pendingResponses; +}; + +class ArbiterReorder final : public Arbiter +{ +public: + ArbiterReorder(sc_module_name, std::string); + SC_HAS_PROCESS(ArbiterReorder); + virtual ~ArbiterReorder() override {} + +private: + virtual void end_of_elaboration() override; + virtual void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) override; + + struct ThreadPayloadIDCompare + { + bool operator() (const tlm::tlm_generic_payload *lhs, const tlm::tlm_generic_payload *rhs) const + { + return DramExtension::getThreadPayloadID(lhs) < DramExtension::getThreadPayloadID(rhs); + } + }; + std::vector> pendingResponses; + + std::vector nextThreadPayloadIDToReturn; +}; + #endif // ARBITER_H diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 86a5a90c..1720a684 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -195,7 +195,10 @@ void DRAMSys::instantiateModules(const std::string &pathToResources, config.pECC = ecc; // Create arbiter - arbiter = new Arbiter("arbiter", pathToResources + "configs/amconfigs/" + amconfig); + if (config.arbiter == Configuration::Arbiter::Fifo) + arbiter = new ArbiterFifo("arbiter", pathToResources + "configs/amconfigs/" + amconfig); + else if (config.arbiter == Configuration::Arbiter::Reorder) + arbiter = new ArbiterReorder("arbiter", pathToResources + "configs/amconfigs/" + amconfig); // Create controllers and DRAMs MemSpec::MemoryType memoryType = config.memSpec->memoryType; diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp index 57a97ff3..3805044c 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp @@ -136,7 +136,10 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, config.pECC = ecc; // Create arbiter - arbiter = new Arbiter("arbiter", pathToResources + "configs/amconfigs/" + amconfig); + if (config.arbiter == Configuration::Arbiter::Fifo) + arbiter = new ArbiterFifo("arbiter", pathToResources + "configs/amconfigs/" + amconfig); + else if (config.arbiter == Configuration::Arbiter::Reorder) + arbiter = new ArbiterReorder("arbiter", pathToResources + "configs/amconfigs/" + amconfig); // Create controllers and DRAMs MemSpec::MemoryType memoryType = config.memSpec->memoryType; From 9315cd1345d1867000a814c78c057d5aae068b80 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 28 Oct 2020 11:59:09 +0100 Subject: [PATCH 38/50] Set payload IDs at correct time. --- DRAMSys/library/src/common/dramExtensions.cpp | 13 ++++++++ DRAMSys/library/src/common/dramExtensions.h | 5 +++ DRAMSys/library/src/simulation/Arbiter.cpp | 32 ++++++++----------- DRAMSys/library/src/simulation/Arbiter.h | 2 -- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/DRAMSys/library/src/common/dramExtensions.cpp b/DRAMSys/library/src/common/dramExtensions.cpp index 6048d138..09a49be9 100644 --- a/DRAMSys/library/src/common/dramExtensions.cpp +++ b/DRAMSys/library/src/common/dramExtensions.cpp @@ -97,6 +97,19 @@ void DramExtension::setExtension(tlm::tlm_generic_payload &payload, threadPayloadID, channelPayloadID); } +void DramExtension::setPayloadIDs(tlm::tlm_generic_payload *payload, uint64_t threadPayloadID, uint64_t channelPayloadID) +{ + DramExtension *extension; + payload->get_extension(extension); + extension->threadPayloadID = threadPayloadID; + extension->channelPayloadID = channelPayloadID; +} + +void DramExtension::setPayloadIDs(tlm::tlm_generic_payload &payload, uint64_t threadPayloadID, uint64_t channelPayloadID) +{ + DramExtension::setPayloadIDs(&payload, threadPayloadID, channelPayloadID); +} + DramExtension &DramExtension::getExtension(const tlm_generic_payload *payload) { DramExtension *result = nullptr; diff --git a/DRAMSys/library/src/common/dramExtensions.h b/DRAMSys/library/src/common/dramExtensions.h index 3b5f75b7..989bb079 100644 --- a/DRAMSys/library/src/common/dramExtensions.h +++ b/DRAMSys/library/src/common/dramExtensions.h @@ -185,6 +185,11 @@ public: static DramExtension &getExtension(const tlm::tlm_generic_payload *payload); static DramExtension &getExtension(const tlm::tlm_generic_payload &payload); + static void setPayloadIDs(tlm::tlm_generic_payload *payload, + uint64_t threadPayloadID, uint64_t channelPayloadID); + static void setPayloadIDs(tlm::tlm_generic_payload &payload, + uint64_t threadPayloadID, uint64_t channelPayloadID); + // Used for convience, caller could also use getExtension(..) to access these field static Thread getThread(const tlm::tlm_generic_payload *payload); static Thread getThread(const tlm::tlm_generic_payload &payload); diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index fd38aa75..055ad967 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -103,21 +103,6 @@ void ArbiterReorder::end_of_elaboration() } } -void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload, sc_time delay) -{ - // Set Generation Extension and DRAM Extension - GenerationExtension::setExtension(&payload, sc_time_stamp() + delay); - - unsigned int burstlength = payload.get_streaming_width(); - DecodedAddress decodedAddress = addressDecoder->decodeAddress(payload.get_address()); - DramExtension::setExtension(payload, Thread(static_cast(socketId)), - Channel(decodedAddress.channel), Rank(decodedAddress.rank), - BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank), - Row(decodedAddress.row), Column(decodedAddress.column), - burstlength, nextThreadPayloadIDToAppend[static_cast(socketId)]++, - nextChannelPayloadIDToAppend[decodedAddress.channel]++); -} - tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, tlm_phase &phase, sc_time &fwDelay) { @@ -128,10 +113,15 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, { // TODO: do not adjust address permanently // adjust address offset: - payload.set_address(payload.get_address() - - Configuration::getInstance().addressOffset); + uint64_t adjustedAddress = payload.get_address() - Configuration::getInstance().addressOffset; + payload.set_address(adjustedAddress); - appendDramExtension(id, payload, fwDelay); + DecodedAddress decodedAddress = addressDecoder->decodeAddress(adjustedAddress); + DramExtension::setExtension(payload, Thread(static_cast(id)), + Channel(decodedAddress.channel), Rank(decodedAddress.rank), + BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank), + Row(decodedAddress.row), Column(decodedAddress.column), + payload.get_streaming_width(), 0, 0); payload.acquire(); } @@ -166,6 +156,9 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c if (cbPhase == BEGIN_REQ) // from initiator { + GenerationExtension::setExtension(cbPayload, sc_time_stamp()); + DramExtension::setPayloadIDs(cbPayload, + nextThreadPayloadIDToAppend[threadId]++, nextChannelPayloadIDToAppend[channelId]++); activeTransactions[threadId]++; if (activeTransactions[threadId] < maxActiveTransactions) @@ -284,6 +277,9 @@ void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase if (cbPhase == BEGIN_REQ) // from initiator { + GenerationExtension::setExtension(cbPayload, sc_time_stamp()); + DramExtension::setPayloadIDs(cbPayload, + nextThreadPayloadIDToAppend[threadId]++, nextChannelPayloadIDToAppend[channelId]++); activeTransactions[threadId]++; if (activeTransactions[threadId] < maxActiveTransactions) diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 42a64ef6..5683bf7d 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -89,8 +89,6 @@ protected: tlm::tlm_phase &phase, sc_time &bwDelay); unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans); - void appendDramExtension(int socketId, tlm::tlm_generic_payload &payload, sc_time delay); - sc_time tCK; }; From 11bfed8b6a5dea7ce5fb7896da8ef8713e40cd58 Mon Sep 17 00:00:00 2001 From: Matthias Jung Date: Mon, 2 Nov 2020 19:53:53 +0100 Subject: [PATCH 39/50] Finished Latency Analysis Tool in TA --- DRAMSys/traceAnalyzer/tracefiletab.cpp | 119 +++++++++++++-------- DRAMSys/traceAnalyzer/tracefiletab.h | 1 + DRAMSys/traceAnalyzer/tracefiletab.ui | 141 +++++++++++++++---------- 3 files changed, 159 insertions(+), 102 deletions(-) diff --git a/DRAMSys/traceAnalyzer/tracefiletab.cpp b/DRAMSys/traceAnalyzer/tracefiletab.cpp index 3acbf409..b67004b7 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.cpp +++ b/DRAMSys/traceAnalyzer/tracefiletab.cpp @@ -44,6 +44,8 @@ #include #include #include +#include "qwt_plot_histogram.h" +#include TraceFileTab::TraceFileTab(QWidget *parent, const QString &path) : QWidget(parent), ui(new Ui::TraceFileTab), savingChangesToDB(false) @@ -127,7 +129,7 @@ public: opt.rect = option.rect; opt.minimum = 0; opt.maximum = 100; - opt.progress = static_cast(progress); + opt.progress = static_cast(floor(progress)); opt.text = QString::number(progress, 'f', 2)+" %"; opt.textVisible = true; QApplication::style()->drawControl(QStyle::CE_ProgressBar, &opt, painter, nullptr); @@ -139,51 +141,6 @@ public: void TraceFileTab::on_tabWidget_currentChanged(int index) { - if(index == 1) // Changed to latency tab: - { - // Create Database Setup and Query: - QString sql = "SELECT ((p2.PhaseEnd - p1.PhaseBegin)/1000) as latency, t.id " - "FROM Transactions t, Phases p1, Phases p2 " - "WHERE t.id = p1.Transact " - "AND t.id = p2.Transact " - "AND p1.PhaseName = \"REQ\" " - "AND p2.PhaseName = \"RESP\" ORDER BY latency;"; - - QSqlDatabase db = navigator->TraceFile().getDatabase(); - QSqlQuery query(db); - query.exec(sql); - - // Creatoe model and fill it from Database: - QStandardItemModel* model = new QStandardItemModel(); - - int currentLatency = 0; - QStandardItem* currentLatencyItem = nullptr; - int counter = 0; - while (query.next()) { - if(query.value(0) != currentLatency) { - currentLatencyItem = new QStandardItem(QString::number(query.value(0).toInt())+" ns"); - currentLatency = query.value(0).toInt(); - QList row; - row.append(currentLatencyItem); - row.append(new QStandardItem()); - model->appendRow(row); - } - QStandardItem * id = new QStandardItem(query.value(1).toString()); - currentLatencyItem->appendRow(id); - counter++; - } - QStringList header = {"Latency","Occurences"}; - model->setHorizontalHeaderLabels(header); - - // Generate Histrogram: - for(int i = 0; i < model->rowCount(); i++) { - int numberOfChilds = model->item(i)->rowCount(); - double percentage = 100*((double(numberOfChilds))/(double(counter))); - model->item(i,1)->setText(QString::number(percentage)); - } - ui->latencyTreeView->setItemDelegate(new ItemDelegate(ui->latencyTreeView)); - ui->latencyTreeView->setModel(model); - } } void TraceFileTab::on_latencyTreeView_doubleClicked(const QModelIndex &index) @@ -196,3 +153,73 @@ void TraceFileTab::on_latencyTreeView_doubleClicked(const QModelIndex &index) } } } + +void TraceFileTab::on_startLatencyAnalysis_clicked() +{ + // Setup Database: + QSqlDatabase db = navigator->TraceFile().getDatabase(); + QSqlQuery query(db); + + // Check the count of transactions: + QString sql = "SELECT COUNT(*) FROM Transactions;"; + query.exec(sql); + query.next(); + int maxTransactions = query.value(0).toInt(); + + // Create Database Setup and Query: + sql = "SELECT ((p2.PhaseEnd - p1.PhaseBegin)/1000) as latency, t.id " + "FROM Transactions t, Phases p1, Phases p2 " + "WHERE t.id = p1.Transact " + "AND t.id = p2.Transact " + "AND p1.PhaseName = \"REQ\" " + "AND p2.PhaseName = \"RESP\" ORDER BY latency;"; + + query.exec(sql); + + // Creatoe model and fill it from Database: + QStandardItemModel* model = new QStandardItemModel(); + + int currentLatency = 0; + QStandardItem* currentLatencyItem = nullptr; + int counter = 0; + while (query.next()) { + if(query.value(0) != currentLatency) { + currentLatencyItem = new QStandardItem(QString::number(query.value(0).toInt())+" ns"); + currentLatency = query.value(0).toInt(); + QList row; + row.append(currentLatencyItem); + row.append(new QStandardItem()); + model->appendRow(row); + } + QStandardItem * id = new QStandardItem(query.value(1).toString()); + currentLatencyItem->appendRow(id); + counter++; + + int percentage = int(ceil((double(counter))/(double(maxTransactions))*100.0)); + ui->latencyAnalysisProgressBar->setValue(percentage); + } + QStringList header = {"Latency","Occurences"}; + model->setHorizontalHeaderLabels(header); + + // Generate Histrogram and Tree: + QwtPlotHistogram *hist = new QwtPlotHistogram; + QVector *intervals = new QVector; + for(int i = 0; i < model->rowCount(); i++) { + double latency = model->item(i,0)->text().replace(" ns","").toDouble(); + int numberOfChilds = model->item(i)->rowCount(); + double percentage = 100*((double(numberOfChilds))/(double(counter))); + model->item(i,1)->setText(QString::number(percentage)); + intervals->append(QwtIntervalSample(percentage, latency, latency+1)); + } + ui->latencyTreeView->setItemDelegate(new ItemDelegate(ui->latencyTreeView)); + ui->latencyTreeView->setModel(model); + hist->setSamples(*intervals); + hist->attach(ui->latencyPlot); + hist->setPen(QPen(QColor(255,0,0,100))); + hist->setBrush(QBrush(QColor(255,0,0,255))); + ui->latencyPlot->setAxisTitle(0,"Occurences [%]"); + QwtText axisTitle( "Latency [ns]" ); + axisTitle.setFont( ui->latencyPlot->axisTitle( QwtPlot::xBottom ).font() ); + ui->latencyPlot->setAxisTitle( QwtPlot::xBottom, axisTitle ); + ui->latencyPlot->replot(); +} diff --git a/DRAMSys/traceAnalyzer/tracefiletab.h b/DRAMSys/traceAnalyzer/tracefiletab.h index a802e5b8..6ec1cec5 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.h +++ b/DRAMSys/traceAnalyzer/tracefiletab.h @@ -82,6 +82,7 @@ Q_SIGNALS: private Q_SLOTS: void on_tabWidget_currentChanged(int index); void on_latencyTreeView_doubleClicked(const QModelIndex &index); + void on_startLatencyAnalysis_clicked(); }; #endif // TRACEFILETAB_H diff --git a/DRAMSys/traceAnalyzer/tracefiletab.ui b/DRAMSys/traceAnalyzer/tracefiletab.ui index 77e62437..726f36c8 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.ui +++ b/DRAMSys/traceAnalyzer/tracefiletab.ui @@ -56,7 +56,7 @@ - + @@ -112,6 +112,61 @@ + + + + + 2 + 1 + + + + + 300 + 200 + + + + + 16777215 + 16777215 + + + + + 1 + + + + + + + + true + + + + 2 + 1 + + + + + 300 + 0 + + + + + 16777215 + 16777215 + + + + true + + + @@ -123,6 +178,30 @@ + + + + Start Analysis + + + + + + + 0 + + + + + + + + 16777215 + 200 + + + + @@ -136,61 +215,6 @@ - - - - - 2 - 1 - - - - - 300 - 200 - - - - - 16777215 - 16777215 - - - - - 1 - - - - - - - - true - - - - 2 - 1 - - - - - 300 - 0 - - - - - 16777215 - 16777215 - - - - true - - - @@ -198,6 +222,11 @@ + + QwtPlot + QFrame +
qwt_plot.h
+
TracePlot QListView From 0fec34240dadc157d93db7c742d16ee67c16fc95 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 4 Nov 2020 11:15:22 +0100 Subject: [PATCH 40/50] Add scheduler buffer depth recording. --- .../resources/scripts/createTraceDB.sql | 8 ++++- DRAMSys/library/src/common/TlmRecorder.cpp | 15 +++++++- DRAMSys/library/src/common/TlmRecorder.h | 10 ++++-- DRAMSys/library/src/controller/Controller.h | 7 ++-- .../src/controller/ControllerRecordable.cpp | 35 +++++++++++++++++++ .../src/controller/ControllerRecordable.h | 12 +++++-- .../scheduler/BufferCounterBankwise.cpp | 13 ++++--- .../scheduler/BufferCounterBankwise.h | 3 +- .../controller/scheduler/BufferCounterIF.h | 1 + .../scheduler/BufferCounterReadWrite.cpp | 20 +++++++---- .../scheduler/BufferCounterReadWrite.h | 4 +-- .../controller/scheduler/SchedulerFifo.cpp | 5 +++ .../src/controller/scheduler/SchedulerFifo.h | 1 + .../controller/scheduler/SchedulerFrFcfs.cpp | 5 +++ .../controller/scheduler/SchedulerFrFcfs.h | 1 + .../scheduler/SchedulerFrFcfsGrp.cpp | 5 +++ .../controller/scheduler/SchedulerFrFcfsGrp.h | 1 + .../src/controller/scheduler/SchedulerIF.h | 1 + 18 files changed, 124 insertions(+), 23 deletions(-) diff --git a/DRAMSys/library/resources/scripts/createTraceDB.sql b/DRAMSys/library/resources/scripts/createTraceDB.sql index 7a127fac..9eca28d4 100644 --- a/DRAMSys/library/resources/scripts/createTraceDB.sql +++ b/DRAMSys/library/resources/scripts/createTraceDB.sql @@ -6,6 +6,7 @@ DROP TABLE IF EXISTS ranges; DROP TABLE IF EXISTS Transactions; DROP TABLE IF EXISTS DebugMessages; DROP TABLE IF EXISTS Power; +DROP TABLE IF EXISTS BufferDepth; CREATE TABLE Phases( ID INTEGER PRIMARY KEY, @@ -54,6 +55,11 @@ CREATE TABLE Power( AveragePower DOUBLE ); +CREATE TABLE BufferDepth( + Time DOUBLE, + BufferNumber INTEGER, + AverageBufferDepth DOUBLE +); CREATE TABLE Comments( Time INTEGER, @@ -87,7 +93,7 @@ CREATE TABLE Transactions( DataStrobeEnd INTEGER, TimeOfGeneration INTEGER, Command TEXT - ); +); CREATE INDEX ranges_index ON Transactions(Range); CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC); diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index 660fd461..ba2ba856 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -80,6 +80,7 @@ TlmRecorder::~TlmRecorder() sqlite3_finalize(insertDebugMessageStatement); sqlite3_finalize(updateDataStrobeStatement); sqlite3_finalize(insertPowerStatement); + sqlite3_finalize(insertBufferDepthStatement); } void TlmRecorder::recordPower(double timeInSeconds, double averagePower) @@ -89,6 +90,17 @@ void TlmRecorder::recordPower(double timeInSeconds, double averagePower) executeSqlStatement(insertPowerStatement); } +void TlmRecorder::recordBufferDepth(double timeInSeconds, const std::vector &averageBufferDepth) +{ + for (size_t index = 0; index < averageBufferDepth.size(); index++) + { + sqlite3_bind_double(insertBufferDepthStatement, 1, timeInSeconds); + sqlite3_bind_int(insertBufferDepthStatement, 2, index); + sqlite3_bind_double(insertBufferDepthStatement, 3, averageBufferDepth[index]); + executeSqlStatement(insertBufferDepthStatement); + } +} + void TlmRecorder::recordPhase(tlm_generic_payload &trans, tlm_phase phase, sc_time time) { @@ -294,6 +306,7 @@ void TlmRecorder::prepareSqlStatements() insertDebugMessageString = "INSERT INTO DebugMessages (Time,Message) Values (:time,:message)"; insertPowerString = "INSERT INTO Power VALUES (:time,:averagePower)"; + insertBufferDepthString = "INSERT INTO BufferDepth VALUES (:time,:bufferNumber,:averageBufferDepth)"; sqlite3_prepare_v2(db, insertTransactionString.c_str(), -1, &insertTransactionStatement, 0); @@ -310,6 +323,7 @@ void TlmRecorder::prepareSqlStatements() sqlite3_prepare_v2(db, insertDebugMessageString.c_str(), -1, &insertDebugMessageStatement, 0); sqlite3_prepare_v2(db, insertPowerString.c_str(), -1, &insertPowerStatement, 0); + sqlite3_prepare_v2(db, insertBufferDepthString.c_str(), -1, &insertBufferDepthStatement, 0); } void TlmRecorder::insertDebugMessageInDB(std::string message, const sc_time &time) @@ -411,7 +425,6 @@ void TlmRecorder::insertTransactionInDB(Transaction &recordingData) recordingData.cmd.c_str(), recordingData.cmd.length(), NULL); executeSqlStatement(insertTransactionStatement); - } void TlmRecorder::insertRangeInDB(unsigned int id, const sc_time &begin, diff --git a/DRAMSys/library/src/common/TlmRecorder.h b/DRAMSys/library/src/common/TlmRecorder.h index 67d7986b..df301216 100644 --- a/DRAMSys/library/src/common/TlmRecorder.h +++ b/DRAMSys/library/src/common/TlmRecorder.h @@ -77,13 +77,15 @@ public: void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time time); void recordPower(double timeInSeconds, double averagePower); + void recordBufferDepth(double timeInSeconds, const std::vector &averageBufferDepth); void recordDebugMessage(std::string message, sc_time time); void updateDataStrobe(const sc_time &begin, const sc_time &end, tlm::tlm_generic_payload &trans); void closeConnection(); private: - struct Transaction { + struct Transaction + { Transaction() {} Transaction(unsigned int id): id(id) {} @@ -142,10 +144,12 @@ private: sqlite3_stmt *insertTransactionStatement, *insertRangeStatement, *updateRangeStatement, *insertPhaseStatement, *updatePhaseStatement, *insertGeneralInfoStatement, *insertCommandLengthsStatement, - *insertDebugMessageStatement, *updateDataStrobeStatement, *insertPowerStatement; + *insertDebugMessageStatement, *updateDataStrobeStatement, + *insertPowerStatement, *insertBufferDepthStatement; std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString, updatePhaseString, insertGeneralInfoString, insertCommandLengthsString, - insertDebugMessageString, updateDataStrobeString, insertPowerString; + insertDebugMessageString, updateDataStrobeString, insertPowerString, + insertBufferDepthString; }; #endif // TLMRECORDER_H diff --git a/DRAMSys/library/src/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h index 7bcd2eee..20e6b3ad 100644 --- a/DRAMSys/library/src/controller/Controller.h +++ b/DRAMSys/library/src/controller/Controller.h @@ -62,7 +62,7 @@ class Controller : public ControllerIF public: Controller(sc_module_name); SC_HAS_PROCESS(Controller); - virtual ~Controller(); + virtual ~Controller() override; protected: virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &) override; @@ -72,6 +72,9 @@ protected: virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase); virtual void sendToDram(Command, tlm::tlm_generic_payload *); + virtual void controllerMethod(); + + SchedulerIF *scheduler; MemSpec *memSpec; private: @@ -82,7 +85,6 @@ private: std::vector bankMachines; std::vector> bankMachinesOnRank; CmdMuxIF *cmdMux; - SchedulerIF *scheduler; CheckerIF *checker; RespQueueIF *respQueue; std::vector refreshManagers; @@ -99,7 +101,6 @@ private: void startBeginResp(); void finishEndResp(); - void controllerMethod(); sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent; }; diff --git a/DRAMSys/library/src/controller/ControllerRecordable.cpp b/DRAMSys/library/src/controller/ControllerRecordable.cpp index 5d3264bf..93186758 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.cpp +++ b/DRAMSys/library/src/controller/ControllerRecordable.cpp @@ -37,6 +37,15 @@ using namespace tlm; +ControllerRecordable::ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder) + : Controller(name), tlmRecorder(tlmRecorder) +{ + sensitive << bufferDepthWindowEvent; + bufferDepthWindowSize = Configuration::getInstance().windowSize * memSpec->tCK; + slidingAverageBufferDepth = std::vector(scheduler->getBufferDepth().size()); + averageBufferDepth = std::vector(scheduler->getBufferDepth().size()); +} + tlm_sync_enum ControllerRecordable::nb_transport_fw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &delay) { @@ -90,3 +99,29 @@ void ControllerRecordable::recordPhase(tlm_generic_payload &trans, tlm_phase pha tlmRecorder->recordPhase(trans, phase, recTime); } + +void ControllerRecordable::controllerMethod() +{ + sc_time timeDiff = sc_time_stamp() - lastTimeCalled; + const std::vector &bufferDepth = scheduler->getBufferDepth(); + + for (size_t index = 0; index < slidingAverageBufferDepth.size(); index++) + slidingAverageBufferDepth[index] += bufferDepth[index] * timeDiff; + + lastTimeCalled = sc_time_stamp(); + + if (sc_time_stamp() % bufferDepthWindowSize == SC_ZERO_TIME && timeDiff != SC_ZERO_TIME) + { + bufferDepthWindowEvent.notify(bufferDepthWindowSize); + + for (size_t index = 0; index < slidingAverageBufferDepth.size(); index++) + { + averageBufferDepth[index] = slidingAverageBufferDepth[index] / bufferDepthWindowSize; + slidingAverageBufferDepth[index] = SC_ZERO_TIME; + } + + tlmRecorder->recordBufferDepth(sc_time_stamp().to_seconds(), averageBufferDepth); + } + + Controller::controllerMethod(); +} diff --git a/DRAMSys/library/src/controller/ControllerRecordable.h b/DRAMSys/library/src/controller/ControllerRecordable.h index e39555f0..356d7250 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.h +++ b/DRAMSys/library/src/controller/ControllerRecordable.h @@ -41,8 +41,8 @@ class ControllerRecordable final : public Controller { public: - ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder) : - Controller(name), tlmRecorder(tlmRecorder) {} + ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder); + virtual ~ControllerRecordable() override {} protected: virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans, @@ -53,9 +53,17 @@ protected: virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase) override; virtual void sendToDram(Command, tlm::tlm_generic_payload *) override; + virtual void controllerMethod() override; + private: void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time delay); TlmRecorder *tlmRecorder; + + sc_event bufferDepthWindowEvent; + sc_time bufferDepthWindowSize; + std::vector slidingAverageBufferDepth; + std::vector averageBufferDepth; + sc_time lastTimeCalled = SC_ZERO_TIME; }; #endif // CONTROLLERRECORDABLE_H diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.cpp b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.cpp index 43648c19..f1c4f5f0 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.cpp +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.cpp @@ -38,21 +38,26 @@ BufferCounterBankwise::BufferCounterBankwise(unsigned requestBufferSize, unsigned numberOfBanks) : requestBufferSize(requestBufferSize) { - requestsOnBank = std::vector(numberOfBanks, 0); + numRequestsOnBank = std::vector(numberOfBanks, 0); } bool BufferCounterBankwise::hasBufferSpace() const { - return (requestsOnBank[lastBankID] < requestBufferSize); + return (numRequestsOnBank[lastBankID] < requestBufferSize); } void BufferCounterBankwise::storeRequest(tlm::tlm_generic_payload *payload) { lastBankID = DramExtension::getBank(payload).ID(); - requestsOnBank[lastBankID]++; + numRequestsOnBank[lastBankID]++; } void BufferCounterBankwise::removeRequest(tlm::tlm_generic_payload *payload) { - requestsOnBank[DramExtension::getBank(payload).ID()]--; + numRequestsOnBank[DramExtension::getBank(payload).ID()]--; +} + +const std::vector &BufferCounterBankwise::getBufferDepth() const +{ + return numRequestsOnBank; } diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h index 4c351fee..8b7d28fb 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h @@ -46,10 +46,11 @@ public: virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *payload) override; virtual void removeRequest(tlm::tlm_generic_payload *payload) override; + virtual const std::vector &getBufferDepth() const override; private: const unsigned requestBufferSize; - std::vector requestsOnBank; + std::vector numRequestsOnBank; unsigned lastBankID; }; diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h b/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h index 2e76bed2..6e5a3589 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h @@ -43,6 +43,7 @@ public: virtual bool hasBufferSpace() const = 0; virtual void storeRequest(tlm::tlm_generic_payload *payload) = 0; virtual void removeRequest(tlm::tlm_generic_payload *payload) = 0; + virtual const std::vector &getBufferDepth() const = 0; }; #endif // BUFFERCOUNTERIF_H diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.cpp b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.cpp index efdf89db..a43b1241 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.cpp +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.cpp @@ -35,25 +35,33 @@ #include "BufferCounterReadWrite.h" BufferCounterReadWrite::BufferCounterReadWrite(unsigned requestBufferSize) - : requestBufferSize(requestBufferSize) {} + : requestBufferSize(requestBufferSize) +{ + numReadWriteRequests = std::vector(2); +} bool BufferCounterReadWrite::hasBufferSpace() const { - return (numberOfReads < requestBufferSize && numberOfWrites < requestBufferSize); + return (numReadWriteRequests[0] < requestBufferSize && numReadWriteRequests[1] < requestBufferSize); } void BufferCounterReadWrite::storeRequest(tlm::tlm_generic_payload *payload) { if (payload->is_read()) - numberOfReads++; + numReadWriteRequests[0]++; else - numberOfWrites++; + numReadWriteRequests[1]++; } void BufferCounterReadWrite::removeRequest(tlm::tlm_generic_payload *payload) { if (payload->is_read()) - numberOfReads--; + numReadWriteRequests[0]--; else - numberOfWrites--; + numReadWriteRequests[1]--; +} + +const std::vector &BufferCounterReadWrite::getBufferDepth() const +{ + return numReadWriteRequests; } diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h index 3a27b7b8..3d7d07c9 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h @@ -44,11 +44,11 @@ public: virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *payload) override; virtual void removeRequest(tlm::tlm_generic_payload *payload) override; + virtual const std::vector &getBufferDepth() const override; private: const unsigned requestBufferSize; - unsigned numberOfReads = 0; - unsigned numberOfWrites = 0; + std::vector numReadWriteRequests; }; #endif // BUFFERCOUNTERREADWRITE_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp index 2a95b40c..b71f1699 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp @@ -94,3 +94,8 @@ bool SchedulerFifo::hasFurtherRequest(Bank bank) const else return false; } + +const std::vector &SchedulerFifo::getBufferDepth() const +{ + return bufferCounter->getBufferDepth(); +} diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h index 7db8cfbd..37f64e89 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h @@ -54,6 +54,7 @@ public: virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; virtual bool hasFurtherRowHit(Bank, Row) const override; virtual bool hasFurtherRequest(Bank) const override; + virtual const std::vector &getBufferDepth() const override; private: std::vector> buffer; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index 3ba640e1..2ff4ceb7 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -115,3 +115,8 @@ bool SchedulerFrFcfs::hasFurtherRequest(Bank bank) const { return (buffer[bank.ID()].size() >= 2); } + +const std::vector &SchedulerFrFcfs::getBufferDepth() const +{ + return bufferCounter->getBufferDepth(); +} diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h index d2dc6ac3..3b282a60 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h @@ -54,6 +54,7 @@ public: virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; virtual bool hasFurtherRowHit(Bank, Row) const override; virtual bool hasFurtherRequest(Bank) const override; + virtual const std::vector &getBufferDepth() const override; private: std::vector> buffer; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp index 1e7b538a..6ccc89da 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp @@ -143,3 +143,8 @@ bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank) const else return false; } + +const std::vector &SchedulerFrFcfsGrp::getBufferDepth() const +{ + return bufferCounter->getBufferDepth(); +} diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h index 670ccdf8..a802ed7c 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h @@ -54,6 +54,7 @@ public: virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; virtual bool hasFurtherRowHit(Bank, Row) const override; virtual bool hasFurtherRequest(Bank) const override; + virtual const std::vector &getBufferDepth() const override; private: std::vector> buffer; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h index 3c695c76..3c853d31 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h @@ -52,6 +52,7 @@ public: virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const = 0; virtual bool hasFurtherRowHit(Bank, Row) const = 0; virtual bool hasFurtherRequest(Bank) const = 0; + virtual const std::vector &getBufferDepth() const = 0; }; #endif // SCHEDULERIF_H From d85790ad63e793cb6d330230a103dfcf665071a7 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 4 Nov 2020 13:26:28 +0100 Subject: [PATCH 41/50] Add shared scheduler buffer counter. --- DRAMSys/library/CMakeLists.txt | 1 + .../src/configuration/Configuration.cpp | 2 + .../library/src/configuration/Configuration.h | 2 +- .../scheduler/BufferCounterBankwise.h | 2 +- .../controller/scheduler/BufferCounterIF.h | 1 + .../scheduler/BufferCounterReadWrite.h | 2 +- .../scheduler/BufferCounterShared.cpp | 61 +++++++++++++++++++ .../scheduler/BufferCounterShared.h | 54 ++++++++++++++++ .../controller/scheduler/SchedulerFifo.cpp | 8 +++ .../src/controller/scheduler/SchedulerFifo.h | 3 +- .../controller/scheduler/SchedulerFrFcfs.cpp | 8 +++ .../controller/scheduler/SchedulerFrFcfs.h | 3 +- .../scheduler/SchedulerFrFcfsGrp.cpp | 8 +++ .../controller/scheduler/SchedulerFrFcfsGrp.h | 3 +- .../src/controller/scheduler/SchedulerIF.h | 2 +- 15 files changed, 153 insertions(+), 7 deletions(-) create mode 100644 DRAMSys/library/src/controller/scheduler/BufferCounterShared.cpp create mode 100644 DRAMSys/library/src/controller/scheduler/BufferCounterShared.h diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index 6c4e39f8..ed428cea 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -138,6 +138,7 @@ add_library(DRAMSysLibrary src/controller/scheduler/BufferCounterIF.h src/controller/scheduler/BufferCounterBankwise.cpp src/controller/scheduler/BufferCounterReadWrite.cpp + src/controller/scheduler/BufferCounterShared.cpp src/error/eccbaseclass.cpp src/error/ecchamming.cpp diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index d41307b6..ccc97f06 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -110,6 +110,8 @@ void Configuration::setParameter(std::string name, nlohmann::json value) schedulerBuffer = SchedulerBuffer::Bankwise; else if (value == "ReadWrite") schedulerBuffer = SchedulerBuffer::ReadWrite; + else if (value == "Shared") + schedulerBuffer = SchedulerBuffer::Shared; else SC_REPORT_FATAL("Configuration", "Unsupported scheduler buffer!"); } diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index 003a8748..f36911e9 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -71,7 +71,7 @@ public: // MCConfig: enum class PagePolicy {Open, Closed, OpenAdaptive, ClosedAdaptive} pagePolicy; enum class Scheduler {Fifo, FrFcfs, FrFcfsGrp} scheduler; - enum class SchedulerBuffer {Bankwise, ReadWrite} schedulerBuffer; + enum class SchedulerBuffer {Bankwise, ReadWrite, Shared} schedulerBuffer; enum class CmdMux {Oldest, Strict} cmdMux; enum class RespQueue {Fifo, Reorder} respQueue; enum class Arbiter {Fifo, Reorder} arbiter; diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h index 8b7d28fb..19d3ab43 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h @@ -39,7 +39,7 @@ #include "BufferCounterIF.h" -class BufferCounterBankwise : public BufferCounterIF +class BufferCounterBankwise final : public BufferCounterIF { public: BufferCounterBankwise(unsigned requestBufferSize, unsigned numberOfBanks); diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h b/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h index 6e5a3589..5deab172 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h @@ -40,6 +40,7 @@ class BufferCounterIF { public: + virtual ~BufferCounterIF() = default; virtual bool hasBufferSpace() const = 0; virtual void storeRequest(tlm::tlm_generic_payload *payload) = 0; virtual void removeRequest(tlm::tlm_generic_payload *payload) = 0; diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h index 3d7d07c9..a99716b9 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h @@ -37,7 +37,7 @@ #include "BufferCounterIF.h" -class BufferCounterReadWrite : public BufferCounterIF +class BufferCounterReadWrite final : public BufferCounterIF { public: BufferCounterReadWrite(unsigned requestBufferSize); diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterShared.cpp b/DRAMSys/library/src/controller/scheduler/BufferCounterShared.cpp new file mode 100644 index 00000000..459a0078 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterShared.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#include "BufferCounterShared.h" + +BufferCounterShared::BufferCounterShared(unsigned requestBufferSize) + : requestBufferSize(requestBufferSize) +{ + numRequests = std::vector(1); +} + +bool BufferCounterShared::hasBufferSpace() const +{ + return (numRequests[0] < requestBufferSize); +} + +void BufferCounterShared::storeRequest(tlm::tlm_generic_payload *) +{ + numRequests[0]++; +} + +void BufferCounterShared::removeRequest(tlm::tlm_generic_payload *) +{ + numRequests[0]--; +} + +const std::vector &BufferCounterShared::getBufferDepth() const +{ + return numRequests; +} diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterShared.h b/DRAMSys/library/src/controller/scheduler/BufferCounterShared.h new file mode 100644 index 00000000..aefd20ad --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterShared.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#ifndef BUFFERCOUNTERSHARED_H +#define BUFFERCOUNTERSHARED_H + +#include "BufferCounterIF.h" + +class BufferCounterShared final : public BufferCounterIF +{ +public: + BufferCounterShared(unsigned requestBufferSize); + virtual bool hasBufferSpace() const override; + virtual void storeRequest(tlm::tlm_generic_payload *payload) override; + virtual void removeRequest(tlm::tlm_generic_payload *payload) override; + virtual const std::vector &getBufferDepth() const override; + +private: + const unsigned requestBufferSize; + std::vector numRequests; +}; + +#endif // BUFFERCOUNTERSHARED_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp index b71f1699..90d38301 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp @@ -36,6 +36,7 @@ #include "../../configuration/Configuration.h" #include "BufferCounterBankwise.h" #include "BufferCounterReadWrite.h" +#include "BufferCounterShared.h" using namespace tlm; @@ -48,6 +49,13 @@ SchedulerFifo::SchedulerFifo() bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) bufferCounter = new BufferCounterReadWrite(config.requestBufferSize); + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared) + bufferCounter = new BufferCounterShared(config.requestBufferSize); +} + +SchedulerFifo::~SchedulerFifo() +{ + delete bufferCounter; } bool SchedulerFifo::hasBufferSpace() const diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h index 37f64e89..ae06ac48 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h @@ -44,10 +44,11 @@ #include "../BankMachine.h" #include "BufferCounterIF.h" -class SchedulerFifo : public SchedulerIF +class SchedulerFifo final : public SchedulerIF { public: SchedulerFifo(); + virtual ~SchedulerFifo() override; virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *) override; virtual void removeRequest(tlm::tlm_generic_payload *) override; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index 2ff4ceb7..a15dc6f2 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -36,6 +36,7 @@ #include "../../configuration/Configuration.h" #include "BufferCounterBankwise.h" #include "BufferCounterReadWrite.h" +#include "BufferCounterShared.h" using namespace tlm; @@ -48,6 +49,13 @@ SchedulerFrFcfs::SchedulerFrFcfs() bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) bufferCounter = new BufferCounterReadWrite(config.requestBufferSize); + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared) + bufferCounter = new BufferCounterShared(config.requestBufferSize); +} + +SchedulerFrFcfs::~SchedulerFrFcfs() +{ + delete bufferCounter; } bool SchedulerFrFcfs::hasBufferSpace() const diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h index 3b282a60..15633b51 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h @@ -44,10 +44,11 @@ #include "../BankMachine.h" #include "BufferCounterIF.h" -class SchedulerFrFcfs : public SchedulerIF +class SchedulerFrFcfs final : public SchedulerIF { public: SchedulerFrFcfs(); + virtual ~SchedulerFrFcfs() override; virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *) override; virtual void removeRequest(tlm::tlm_generic_payload *) override; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp index 6ccc89da..a1510123 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp @@ -36,6 +36,7 @@ #include "../../configuration/Configuration.h" #include "BufferCounterBankwise.h" #include "BufferCounterReadWrite.h" +#include "BufferCounterShared.h" using namespace tlm; @@ -48,6 +49,13 @@ SchedulerFrFcfsGrp::SchedulerFrFcfsGrp() bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) bufferCounter = new BufferCounterReadWrite(config.requestBufferSize); + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared) + bufferCounter = new BufferCounterShared(config.requestBufferSize); +} + +SchedulerFrFcfsGrp::~SchedulerFrFcfsGrp() +{ + delete bufferCounter; } bool SchedulerFrFcfsGrp::hasBufferSpace() const diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h index a802ed7c..b6f67e1c 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h @@ -44,10 +44,11 @@ #include "../BankMachine.h" #include "BufferCounterIF.h" -class SchedulerFrFcfsGrp : public SchedulerIF +class SchedulerFrFcfsGrp final : public SchedulerIF { public: SchedulerFrFcfsGrp(); + virtual ~SchedulerFrFcfsGrp() override; virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *) override; virtual void removeRequest(tlm::tlm_generic_payload *) override; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h index 3c853d31..fbde3fdb 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h @@ -45,7 +45,7 @@ class BankMachine; class SchedulerIF { public: - virtual ~SchedulerIF() {} + virtual ~SchedulerIF() = default; virtual bool hasBufferSpace() const = 0; virtual void storeRequest(tlm::tlm_generic_payload *) = 0; virtual void removeRequest(tlm::tlm_generic_payload *) = 0; From d7409542a1023e4642a6a7a7ac6ffb5d104d4493 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 4 Nov 2020 15:26:51 +0100 Subject: [PATCH 42/50] Add simple arbiter. --- .../src/configuration/Configuration.cpp | 4 +- .../library/src/configuration/Configuration.h | 2 +- DRAMSys/library/src/controller/Controller.cpp | 10 +- .../src/controller/ControllerRecordable.cpp | 1 + DRAMSys/library/src/simulation/Arbiter.cpp | 100 +++++++++++++++++- DRAMSys/library/src/simulation/Arbiter.h | 14 ++- DRAMSys/library/src/simulation/DRAMSys.cpp | 4 +- .../src/simulation/DRAMSysRecordable.cpp | 4 +- DRAMSys/tests/DDR4/scripts/createTraceDB.sql | 8 +- DRAMSys/tests/HBM2/scripts/createTraceDB.sql | 8 +- .../ddr3_multirank/scripts/createTraceDB.sql | 8 +- .../tests/lpddr4/scripts/createTraceDB.sql | 8 +- 12 files changed, 153 insertions(+), 18 deletions(-) diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index ccc97f06..eb16918b 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -141,7 +141,9 @@ void Configuration::setParameter(std::string name, nlohmann::json value) } else if (name == "Arbiter") { - if (value == "Fifo") + if (value == "Simple") + arbiter = Arbiter::Simple; + else if (value == "Fifo") arbiter = Arbiter::Fifo; else if (value == "Reorder") arbiter = Arbiter::Reorder; diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index f36911e9..0482af9f 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -74,7 +74,7 @@ public: enum class SchedulerBuffer {Bankwise, ReadWrite, Shared} schedulerBuffer; enum class CmdMux {Oldest, Strict} cmdMux; enum class RespQueue {Fifo, Reorder} respQueue; - enum class Arbiter {Fifo, Reorder} arbiter; + enum class Arbiter {Simple, Fifo, Reorder} arbiter; unsigned int requestBufferSize = 8; enum class RefreshPolicy {NoRefresh, Rankwise, Bankwise} refreshPolicy; unsigned int refreshMaxPostponed = 0; diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index f27a1511..3c0fc41b 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -318,16 +318,18 @@ void Controller::controllerMethod() tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &delay) { + sc_time notificationDelay = delay + Configuration::getInstance().memSpec->tCK; + if (phase == BEGIN_REQ) { transToAcquire.payload = &trans; - transToAcquire.time = sc_time_stamp() + delay; - beginReqEvent.notify(delay); + transToAcquire.time = sc_time_stamp() + notificationDelay; + beginReqEvent.notify(notificationDelay); } else if (phase == END_RESP) { - transToRelease.time = sc_time_stamp() + delay; - endRespEvent.notify(delay); + transToRelease.time = sc_time_stamp() + notificationDelay; + endRespEvent.notify(notificationDelay); } else SC_REPORT_FATAL("Controller", "nb_transport_fw in controller was triggered with unknown phase"); diff --git a/DRAMSys/library/src/controller/ControllerRecordable.cpp b/DRAMSys/library/src/controller/ControllerRecordable.cpp index 93186758..3f2a5b44 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.cpp +++ b/DRAMSys/library/src/controller/ControllerRecordable.cpp @@ -44,6 +44,7 @@ ControllerRecordable::ControllerRecordable(sc_module_name name, TlmRecorder *tlm bufferDepthWindowSize = Configuration::getInstance().windowSize * memSpec->tCK; slidingAverageBufferDepth = std::vector(scheduler->getBufferDepth().size()); averageBufferDepth = std::vector(scheduler->getBufferDepth().size()); + bufferDepthWindowEvent.notify(bufferDepthWindowSize); } tlm_sync_enum ControllerRecordable::nb_transport_fw(tlm_generic_payload &trans, diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 055ad967..3b87fa98 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -55,6 +55,9 @@ Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) : addressDecoder->print(); } +ArbiterSimple::ArbiterSimple(sc_module_name name, std::string pathToAddressMapping) : + Arbiter(name, pathToAddressMapping) {} + ArbiterFifo::ArbiterFifo(sc_module_name name, std::string pathToAddressMapping) : Arbiter(name, pathToAddressMapping) {} @@ -84,6 +87,14 @@ void Arbiter::end_of_elaboration() } } +void ArbiterSimple::end_of_elaboration() +{ + Arbiter::end_of_elaboration(); + + for (unsigned i = 0; i < tSocket.size(); i++) // initiator side + pendingResponses.push_back(std::queue()); +} + void ArbiterFifo::end_of_elaboration() { Arbiter::end_of_elaboration(); @@ -124,6 +135,8 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, payload.get_streaming_width(), 0, 0); payload.acquire(); } + else if (phase == END_RESP) + notDelay += tCK; PRINTDEBUGMESSAGE(name(), "[fw] " + getPhaseName(phase) + " notification in " + notDelay.to_string()); @@ -149,6 +162,87 @@ unsigned int Arbiter::transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) return iSocket[static_cast(decodedAddress.channel)]->transport_dbg(trans); } +void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &cbPhase) +{ + unsigned int threadId = DramExtension::getExtension(cbPayload).getThread().ID(); + unsigned int channelId = DramExtension::getExtension(cbPayload).getChannel().ID(); + + if (cbPhase == BEGIN_REQ) // from initiator + { + GenerationExtension::setExtension(cbPayload, sc_time_stamp()); + DramExtension::setPayloadIDs(cbPayload, + nextThreadPayloadIDToAppend[threadId]++, nextChannelPayloadIDToAppend[channelId]++); + + if (!channelIsBusy[channelId]) + { + channelIsBusy[channelId] = true; + + tlm_phase tPhase = BEGIN_REQ; + sc_time tDelay = SC_ZERO_TIME; + iSocket[static_cast(channelId)]->nb_transport_fw(cbPayload, tPhase, tDelay); + } + else + pendingRequests[channelId].push(&cbPayload); + } + else if (cbPhase == END_REQ) // from target + { + { + tlm_phase tPhase = END_REQ; + sc_time tDelay = SC_ZERO_TIME; + tSocket[static_cast(threadId)]->nb_transport_bw(cbPayload, tPhase, tDelay); + } + + if (!pendingRequests[channelId].empty()) + { + tlm_generic_payload &tPayload = *pendingRequests[channelId].front(); + pendingRequests[channelId].pop(); + tlm_phase tPhase = BEGIN_REQ; + sc_time tDelay = SC_ZERO_TIME; + iSocket[static_cast(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay); + } + else + channelIsBusy[channelId] = false; + } + else if (cbPhase == BEGIN_RESP) // from memory controller + { + if (!threadIsBusy[threadId]) + { + tlm_phase tPhase = BEGIN_RESP; + sc_time tDelay = SC_ZERO_TIME; + tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(cbPayload, tPhase, tDelay); + if (returnValue == TLM_UPDATED) + payloadEventQueue.notify(cbPayload, tPhase, tDelay); + threadIsBusy[threadId] = true; + } + else + pendingResponses[threadId].push(&cbPayload); + } + else if (cbPhase == END_RESP) // from initiator + { + { + tlm_phase tPhase = END_RESP; + sc_time tDelay = SC_ZERO_TIME; + iSocket[static_cast(channelId)]->nb_transport_fw(cbPayload, tPhase, tDelay); + } + cbPayload.release(); + + if (!pendingResponses[threadId].empty()) + { + tlm_generic_payload &tPayload = *pendingResponses[threadId].front(); + pendingResponses[threadId].pop(); + tlm_phase tPhase = BEGIN_RESP; + sc_time tDelay = SC_ZERO_TIME; + tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay); + if (returnValue == TLM_UPDATED) + payloadEventQueue.notify(tPayload, tPhase, tDelay); + } + else + threadIsBusy[threadId] = false; + } + else + SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase"); +} + void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &cbPhase) { unsigned int threadId = DramExtension::getExtension(cbPayload).getThread().ID(); @@ -266,8 +360,7 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c } } else - SC_REPORT_FATAL(0, - "Payload event queue in arbiter was triggered with unknown phase"); + SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase"); } void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &cbPhase) @@ -395,6 +488,5 @@ void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase } } else - SC_REPORT_FATAL(0, - "Payload event queue in arbiter was triggered with unknown phase"); + SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase"); } diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 5683bf7d..c3185e2b 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -92,12 +92,23 @@ protected: sc_time tCK; }; +class ArbiterSimple final : public Arbiter +{ +public: + ArbiterSimple(sc_module_name, std::string); + SC_HAS_PROCESS(ArbiterSimple); + +private: + virtual void end_of_elaboration() override; + virtual void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) override; + std::vector> pendingResponses; +}; + class ArbiterFifo final : public Arbiter { public: ArbiterFifo(sc_module_name, std::string); SC_HAS_PROCESS(ArbiterFifo); - virtual ~ArbiterFifo() override {} private: virtual void end_of_elaboration() override; @@ -110,7 +121,6 @@ class ArbiterReorder final : public Arbiter public: ArbiterReorder(sc_module_name, std::string); SC_HAS_PROCESS(ArbiterReorder); - virtual ~ArbiterReorder() override {} private: virtual void end_of_elaboration() override; diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 1720a684..1306b6df 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -195,7 +195,9 @@ void DRAMSys::instantiateModules(const std::string &pathToResources, config.pECC = ecc; // Create arbiter - if (config.arbiter == Configuration::Arbiter::Fifo) + if (config.arbiter == Configuration::Arbiter::Simple) + arbiter = new ArbiterSimple("arbiter", pathToResources + "configs/amconfigs/" + amconfig); + else if (config.arbiter == Configuration::Arbiter::Fifo) arbiter = new ArbiterFifo("arbiter", pathToResources + "configs/amconfigs/" + amconfig); else if (config.arbiter == Configuration::Arbiter::Reorder) arbiter = new ArbiterReorder("arbiter", pathToResources + "configs/amconfigs/" + amconfig); diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp index 3805044c..d2a11d48 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp @@ -136,7 +136,9 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, config.pECC = ecc; // Create arbiter - if (config.arbiter == Configuration::Arbiter::Fifo) + if (config.arbiter == Configuration::Arbiter::Simple) + arbiter = new ArbiterSimple("arbiter", pathToResources + "configs/amconfigs/" + amconfig); + else if (config.arbiter == Configuration::Arbiter::Fifo) arbiter = new ArbiterFifo("arbiter", pathToResources + "configs/amconfigs/" + amconfig); else if (config.arbiter == Configuration::Arbiter::Reorder) arbiter = new ArbiterReorder("arbiter", pathToResources + "configs/amconfigs/" + amconfig); diff --git a/DRAMSys/tests/DDR4/scripts/createTraceDB.sql b/DRAMSys/tests/DDR4/scripts/createTraceDB.sql index 7a127fac..9eca28d4 100644 --- a/DRAMSys/tests/DDR4/scripts/createTraceDB.sql +++ b/DRAMSys/tests/DDR4/scripts/createTraceDB.sql @@ -6,6 +6,7 @@ DROP TABLE IF EXISTS ranges; DROP TABLE IF EXISTS Transactions; DROP TABLE IF EXISTS DebugMessages; DROP TABLE IF EXISTS Power; +DROP TABLE IF EXISTS BufferDepth; CREATE TABLE Phases( ID INTEGER PRIMARY KEY, @@ -54,6 +55,11 @@ CREATE TABLE Power( AveragePower DOUBLE ); +CREATE TABLE BufferDepth( + Time DOUBLE, + BufferNumber INTEGER, + AverageBufferDepth DOUBLE +); CREATE TABLE Comments( Time INTEGER, @@ -87,7 +93,7 @@ CREATE TABLE Transactions( DataStrobeEnd INTEGER, TimeOfGeneration INTEGER, Command TEXT - ); +); CREATE INDEX ranges_index ON Transactions(Range); CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC); diff --git a/DRAMSys/tests/HBM2/scripts/createTraceDB.sql b/DRAMSys/tests/HBM2/scripts/createTraceDB.sql index 7a127fac..9eca28d4 100644 --- a/DRAMSys/tests/HBM2/scripts/createTraceDB.sql +++ b/DRAMSys/tests/HBM2/scripts/createTraceDB.sql @@ -6,6 +6,7 @@ DROP TABLE IF EXISTS ranges; DROP TABLE IF EXISTS Transactions; DROP TABLE IF EXISTS DebugMessages; DROP TABLE IF EXISTS Power; +DROP TABLE IF EXISTS BufferDepth; CREATE TABLE Phases( ID INTEGER PRIMARY KEY, @@ -54,6 +55,11 @@ CREATE TABLE Power( AveragePower DOUBLE ); +CREATE TABLE BufferDepth( + Time DOUBLE, + BufferNumber INTEGER, + AverageBufferDepth DOUBLE +); CREATE TABLE Comments( Time INTEGER, @@ -87,7 +93,7 @@ CREATE TABLE Transactions( DataStrobeEnd INTEGER, TimeOfGeneration INTEGER, Command TEXT - ); +); CREATE INDEX ranges_index ON Transactions(Range); CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC); diff --git a/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql b/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql index 7a127fac..9eca28d4 100644 --- a/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql +++ b/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql @@ -6,6 +6,7 @@ DROP TABLE IF EXISTS ranges; DROP TABLE IF EXISTS Transactions; DROP TABLE IF EXISTS DebugMessages; DROP TABLE IF EXISTS Power; +DROP TABLE IF EXISTS BufferDepth; CREATE TABLE Phases( ID INTEGER PRIMARY KEY, @@ -54,6 +55,11 @@ CREATE TABLE Power( AveragePower DOUBLE ); +CREATE TABLE BufferDepth( + Time DOUBLE, + BufferNumber INTEGER, + AverageBufferDepth DOUBLE +); CREATE TABLE Comments( Time INTEGER, @@ -87,7 +93,7 @@ CREATE TABLE Transactions( DataStrobeEnd INTEGER, TimeOfGeneration INTEGER, Command TEXT - ); +); CREATE INDEX ranges_index ON Transactions(Range); CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC); diff --git a/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql b/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql index 7a127fac..9eca28d4 100644 --- a/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql +++ b/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql @@ -6,6 +6,7 @@ DROP TABLE IF EXISTS ranges; DROP TABLE IF EXISTS Transactions; DROP TABLE IF EXISTS DebugMessages; DROP TABLE IF EXISTS Power; +DROP TABLE IF EXISTS BufferDepth; CREATE TABLE Phases( ID INTEGER PRIMARY KEY, @@ -54,6 +55,11 @@ CREATE TABLE Power( AveragePower DOUBLE ); +CREATE TABLE BufferDepth( + Time DOUBLE, + BufferNumber INTEGER, + AverageBufferDepth DOUBLE +); CREATE TABLE Comments( Time INTEGER, @@ -87,7 +93,7 @@ CREATE TABLE Transactions( DataStrobeEnd INTEGER, TimeOfGeneration INTEGER, Command TEXT - ); +); CREATE INDEX ranges_index ON Transactions(Range); CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC); From 5b4f5e0c749931c2538f159788977219b5402041 Mon Sep 17 00:00:00 2001 From: Matthias Jung Date: Wed, 4 Nov 2020 15:36:13 +0100 Subject: [PATCH 43/50] Added Queue Analysis Plot --- DRAMSys/traceAnalyzer/scripts/plots.py | 50 +++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/DRAMSys/traceAnalyzer/scripts/plots.py b/DRAMSys/traceAnalyzer/scripts/plots.py index 990ba912..dc6def9f 100755 --- a/DRAMSys/traceAnalyzer/scripts/plots.py +++ b/DRAMSys/traceAnalyzer/scripts/plots.py @@ -196,6 +196,55 @@ def memory_utilisation_window(connection, tracePath, steps): return outputFiles +@plot +def queue_window(connection, tracePath, steps): + + import matplotlib.pyplot as plt + from matplotlib.backends.backend_pdf import PdfPages + + cursor = connection.cursor() + cursor.execute("select max(BufferNumber) from BufferDepth;") + bufferNumber = int(cursor.fetchone()[0]) + 1 + + cursor = connection.cursor() + cursor.execute("select MaxBufferDepth from GeneralInfo;") + maxBufferDepth = int(cursor.fetchone()[0]) + + outputFile = "" + outputFileName, basename = createOutputFilename(tracePath, 'queue', '', 'pdf') + outputFile = "{0}\n\t".format(outputFileName) + + QueueFigure = plt.figure(figsize=(10, 5), dpi=300) + QueueFigurePlot = QueueFigure.add_subplot(111) + QueueFigurePlot.set_xlabel('Time [s]') + QueueFigurePlot.set_ylabel('Queue Utilization') + QueueFigurePlot.set_title('Average Queue Utilization: ' + str(basename)) + QueueFigurePlot.grid(True) + + + for b in range(bufferNumber): + cursor.execute("select Time, AverageBufferDepth from BufferDepth where BufferNumber = {};".format(b)) + time = [None] * steps + queue = [None] * steps + for i in range(steps-1): + result = cursor.fetchone() + time[i] = result[0] + queue[i] = result[1] + + QueueFigurePlot.plot(time, queue, linewidth=0.5, label="Queue {}".format(b)) + + QueueFigurePlot.legend(loc="upper left") + + x1,x2,y1,y2 = QueueFigurePlot.axis() + QueueFigurePlot.axis((x1,x2,0,maxBufferDepth)) + + pdf = PdfPages(outputFileName) + pdf.savefig(QueueFigure) + pdf.close() + QueueFigurePlot.clear() + plt.close() + + return outputFile @plot def power_window(connection, tracePath, steps): @@ -252,7 +301,6 @@ def power_window(connection, tracePath, steps): return outputFile -@plot def latency_analysis(connection, tracePath, steps): from collections import Counter query = """ SELECT ((p2.PhaseEnd - p1.PhaseBegin)/1000), t.id From 6108c6ca937ac5d19805e576591e684d274b5baf Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 4 Nov 2020 15:46:08 +0100 Subject: [PATCH 44/50] Add max buffer depth to general info table. --- DRAMSys/library/resources/scripts/createTraceDB.sql | 3 ++- DRAMSys/library/src/common/TlmRecorder.cpp | 3 ++- DRAMSys/tests/DDR4/scripts/createTraceDB.sql | 3 ++- DRAMSys/tests/HBM2/scripts/createTraceDB.sql | 3 ++- DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql | 3 ++- DRAMSys/tests/lpddr4/scripts/createTraceDB.sql | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/DRAMSys/library/resources/scripts/createTraceDB.sql b/DRAMSys/library/resources/scripts/createTraceDB.sql index 9eca28d4..680951fb 100644 --- a/DRAMSys/library/resources/scripts/createTraceDB.sql +++ b/DRAMSys/library/resources/scripts/createTraceDB.sql @@ -29,7 +29,8 @@ CREATE TABLE GeneralInfo( WindowSize INTEGER, FlexibleRefresh INTEGER, MaxRefBurst INTEGER, - ControllerThread INTEGER + ControllerThread INTEGER, + MaxBufferDepth INTEGER ); CREATE TABLE CommandLengths( diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index ba2ba856..16d8e14a 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -299,7 +299,7 @@ void TlmRecorder::prepareSqlStatements() insertGeneralInfoString = "INSERT INTO GeneralInfo VALUES" "(:numberOfTransactions,:end,:numberOfRanks,:numberOfBanks,:clk,:unitOfTime,:mcconfig,:memspec," - ":traces,:windowSize, :flexibleRefresh, :maxRefBurst, :controllerThread)"; + ":traces,:windowSize, :flexibleRefresh, :maxRefBurst, :controllerThread, :maxBufferDepth)"; insertCommandLengthsString = "INSERT INTO CommandLengths VALUES" "(:ACT, :PRE, :PREA, :RD, :RDA, :WR, :WRA, :REFA, :REFB, :PDEA, :PDXA, :PDEP, :PDXP, :SREFEN, :SREFEX)"; @@ -369,6 +369,7 @@ void TlmRecorder::insertGeneralInfo() sqlite3_bind_int(insertGeneralInfoStatement, 12, 0); } sqlite3_bind_int(insertGeneralInfoStatement, 13, UINT_MAX); + sqlite3_bind_int(insertGeneralInfoStatement, 14, Configuration::getInstance().requestBufferSize); executeSqlStatement(insertGeneralInfoStatement); } diff --git a/DRAMSys/tests/DDR4/scripts/createTraceDB.sql b/DRAMSys/tests/DDR4/scripts/createTraceDB.sql index 9eca28d4..680951fb 100644 --- a/DRAMSys/tests/DDR4/scripts/createTraceDB.sql +++ b/DRAMSys/tests/DDR4/scripts/createTraceDB.sql @@ -29,7 +29,8 @@ CREATE TABLE GeneralInfo( WindowSize INTEGER, FlexibleRefresh INTEGER, MaxRefBurst INTEGER, - ControllerThread INTEGER + ControllerThread INTEGER, + MaxBufferDepth INTEGER ); CREATE TABLE CommandLengths( diff --git a/DRAMSys/tests/HBM2/scripts/createTraceDB.sql b/DRAMSys/tests/HBM2/scripts/createTraceDB.sql index 9eca28d4..680951fb 100644 --- a/DRAMSys/tests/HBM2/scripts/createTraceDB.sql +++ b/DRAMSys/tests/HBM2/scripts/createTraceDB.sql @@ -29,7 +29,8 @@ CREATE TABLE GeneralInfo( WindowSize INTEGER, FlexibleRefresh INTEGER, MaxRefBurst INTEGER, - ControllerThread INTEGER + ControllerThread INTEGER, + MaxBufferDepth INTEGER ); CREATE TABLE CommandLengths( diff --git a/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql b/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql index 9eca28d4..680951fb 100644 --- a/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql +++ b/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql @@ -29,7 +29,8 @@ CREATE TABLE GeneralInfo( WindowSize INTEGER, FlexibleRefresh INTEGER, MaxRefBurst INTEGER, - ControllerThread INTEGER + ControllerThread INTEGER, + MaxBufferDepth INTEGER ); CREATE TABLE CommandLengths( diff --git a/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql b/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql index 9eca28d4..680951fb 100644 --- a/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql +++ b/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql @@ -29,7 +29,8 @@ CREATE TABLE GeneralInfo( WindowSize INTEGER, FlexibleRefresh INTEGER, MaxRefBurst INTEGER, - ControllerThread INTEGER + ControllerThread INTEGER, + MaxBufferDepth INTEGER ); CREATE TABLE CommandLengths( From 7d7dba4c68c9603b7593fcc3026c126e2edfe0f8 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 4 Nov 2020 16:03:49 +0100 Subject: [PATCH 45/50] Reset simulator config. --- DRAMSys/library/resources/configs/simulator/ddr3.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DRAMSys/library/resources/configs/simulator/ddr3.json b/DRAMSys/library/resources/configs/simulator/ddr3.json index 3f8bf627..99ccdb45 100644 --- a/DRAMSys/library/resources/configs/simulator/ddr3.json +++ b/DRAMSys/library/resources/configs/simulator/ddr3.json @@ -5,10 +5,10 @@ "DatabaseRecording": true, "Debug": false, "ECCControllerMode": "Disabled", - "EnableWindowing": true, + "EnableWindowing": false, "ErrorCSVFile": "", "ErrorChipSeed": 42, - "PowerAnalysis": true, + "PowerAnalysis": false, "SimulationName": "ddr3", "SimulationProgressBar": true, "StoreMode": "NoStorage", From 3be2d9f56be548a836c87e2a7d461dfd1cfa0e39 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 11 Nov 2020 09:51:31 +0100 Subject: [PATCH 46/50] Include average bandwidth windowing. --- .../resources/scripts/createTraceDB.sql | 6 ++++ DRAMSys/library/src/common/TlmRecorder.cpp | 10 ++++++ DRAMSys/library/src/common/TlmRecorder.h | 5 +-- DRAMSys/library/src/controller/Controller.cpp | 2 +- .../src/controller/ControllerRecordable.cpp | 35 ++++++++++++------- .../src/controller/ControllerRecordable.h | 12 +++++-- DRAMSys/tests/DDR4/scripts/createTraceDB.sql | 6 ++++ DRAMSys/tests/HBM2/scripts/createTraceDB.sql | 6 ++++ .../ddr3_multirank/scripts/createTraceDB.sql | 6 ++++ .../tests/lpddr4/scripts/createTraceDB.sql | 6 ++++ 10 files changed, 76 insertions(+), 18 deletions(-) diff --git a/DRAMSys/library/resources/scripts/createTraceDB.sql b/DRAMSys/library/resources/scripts/createTraceDB.sql index fa64b6da..ba429652 100644 --- a/DRAMSys/library/resources/scripts/createTraceDB.sql +++ b/DRAMSys/library/resources/scripts/createTraceDB.sql @@ -7,6 +7,7 @@ DROP TABLE IF EXISTS Transactions; DROP TABLE IF EXISTS DebugMessages; DROP TABLE IF EXISTS Power; DROP TABLE IF EXISTS BufferDepth; +DROP TABLE IF EXISTS Bandwidth; CREATE TABLE Phases( ID INTEGER PRIMARY KEY, @@ -66,6 +67,11 @@ CREATE TABLE BufferDepth( AverageBufferDepth DOUBLE ); +CREATE TABLE Bandwidth( + Time DOUBLE, + AverageBandwidth DOUBLE +); + CREATE TABLE Comments( Time INTEGER, Text TEXT diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index 619aaf75..571d9b0f 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -81,6 +81,7 @@ TlmRecorder::~TlmRecorder() sqlite3_finalize(updateDataStrobeStatement); sqlite3_finalize(insertPowerStatement); sqlite3_finalize(insertBufferDepthStatement); + sqlite3_finalize(insertBandwidthStatement); } void TlmRecorder::recordPower(double timeInSeconds, double averagePower) @@ -101,6 +102,13 @@ void TlmRecorder::recordBufferDepth(double timeInSeconds, const std::vector &averageBufferDepth); + void recordBandwidth(double timeInSeconds, double averageBandwidth); void recordDebugMessage(std::string message, sc_time time); void updateDataStrobe(const sc_time &begin, const sc_time &end, tlm::tlm_generic_payload &trans); @@ -145,11 +146,11 @@ private: *updateRangeStatement, *insertPhaseStatement, *updatePhaseStatement, *insertGeneralInfoStatement, *insertCommandLengthsStatement, *insertDebugMessageStatement, *updateDataStrobeStatement, - *insertPowerStatement, *insertBufferDepthStatement; + *insertPowerStatement, *insertBufferDepthStatement, *insertBandwidthStatement; std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString, updatePhaseString, insertGeneralInfoString, insertCommandLengthsString, insertDebugMessageString, updateDataStrobeString, insertPowerString, - insertBufferDepthString; + insertBufferDepthString, insertBandwidthString; }; #endif // TLMRECORDER_H diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index cdd55f56..7e870207 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -422,6 +422,7 @@ void Controller::startBeginResp() { transToRelease.time = sc_max_time(); sendToFrontend(transToRelease.payload, BEGIN_RESP); + numberOfTransactionsServed++; } else { @@ -441,7 +442,6 @@ void Controller::finishEndResp() transToRelease.payload->release(); transToRelease.payload = nullptr; - numberOfTransactionsServed++; totalNumberOfPayloads--; if (totalNumberOfPayloads == 0) diff --git a/DRAMSys/library/src/controller/ControllerRecordable.cpp b/DRAMSys/library/src/controller/ControllerRecordable.cpp index 3f2a5b44..076e5f04 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.cpp +++ b/DRAMSys/library/src/controller/ControllerRecordable.cpp @@ -40,11 +40,12 @@ using namespace tlm; ControllerRecordable::ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder) : Controller(name), tlmRecorder(tlmRecorder) { - sensitive << bufferDepthWindowEvent; - bufferDepthWindowSize = Configuration::getInstance().windowSize * memSpec->tCK; + sensitive << windowEvent; + windowSizeTime = Configuration::getInstance().windowSize * memSpec->tCK; slidingAverageBufferDepth = std::vector(scheduler->getBufferDepth().size()); - averageBufferDepth = std::vector(scheduler->getBufferDepth().size()); - bufferDepthWindowEvent.notify(bufferDepthWindowSize); + windowAverageBufferDepth = std::vector(scheduler->getBufferDepth().size()); + windowEvent.notify(windowSizeTime); + nextWindowEventTime = windowSizeTime; } tlm_sync_enum ControllerRecordable::nb_transport_fw(tlm_generic_payload &trans, @@ -104,25 +105,35 @@ void ControllerRecordable::recordPhase(tlm_generic_payload &trans, tlm_phase pha void ControllerRecordable::controllerMethod() { sc_time timeDiff = sc_time_stamp() - lastTimeCalled; + lastTimeCalled = sc_time_stamp(); const std::vector &bufferDepth = scheduler->getBufferDepth(); for (size_t index = 0; index < slidingAverageBufferDepth.size(); index++) slidingAverageBufferDepth[index] += bufferDepth[index] * timeDiff; - lastTimeCalled = sc_time_stamp(); - - if (sc_time_stamp() % bufferDepthWindowSize == SC_ZERO_TIME && timeDiff != SC_ZERO_TIME) + if (sc_time_stamp() == nextWindowEventTime) { - bufferDepthWindowEvent.notify(bufferDepthWindowSize); + windowEvent.notify(windowSizeTime); + nextWindowEventTime += windowSizeTime; for (size_t index = 0; index < slidingAverageBufferDepth.size(); index++) { - averageBufferDepth[index] = slidingAverageBufferDepth[index] / bufferDepthWindowSize; + windowAverageBufferDepth[index] = slidingAverageBufferDepth[index] / windowSizeTime; slidingAverageBufferDepth[index] = SC_ZERO_TIME; } - tlmRecorder->recordBufferDepth(sc_time_stamp().to_seconds(), averageBufferDepth); - } + tlmRecorder->recordBufferDepth(sc_time_stamp().to_seconds(), windowAverageBufferDepth); - Controller::controllerMethod(); + Controller::controllerMethod(); + + uint64_t windowNumberOfTransactionsServed = numberOfTransactionsServed - lastNumberOfTransactionsServed; + lastNumberOfTransactionsServed = numberOfTransactionsServed; + sc_time windowActiveTime = windowNumberOfTransactionsServed * activeTimeMultiplier; + double windowAverageBandwidth = windowActiveTime / windowSizeTime; + tlmRecorder->recordBandwidth(sc_time_stamp().to_seconds(), windowAverageBandwidth); + } + else + { + Controller::controllerMethod(); + } } diff --git a/DRAMSys/library/src/controller/ControllerRecordable.h b/DRAMSys/library/src/controller/ControllerRecordable.h index 356d7250..acb910f4 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.h +++ b/DRAMSys/library/src/controller/ControllerRecordable.h @@ -59,11 +59,17 @@ private: void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time delay); TlmRecorder *tlmRecorder; - sc_event bufferDepthWindowEvent; - sc_time bufferDepthWindowSize; + sc_event windowEvent; + sc_time windowSizeTime; + sc_time nextWindowEventTime; std::vector slidingAverageBufferDepth; - std::vector averageBufferDepth; + std::vector windowAverageBufferDepth; sc_time lastTimeCalled = SC_ZERO_TIME; + + uint64_t lastNumberOfTransactionsServed = 0; + sc_time activeTimeMultiplier = Configuration::getInstance().memSpec->burstLength + / Configuration::getInstance().memSpec->dataRate + * Configuration::getInstance().memSpec->tCK; }; #endif // CONTROLLERRECORDABLE_H diff --git a/DRAMSys/tests/DDR4/scripts/createTraceDB.sql b/DRAMSys/tests/DDR4/scripts/createTraceDB.sql index fa64b6da..ba429652 100644 --- a/DRAMSys/tests/DDR4/scripts/createTraceDB.sql +++ b/DRAMSys/tests/DDR4/scripts/createTraceDB.sql @@ -7,6 +7,7 @@ DROP TABLE IF EXISTS Transactions; DROP TABLE IF EXISTS DebugMessages; DROP TABLE IF EXISTS Power; DROP TABLE IF EXISTS BufferDepth; +DROP TABLE IF EXISTS Bandwidth; CREATE TABLE Phases( ID INTEGER PRIMARY KEY, @@ -66,6 +67,11 @@ CREATE TABLE BufferDepth( AverageBufferDepth DOUBLE ); +CREATE TABLE Bandwidth( + Time DOUBLE, + AverageBandwidth DOUBLE +); + CREATE TABLE Comments( Time INTEGER, Text TEXT diff --git a/DRAMSys/tests/HBM2/scripts/createTraceDB.sql b/DRAMSys/tests/HBM2/scripts/createTraceDB.sql index fa64b6da..ba429652 100644 --- a/DRAMSys/tests/HBM2/scripts/createTraceDB.sql +++ b/DRAMSys/tests/HBM2/scripts/createTraceDB.sql @@ -7,6 +7,7 @@ DROP TABLE IF EXISTS Transactions; DROP TABLE IF EXISTS DebugMessages; DROP TABLE IF EXISTS Power; DROP TABLE IF EXISTS BufferDepth; +DROP TABLE IF EXISTS Bandwidth; CREATE TABLE Phases( ID INTEGER PRIMARY KEY, @@ -66,6 +67,11 @@ CREATE TABLE BufferDepth( AverageBufferDepth DOUBLE ); +CREATE TABLE Bandwidth( + Time DOUBLE, + AverageBandwidth DOUBLE +); + CREATE TABLE Comments( Time INTEGER, Text TEXT diff --git a/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql b/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql index fa64b6da..ba429652 100644 --- a/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql +++ b/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql @@ -7,6 +7,7 @@ DROP TABLE IF EXISTS Transactions; DROP TABLE IF EXISTS DebugMessages; DROP TABLE IF EXISTS Power; DROP TABLE IF EXISTS BufferDepth; +DROP TABLE IF EXISTS Bandwidth; CREATE TABLE Phases( ID INTEGER PRIMARY KEY, @@ -66,6 +67,11 @@ CREATE TABLE BufferDepth( AverageBufferDepth DOUBLE ); +CREATE TABLE Bandwidth( + Time DOUBLE, + AverageBandwidth DOUBLE +); + CREATE TABLE Comments( Time INTEGER, Text TEXT diff --git a/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql b/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql index fa64b6da..ba429652 100644 --- a/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql +++ b/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql @@ -7,6 +7,7 @@ DROP TABLE IF EXISTS Transactions; DROP TABLE IF EXISTS DebugMessages; DROP TABLE IF EXISTS Power; DROP TABLE IF EXISTS BufferDepth; +DROP TABLE IF EXISTS Bandwidth; CREATE TABLE Phases( ID INTEGER PRIMARY KEY, @@ -66,6 +67,11 @@ CREATE TABLE BufferDepth( AverageBufferDepth DOUBLE ); +CREATE TABLE Bandwidth( + Time DOUBLE, + AverageBandwidth DOUBLE +); + CREATE TABLE Comments( Time INTEGER, Text TEXT From 7bba11e047a0d2caa7fd08eb024a2a57bf655b17 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 11 Nov 2020 09:52:34 +0100 Subject: [PATCH 47/50] Move initial SQL table into source file. --- .../resources/scripts/createTraceDB.sql | 111 ---------------- DRAMSys/library/src/common/TlmRecorder.cpp | 27 +--- DRAMSys/library/src/common/TlmRecorder.h | 121 +++++++++++++++++- .../src/simulation/DRAMSysRecordable.cpp | 10 +- .../src/simulation/DRAMSysRecordable.h | 3 +- DRAMSys/tests/DDR4/scripts/createTraceDB.sql | 111 ---------------- DRAMSys/tests/HBM2/scripts/createTraceDB.sql | 111 ---------------- .../ddr3_multirank/scripts/createTraceDB.sql | 111 ---------------- .../tests/lpddr4/scripts/createTraceDB.sql | 111 ---------------- 9 files changed, 126 insertions(+), 590 deletions(-) delete mode 100644 DRAMSys/library/resources/scripts/createTraceDB.sql delete mode 100644 DRAMSys/tests/DDR4/scripts/createTraceDB.sql delete mode 100644 DRAMSys/tests/HBM2/scripts/createTraceDB.sql delete mode 100644 DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql delete mode 100644 DRAMSys/tests/lpddr4/scripts/createTraceDB.sql diff --git a/DRAMSys/library/resources/scripts/createTraceDB.sql b/DRAMSys/library/resources/scripts/createTraceDB.sql deleted file mode 100644 index ba429652..00000000 --- a/DRAMSys/library/resources/scripts/createTraceDB.sql +++ /dev/null @@ -1,111 +0,0 @@ -DROP TABLE IF EXISTS Phases; -DROP TABLE IF EXISTS GeneralInfo; -DROP TABLE IF EXISTS CommandLengths; -DROP TABLE IF EXISTS Comments; -DROP TABLE IF EXISTS ranges; -DROP TABLE IF EXISTS Transactions; -DROP TABLE IF EXISTS DebugMessages; -DROP TABLE IF EXISTS Power; -DROP TABLE IF EXISTS BufferDepth; -DROP TABLE IF EXISTS Bandwidth; - -CREATE TABLE Phases( - ID INTEGER PRIMARY KEY, - PhaseName TEXT, - PhaseBegin INTEGER, - PhaseEnd INTEGER, - Transact INTEGER -); - -CREATE TABLE GeneralInfo( - NumberOfTransactions INTEGER, - TraceEnd INTEGER, - NumberOfRanks INTEGER, - NumberOfBankgroups INTEGER, - NumberOfBanks INTEGER, - clk INTEGER, - UnitOfTime TEXT, - MCconfig TEXT, - Memspec TEXT, - Traces TEXT, - WindowSize INTEGER, - FlexibleRefresh INTEGER, - MaxRefBurst INTEGER, - ControllerThread INTEGER, - MaxBufferDepth INTEGER -); - -CREATE TABLE CommandLengths( - NOP INTEGER, - RD INTEGER, - WR INTEGER, - RDA INTEGER, - WRA INTEGER, - ACT INTEGER, - PRE INTEGER, - REFB INTEGER, - PRESB INTEGER, - REFSB INTEGER, - PREA INTEGER, - REFA INTEGER, - PDEA INTEGER, - PDXA INTEGER, - PDEP INTEGER, - PDXP INTEGER, - SREFEN INTEGER, - SREFEX INTEGER -); - -CREATE TABLE Power( - time DOUBLE, - AveragePower DOUBLE -); - -CREATE TABLE BufferDepth( - Time DOUBLE, - BufferNumber INTEGER, - AverageBufferDepth DOUBLE -); - -CREATE TABLE Bandwidth( - Time DOUBLE, - AverageBandwidth DOUBLE -); - -CREATE TABLE Comments( - Time INTEGER, - Text TEXT -); - -CREATE TABLE DebugMessages( - Time INTEGER, - Message TEXT -); - --- use SQLITE R* TREE Module to make queries on timespans effecient (see http://www.sqlite.org/rtree.html) -CREATE VIRTUAL TABLE ranges USING rtree( - id, - begin, end -); - -CREATE TABLE Transactions( - ID INTEGER, - Range INTEGER, - Address INTEGER, - Burstlength INTEGER, - TThread INTEGER, - TChannel INTEGER, - TRank INTEGER, - TBankgroup INTEGER, - TBank INTEGER, - TRow INTEGER, - TColumn INTEGER, - DataStrobeBegin INTEGER, - DataStrobeEnd INTEGER, - TimeOfGeneration INTEGER, - Command TEXT -); - -CREATE INDEX ranges_index ON Transactions(Range); -CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC); -CREATE INDEX "messageTimes" ON "DebugMessages" ("Time" ASC); diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index 571d9b0f..51e941de 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -46,8 +46,8 @@ using namespace tlm; -TlmRecorder::TlmRecorder(std::string name, std::string uri, std::string dbname) : - name(name), sqlScriptURI(uri), dbName(dbname), +TlmRecorder::TlmRecorder(std::string name, std::string dbname) : + dbName(dbname), name(name), totalNumTransactions(1), simulationTimeCoveredByRecording(SC_ZERO_TIME) { recordedData.reserve(transactionCommitRate); @@ -60,7 +60,7 @@ TlmRecorder::TlmRecorder(std::string name, std::string uri, std::string dbname) sqlite3_exec(db, "PRAGMA main.synchronous=OFF", NULL, NULL, &sErrMsg); sqlite3_exec(db, "PRAGMA journal_mode = OFF", NULL, NULL, &sErrMsg); - createTables(TlmRecorder::sqlScriptURI); + executeInitialSqlCommand(); prepareSqlStatements(); PRINTDEBUGMESSAGE(name, "Starting new database transaction"); @@ -256,23 +256,6 @@ void TlmRecorder::openDB(std::string name) } } -void TlmRecorder::createTables(std::string pathToURI) -{ - std::string initial; - ifstream in(pathToURI.c_str(), ios::in | ios::binary); - - if (!in) - SC_REPORT_FATAL("Error loading file", ("Could not load textfile from " + pathToURI).c_str()); - - in.seekg(0, ios::end); - initial.resize(in.tellg()); - in.seekg(0, ios::beg); - in.read(&initial[0], initial.size()); - in.close(); - - executeSqlCommand(initial); -} - void TlmRecorder::setUpTransactionTerminatingPhases() { transactionTerminatingPhases.push_back(END_RESP); @@ -480,12 +463,12 @@ void TlmRecorder::executeSqlStatement(sqlite3_stmt *statement) sqlite3_reset(statement); } -void TlmRecorder::executeSqlCommand(std::string command) +void TlmRecorder::executeInitialSqlCommand() { PRINTDEBUGMESSAGE(name, "Creating database by running provided sql script"); char *errMsg = 0; - int rc = sqlite3_exec(db, command.c_str(), NULL, 0, &errMsg); + int rc = sqlite3_exec(db, initialCommand.c_str(), NULL, 0, &errMsg); if (rc != SQLITE_OK) { SC_REPORT_FATAL("SQLITE Error", errMsg); sqlite3_free(errMsg); diff --git a/DRAMSys/library/src/common/TlmRecorder.h b/DRAMSys/library/src/common/TlmRecorder.h index 2b32b011..8480b966 100644 --- a/DRAMSys/library/src/common/TlmRecorder.h +++ b/DRAMSys/library/src/common/TlmRecorder.h @@ -58,7 +58,7 @@ public: std::string sqlScriptURI; std::string dbName; - TlmRecorder(std::string name, std::string uri, std::string dbname); + TlmRecorder(std::string name, std::string dbname); ~TlmRecorder(); void recordMCconfig(std::string mcconfig) @@ -98,7 +98,8 @@ private: sc_time timeOfGeneration; TimeInterval timeOnDataStrobe; - struct Phase { + struct Phase + { Phase(std::string name, sc_time begin): name(name), interval(begin, SC_ZERO_TIME) {} std::string name; TimeInterval interval; @@ -114,11 +115,10 @@ private: std::string mcconfig, memspec, traces; void prepareSqlStatements(); - void executeSqlCommand(std::string command); + void executeInitialSqlCommand(); void executeSqlStatement(sqlite3_stmt *statement); void openDB(std::string name); - void createTables(std::string pathToURI); void setUpTransactionTerminatingPhases(); void introduceTransactionSystem(tlm::tlm_generic_payload &trans); @@ -151,6 +151,119 @@ private: updatePhaseString, insertGeneralInfoString, insertCommandLengthsString, insertDebugMessageString, updateDataStrobeString, insertPowerString, insertBufferDepthString, insertBandwidthString; + + std::string initialCommand = + "DROP TABLE IF EXISTS Phases; \n" + "DROP TABLE IF EXISTS GeneralInfo; \n" + "DROP TABLE IF EXISTS CommandLengths; \n" + "DROP TABLE IF EXISTS Comments; \n" + "DROP TABLE IF EXISTS ranges; \n" + "DROP TABLE IF EXISTS Transactions; \n" + "DROP TABLE IF EXISTS DebugMessages; \n" + "DROP TABLE IF EXISTS Power; \n" + "DROP TABLE IF EXISTS BufferDepth; \n" + "DROP TABLE IF EXISTS Bandwidth; \n" + " \n" + "CREATE TABLE Phases( \n" + " ID INTEGER PRIMARY KEY, \n" + " PhaseName TEXT, \n" + " PhaseBegin INTEGER, \n" + " PhaseEnd INTEGER, \n" + " Transact INTEGER \n" + "); \n" + " \n" + "CREATE TABLE GeneralInfo( \n" + " NumberOfTransactions INTEGER, \n" + " TraceEnd INTEGER, \n" + " NumberOfRanks INTEGER, \n" + " NumberOfBankgroups INTEGER, \n" + " NumberOfBanks INTEGER, \n" + " clk INTEGER, \n" + " UnitOfTime TEXT, \n" + " MCconfig TEXT, \n" + " Memspec TEXT, \n" + " Traces TEXT, \n" + " WindowSize INTEGER, \n" + " FlexibleRefresh INTEGER, \n" + " MaxRefBurst INTEGER, \n" + " ControllerThread INTEGER, \n" + " MaxBufferDepth INTEGER \n" + "); \n" + " \n" + "CREATE TABLE CommandLengths( \n" + " NOP INTEGER, \n" + " RD INTEGER, \n" + " WR INTEGER, \n" + " RDA INTEGER, \n" + " WRA INTEGER, \n" + " ACT INTEGER, \n" + " PRE INTEGER, \n" + " REFB INTEGER, \n" + " PRESB INTEGER, \n" + " REFSB INTEGER, \n" + " PREA INTEGER, \n" + " REFA INTEGER, \n" + " PDEA INTEGER, \n" + " PDXA INTEGER, \n" + " PDEP INTEGER, \n" + " PDXP INTEGER, \n" + " SREFEN INTEGER, \n" + " SREFEX INTEGER \n" + "); \n" + " \n" + "CREATE TABLE Power( \n" + " time DOUBLE, \n" + " AveragePower DOUBLE \n" + "); \n" + " \n" + "CREATE TABLE BufferDepth( \n" + " Time DOUBLE, \n" + " BufferNumber INTEGER, \n" + " AverageBufferDepth DOUBLE \n" + "); \n" + " \n" + "CREATE TABLE Bandwidth( \n" + " Time DOUBLE, \n" + " AverageBandwidth DOUBLE \n" + "); \n" + " \n" + "CREATE TABLE Comments( \n" + " Time INTEGER, \n" + " Text TEXT \n" + "); \n" + " \n" + "CREATE TABLE DebugMessages( \n" + " Time INTEGER, \n" + " Message TEXT \n" + "); \n" + " \n" + "-- use SQLITE R* TREE Module to make queries on timespans effecient (see http://www.sqlite.org/rtree.html)\n" + "CREATE VIRTUAL TABLE ranges USING rtree( \n" + " id, \n" + " begin, end \n" + "); \n" + " \n" + "CREATE TABLE Transactions( \n" + " ID INTEGER, \n" + " Range INTEGER, \n" + " Address INTEGER, \n" + " Burstlength INTEGER, \n" + " TThread INTEGER, \n" + " TChannel INTEGER, \n" + " TRank INTEGER, \n" + " TBankgroup INTEGER, \n" + " TBank INTEGER, \n" + " TRow INTEGER, \n" + " TColumn INTEGER, \n" + " DataStrobeBegin INTEGER, \n" + " DataStrobeEnd INTEGER, \n" + " TimeOfGeneration INTEGER, \n" + " Command TEXT \n" + "); \n" + " \n" + "CREATE INDEX ranges_index ON Transactions(Range); \n" + "CREATE INDEX \"phasesTransactions\" ON \"Phases\" (\"Transact\" ASC); \n" + "CREATE INDEX \"messageTimes\" ON \"DebugMessages\" (\"Time\" ASC); \n"; }; #endif // TLMRECORDER_H diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp index 5c50081f..cdc0caf5 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp @@ -88,21 +88,17 @@ DRAMSysRecordable::~DRAMSysRecordable() delete rec; } -void DRAMSysRecordable::setupTlmRecorders(const std::string &traceName, - const std::string &pathToResources) +void DRAMSysRecordable::setupTlmRecorders(const std::string &traceName) { // Create TLM Recorders, one per channel. for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) { - std::string sqlScriptURI = pathToResources - + std::string("scripts/createTraceDB.sql"); - std::string dbName = traceName + std::string("_ch") + std::to_string(i) + ".tdb"; std::string recorderName = "tlmRecorder" + std::to_string(i); TlmRecorder *tlmRecorder = - new TlmRecorder(recorderName, sqlScriptURI.c_str(), dbName.c_str()); + new TlmRecorder(recorderName, dbName.c_str()); tlmRecorder->recordMCconfig(Configuration::getInstance().mcconfigUri); tlmRecorder->recordMemspec(Configuration::getInstance().memspecUri); @@ -125,7 +121,7 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, // Create and properly initialize TLM recorders. // They need to be ready before creating some modules. - setupTlmRecorders(traceName, pathToResources); + setupTlmRecorders(traceName); // Create new ECC Controller if (config.eccMode == Configuration::ECCMode::Hamming) diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.h b/DRAMSys/library/src/simulation/DRAMSysRecordable.h index b2f10c8f..6640d40d 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.h +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.h @@ -53,8 +53,7 @@ private: // They generate the output databases. std::vector tlmRecorders; - void setupTlmRecorders(const std::string &traceName, - const std::string &pathToResources); + void setupTlmRecorders(const std::string &traceName); void instantiateModules(const std::string &traceName, const std::string &pathToResources, diff --git a/DRAMSys/tests/DDR4/scripts/createTraceDB.sql b/DRAMSys/tests/DDR4/scripts/createTraceDB.sql deleted file mode 100644 index ba429652..00000000 --- a/DRAMSys/tests/DDR4/scripts/createTraceDB.sql +++ /dev/null @@ -1,111 +0,0 @@ -DROP TABLE IF EXISTS Phases; -DROP TABLE IF EXISTS GeneralInfo; -DROP TABLE IF EXISTS CommandLengths; -DROP TABLE IF EXISTS Comments; -DROP TABLE IF EXISTS ranges; -DROP TABLE IF EXISTS Transactions; -DROP TABLE IF EXISTS DebugMessages; -DROP TABLE IF EXISTS Power; -DROP TABLE IF EXISTS BufferDepth; -DROP TABLE IF EXISTS Bandwidth; - -CREATE TABLE Phases( - ID INTEGER PRIMARY KEY, - PhaseName TEXT, - PhaseBegin INTEGER, - PhaseEnd INTEGER, - Transact INTEGER -); - -CREATE TABLE GeneralInfo( - NumberOfTransactions INTEGER, - TraceEnd INTEGER, - NumberOfRanks INTEGER, - NumberOfBankgroups INTEGER, - NumberOfBanks INTEGER, - clk INTEGER, - UnitOfTime TEXT, - MCconfig TEXT, - Memspec TEXT, - Traces TEXT, - WindowSize INTEGER, - FlexibleRefresh INTEGER, - MaxRefBurst INTEGER, - ControllerThread INTEGER, - MaxBufferDepth INTEGER -); - -CREATE TABLE CommandLengths( - NOP INTEGER, - RD INTEGER, - WR INTEGER, - RDA INTEGER, - WRA INTEGER, - ACT INTEGER, - PRE INTEGER, - REFB INTEGER, - PRESB INTEGER, - REFSB INTEGER, - PREA INTEGER, - REFA INTEGER, - PDEA INTEGER, - PDXA INTEGER, - PDEP INTEGER, - PDXP INTEGER, - SREFEN INTEGER, - SREFEX INTEGER -); - -CREATE TABLE Power( - time DOUBLE, - AveragePower DOUBLE -); - -CREATE TABLE BufferDepth( - Time DOUBLE, - BufferNumber INTEGER, - AverageBufferDepth DOUBLE -); - -CREATE TABLE Bandwidth( - Time DOUBLE, - AverageBandwidth DOUBLE -); - -CREATE TABLE Comments( - Time INTEGER, - Text TEXT -); - -CREATE TABLE DebugMessages( - Time INTEGER, - Message TEXT -); - --- use SQLITE R* TREE Module to make queries on timespans effecient (see http://www.sqlite.org/rtree.html) -CREATE VIRTUAL TABLE ranges USING rtree( - id, - begin, end -); - -CREATE TABLE Transactions( - ID INTEGER, - Range INTEGER, - Address INTEGER, - Burstlength INTEGER, - TThread INTEGER, - TChannel INTEGER, - TRank INTEGER, - TBankgroup INTEGER, - TBank INTEGER, - TRow INTEGER, - TColumn INTEGER, - DataStrobeBegin INTEGER, - DataStrobeEnd INTEGER, - TimeOfGeneration INTEGER, - Command TEXT -); - -CREATE INDEX ranges_index ON Transactions(Range); -CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC); -CREATE INDEX "messageTimes" ON "DebugMessages" ("Time" ASC); diff --git a/DRAMSys/tests/HBM2/scripts/createTraceDB.sql b/DRAMSys/tests/HBM2/scripts/createTraceDB.sql deleted file mode 100644 index ba429652..00000000 --- a/DRAMSys/tests/HBM2/scripts/createTraceDB.sql +++ /dev/null @@ -1,111 +0,0 @@ -DROP TABLE IF EXISTS Phases; -DROP TABLE IF EXISTS GeneralInfo; -DROP TABLE IF EXISTS CommandLengths; -DROP TABLE IF EXISTS Comments; -DROP TABLE IF EXISTS ranges; -DROP TABLE IF EXISTS Transactions; -DROP TABLE IF EXISTS DebugMessages; -DROP TABLE IF EXISTS Power; -DROP TABLE IF EXISTS BufferDepth; -DROP TABLE IF EXISTS Bandwidth; - -CREATE TABLE Phases( - ID INTEGER PRIMARY KEY, - PhaseName TEXT, - PhaseBegin INTEGER, - PhaseEnd INTEGER, - Transact INTEGER -); - -CREATE TABLE GeneralInfo( - NumberOfTransactions INTEGER, - TraceEnd INTEGER, - NumberOfRanks INTEGER, - NumberOfBankgroups INTEGER, - NumberOfBanks INTEGER, - clk INTEGER, - UnitOfTime TEXT, - MCconfig TEXT, - Memspec TEXT, - Traces TEXT, - WindowSize INTEGER, - FlexibleRefresh INTEGER, - MaxRefBurst INTEGER, - ControllerThread INTEGER, - MaxBufferDepth INTEGER -); - -CREATE TABLE CommandLengths( - NOP INTEGER, - RD INTEGER, - WR INTEGER, - RDA INTEGER, - WRA INTEGER, - ACT INTEGER, - PRE INTEGER, - REFB INTEGER, - PRESB INTEGER, - REFSB INTEGER, - PREA INTEGER, - REFA INTEGER, - PDEA INTEGER, - PDXA INTEGER, - PDEP INTEGER, - PDXP INTEGER, - SREFEN INTEGER, - SREFEX INTEGER -); - -CREATE TABLE Power( - time DOUBLE, - AveragePower DOUBLE -); - -CREATE TABLE BufferDepth( - Time DOUBLE, - BufferNumber INTEGER, - AverageBufferDepth DOUBLE -); - -CREATE TABLE Bandwidth( - Time DOUBLE, - AverageBandwidth DOUBLE -); - -CREATE TABLE Comments( - Time INTEGER, - Text TEXT -); - -CREATE TABLE DebugMessages( - Time INTEGER, - Message TEXT -); - --- use SQLITE R* TREE Module to make queries on timespans effecient (see http://www.sqlite.org/rtree.html) -CREATE VIRTUAL TABLE ranges USING rtree( - id, - begin, end -); - -CREATE TABLE Transactions( - ID INTEGER, - Range INTEGER, - Address INTEGER, - Burstlength INTEGER, - TThread INTEGER, - TChannel INTEGER, - TRank INTEGER, - TBankgroup INTEGER, - TBank INTEGER, - TRow INTEGER, - TColumn INTEGER, - DataStrobeBegin INTEGER, - DataStrobeEnd INTEGER, - TimeOfGeneration INTEGER, - Command TEXT -); - -CREATE INDEX ranges_index ON Transactions(Range); -CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC); -CREATE INDEX "messageTimes" ON "DebugMessages" ("Time" ASC); diff --git a/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql b/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql deleted file mode 100644 index ba429652..00000000 --- a/DRAMSys/tests/ddr3_multirank/scripts/createTraceDB.sql +++ /dev/null @@ -1,111 +0,0 @@ -DROP TABLE IF EXISTS Phases; -DROP TABLE IF EXISTS GeneralInfo; -DROP TABLE IF EXISTS CommandLengths; -DROP TABLE IF EXISTS Comments; -DROP TABLE IF EXISTS ranges; -DROP TABLE IF EXISTS Transactions; -DROP TABLE IF EXISTS DebugMessages; -DROP TABLE IF EXISTS Power; -DROP TABLE IF EXISTS BufferDepth; -DROP TABLE IF EXISTS Bandwidth; - -CREATE TABLE Phases( - ID INTEGER PRIMARY KEY, - PhaseName TEXT, - PhaseBegin INTEGER, - PhaseEnd INTEGER, - Transact INTEGER -); - -CREATE TABLE GeneralInfo( - NumberOfTransactions INTEGER, - TraceEnd INTEGER, - NumberOfRanks INTEGER, - NumberOfBankgroups INTEGER, - NumberOfBanks INTEGER, - clk INTEGER, - UnitOfTime TEXT, - MCconfig TEXT, - Memspec TEXT, - Traces TEXT, - WindowSize INTEGER, - FlexibleRefresh INTEGER, - MaxRefBurst INTEGER, - ControllerThread INTEGER, - MaxBufferDepth INTEGER -); - -CREATE TABLE CommandLengths( - NOP INTEGER, - RD INTEGER, - WR INTEGER, - RDA INTEGER, - WRA INTEGER, - ACT INTEGER, - PRE INTEGER, - REFB INTEGER, - PRESB INTEGER, - REFSB INTEGER, - PREA INTEGER, - REFA INTEGER, - PDEA INTEGER, - PDXA INTEGER, - PDEP INTEGER, - PDXP INTEGER, - SREFEN INTEGER, - SREFEX INTEGER -); - -CREATE TABLE Power( - time DOUBLE, - AveragePower DOUBLE -); - -CREATE TABLE BufferDepth( - Time DOUBLE, - BufferNumber INTEGER, - AverageBufferDepth DOUBLE -); - -CREATE TABLE Bandwidth( - Time DOUBLE, - AverageBandwidth DOUBLE -); - -CREATE TABLE Comments( - Time INTEGER, - Text TEXT -); - -CREATE TABLE DebugMessages( - Time INTEGER, - Message TEXT -); - --- use SQLITE R* TREE Module to make queries on timespans effecient (see http://www.sqlite.org/rtree.html) -CREATE VIRTUAL TABLE ranges USING rtree( - id, - begin, end -); - -CREATE TABLE Transactions( - ID INTEGER, - Range INTEGER, - Address INTEGER, - Burstlength INTEGER, - TThread INTEGER, - TChannel INTEGER, - TRank INTEGER, - TBankgroup INTEGER, - TBank INTEGER, - TRow INTEGER, - TColumn INTEGER, - DataStrobeBegin INTEGER, - DataStrobeEnd INTEGER, - TimeOfGeneration INTEGER, - Command TEXT -); - -CREATE INDEX ranges_index ON Transactions(Range); -CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC); -CREATE INDEX "messageTimes" ON "DebugMessages" ("Time" ASC); diff --git a/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql b/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql deleted file mode 100644 index ba429652..00000000 --- a/DRAMSys/tests/lpddr4/scripts/createTraceDB.sql +++ /dev/null @@ -1,111 +0,0 @@ -DROP TABLE IF EXISTS Phases; -DROP TABLE IF EXISTS GeneralInfo; -DROP TABLE IF EXISTS CommandLengths; -DROP TABLE IF EXISTS Comments; -DROP TABLE IF EXISTS ranges; -DROP TABLE IF EXISTS Transactions; -DROP TABLE IF EXISTS DebugMessages; -DROP TABLE IF EXISTS Power; -DROP TABLE IF EXISTS BufferDepth; -DROP TABLE IF EXISTS Bandwidth; - -CREATE TABLE Phases( - ID INTEGER PRIMARY KEY, - PhaseName TEXT, - PhaseBegin INTEGER, - PhaseEnd INTEGER, - Transact INTEGER -); - -CREATE TABLE GeneralInfo( - NumberOfTransactions INTEGER, - TraceEnd INTEGER, - NumberOfRanks INTEGER, - NumberOfBankgroups INTEGER, - NumberOfBanks INTEGER, - clk INTEGER, - UnitOfTime TEXT, - MCconfig TEXT, - Memspec TEXT, - Traces TEXT, - WindowSize INTEGER, - FlexibleRefresh INTEGER, - MaxRefBurst INTEGER, - ControllerThread INTEGER, - MaxBufferDepth INTEGER -); - -CREATE TABLE CommandLengths( - NOP INTEGER, - RD INTEGER, - WR INTEGER, - RDA INTEGER, - WRA INTEGER, - ACT INTEGER, - PRE INTEGER, - REFB INTEGER, - PRESB INTEGER, - REFSB INTEGER, - PREA INTEGER, - REFA INTEGER, - PDEA INTEGER, - PDXA INTEGER, - PDEP INTEGER, - PDXP INTEGER, - SREFEN INTEGER, - SREFEX INTEGER -); - -CREATE TABLE Power( - time DOUBLE, - AveragePower DOUBLE -); - -CREATE TABLE BufferDepth( - Time DOUBLE, - BufferNumber INTEGER, - AverageBufferDepth DOUBLE -); - -CREATE TABLE Bandwidth( - Time DOUBLE, - AverageBandwidth DOUBLE -); - -CREATE TABLE Comments( - Time INTEGER, - Text TEXT -); - -CREATE TABLE DebugMessages( - Time INTEGER, - Message TEXT -); - --- use SQLITE R* TREE Module to make queries on timespans effecient (see http://www.sqlite.org/rtree.html) -CREATE VIRTUAL TABLE ranges USING rtree( - id, - begin, end -); - -CREATE TABLE Transactions( - ID INTEGER, - Range INTEGER, - Address INTEGER, - Burstlength INTEGER, - TThread INTEGER, - TChannel INTEGER, - TRank INTEGER, - TBankgroup INTEGER, - TBank INTEGER, - TRow INTEGER, - TColumn INTEGER, - DataStrobeBegin INTEGER, - DataStrobeEnd INTEGER, - TimeOfGeneration INTEGER, - Command TEXT -); - -CREATE INDEX ranges_index ON Transactions(Range); -CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC); -CREATE INDEX "messageTimes" ON "DebugMessages" ("Time" ASC); From 362ca313038d41b7ccdd34a8d671dd5a1cbcf7a0 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 13 Nov 2020 09:01:05 +0100 Subject: [PATCH 48/50] Use uint64_t for number of lines in trace player. --- DRAMSys/library/src/common/utils.h | 37 ------------------------------ DRAMSys/simulator/StlPlayer.h | 2 +- DRAMSys/simulator/TracePlayer.cpp | 6 ++--- DRAMSys/simulator/TracePlayer.h | 8 +++---- DRAMSys/simulator/TraceSetup.cpp | 34 +++++++++++++++++++++++++++ DRAMSys/simulator/TraceSetup.h | 6 +++-- 6 files changed, 46 insertions(+), 47 deletions(-) diff --git a/DRAMSys/library/src/common/utils.h b/DRAMSys/library/src/common/utils.h index 6d539506..e29a430d 100644 --- a/DRAMSys/library/src/common/utils.h +++ b/DRAMSys/library/src/common/utils.h @@ -65,43 +65,6 @@ public: constexpr const char headline[] = "==========================================================================="; -static inline void loadbar(unsigned int x, - unsigned int n, - unsigned int w = 50, - unsigned int granularity = 1) -{ - 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.125 && c != w) - std::cout << " "; - if (rest >= 0.125 && rest < 2 * 0.125) - std::cout << "▏"; - if (rest >= 2 * 0.125 && rest < 3 * 0.125) - std::cout << "▎"; - if (rest >= 3 * 0.125 && rest < 4 * 0.125) - std::cout << "▍"; - if (rest >= 4 * 0.125 && rest < 5 * 0.125) - std::cout << "▌"; - if (rest >= 5 * 0.125 && rest < 6 * 0.125) - std::cout << "▋"; - if (rest >= 6 * 0.125 && rest < 7 * 0.125) - std::cout << "▊"; - if (rest >= 7 * 0.125 && rest < 8 * 0.125) - std::cout << "▉"; - - for (unsigned int x = c; x < (w - 1); x++) - std::cout << " "; - std::cout << "|\r" << std::flush; -} - std::string getPhaseName(tlm::tlm_phase phase); nlohmann::json parseJSON(std::string path); diff --git a/DRAMSys/simulator/StlPlayer.h b/DRAMSys/simulator/StlPlayer.h index 74e4f713..27081d41 100644 --- a/DRAMSys/simulator/StlPlayer.h +++ b/DRAMSys/simulator/StlPlayer.h @@ -73,7 +73,7 @@ private: std::vector::const_iterator swapBuffers(); std::ifstream file; - unsigned int lineCnt; + uint64_t lineCnt; unsigned int burstlength; unsigned int dataLength; diff --git a/DRAMSys/simulator/TracePlayer.cpp b/DRAMSys/simulator/TracePlayer.cpp index dfdcf848..addee512 100644 --- a/DRAMSys/simulator/TracePlayer.cpp +++ b/DRAMSys/simulator/TracePlayer.cpp @@ -106,7 +106,7 @@ void TracePlayer::sendToTarget(tlm_generic_payload &payload, const tlm_phase &ph iSocket->nb_transport_fw(payload, TPhase, TDelay); } -unsigned int TracePlayer::getNumberOfLines(std::string pathToTrace) +uint64_t TracePlayer::getNumberOfLines(std::string pathToTrace) { // Reference: http://stackoverflow.com/questions/3482064/counting-the-number-of-lines-in-a-text-file ifstream newFile; @@ -114,8 +114,8 @@ unsigned int TracePlayer::getNumberOfLines(std::string pathToTrace) // new lines will be skipped unless we stop it from happening: newFile.unsetf(std::ios_base::skipws); // count the lines with an algorithm specialized for counting: - unsigned int lineCount = std::count(std::istream_iterator(newFile), - std::istream_iterator(), ':'); + uint64_t lineCount = static_cast(std::count(std::istream_iterator(newFile), + std::istream_iterator(), ':')); newFile.close(); return lineCount; diff --git a/DRAMSys/simulator/TracePlayer.h b/DRAMSys/simulator/TracePlayer.h index 998929c9..ad80ec9e 100644 --- a/DRAMSys/simulator/TracePlayer.h +++ b/DRAMSys/simulator/TracePlayer.h @@ -57,7 +57,7 @@ public: TracePlayer(sc_module_name name, TraceSetup *setup); SC_HAS_PROCESS(TracePlayer); virtual void nextPayload() = 0; - unsigned int getNumberOfLines(std::string pathToTrace); + uint64_t getNumberOfLines(std::string pathToTrace); protected: tlm_utils::peq_with_cb_and_phase payloadEventQueue; @@ -67,14 +67,14 @@ protected: TraceSetup *setup; void sendToTarget(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase, const sc_time &delay); - unsigned int numberOfTransactions = 0; - unsigned int transactionsSent = 0; + uint64_t numberOfTransactions = 0; + uint64_t transactionsSent = 0; private: tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_time &bwDelay); void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); - unsigned int transactionsReceived = 0; + uint64_t transactionsReceived = 0; bool finished = false; }; diff --git a/DRAMSys/simulator/TraceSetup.cpp b/DRAMSys/simulator/TraceSetup.cpp index decd5423..91bf1070 100644 --- a/DRAMSys/simulator/TraceSetup.cpp +++ b/DRAMSys/simulator/TraceSetup.cpp @@ -121,3 +121,37 @@ tlm_generic_payload *TraceSetup::allocatePayload() { return memoryManager.allocate(); } + +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/DRAMSys/simulator/TraceSetup.h b/DRAMSys/simulator/TraceSetup.h index 165c8747..5194c29a 100644 --- a/DRAMSys/simulator/TraceSetup.h +++ b/DRAMSys/simulator/TraceSetup.h @@ -56,10 +56,12 @@ public: private: unsigned int numberOfTracePlayers; - unsigned int totalTransactions = 0; - unsigned int remainingTransactions; + uint64_t totalTransactions = 0; + uint64_t remainingTransactions; unsigned int finishedTracePlayers = 0; MemoryManager memoryManager; + + void loadbar(uint64_t x, uint64_t n, unsigned int w = 50, unsigned int granularity = 1); }; #endif // TRACESETUP_H From fc3252f6ef0c1bba33cd2e94413b2986db2a04d0 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 13 Nov 2020 10:57:48 +0100 Subject: [PATCH 49/50] Handle empty configuration files. --- DRAMSys/library/src/common/utils.cpp | 35 ++++++++------- .../src/configuration/Configuration.cpp | 6 +++ DRAMSys/library/src/simulation/DRAMSys.cpp | 4 -- DRAMSys/simulator/StlPlayer.cpp | 15 ++++--- DRAMSys/simulator/TracePlayer.cpp | 43 +++++++++++-------- DRAMSys/simulator/TracePlayer.h | 3 +- DRAMSys/simulator/TraceSetup.cpp | 6 ++- 7 files changed, 61 insertions(+), 51 deletions(-) diff --git a/DRAMSys/library/src/common/utils.cpp b/DRAMSys/library/src/common/utils.cpp index 369bd889..75ceda79 100644 --- a/DRAMSys/library/src/common/utils.cpp +++ b/DRAMSys/library/src/common/utils.cpp @@ -74,18 +74,17 @@ std::string getPhaseName(tlm_phase phase) json parseJSON(std::string path) { - try + std::ifstream file(path); + if (file.is_open()) { - // parsing input with a syntax error - json j = json::parse(std::ifstream(path)); - return j; - } - catch (json::parse_error& e) - { - // output exception information - std::cout << "Error while trying to parse file: " << path << '\n' - << "message: " << e.what() << std::endl; + json j = json::parse(file, nullptr, false); + if (!j.is_discarded()) + return j; + else + throw std::invalid_argument("JSON parse error in file '" + path + "'."); } + else + throw std::invalid_argument("Failed to open file '" + path + "'."); } bool parseBool(json &obj, std::string name) @@ -95,10 +94,10 @@ bool parseBool(json &obj, std::string name) if (obj.is_boolean()) return obj; else - throw std::invalid_argument("Expected type for '" + name + "': bool"); + throw std::invalid_argument("Expected type for parameter '" + name + "': bool"); } else - SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str()); + throw std::invalid_argument("Parameter '" + name + "' does not exist."); } unsigned int parseUint(json &obj, std::string name) @@ -108,10 +107,10 @@ unsigned int parseUint(json &obj, std::string name) if (obj.is_number_unsigned()) return obj; else - throw std::invalid_argument("Expected type for '" + name + "': unsigned int"); + throw std::invalid_argument("Expected type for parameter '" + name + "': unsigned int"); } else - SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str()); + throw std::invalid_argument("Parameter '" + name + "' does not exist."); } double parseUdouble(json &obj, std::string name) @@ -121,10 +120,10 @@ double parseUdouble(json &obj, std::string name) if (obj.is_number() && (obj > 0)) return obj; else - throw std::invalid_argument("Expected type for '" + name + "': positive double"); + throw std::invalid_argument("Expected type for parameter '" + name + "': positive double"); } else - SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str()); + throw std::invalid_argument("Parameter '" + name + "' does not exist."); } std::string parseString(json &obj, std::string name) @@ -134,10 +133,10 @@ std::string parseString(json &obj, std::string name) if (obj.is_string()) return obj; else - throw std::invalid_argument("Expected type for '" + name + "': string"); + throw std::invalid_argument("Expected type for parameter '" + name + "': string"); } else - SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str()); + throw std::invalid_argument("Parameter '" + name + "' does not exist."); } void setUpDummy(tlm_generic_payload &payload, uint64_t channelPayloadID, Rank rank, BankGroup bankgroup, Bank bank) diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 908f37f1..04c03378 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -292,6 +292,8 @@ unsigned int Configuration::adjustNumBytesAfterECC(unsigned nBytes) void Configuration::loadSimConfig(Configuration &config, std::string simconfigUri) { json doc = parseJSON(simconfigUri); + if (doc["simconfig"].empty()) + SC_REPORT_FATAL("Configuration", "simconfig is empty."); for (auto& x : doc["simconfig"].items()) config.setParameter(x.key(), x.value()); } @@ -299,6 +301,8 @@ void Configuration::loadSimConfig(Configuration &config, std::string simconfigUr void Configuration::loadTemperatureSimConfig(Configuration &config, std::string thermalsimconfigUri) { json doc = parseJSON(thermalsimconfigUri); + if (doc["thermalsimconfig"].empty()) + SC_REPORT_FATAL("Configuration", "thermalsimconfig is empty."); for (auto& x : doc["thermalsimconfig"].items()) config.setParameter(x.key(), x.value()); } @@ -307,6 +311,8 @@ void Configuration::loadMCConfig(Configuration &config, std::string mcconfigUri) { config.mcconfigUri = mcconfigUri; json doc = parseJSON(mcconfigUri); + if (doc["mcconfig"].empty()) + SC_REPORT_FATAL("Configuration", "mcconfig is empty."); for (auto& x : doc["mcconfig"].items()) config.setParameter(x.key(), x.value()); } diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 2a6c0ba3..c0d2c123 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -81,10 +81,6 @@ DRAMSys::DRAMSys(sc_module_name name, // Read Configuration Setup: nlohmann::json simulationdoc = parseJSON(simulationToRun); - if (simulationdoc["simulation"].empty()) - SC_REPORT_FATAL("SimulationManager", - "Cannot load simulation: simulation node expected"); - Configuration::getInstance().setPathToResources(pathToResources); // Load config and initialize modules diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index 24fb7227..6c2ea4fb 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -52,7 +52,7 @@ StlPlayer::StlPlayer(sc_module_name name, relative(relative) { if (!file.is_open()) - SC_REPORT_FATAL(0, (std::string("Could not open trace ") + pathToTrace).c_str()); + SC_REPORT_FATAL("StlPlayer", (std::string("Could not open trace ") + pathToTrace).c_str()); this->playerClk = playerClk; burstlength = Configuration::getInstance().memSpec->burstLength; @@ -80,7 +80,7 @@ void StlPlayer::nextPayload() if (lineIterator == currentBuffer->cend()) { // The file is empty. Nothing more to do. - this->finish(); + finished = true; return; } } @@ -125,8 +125,9 @@ void StlPlayer::parseTraceFile() // Get a new line from the input file. std::getline(file, line); lineCnt++; - // If the line starts with '#' (commented lines) the transaction is ignored. - if (line.empty() || line.at(0) == '#') + + // 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++; @@ -160,9 +161,9 @@ void StlPlayer::parseTraceFile() lineCnt) + ").").c_str()); if (command == "read") - content.cmd = tlm::TLM_READ_COMMAND; + content.cmd = TLM_READ_COMMAND; else if (command == "write") - content.cmd = tlm::TLM_WRITE_COMMAND; + content.cmd = TLM_WRITE_COMMAND; else SC_REPORT_FATAL("StlPlayer", (std::string("Corrupted tracefile, command ") + command + @@ -177,7 +178,7 @@ void StlPlayer::parseTraceFile() content.addr = std::stoull(address.c_str(), nullptr, 16); // Get the data if necessary. - if (storageEnabled && content.cmd == tlm::TLM_WRITE_COMMAND) + if (storageEnabled && content.cmd == TLM_WRITE_COMMAND) { // The input trace file must provide the data to be stored into the memory. iss >> dataStr; diff --git a/DRAMSys/simulator/TracePlayer.cpp b/DRAMSys/simulator/TracePlayer.cpp index addee512..7514be7e 100644 --- a/DRAMSys/simulator/TracePlayer.cpp +++ b/DRAMSys/simulator/TracePlayer.cpp @@ -55,14 +55,9 @@ TracePlayer::TracePlayer(sc_module_name name, TraceSetup *setup) : storageEnabled = true; } -void TracePlayer::finish() -{ - finished = true; -} - void TracePlayer::terminate() { - cout << sc_time_stamp() << " " << this->name() << " terminated " << std::endl; + std::cout << sc_time_stamp() << " " << this->name() << " terminated " << std::endl; setup->tracePlayerTerminates(); } @@ -91,11 +86,11 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload, // If all answers were received: if (finished == true && numberOfTransactions == transactionsReceived) - this->terminate(); + terminate(); } else { - SC_REPORT_FATAL(0, "TracePlayer PEQ was triggered with unknown phase"); + SC_REPORT_FATAL("TracePlayer", "PEQ was triggered with unknown phase"); } } @@ -108,15 +103,27 @@ void TracePlayer::sendToTarget(tlm_generic_payload &payload, const tlm_phase &ph uint64_t TracePlayer::getNumberOfLines(std::string pathToTrace) { - // Reference: http://stackoverflow.com/questions/3482064/counting-the-number-of-lines-in-a-text-file - ifstream newFile; - newFile.open(pathToTrace); - // new lines will be skipped unless we stop it from happening: - newFile.unsetf(std::ios_base::skipws); - // count the lines with an algorithm specialized for counting: - uint64_t lineCount = static_cast(std::count(std::istream_iterator(newFile), - std::istream_iterator(), ':')); + std::ifstream file; + file.open(pathToTrace); - newFile.close(); - return lineCount; + if (file.is_open()) + { + uint64_t lineCount = 0; + std::string line; + while (std::getline(file, line)) + { + if (line.size() > 1 && line[0] != '#') + lineCount++; + } + file.close(); + + if (lineCount == 0) + SC_REPORT_FATAL("TracePlayer", "Trace file is empty"); + return lineCount; + } + else + { + SC_REPORT_FATAL("TracePlayer", "Unable to open trace file"); + return 0; + } } diff --git a/DRAMSys/simulator/TracePlayer.h b/DRAMSys/simulator/TracePlayer.h index ad80ec9e..7fc4df35 100644 --- a/DRAMSys/simulator/TracePlayer.h +++ b/DRAMSys/simulator/TracePlayer.h @@ -61,7 +61,6 @@ public: protected: tlm_utils::peq_with_cb_and_phase payloadEventQueue; - void finish(); void terminate(); bool storageEnabled = false; TraceSetup *setup; @@ -69,13 +68,13 @@ protected: const sc_time &delay); uint64_t numberOfTransactions = 0; uint64_t transactionsSent = 0; + bool finished = false; private: tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_time &bwDelay); void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); uint64_t transactionsReceived = 0; - bool finished = false; }; #endif // TRACEPLAYER_H diff --git a/DRAMSys/simulator/TraceSetup.cpp b/DRAMSys/simulator/TraceSetup.cpp index 91bf1070..871be829 100644 --- a/DRAMSys/simulator/TraceSetup.cpp +++ b/DRAMSys/simulator/TraceSetup.cpp @@ -47,10 +47,12 @@ TraceSetup::TraceSetup(std::string uri, nlohmann::json simulationdoc = parseJSON(uri); if (simulationdoc["simulation"].empty()) - SC_REPORT_FATAL("traceSetup", + SC_REPORT_FATAL("TraceSetup", "Cannot load simulation: simulation node expected"); // Load TracePlayers: + if (simulationdoc["simulation"]["tracesetup"].empty()) + SC_REPORT_FATAL("TraceSetup", "tracesetup is empty"); for (auto it : simulationdoc["simulation"]["tracesetup"].items()) { auto value = it.value(); @@ -60,7 +62,7 @@ TraceSetup::TraceSetup(std::string uri, unsigned int frequencyMHz = value["clkMhz"]; if (frequencyMHz == 0) - SC_REPORT_FATAL("traceSetup", "No Frequency Defined"); + SC_REPORT_FATAL("TraceSetup", "No frequency defined"); else playerClk = sc_time(1.0 / frequencyMHz, SC_US); From c5f89293bd7c982b4c5341f364df3c74e6302eb4 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 23 Nov 2020 11:50:44 +0100 Subject: [PATCH 50/50] Insert window bandwidth/buffer depth only when windowing is enabled. --- .../src/controller/ControllerRecordable.cpp | 66 +++++++++++-------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/DRAMSys/library/src/controller/ControllerRecordable.cpp b/DRAMSys/library/src/controller/ControllerRecordable.cpp index 076e5f04..c8ab5efd 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.cpp +++ b/DRAMSys/library/src/controller/ControllerRecordable.cpp @@ -40,12 +40,15 @@ using namespace tlm; ControllerRecordable::ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder) : Controller(name), tlmRecorder(tlmRecorder) { - sensitive << windowEvent; - windowSizeTime = Configuration::getInstance().windowSize * memSpec->tCK; - slidingAverageBufferDepth = std::vector(scheduler->getBufferDepth().size()); - windowAverageBufferDepth = std::vector(scheduler->getBufferDepth().size()); - windowEvent.notify(windowSizeTime); - nextWindowEventTime = windowSizeTime; + if (Configuration::getInstance().enableWindowing) + { + sensitive << windowEvent; + windowSizeTime = Configuration::getInstance().windowSize * memSpec->tCK; + slidingAverageBufferDepth = std::vector(scheduler->getBufferDepth().size()); + windowAverageBufferDepth = std::vector(scheduler->getBufferDepth().size()); + windowEvent.notify(windowSizeTime); + nextWindowEventTime = windowSizeTime; + } } tlm_sync_enum ControllerRecordable::nb_transport_fw(tlm_generic_payload &trans, @@ -104,33 +107,40 @@ void ControllerRecordable::recordPhase(tlm_generic_payload &trans, tlm_phase pha void ControllerRecordable::controllerMethod() { - sc_time timeDiff = sc_time_stamp() - lastTimeCalled; - lastTimeCalled = sc_time_stamp(); - const std::vector &bufferDepth = scheduler->getBufferDepth(); - - for (size_t index = 0; index < slidingAverageBufferDepth.size(); index++) - slidingAverageBufferDepth[index] += bufferDepth[index] * timeDiff; - - if (sc_time_stamp() == nextWindowEventTime) + if (Configuration::getInstance().enableWindowing) { - windowEvent.notify(windowSizeTime); - nextWindowEventTime += windowSizeTime; + sc_time timeDiff = sc_time_stamp() - lastTimeCalled; + lastTimeCalled = sc_time_stamp(); + const std::vector &bufferDepth = scheduler->getBufferDepth(); for (size_t index = 0; index < slidingAverageBufferDepth.size(); index++) + slidingAverageBufferDepth[index] += bufferDepth[index] * timeDiff; + + if (sc_time_stamp() == nextWindowEventTime) { - windowAverageBufferDepth[index] = slidingAverageBufferDepth[index] / windowSizeTime; - slidingAverageBufferDepth[index] = SC_ZERO_TIME; + windowEvent.notify(windowSizeTime); + nextWindowEventTime += windowSizeTime; + + for (size_t index = 0; index < slidingAverageBufferDepth.size(); index++) + { + windowAverageBufferDepth[index] = slidingAverageBufferDepth[index] / windowSizeTime; + slidingAverageBufferDepth[index] = SC_ZERO_TIME; + } + + tlmRecorder->recordBufferDepth(sc_time_stamp().to_seconds(), windowAverageBufferDepth); + + Controller::controllerMethod(); + + uint64_t windowNumberOfTransactionsServed = numberOfTransactionsServed - lastNumberOfTransactionsServed; + lastNumberOfTransactionsServed = numberOfTransactionsServed; + sc_time windowActiveTime = windowNumberOfTransactionsServed * activeTimeMultiplier; + double windowAverageBandwidth = windowActiveTime / windowSizeTime; + tlmRecorder->recordBandwidth(sc_time_stamp().to_seconds(), windowAverageBandwidth); + } + else + { + Controller::controllerMethod(); } - - tlmRecorder->recordBufferDepth(sc_time_stamp().to_seconds(), windowAverageBufferDepth); - - Controller::controllerMethod(); - - uint64_t windowNumberOfTransactionsServed = numberOfTransactionsServed - lastNumberOfTransactionsServed; - lastNumberOfTransactionsServed = numberOfTransactionsServed; - sc_time windowActiveTime = windowNumberOfTransactionsServed * activeTimeMultiplier; - double windowAverageBandwidth = windowActiveTime / windowSizeTime; - tlmRecorder->recordBandwidth(sc_time_stamp().to_seconds(), windowAverageBandwidth); } else {