Add initial version of DDR5 based on DDR4.

This commit is contained in:
Lukas Steiner
2020-08-19 09:46:24 +02:00
parent d2a90773eb
commit c15434c4fa
16 changed files with 845 additions and 39 deletions

View File

@@ -99,6 +99,7 @@ add_library(DRAMSysLibrary
src/configuration/memspec/MemSpec.cpp
src/configuration/memspec/MemSpecDDR3.cpp
src/configuration/memspec/MemSpecDDR4.cpp
src/configuration/memspec/MemSpecDDR5.cpp
src/configuration/memspec/MemSpecLPDDR4.cpp
src/configuration/memspec/MemSpecWideIO.cpp
src/configuration/memspec/MemSpecWideIO2.cpp
@@ -115,6 +116,7 @@ add_library(DRAMSysLibrary
src/controller/checker/CheckerIF.h
src/controller/checker/CheckerDDR3.cpp
src/controller/checker/CheckerDDR4.cpp
src/controller/checker/CheckerDDR5.cpp
src/controller/checker/CheckerLPDDR4.cpp
src/controller/checker/CheckerWideIO.cpp
src/controller/checker/CheckerWideIO2.cpp
@@ -161,6 +163,7 @@ add_library(DRAMSysLibrary
src/simulation/dram/Dram.cpp
src/simulation/dram/DramDDR3.cpp
src/simulation/dram/DramDDR4.cpp
src/simulation/dram/DramDDR5.cpp
src/simulation/dram/DramLPDDR4.cpp
src/simulation/dram/DramWideIO.cpp
src/simulation/dram/DramWideIO2.cpp

View File

@@ -0,0 +1,49 @@
{
"CONGEN": {
"BYTE_BIT": [
0,
1
],
"COLUMN_BIT": [
2,
3,
4,
5,
6,
7,
8,
9,
10,
11
],
"BANKGROUP_BIT": [
12,
13,
14
],
"BANK_BIT": [
15
],
"ROW_BIT": [
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31
],
"CHANNEL_BIT": [
32
]
}
}

View File

@@ -0,0 +1,54 @@
{
"memspec": {
"memarchitecturespec": {
"burstLength": 16,
"dataRate": 2,
"nbrOfBankGroups": 8,
"nbrOfBanks": 16,
"nbrOfColumns": 1024,
"nbrOfRanks": 1,
"nbrOfRows": 65536,
"width": 8,
"nbrOfDevicesOnDIMM": 4,
"nbrOfChannels": 2
},
"memoryId": "JEDEC_2x8Gb_DDR5-3200A_8bit",
"memoryType": "DDR5",
"memtimingspec": {
"AL": 0,
"CCD_L": 16,
"CCD_S": 8,
"CKE": 6,
"CKESR": 7,
"DQSCK": 2,
"FAW": 32,
"RAS": 52,
"RC": 74,
"RCD": 22,
"REFM": 1,
"REFI": 6240,
"RFC": 312,
"RL": 22,
"RPRE": 1,
"RP": 22,
"RRD_L": 8,
"RRD_S": 8,
"RTP": 12,
"WL": 20,
"WPRE": 2,
"WR": 48,
"WTR_L": 16,
"WTR_S": 4,
"XP": 12,
"XPDLL": 0,
"XS": 312,
"XSDLL": 1024,
"ACTPDEN": 2,
"PRPDEN": 2,
"REFPDEN": 2,
"RTRS": 1,
"clkMhz": 1600
}
}
}

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": "ddr5",
"SimulationProgressBar": true,
"StoreMode": "NoStorage",
"ThermalSimulation": false,
"UseMalloc": false,
"WindowSize": 1000
}
}

View File

@@ -0,0 +1,16 @@
{
"simulation": {
"addressmapping": "am_ddr5_2x4x8Gbx8_dimm_p1KB_rbc.json",
"mcconfig": "fr_fcfs.json",
"memspec": "JEDEC_2x8Gb_DDR5-3200A_8bit.json",
"simconfig": "ddr5.json",
"simulationid": "ddr5-example",
"thermalconfig": "config.json",
"tracesetup": [
{
"clkMhz": 200,
"name": "ddr3_example.stl"
}
]
}
}

View File

@@ -43,6 +43,7 @@
#include "Configuration.h"
#include "memspec/MemSpecDDR3.h"
#include "memspec/MemSpecDDR4.h"
#include "memspec/MemSpecDDR5.h"
#include "memspec/MemSpecWideIO.h"
#include "memspec/MemSpecLPDDR4.h"
#include "memspec/MemSpecWideIO2.h"
@@ -291,6 +292,8 @@ void Configuration::loadMemSpec(Configuration &config, std::string memspecUri)
memSpec = new MemSpecDDR3(jMemSpec);
else if (memoryType == "DDR4")
memSpec = new MemSpecDDR4(jMemSpec);
else if (memoryType == "DDR5")
memSpec = new MemSpecDDR5(jMemSpec);
else if (memoryType == "LPDDR4")
memSpec = new MemSpecLPDDR4(jMemSpec);
else if (memoryType == "WIDEIO_SDR")

View File

@@ -55,19 +55,17 @@ MemSpecDDR5::MemSpecDDR5(json &memspec)
tCKE (tCK * parseUint(memspec["memtimingspec"]["CKE"], "CKE")),
tPD (tCKE),
tCKESR (tCK * parseUint(memspec["memtimingspec"]["CKESR"], "CKESR")),
tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")),
tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")),
tRC (tCK * parseUint(memspec["memtimingspec"]["RC"], "RC")),
tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")),
tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")),
tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")),
tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")),
tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")),
tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")),
tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")),
tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")),
tXS (tCK * parseUint(memspec["memtimingspec"]["XS"], "XS")),
tCCD_S (tCK * parseUint(memspec["memtimingspec"]["CCD_S"], "CCD_S")),
tCCD_L (tCK * parseUint(memspec["memtimingspec"]["CCD_L"], "CCD_L")),
tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")),
tREFI ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 4) ?
(tCK * (parseUint(memspec["memtimingspec"]["REFI"], "REFI") / 4)) :
((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 2) ?
@@ -79,6 +77,10 @@ MemSpecDDR5::MemSpecDDR5(json &memspec)
(tCK * parseUint(memspec["memtimingspec"]["RFC2"], "RFC2")) :
(tCK * parseUint(memspec["memtimingspec"]["RFC"], "RFC")))),
tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")),
tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")),
tCCD_S (tCK * parseUint(memspec["memtimingspec"]["CCD_S"], "CCD_S")),
tCCD_L (tCK * parseUint(memspec["memtimingspec"]["CCD_L"], "CCD_L")),
tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")),
tRRD_S (tCK * parseUint(memspec["memtimingspec"]["RRD_S"], "RRD_S")),
tRRD_L (tCK * parseUint(memspec["memtimingspec"]["RRD_L"], "RRD_L")),
tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")),
@@ -90,7 +92,13 @@ MemSpecDDR5::MemSpecDDR5(json &memspec)
tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")),
tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")),
tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS"))
{}
{
commandLengthInCycles[Command::ACT] = 2;
commandLengthInCycles[Command::RD] = 2;
commandLengthInCycles[Command::RDA] = 2;
commandLengthInCycles[Command::WR] = 2;
commandLengthInCycles[Command::WRA] = 2;
}
sc_time MemSpecDDR5::getRefreshIntervalAB() const
{
@@ -109,15 +117,15 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload
if (command == Command::PRE || command == Command::PREA)
return tRP;
else if (command == Command::ACT)
return tRCD;
return tRCD + tCK;
else if (command == Command::RD)
return tRL + burstDuration;
return tRL + burstDuration + tCK;
else if (command == Command::RDA)
return tRTP + tRP;
return tRTP + tRP + tCK;
else if (command == Command::WR)
return tWL + burstDuration;
return tWL + burstDuration + tCK;
else if (command == Command::WRA)
return tWL + burstDuration + tWR + tRP;
return tWL + burstDuration + tWR + tRP + tCK;
else if (command == Command::REFA)
return tRFC;
else
@@ -131,9 +139,9 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload
TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(sc_time_stamp() + tRL, sc_time_stamp() + tRL + burstDuration);
return TimeInterval(sc_time_stamp() + tRL + tCK, sc_time_stamp() + tRL + burstDuration + tCK);
else if (command == Command::WR || command == Command::WRA)
return TimeInterval(sc_time_stamp() + tWL, sc_time_stamp() + tWL + burstDuration);
return TimeInterval(sc_time_stamp() + tWL + tCK, sc_time_stamp() + tWL + burstDuration + tCK);
else
{
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");

View File

@@ -45,36 +45,38 @@ public:
MemSpecDDR5(nlohmann::json &memspec);
// Memspec Variables:
const sc_time tRCD;
const sc_time tPPD;
const sc_time tRP;
const sc_time tCKE;
const sc_time tPD;
const sc_time tCKESR;
const sc_time tRAS;
const sc_time tRC;
const sc_time tRCD;
const sc_time tRL;
const sc_time tRTP;
const sc_time tRPRE;
const sc_time tRPST;
const sc_time tRDQSOFF;
const sc_time tRTP;
const sc_time tWL;
const sc_time tWR;
const sc_time tWTR_L;
const sc_time tWTR_S;
const sc_time tWPRE;
const sc_time tWPST;
const sc_time tCCD_L_slr;
const sc_time tCCD_S_slr;
const sc_time tCCD_dlr;
const sc_time tCCD_L_WR_slr;
const sc_time tCCD_S_WR_slr;
const sc_time tCCD_WR_dlr;
const sc_time tCCD_WR_dpr;
const sc_time
const sc_time
const sc_time
const sc_time
const sc_time
const sc_time
const sc_time
const sc_time
const sc_time tWR;
const sc_time tXP;
const sc_time tXS;
const sc_time tREFI;
const sc_time tRFC;
const sc_time tRP;
const sc_time tDQSCK;
const sc_time tCCD_S;
const sc_time tCCD_L;
const sc_time tFAW;
const sc_time tRRD_S;
const sc_time tRRD_L;
const sc_time tWTR_S;
const sc_time tWTR_L;
const sc_time tAL;
const sc_time tXPDLL;
const sc_time tXSDLL;
const sc_time tACTPDEN;
const sc_time tPRPDEN;
const sc_time tREFPDEN;
const sc_time tRTRS;
// Currents and Voltages:
// TODO: to be completed

View File

@@ -39,6 +39,7 @@
#include "Command.h"
#include "checker/CheckerDDR3.h"
#include "checker/CheckerDDR4.h"
#include "checker/CheckerDDR5.h"
#include "checker/CheckerWideIO.h"
#include "checker/CheckerLPDDR4.h"
#include "checker/CheckerWideIO2.h"
@@ -76,6 +77,8 @@ Controller::Controller(sc_module_name name) :
checker = new CheckerDDR3();
else if (memSpec->memoryType == "DDR4")
checker = new CheckerDDR4();
else if (memSpec->memoryType == "DDR5")
checker = new CheckerDDR5();
else if (memSpec->memoryType == "WIDEIO_SDR")
checker = new CheckerWideIO();
else if (memSpec->memoryType == "LPDDR4")

View File

@@ -0,0 +1,462 @@
/*
* Copyright (c) 2020, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author: Lukas Steiner
*/
#include "CheckerDDR5.h"
CheckerDDR5::CheckerDDR5()
{
Configuration &config = Configuration::getInstance();
memSpec = dynamic_cast<MemSpecDDR5 *>(config.memSpec);
if (memSpec == nullptr)
SC_REPORT_FATAL("CheckerDDR5", "Wrong MemSpec chosen");
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBankGroups));
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
last4Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
tRDWR = memSpec->tRL + tBURST + memSpec->tCK - memSpec->tWL + memSpec->tWPRE;
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL + memSpec->tWPRE;
tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S;
tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L;
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL + memSpec->tRPRE;
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK;
tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR;
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR;
}
sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
{
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME;
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME;
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
if (command == Command::RDA)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L);
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S);
lastCommandStart = lastScheduledByCommand[Command::WR];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S);
lastCommandStart = lastScheduledByCommand[Command::WRA];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
}
else if (command == Command::WR || command == Command::WRA)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME;
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME;
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME;
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : SC_ZERO_TIME;
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
}
else if (command == Command::ACT)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankgroup.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L);
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_S);
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
if (last4Activates[rank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
}
else if (command == Command::PRE)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
}
else if (command == Command::PREA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
}
else if (command == Command::REFA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
}
else if (command == Command::PDEA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
}
else if (command == Command::PDXA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
}
else if (command == Command::PDEP)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
}
else if (command == Command::PDXP)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
}
else if (command == Command::SREFEN)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
}
else if (command == Command::SREFEX)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
}
else
SC_REPORT_FATAL("CheckerDDR5", "Unknown command!");
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
return earliestTimeToStart;
}
void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
{
PRINTDEBUGMESSAGE("CheckerDDR5", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
lastScheduledByCommandAndBankGroup[command][bankgroup.ID()] = sc_time_stamp();
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
lastScheduledByCommand[command] = sc_time_stamp();
lastCommandOnBus = sc_time_stamp();
if (command == Command::ACT)
{
if (last4Activates[rank.ID()].size() == 4)
last4Activates[rank.ID()].pop();
last4Activates[rank.ID()].push(sc_time_stamp());
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2020, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author: Lukas Steiner
*/
#ifndef CHECKERDDR5_H
#define CHECKERDDR5_H
#include "CheckerIF.h"
#include <queue>
#include <vector>
#include "../../configuration/memspec/MemSpecDDR5.h"
#include "../../configuration/Configuration.h"
class CheckerDDR5 final : public CheckerIF
{
public:
CheckerDDR5();
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
virtual void insert(Command, Rank, BankGroup, Bank) override;
private:
const MemSpecDDR5 *memSpec;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankGroup;
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_S;
sc_time tWRRD_L;
sc_time tWRRD_R;
sc_time tRDAACT;
sc_time tWRPRE;
sc_time tWRAACT;
sc_time tRDPDEN;
sc_time tWRPDEN;
sc_time tWRAPDEN;
};
#endif // CHECKERDDR5_H

View File

@@ -51,6 +51,7 @@
#include "../error/ecchamming.h"
#include "dram/DramDDR3.h"
#include "dram/DramDDR4.h"
#include "dram/DramDDR5.h"
#include "dram/DramWideIO.h"
#include "dram/DramLPDDR4.h"
#include "dram/DramWideIO2.h"
@@ -216,6 +217,8 @@ void DRAMSys::instantiateModules(const std::string &pathToResources,
dram = new DramWideIO(str.c_str());
else if (memoryType == "DDR4")
dram = new DramDDR4(str.c_str());
else if (memoryType == "DDR5")
dram = new DramDDR5(str.c_str());
else if (memoryType == "LPDDR4")
dram = new DramLPDDR4(str.c_str());
else if (memoryType == "WIDEIO2")

View File

@@ -38,6 +38,7 @@
#include "dram/DramRecordable.h"
#include "dram/DramDDR3.h"
#include "dram/DramDDR4.h"
#include "dram/DramDDR5.h"
#include "dram/DramWideIO.h"
#include "dram/DramLPDDR4.h"
#include "dram/DramWideIO2.h"
@@ -152,12 +153,14 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName,
if (memoryType == "DDR3")
dram = new DramRecordable<DramDDR3>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "WIDEIO_SDR")
dram = new DramRecordable<DramWideIO>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "DDR4")
dram = new DramRecordable<DramDDR4>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "DDR5")
dram = new DramRecordable<DramDDR5>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "LPDDR4")
dram = new DramRecordable<DramLPDDR4>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "WIDEIO_SDR")
dram = new DramRecordable<DramWideIO>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "WIDEIO2")
dram = new DramRecordable<DramWideIO2>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "HBM2")

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2020, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Lukas Steiner
*/
#include "DramDDR5.h"
#include "Dram.h"
#include "../../configuration/Configuration.h"
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
#include "../../configuration/memspec/MemSpecDDR5.h"
using namespace DRAMPower;
DramDDR5::DramDDR5(sc_module_name name) : Dram(name)
{
if (storeMode == StorageMode::ErrorModel)
SC_REPORT_FATAL("DramDDR5", "Error Model not supported for DDR5");
if (Configuration::getInstance().powerAnalysis)
SC_REPORT_FATAL("DramDDR5", "DRAMPower does not support DDR5");
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2020, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Lukas Steiner
*/
#ifndef DRAMDDR5_H
#define DRAMDDR5_H
#include <systemc.h>
#include "Dram.h"
class DramDDR5 : public Dram
{
public:
DramDDR5(sc_module_name);
SC_HAS_PROCESS(DramDDR5);
virtual ~DramDDR5() {}
};
#endif // DRAMDDR5_H

View File

@@ -41,6 +41,7 @@
#include "../../common/utils.h"
#include "DramDDR3.h"
#include "DramDDR4.h"
#include "DramDDR5.h"
#include "DramWideIO.h"
#include "DramLPDDR4.h"
#include "DramWideIO2.h"
@@ -147,6 +148,7 @@ void DramRecordable<BaseDram>::powerWindow()
template class DramRecordable<DramDDR3>;
template class DramRecordable<DramDDR4>;
template class DramRecordable<DramDDR5>;
template class DramRecordable<DramLPDDR4>;
template class DramRecordable<DramWideIO>;
template class DramRecordable<DramWideIO2>;