Merge branch 'STT-MRAM' into 'develop'

Add STT-MRAM standard.

See merge request ems/astdm/dram.sys!283
This commit is contained in:
Lukas Steiner
2021-05-19 08:44:46 +00:00
23 changed files with 1048 additions and 6 deletions

View File

@@ -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}

View File

@@ -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
]
}
}

View File

@@ -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
}
}

View File

@@ -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.

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}

View File

@@ -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"
}
]
}
}

View File

@@ -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");
}

View File

@@ -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() {}

View File

@@ -0,0 +1,136 @@
/*
* 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")),
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")),
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
{
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<uint64_t>(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;
}

View File

@@ -0,0 +1,82 @@
/*
* 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 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 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

View File

@@ -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)

View File

@@ -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()];

View File

@@ -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()];

View File

@@ -0,0 +1,388 @@
/*
* 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<const MemSpecSTTMRAM *>(config.memSpec);
if (memSpec == nullptr)
SC_REPORT_FATAL("CheckerSTTMRAM", "Wrong MemSpec chosen");
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks, sc_max_time()));
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks, sc_max_time()));
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands(), sc_max_time());
lastCommandOnBus = sc_max_time();
last4Activates = std::vector<std::queue<sc_time>>(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 - memSpec->tAL;
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 - memSpec->tAL);
}
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::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::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::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::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());
}
}

View File

@@ -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 <queue>
#include <vector>
#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<std::vector<sc_time>> lastScheduledByCommandAndBank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndRank;
std::vector<sc_time> lastScheduledByCommand;
sc_time lastCommandOnBus;
// Four activate window
std::vector<std::queue<sc_time>> 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

View File

@@ -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);

View File

@@ -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<DramGDDR5X>(str.c_str(), tlmRecorders[i]);
else if (memoryType == MemSpec::MemoryType::GDDR6)
dram = new DramRecordable<DramGDDR6>(str.c_str(), tlmRecorders[i]);
else if (memoryType == MemSpec::MemoryType::STTMRAM)
dram = new DramRecordable<DramSTTMRAM>(str.c_str(), tlmRecorders[i]);
drams.push_back(dram);

View File

@@ -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<DramGDDR5>;
template class DramRecordable<DramGDDR5X>;
template class DramRecordable<DramGDDR6>;
template class DramRecordable<DramHBM2>;
template class DramRecordable<DramSTTMRAM>;

View File

@@ -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");
}

View File

@@ -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 <systemc.h>
#include "Dram.h"
class DramSTTMRAM : public Dram
{
public:
DramSTTMRAM(sc_module_name);
SC_HAS_PROCESS(DramSTTMRAM);
virtual ~DramSTTMRAM() {}
};
#endif // DRAMSTTMRAM_H