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