From 77b79aac13a6396aa6064aab41da73f0e87f0f30 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 17 May 2021 14:03:34 +0200 Subject: [PATCH 1/5] Initial version of STT-MRAM. --- DRAMSys/library/CMakeLists.txt | 3 + .../src/configuration/Configuration.cpp | 3 + .../src/configuration/memspec/MemSpec.h | 3 +- .../configuration/memspec/MemSpecSTTMRAM.cpp | 141 ++++++ .../configuration/memspec/MemSpecSTTMRAM.h | 85 ++++ DRAMSys/library/src/controller/Controller.cpp | 3 + .../src/controller/checker/CheckerSTTMRAM.cpp | 432 ++++++++++++++++++ .../src/controller/checker/CheckerSTTMRAM.h | 74 +++ DRAMSys/library/src/simulation/DRAMSys.cpp | 3 + .../src/simulation/DRAMSysRecordable.cpp | 3 + .../src/simulation/dram/DramRecordable.cpp | 2 + .../src/simulation/dram/DramSTTMRAM.cpp | 52 +++ .../library/src/simulation/dram/DramSTTMRAM.h | 50 ++ 13 files changed, 853 insertions(+), 1 deletion(-) create mode 100644 DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp create mode 100644 DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h create mode 100644 DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp create mode 100644 DRAMSys/library/src/controller/checker/CheckerSTTMRAM.h create mode 100644 DRAMSys/library/src/simulation/dram/DramSTTMRAM.cpp create mode 100644 DRAMSys/library/src/simulation/dram/DramSTTMRAM.h diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index bf784fb5..165a3e54 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -97,6 +97,7 @@ add_library(DRAMSysLibrary src/configuration/memspec/MemSpecGDDR5X.cpp src/configuration/memspec/MemSpecGDDR6.cpp src/configuration/memspec/MemSpecHBM2.cpp + src/configuration/memspec/MemSpecSTTMRAM.cpp src/controller/BankMachine.cpp src/controller/Command.cpp @@ -114,6 +115,7 @@ add_library(DRAMSysLibrary src/controller/checker/CheckerGDDR5X.cpp src/controller/checker/CheckerGDDR6.cpp src/controller/checker/CheckerHBM2.cpp + src/controller/checker/CheckerSTTMRAM.cpp src/controller/cmdmux/CmdMuxIF.h src/controller/cmdmux/CmdMuxOldest.cpp @@ -168,6 +170,7 @@ add_library(DRAMSysLibrary src/simulation/dram/DramGDDR5X.cpp src/simulation/dram/DramGDDR6.cpp src/simulation/dram/DramHBM2.cpp + src/simulation/dram/DramSTTMRAM.cpp ${RECORDING_SOURCES} diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index cdcee1af..065aee78 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -51,6 +51,7 @@ #include "memspec/MemSpecGDDR5.h" #include "memspec/MemSpecGDDR5X.h" #include "memspec/MemSpecGDDR6.h" +#include "memspec/MemSpecSTTMRAM.h" using json = nlohmann::json; @@ -357,6 +358,8 @@ void Configuration::loadMemSpec(Configuration &config, std::string memspecUri) memSpec = new MemSpecGDDR5X(jMemSpec); else if (memoryType == "GDDR6") memSpec = new MemSpecGDDR6(jMemSpec); + else if (memoryType == "STT-MRAM") + memSpec = new MemSpecSTTMRAM(jMemSpec); else SC_REPORT_FATAL("Configuration", "Unsupported DRAM type"); } diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index 82c1987d..3e5c0c1f 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -69,7 +69,8 @@ public: const sc_time tCK; const std::string memoryId; - const enum class MemoryType {DDR3, DDR4, DDR5, LPDDR4, WideIO, WideIO2, GDDR5, GDDR5X, GDDR6, HBM2} memoryType; + const enum class MemoryType {DDR3, DDR4, DDR5, LPDDR4, WideIO, + WideIO2, GDDR5, GDDR5X, GDDR6, HBM2, STTMRAM} memoryType; virtual ~MemSpec() {} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp new file mode 100644 index 00000000..bab51776 --- /dev/null +++ b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#include "MemSpecSTTMRAM.h" + +using namespace tlm; +using json = nlohmann::json; + +MemSpecSTTMRAM::MemSpecSTTMRAM(json &memspec) + : MemSpec(memspec, MemoryType::STTMRAM, + parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), + parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), + parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), + 1, + parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), + parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks") + * 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")), + 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 (tCK * parseUint(memspec["memtimingspec"]["CCD"], "CCD")), + tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")), + tREFI (tCK * parseUint(memspec["memtimingspec"]["REFI"], "REFI")), + tRFC (tCK * parseUint(memspec["memtimingspec"]["RFC"], "RFC")), + tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), + tRRD (tCK * parseUint(memspec["memtimingspec"]["RRD"], "RRD")), + tWTR (tCK * parseUint(memspec["memtimingspec"]["WTR"], "WTR")), + 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")) +{} + +// Returns the execution time for commands that have a fixed execution time +sc_time MemSpecSTTMRAM::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 MemSpecSTTMRAM::getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &) const +{ + if (command == Command::RD || command == Command::RDA) + return TimeInterval(tRL, tRL + burstDuration); + else if (command == Command::WR || command == Command::WRA) + return TimeInterval(tWL, tWL + burstDuration); + else + { + SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument"); + return TimeInterval(); + } +} + +uint64_t MemSpecSTTMRAM::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: " << "STT-MRAM" << 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/MemSpecSTTMRAM.h b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h new file mode 100644 index 00000000..a8a5753f --- /dev/null +++ b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#ifndef MEMSPECSTTMRAM_H +#define MEMSPECSTTMRAM_H + +#include "MemSpec.h" +#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" + +class MemSpecSTTMRAM final : public MemSpec +{ +public: + MemSpecSTTMRAM(nlohmann::json &memspec); + + // Memspec Variables: + 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 tWL; + 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; + const sc_time tFAW; + const sc_time tRRD; + const sc_time tWTR; + const sc_time tXPDLL; + const sc_time tXSDLL; + const sc_time tAL; + const sc_time tACTPDEN; + const sc_time tPRPDEN; + const sc_time tREFPDEN; + const sc_time tRTRS; + + // Currents and Voltages: + // TODO: to be completed + + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; +}; + +#endif // MEMSPECSTTMRAM_H diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 45b04c39..c9c93f05 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -47,6 +47,7 @@ #include "checker/CheckerGDDR5.h" #include "checker/CheckerGDDR5X.h" #include "checker/CheckerGDDR6.h" +#include "checker/CheckerSTTMRAM.h" #include "scheduler/SchedulerFifo.h" #include "scheduler/SchedulerFrFcfs.h" #include "scheduler/SchedulerFrFcfsGrp.h" @@ -102,6 +103,8 @@ Controller::Controller(sc_module_name name) : checker = new CheckerGDDR5X(); else if (memSpec->memoryType == MemSpec::MemoryType::GDDR6) checker = new CheckerGDDR6(); + else if (memSpec->memoryType == MemSpec::MemoryType::STTMRAM) + checker = new CheckerSTTMRAM(); // instantiate scheduler and command mux if (config.scheduler == Configuration::Scheduler::Fifo) diff --git a/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp new file mode 100644 index 00000000..99c00fe5 --- /dev/null +++ b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Lukas Steiner + */ + +#include "CheckerSTTMRAM.h" + +CheckerSTTMRAM::CheckerSTTMRAM() +{ + Configuration &config = Configuration::getInstance(); + memSpec = dynamic_cast(config.memSpec); + if (memSpec == nullptr) + SC_REPORT_FATAL("CheckerSTTMRAM", "Wrong MemSpec chosen"); + + lastScheduledByCommandAndBank = std::vector> + (numberOfCommands(), std::vector(memSpec->numberOfBanks, sc_max_time())); + lastScheduledByCommandAndRank = std::vector> + (numberOfCommands(), std::vector(memSpec->numberOfRanks, sc_max_time())); + lastScheduledByCommand = std::vector(numberOfCommands(), sc_max_time()); + lastCommandOnBus = sc_max_time(); + last4Activates = std::vector>(memSpec->numberOfRanks); + + tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL; + tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; + tWRRD = memSpec->tWL + tBURST + memSpec->tWTR; + tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL; + tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; + tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK; + tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR; + tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR + memSpec->tCK; +} + +sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) 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_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : sc_max_time(); + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : sc_max_time(); + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + if (command == Command::RDA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP); + } + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD); + + lastCommandStart = lastScheduledByCommand[Command::WR]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD); + + lastCommandStart = lastScheduledByCommand[Command::WRA]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != sc_max_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_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : sc_max_time(); + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : sc_max_time(); + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + + lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : sc_max_time(); + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + + lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : sc_max_time(); + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL); + } + else if (command == Command::ACT) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD); + + lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != sc_max_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_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + + lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + } + else if (command == Command::PREA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + } + else if (command == Command::REFA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::PDEA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + } + else if (command == Command::PDXA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); + } + else if (command == Command::PDEP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::PDXP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); + } + else if (command == Command::SREFEN) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::SREFEX) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR); + } + else + SC_REPORT_FATAL("CheckerSTTMRAM", "Unknown command!"); + + if (lastCommandOnBus != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK); + + return earliestTimeToStart; +} + +void CheckerSTTMRAM::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned) +{ + PRINTDEBUGMESSAGE("CheckerSTTMRAM", "Changing state on bank " + std::to_string(bank.ID()) + + " command is " + commandToString(command)); + + lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp(); + lastScheduledByCommandAndBank[command][bank.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/CheckerSTTMRAM.h b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.h new file mode 100644 index 00000000..50d48d53 --- /dev/null +++ b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Lukas Steiner + */ + +#ifndef CHECKERSTTMRAM_H +#define CHECKERSTTMRAM_H + +#include "CheckerIF.h" +#include +#include +#include "../../configuration/memspec/MemSpecSTTMRAM.h" +#include "../../configuration/Configuration.h" + +class CheckerSTTMRAM final : public CheckerIF +{ +public: + CheckerSTTMRAM(); + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override; + +private: + const MemSpecSTTMRAM *memSpec; + + std::vector> lastScheduledByCommandAndBank; + 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; + sc_time tWRPRE; + sc_time tWRRD_R; + sc_time tRDPDEN; + sc_time tWRPDEN; + sc_time tWRAPDEN; +}; + +#endif // CHECKERSTTMRAM_H diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 1e76d1d9..395f4742 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -59,6 +59,7 @@ #include "dram/DramGDDR5.h" #include "dram/DramGDDR5X.h" #include "dram/DramGDDR6.h" +#include "dram/DramSTTMRAM.h" #include "../controller/Controller.h" DRAMSys::DRAMSys(sc_module_name name, @@ -231,6 +232,8 @@ void DRAMSys::instantiateModules(const std::string &pathToResources, dram = new DramGDDR5X(str.c_str()); else if (memoryType == MemSpec::MemoryType::GDDR6) dram = new DramGDDR6(str.c_str()); + else if (memoryType == MemSpec::MemoryType::STTMRAM) + dram = new DramSTTMRAM(str.c_str()); drams.push_back(dram); diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp index cdc0caf5..25a89d5c 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp @@ -46,6 +46,7 @@ #include "dram/DramGDDR5.h" #include "dram/DramGDDR5X.h" #include "dram/DramGDDR6.h" +#include "dram/DramSTTMRAM.h" #include "../common/TlmRecorder.h" #include "../simulation/TemperatureController.h" #include "../error/ecchamming.h" @@ -172,6 +173,8 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, dram = new DramRecordable(str.c_str(), tlmRecorders[i]); else if (memoryType == MemSpec::MemoryType::GDDR6) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == MemSpec::MemoryType::STTMRAM) + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); drams.push_back(dram); diff --git a/DRAMSys/library/src/simulation/dram/DramRecordable.cpp b/DRAMSys/library/src/simulation/dram/DramRecordable.cpp index 4c6701ce..5167bccf 100644 --- a/DRAMSys/library/src/simulation/dram/DramRecordable.cpp +++ b/DRAMSys/library/src/simulation/dram/DramRecordable.cpp @@ -49,6 +49,7 @@ #include "DramGDDR5.h" #include "DramGDDR5X.h" #include "DramGDDR6.h" +#include "DramSTTMRAM.h" using namespace tlm; @@ -156,3 +157,4 @@ template class DramRecordable; template class DramRecordable; template class DramRecordable; template class DramRecordable; +template class DramRecordable; diff --git a/DRAMSys/library/src/simulation/dram/DramSTTMRAM.cpp b/DRAMSys/library/src/simulation/dram/DramSTTMRAM.cpp new file mode 100644 index 00000000..3680ce05 --- /dev/null +++ b/DRAMSys/library/src/simulation/dram/DramSTTMRAM.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#include "DramSTTMRAM.h" + +#include "Dram.h" +#include "../../configuration/Configuration.h" +#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h" +#include "../../configuration/memspec/MemSpecSTTMRAM.h" + +using namespace DRAMPower; + +DramSTTMRAM::DramSTTMRAM(sc_module_name name) : Dram(name) +{ + if (storeMode == Configuration::StoreMode::ErrorModel) + SC_REPORT_FATAL("DramSTTMRAM", "Error Model not supported for STT-MRAM"); + + if (Configuration::getInstance().powerAnalysis) + SC_REPORT_FATAL("DramSTTMRAM", "DRAMPower does not support STT-MRAM"); +} diff --git a/DRAMSys/library/src/simulation/dram/DramSTTMRAM.h b/DRAMSys/library/src/simulation/dram/DramSTTMRAM.h new file mode 100644 index 00000000..3d481be1 --- /dev/null +++ b/DRAMSys/library/src/simulation/dram/DramSTTMRAM.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#ifndef DRAMSTTMRAM_H +#define DRAMSTTMRAM_H + +#include +#include "Dram.h" + +class DramSTTMRAM : public Dram +{ +public: + DramSTTMRAM(sc_module_name); + SC_HAS_PROCESS(DramSTTMRAM); + virtual ~DramSTTMRAM() {} +}; + +#endif // DRAMSTTMRAM_H From cb4455710dda9112869411f29699792489699ac1 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 17 May 2021 15:51:55 +0200 Subject: [PATCH 2/5] Add config files for STT-MRAM. --- .../am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json | 43 ++++++++++++++ .../configs/mcconfigs/fr_fcfs_noref.json | 16 ++++++ .../configs/memspecs/STT-MRAM-1.2x.json | 44 +++++++++++++++ .../configs/memspecs/STT-MRAM-1.5x.json | 44 +++++++++++++++ .../configs/memspecs/STT-MRAM-2.0x.json | 44 +++++++++++++++ .../resources/configs/simulator/stt-mram.json | 19 +++++++ .../simulations/stt-mram-example.json | 16 ++++++ .../configuration/memspec/MemSpecSTTMRAM.cpp | 5 -- .../configuration/memspec/MemSpecSTTMRAM.h | 19 +++---- .../src/controller/checker/CheckerDDR3.cpp | 4 +- .../src/controller/checker/CheckerDDR4.cpp | 6 +- .../src/controller/checker/CheckerSTTMRAM.cpp | 56 ++----------------- 12 files changed, 245 insertions(+), 71 deletions(-) create mode 100644 DRAMSys/library/resources/configs/amconfigs/am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json create mode 100644 DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_noref.json create mode 100644 DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.2x.json create mode 100644 DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.5x.json create mode 100644 DRAMSys/library/resources/configs/memspecs/STT-MRAM-2.0x.json create mode 100644 DRAMSys/library/resources/configs/simulator/stt-mram.json create mode 100644 DRAMSys/library/resources/simulations/stt-mram-example.json diff --git a/DRAMSys/library/resources/configs/amconfigs/am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json b/DRAMSys/library/resources/configs/amconfigs/am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json new file mode 100644 index 00000000..d1bcfe70 --- /dev/null +++ b/DRAMSys/library/resources/configs/amconfigs/am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json @@ -0,0 +1,43 @@ +{ + "CONGEN": { + "BANK_BIT": [ + 13, + 14, + 15 + ], + "BYTE_BIT": [ + 0, + 1, + 2 + ], + "COLUMN_BIT": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12 + ], + "ROW_BIT": [ + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30 + ] + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_noref.json b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_noref.json new file mode 100644 index 00000000..b0d0a554 --- /dev/null +++ b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_noref.json @@ -0,0 +1,16 @@ +{ + "mcconfig": { + "PagePolicy": "Open", + "Scheduler": "FrFcfs", + "SchedulerBuffer": "Bankwise", + "RequestBufferSize": 8, + "CmdMux": "Oldest", + "RespQueue": "Fifo", + "RefreshPolicy": "NoRefresh", + "RefreshMaxPostponed": 0, + "RefreshMaxPulledin": 0, + "PowerDownPolicy": "NoPowerDown", + "Arbiter": "Simple", + "MaxActiveTransactions": 128 + } +} diff --git a/DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.2x.json b/DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.2x.json new file mode 100644 index 00000000..88511099 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.2x.json @@ -0,0 +1,44 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 8, + "dataRate": 2, + "nbrOfBanks": 8, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfRows": 32768, + "width": 8, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 1 + }, + "memoryId": "STT-MRAM-1.2x", + "memoryType": "STT-MRAM", + "memtimingspec": { + "AL": 0, + "CCD": 4, + "CKE": 4, + "CKESR": 7, + "CL": 11, + "DQSCK": 0, + "FAW": 29, + "RAS": 20, + "RC": 34, + "RCD": 14, + "RL": 11, + "RP": 14, + "RRD": 6, + "RTP": 6, + "WL": 11, + "WR": 12, + "WTR": 2, + "XP": 5, + "XPDLL": 325, + "XS": 324, + "XSDLL": 512, + "ACTPDEN": 2, + "PRPDEN": 2, + "RTRS": 1, + "clkMhz": 800 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.5x.json b/DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.5x.json new file mode 100644 index 00000000..57440f78 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.5x.json @@ -0,0 +1,44 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 8, + "dataRate": 2, + "nbrOfBanks": 8, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfRows": 32768, + "width": 8, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 1 + }, + "memoryId": "STT-MRAM-1.5x", + "memoryType": "STT-MRAM", + "memtimingspec": { + "AL": 0, + "CCD": 4, + "CKE": 4, + "CKESR": 7, + "CL": 11, + "DQSCK": 0, + "FAW": 36, + "RAS": 23, + "RC": 40, + "RCD": 14, + "RL": 11, + "RP": 17, + "RRD": 8, + "RTP": 6, + "WL": 11, + "WR": 12, + "WTR": 6, + "XP": 5, + "XPDLL": 325, + "XS": 324, + "XSDLL": 512, + "ACTPDEN": 2, + "PRPDEN": 2, + "RTRS": 1, + "clkMhz": 800 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/STT-MRAM-2.0x.json b/DRAMSys/library/resources/configs/memspecs/STT-MRAM-2.0x.json new file mode 100644 index 00000000..08d0ba9b --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/STT-MRAM-2.0x.json @@ -0,0 +1,44 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 8, + "dataRate": 2, + "nbrOfBanks": 8, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfRows": 32768, + "width": 8, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 1 + }, + "memoryId": "STT-MRAM-2.0x", + "memoryType": "STT-MRAM", + "memtimingspec": { + "AL": 0, + "CCD": 4, + "CKE": 4, + "CKESR": 7, + "CL": 11, + "DQSCK": 0, + "FAW": 36, + "RAS": 28, + "RC": 50, + "RCD": 14, + "RL": 11, + "RP": 22, + "RRD": 10, + "RTP": 6, + "WL": 11, + "WR": 48, + "WTR": 6, + "XP": 5, + "XPDLL": 325, + "XS": 324, + "XSDLL": 512, + "ACTPDEN": 2, + "PRPDEN": 2, + "RTRS": 1, + "clkMhz": 800 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/simulator/stt-mram.json b/DRAMSys/library/resources/configs/simulator/stt-mram.json new file mode 100644 index 00000000..3248e9f0 --- /dev/null +++ b/DRAMSys/library/resources/configs/simulator/stt-mram.json @@ -0,0 +1,19 @@ +{ + "simconfig": { + "AddressOffset": 0, + "CheckTLM2Protocol": false, + "DatabaseRecording": true, + "Debug": false, + "ECCControllerMode": "Disabled", + "EnableWindowing": false, + "ErrorCSVFile": "", + "ErrorChipSeed": 42, + "PowerAnalysis": false, + "SimulationName": "stt-mram", + "SimulationProgressBar": true, + "StoreMode": "NoStorage", + "ThermalSimulation": false, + "UseMalloc": false, + "WindowSize": 1000 + } +} diff --git a/DRAMSys/library/resources/simulations/stt-mram-example.json b/DRAMSys/library/resources/simulations/stt-mram-example.json new file mode 100644 index 00000000..fd9e3fce --- /dev/null +++ b/DRAMSys/library/resources/simulations/stt-mram-example.json @@ -0,0 +1,16 @@ +{ + "simulation": { + "addressmapping": "am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json", + "mcconfig": "fr_fcfs_noref.json", + "memspec": "STT-MRAM-1.2x.json", + "simconfig": "stt-mram.json", + "simulationid": "stt-mram-example", + "thermalconfig": "config.json", + "tracesetup": [ + { + "clkMhz": 800, + "name": "ddr3_example.stl" + } + ] + } +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp index bab51776..1d4d52c6 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp @@ -64,8 +64,6 @@ MemSpecSTTMRAM::MemSpecSTTMRAM(json &memspec) tXS (tCK * parseUint(memspec["memtimingspec"]["XS"], "XS")), tCCD (tCK * parseUint(memspec["memtimingspec"]["CCD"], "CCD")), tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")), - tREFI (tCK * parseUint(memspec["memtimingspec"]["REFI"], "REFI")), - tRFC (tCK * parseUint(memspec["memtimingspec"]["RFC"], "RFC")), tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), tRRD (tCK * parseUint(memspec["memtimingspec"]["RRD"], "RRD")), tWTR (tCK * parseUint(memspec["memtimingspec"]["WTR"], "WTR")), @@ -74,7 +72,6 @@ MemSpecSTTMRAM::MemSpecSTTMRAM(json &memspec) 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")) {} @@ -93,8 +90,6 @@ sc_time MemSpecSTTMRAM::getExecutionTime(Command command, const tlm_generic_payl 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", diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h index a8a5753f..cdd72a0f 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h @@ -46,8 +46,8 @@ public: // Memspec Variables: const sc_time tCKE; - const sc_time tPD; - const sc_time tCKESR; + const sc_time tPD;//-- + const sc_time tCKESR;//-- const sc_time tRAS; const sc_time tRC; const sc_time tRCD; @@ -56,21 +56,18 @@ public: const sc_time tWL; const sc_time tWR; const sc_time tXP; - const sc_time tXS; - const sc_time tREFI; - const sc_time tRFC; + const sc_time tXS;//-- const sc_time tRP; - const sc_time tDQSCK; + const sc_time tDQSCK;//-- const sc_time tCCD; const sc_time tFAW; const sc_time tRRD; const sc_time tWTR; - const sc_time tXPDLL; - const sc_time tXSDLL; + const sc_time tXPDLL;//-- + const sc_time tXSDLL;//-- const sc_time tAL; - const sc_time tACTPDEN; - const sc_time tPRPDEN; - const sc_time tREFPDEN; + const sc_time tACTPDEN;//-- + const sc_time tPRPDEN;//-- const sc_time tRTRS; // Currents and Voltages: diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp index 0d52b904..089a753b 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp @@ -52,7 +52,7 @@ CheckerDDR3::CheckerDDR3() tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL; tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; - tWRRD = memSpec->tWL + tBURST + memSpec->tWTR; + tWRRD = memSpec->tWL + tBURST + memSpec->tWTR - memSpec->tAL; tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL; tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK; @@ -91,7 +91,7 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL); } lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp index 25544d7b..3dda147b 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp @@ -54,8 +54,8 @@ CheckerDDR4::CheckerDDR4() 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_S = memSpec->tWL + tBURST + memSpec->tWTR_S - memSpec->tAL; + tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L - memSpec->tAL; tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL + memSpec->tRPRE; tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK; @@ -102,7 +102,7 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL); } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; diff --git a/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp index 99c00fe5..bb157ee7 100644 --- a/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp @@ -52,7 +52,7 @@ CheckerSTTMRAM::CheckerSTTMRAM() tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL; tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; - tWRRD = memSpec->tWL + tBURST + memSpec->tWTR; + tWRRD = memSpec->tWL + tBURST + memSpec->tWTR - memSpec->tAL; tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL; tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK; @@ -75,7 +75,8 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); - lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : sc_max_time(); + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? + lastScheduledByCommand[Command::RD] : sc_max_time(); if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); @@ -83,7 +84,8 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); - lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : sc_max_time(); + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? + lastScheduledByCommand[Command::RDA] : sc_max_time(); if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); @@ -91,7 +93,7 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban { lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL); } lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; @@ -198,10 +200,6 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); @@ -253,40 +251,6 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); } - else if (command == Command::REFA) - { - lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); - - lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); - } else if (command == Command::PDEA) { lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; @@ -349,10 +313,6 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN); - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); @@ -389,10 +349,6 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); From 4d8d5caf72e01ad370d66ea88744de907459c47f Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 19 May 2021 09:32:32 +0200 Subject: [PATCH 3/5] Add STT-MRAM copyright notice. --- .../configs/memspecs/COPYRIGHT_STT-MRAM.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 DRAMSys/library/resources/configs/memspecs/COPYRIGHT_STT-MRAM.md diff --git a/DRAMSys/library/resources/configs/memspecs/COPYRIGHT_STT-MRAM.md b/DRAMSys/library/resources/configs/memspecs/COPYRIGHT_STT-MRAM.md new file mode 100644 index 00000000..5ff0d2d2 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/COPYRIGHT_STT-MRAM.md @@ -0,0 +1,16 @@ +*The following copyright notice only applies to the files "STT-MRAM-1.2x.json", "STT-MRAM-1.5x.json" and "STT-MRAM-2.0x.json".* + + + (C) Copyright 2006-2018 Barcelona Supercomputing Center (BSC) + +The copyright holder is BSC-CNS, and the authorship correspond to Kazi Asifuzzaman, Rommel Sanchez Verdejo, and Petar Radojkovic. The complete explanation of the derivation of the data can be found in the following study: Kazi Asifuzzaman, Rommel Sanchez Verdejo, and Petar Radojkovic. 2017. Enabling a reliable STT-MRAM main memory simulation. In Proceedings of the International Symposium on Memory Systems (MEMSYS '17). Washington DC, USA, 283-292. DOI: https://doi.org/10.1145/3132402.3132416 + +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. + +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.” + +The configuration files list detailed timing parameters for STT-MRAM main memory, specifying a 1.2x/1.5x/2.0x deviation from respective DRAM timing parameters. From d4609ff66958f4e738c989eb228c2e8109b2017e Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 19 May 2021 09:34:30 +0200 Subject: [PATCH 4/5] Rename copyright notice. --- .../configs/memspecs/{COPYRIGHT_STT-MRAM.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename DRAMSys/library/resources/configs/memspecs/{COPYRIGHT_STT-MRAM.md => README.md} (100%) diff --git a/DRAMSys/library/resources/configs/memspecs/COPYRIGHT_STT-MRAM.md b/DRAMSys/library/resources/configs/memspecs/README.md similarity index 100% rename from DRAMSys/library/resources/configs/memspecs/COPYRIGHT_STT-MRAM.md rename to DRAMSys/library/resources/configs/memspecs/README.md From dbe76bd906521891cdbbfe0540c332a44d1ecbc6 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 19 May 2021 09:41:45 +0200 Subject: [PATCH 5/5] Remove comments from memspec file. --- .../src/configuration/memspec/MemSpecSTTMRAM.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h index cdd72a0f..0f29a5c1 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h @@ -46,8 +46,8 @@ public: // Memspec Variables: const sc_time tCKE; - const sc_time tPD;//-- - const sc_time tCKESR;//-- + const sc_time tPD; + const sc_time tCKESR; const sc_time tRAS; const sc_time tRC; const sc_time tRCD; @@ -56,18 +56,18 @@ public: const sc_time tWL; const sc_time tWR; const sc_time tXP; - const sc_time tXS;//-- + const sc_time tXS; const sc_time tRP; - const sc_time tDQSCK;//-- + const sc_time tDQSCK; const sc_time tCCD; const sc_time tFAW; const sc_time tRRD; const sc_time tWTR; - const sc_time tXPDLL;//-- - const sc_time tXSDLL;//-- + const sc_time tXPDLL; + const sc_time tXSDLL; const sc_time tAL; - const sc_time tACTPDEN;//-- - const sc_time tPRPDEN;//-- + const sc_time tACTPDEN; + const sc_time tPRPDEN; const sc_time tRTRS; // Currents and Voltages: