Included memspec, dram and checker for GDDR5, GDDR5X and GDDR6.
This commit is contained in:
@@ -146,7 +146,16 @@ SOURCES += \
|
||||
src/controller/checker/CheckerWideIO2.cpp \
|
||||
src/configuration/memspec/MemSpecHBM2.cpp \
|
||||
src/simulation/dram/DramHBM2.cpp \
|
||||
src/controller/checker/CheckerHBM2.cpp
|
||||
src/controller/checker/CheckerHBM2.cpp \
|
||||
src/configuration/memspec/MemSpecGDDR5.cpp \
|
||||
src/configuration/memspec/MemSpecGDDR5X.cpp \
|
||||
src/configuration/memspec/MemSpecGDDR6.cpp \
|
||||
src/controller/checker/CheckerGDDR5.cpp \
|
||||
src/controller/checker/CheckerGDDR5X.cpp \
|
||||
src/controller/checker/CheckerGDDR6.cpp \
|
||||
src/simulation/dram/DramGDDR5.cpp \
|
||||
src/simulation/dram/DramGDDR5X.cpp \
|
||||
src/simulation/dram/DramGDDR6.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/common/third_party/tinyxml2/tinyxml2.h \
|
||||
@@ -226,7 +235,16 @@ HEADERS += \
|
||||
src/controller/checker/CheckerWideIO2.h \
|
||||
src/configuration/memspec/MemSpecHBM2.h \
|
||||
src/simulation/dram/DramHBM2.h \
|
||||
src/controller/checker/CheckerHBM2.h
|
||||
src/controller/checker/CheckerHBM2.h \
|
||||
src/configuration/memspec/MemSpecGDDR5.h \
|
||||
src/configuration/memspec/MemSpecGDDR5X.h \
|
||||
src/configuration/memspec/MemSpecGDDR6.h \
|
||||
src/controller/checker/CheckerGDDR5.h \
|
||||
src/controller/checker/CheckerGDDR5X.h \
|
||||
src/controller/checker/CheckerGDDR6.h \
|
||||
src/simulation/dram/DramGDDR5.h \
|
||||
src/simulation/dram/DramGDDR5X.h \
|
||||
src/simulation/dram/DramGDDR6.h
|
||||
#src/common/third_party/json/include/nlohmann/json.hpp \
|
||||
|
||||
thermalsim = $$(THERMALSIM)
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
#include "memspec/MemSpecLPDDR4.h"
|
||||
#include "memspec/MemSpecWideIO2.h"
|
||||
#include "memspec/MemSpecHBM2.h"
|
||||
#include "memspec/MemSpecGDDR5.h"
|
||||
#include "memspec/MemSpecGDDR5X.h"
|
||||
#include "memspec/MemSpecGDDR6.h"
|
||||
#include "../common/timingCalculations.h"
|
||||
|
||||
using namespace tinyxml2;
|
||||
@@ -182,6 +185,24 @@ void ConfigurationLoader::loadMemSpec(Configuration &config,
|
||||
loadCommons(config, memspec);
|
||||
loadHBM2(config, memspec);
|
||||
}
|
||||
else if (memoryType == "GDDR5")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecGDDR5();
|
||||
loadCommons(config, memspec);
|
||||
loadGDDR5(config, memspec);
|
||||
}
|
||||
else if (memoryType == "GDDR5X")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecGDDR5X();
|
||||
loadCommons(config, memspec);
|
||||
loadGDDR5X(config, memspec);
|
||||
}
|
||||
else if (memoryType == "GDDR6")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecGDDR6();
|
||||
loadCommons(config, memspec);
|
||||
loadGDDR6(config, memspec);
|
||||
}
|
||||
else
|
||||
reportFatal("ConfigurationLoader", "Unsupported DRAM type");
|
||||
}
|
||||
@@ -549,8 +570,16 @@ void ConfigurationLoader::loadHBM2(Configuration &config, XMLElement *xmlSpec)
|
||||
memSpec->tRTW = clk * queryUIntParameter(timings, "RTW");
|
||||
memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
// memSpec->tPD = clk * queryUIntParameter(timings, "PD");
|
||||
// memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
memSpec->tPD = memSpec->tCKE;
|
||||
memSpec->tRDPDE = memSpec->tRL + memSpec->tPL
|
||||
+ (memSpec->BurstLength / memSpec->DataRate + 1) * memSpec->clk;
|
||||
memSpec->tWRPDE = memSpec->tWL + memSpec->tPL
|
||||
+ (memSpec->BurstLength / memSpec->DataRate + 1) * memSpec->clk + memSpec->tWR;
|
||||
memSpec->tWRAPDE = memSpec->tWL + memSpec->tPL
|
||||
+ (memSpec->BurstLength / memSpec->DataRate + 1) * memSpec->clk + memSpec->tWR;
|
||||
memSpec->tCKESR = memSpec->tCKE + memSpec->clk;
|
||||
memSpec->tRDSRE = memSpec->tRL + memSpec->tPL
|
||||
+ (memSpec->BurstLength / memSpec->DataRate + 1) * memSpec->clk;
|
||||
memSpec->tXS = clk * queryUIntParameter(timings, "XS");
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRFCSB = clk * queryUIntParameter(timings, "RFCSB");
|
||||
@@ -561,3 +590,186 @@ void ConfigurationLoader::loadHBM2(Configuration &config, XMLElement *xmlSpec)
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadGDDR5(Configuration &config, XMLElement *xmlSpec)
|
||||
{
|
||||
MemSpecGDDR5 *memSpec = dynamic_cast<MemSpecGDDR5 *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
||||
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
|
||||
// MemTimings specific for GDDR5
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
sc_time clk = memSpec->clk;
|
||||
memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCDRD = clk * queryUIntParameter(timings, "RCDRD");
|
||||
memSpec->tRCDWR = clk * queryUIntParameter(timings, "RCDWR");
|
||||
memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRRDS = clk * queryUIntParameter(timings, "RRDS");
|
||||
memSpec->tRRDL = clk * queryUIntParameter(timings, "RRDL");
|
||||
memSpec->tCCDS = clk * queryUIntParameter(timings, "CCDS");
|
||||
memSpec->tCCDL = clk * queryUIntParameter(timings, "CCDL");
|
||||
memSpec->tCL = clk * queryUIntParameter(timings, "CL");
|
||||
memSpec->tWCK2CKPIN = clk * queryUIntParameter(timings, "WCK2CKPIN");
|
||||
memSpec->tWCK2CK = clk * queryUIntParameter(timings, "WCK2CK");
|
||||
memSpec->tWCK2DQO = clk * queryUIntParameter(timings, "WCK2DQO");
|
||||
memSpec->tRTW = clk * queryUIntParameter(timings, "RTW");
|
||||
memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWCK2DQI = clk * queryUIntParameter(timings, "WCK2DQI");
|
||||
memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWTRS = clk * queryUIntParameter(timings, "WTRS");
|
||||
memSpec->tWTRL = clk * queryUIntParameter(timings, "WTRL");
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tPD = memSpec->tCKE;
|
||||
memSpec->tXPN = clk * queryUIntParameter(timings, "XPN");
|
||||
memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIPB = clk * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRFCPB = clk * queryUIntParameter(timings, "RFCPB");
|
||||
memSpec->tRREFD = clk * queryUIntParameter(timings, "RREFD");
|
||||
memSpec->tXS = clk * queryUIntParameter(timings, "XS");
|
||||
memSpec->tFAW = clk * queryUIntParameter(timings, "FAW");
|
||||
memSpec->t32AW = clk * queryUIntParameter(timings, "32AW");
|
||||
memSpec->tRDSRE = memSpec->tCL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
+ memSpec->tWCK2DQO + memSpec->BurstLength / memSpec->DataRate * clk;
|
||||
memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
+ memSpec->tWCK2DQI + memSpec->BurstLength / memSpec->DataRate * clk;
|
||||
memSpec->tPPD = clk * queryUIntParameter(timings, "PPD");
|
||||
memSpec->tLK = clk * queryUIntParameter(timings, "LK");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadGDDR5X(Configuration &config, XMLElement *xmlSpec)
|
||||
{
|
||||
MemSpecGDDR5X *memSpec = dynamic_cast<MemSpecGDDR5X *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
||||
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
|
||||
// MemTimings specific for GDDR5X
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
sc_time clk = memSpec->clk;
|
||||
memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCDRD = clk * queryUIntParameter(timings, "RCDRD");
|
||||
memSpec->tRCDWR = clk * queryUIntParameter(timings, "RCDWR");
|
||||
memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRRDS = clk * queryUIntParameter(timings, "RRDS");
|
||||
memSpec->tRRDL = clk * queryUIntParameter(timings, "RRDL");
|
||||
memSpec->tCCDS = clk * queryUIntParameter(timings, "CCDS");
|
||||
memSpec->tCCDL = clk * queryUIntParameter(timings, "CCDL");
|
||||
memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
memSpec->tWCK2CKPIN = clk * queryUIntParameter(timings, "WCK2CKPIN");
|
||||
memSpec->tWCK2CK = clk * queryUIntParameter(timings, "WCK2CK");
|
||||
memSpec->tWCK2DQO = clk * queryUIntParameter(timings, "WCK2DQO");
|
||||
memSpec->tRTW = clk * queryUIntParameter(timings, "RTW");
|
||||
memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWCK2DQI = clk * queryUIntParameter(timings, "WCK2DQI");
|
||||
memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWTRS = clk * queryUIntParameter(timings, "WTRS");
|
||||
memSpec->tWTRL = clk * queryUIntParameter(timings, "WTRL");
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tPD = memSpec->tCKE;
|
||||
memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIPB = clk * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRFCPB = clk * queryUIntParameter(timings, "RFCPB");
|
||||
memSpec->tRREFD = clk * queryUIntParameter(timings, "RREFD");
|
||||
memSpec->tXS = clk * queryUIntParameter(timings, "XS");
|
||||
memSpec->tFAW = clk * queryUIntParameter(timings, "FAW");
|
||||
memSpec->t32AW = clk * queryUIntParameter(timings, "32AW");
|
||||
memSpec->tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
+ memSpec->tWCK2DQO + memSpec->BurstLength / memSpec->DataRate * clk;
|
||||
memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
+ memSpec->tWCK2DQI + memSpec->BurstLength / memSpec->DataRate * clk;
|
||||
memSpec->tPPD = clk * queryUIntParameter(timings, "PPD");
|
||||
memSpec->tLK = clk * queryUIntParameter(timings, "LK");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadGDDR6(Configuration &config, XMLElement *xmlSpec)
|
||||
{
|
||||
MemSpecGDDR6 *memSpec = dynamic_cast<MemSpecGDDR6 *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
||||
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
|
||||
// MemTimings specific for GDDR6
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
sc_time clk = memSpec->clk;
|
||||
memSpec->tRP = clk * queryUIntParameter(timings, "RP");
|
||||
memSpec->tRAS = clk * queryUIntParameter(timings, "RAS");
|
||||
memSpec->tRC = clk * queryUIntParameter(timings, "RC");
|
||||
memSpec->tRCDRD = clk * queryUIntParameter(timings, "RCDRD");
|
||||
memSpec->tRCDWR = clk * queryUIntParameter(timings, "RCDWR");
|
||||
memSpec->tRTP = clk * queryUIntParameter(timings, "RTP");
|
||||
memSpec->tRRDS = clk * queryUIntParameter(timings, "RRDS");
|
||||
memSpec->tRRDL = clk * queryUIntParameter(timings, "RRDL");
|
||||
memSpec->tCCDS = clk * queryUIntParameter(timings, "CCDS");
|
||||
memSpec->tCCDL = clk * queryUIntParameter(timings, "CCDL");
|
||||
memSpec->tRL = clk * queryUIntParameter(timings, "RL");
|
||||
memSpec->tWCK2CKPIN = clk * queryUIntParameter(timings, "WCK2CKPIN");
|
||||
memSpec->tWCK2CK = clk * queryUIntParameter(timings, "WCK2CK");
|
||||
memSpec->tWCK2DQO = clk * queryUIntParameter(timings, "WCK2DQO");
|
||||
memSpec->tRTW = clk * queryUIntParameter(timings, "RTW");
|
||||
memSpec->tWL = clk * queryUIntParameter(timings, "WL");
|
||||
memSpec->tWCK2DQI = clk * queryUIntParameter(timings, "WCK2DQI");
|
||||
memSpec->tWR = clk * queryUIntParameter(timings, "WR");
|
||||
memSpec->tWTRS = clk * queryUIntParameter(timings, "WTRS");
|
||||
memSpec->tWTRL = clk * queryUIntParameter(timings, "WTRL");
|
||||
memSpec->tCKE = clk * queryUIntParameter(timings, "CKE");
|
||||
memSpec->tPD = memSpec->tCKE;
|
||||
memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
||||
memSpec->tXP = clk * queryUIntParameter(timings, "XP");
|
||||
memSpec->tREFI = clk * queryUIntParameter(timings, "REFI");
|
||||
memSpec->tREFIPB = clk * queryUIntParameter(timings, "REFIPB");
|
||||
memSpec->tRFC = clk * queryUIntParameter(timings, "RFC");
|
||||
memSpec->tRFCPB = clk * queryUIntParameter(timings, "RFCPB");
|
||||
memSpec->tRREFD = clk * queryUIntParameter(timings, "RREFD");
|
||||
memSpec->tXS = clk * queryUIntParameter(timings, "XS");
|
||||
memSpec->tFAW = clk * queryUIntParameter(timings, "FAW");
|
||||
memSpec->tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
+ memSpec->tWCK2DQO + memSpec->BurstLength / memSpec->DataRate * clk;
|
||||
memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
+ memSpec->tWCK2DQI + memSpec->BurstLength / memSpec->DataRate * clk;
|
||||
memSpec->tPPD = clk * queryUIntParameter(timings, "PPD");
|
||||
memSpec->tLK = clk * queryUIntParameter(timings, "LK");
|
||||
memSpec->tACTPDE = clk * queryUIntParameter(timings, "ACTPDE");
|
||||
memSpec->tPREPDE = clk * queryUIntParameter(timings, "PREPDE");
|
||||
memSpec->tREFPDE = clk * queryUIntParameter(timings, "REFPDE");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
@@ -75,6 +75,9 @@ private:
|
||||
static void loadWideIO(Configuration &config, tinyxml2::XMLElement *memspec);
|
||||
static void loadWideIO2(Configuration &config, tinyxml2::XMLElement *memspec);
|
||||
static void loadHBM2(Configuration &config, tinyxml2::XMLElement *memspec);
|
||||
static void loadGDDR5(Configuration &config, tinyxml2::XMLElement *memspec);
|
||||
static void loadGDDR5X(Configuration &config, tinyxml2::XMLElement *memspec);
|
||||
static void loadGDDR6(Configuration &config, tinyxml2::XMLElement *memspec);
|
||||
};
|
||||
|
||||
|
||||
|
||||
88
DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp
Normal file
88
DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 "MemSpecGDDR5.h"
|
||||
|
||||
sc_time MemSpecGDDR5::getRefreshIntervalAB() const
|
||||
{
|
||||
return tREFI;
|
||||
}
|
||||
|
||||
sc_time MemSpecGDDR5::getRefreshIntervalPB() const
|
||||
{
|
||||
return tREFIPB;
|
||||
}
|
||||
|
||||
sc_time MemSpecGDDR5::getExecutionTime(Command command, const tlm_generic_payload &payload) const
|
||||
{
|
||||
if (command == Command::PRE || command == Command::PREA)
|
||||
return tRP;
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
if (payload.get_command() == TLM_READ_COMMAND)
|
||||
return tRCDRD + clk;
|
||||
else
|
||||
return tRCDWR + clk;
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
return tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + getReadAccessTime();
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + getWriteAccessTime();
|
||||
else if (command == Command::REFA)
|
||||
return tRFC;
|
||||
else if (command == Command::REFB)
|
||||
return tRFCPB;
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("getExecutionTime",
|
||||
"command not known or command doesn't have a fixed execution time");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecGDDR5::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,
|
||||
sc_time_stamp() + tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + getReadAccessTime());
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI,
|
||||
sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + getWriteAccessTime());
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecGDDR5", "Method was called with invalid argument");
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
90
DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h
Normal file
90
DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 MEMSPECGDDR5_H
|
||||
#define MEMSPECGDDR5_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
|
||||
struct MemSpecGDDR5 final : public MemSpec
|
||||
{
|
||||
// Memspec Variables:
|
||||
sc_time tRP;
|
||||
sc_time tRAS;
|
||||
sc_time tRC;
|
||||
sc_time tRCDRD;
|
||||
sc_time tRCDWR;
|
||||
sc_time tRTP;
|
||||
sc_time tRRDS;
|
||||
sc_time tRRDL;
|
||||
sc_time tCCDS;
|
||||
sc_time tCCDL;
|
||||
sc_time tCL;
|
||||
sc_time tWCK2CKPIN;
|
||||
sc_time tWCK2CK;
|
||||
sc_time tWCK2DQO;
|
||||
sc_time tRTW;
|
||||
sc_time tWL;
|
||||
sc_time tWCK2DQI;
|
||||
sc_time tWR;
|
||||
sc_time tWTRS;
|
||||
sc_time tWTRL;
|
||||
sc_time tCKE;
|
||||
sc_time tPD; // = tCKE;
|
||||
sc_time tXPN;
|
||||
sc_time tREFI;
|
||||
sc_time tREFIPB;
|
||||
sc_time tRFC;
|
||||
sc_time tRFCPB;
|
||||
sc_time tRREFD;
|
||||
sc_time tXS;
|
||||
sc_time tFAW;
|
||||
sc_time t32AW;
|
||||
sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK;
|
||||
sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK;
|
||||
sc_time tPPD;
|
||||
sc_time tLK;
|
||||
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECGDDR5_H
|
||||
88
DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp
Normal file
88
DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 "MemSpecGDDR5X.h"
|
||||
|
||||
sc_time MemSpecGDDR5X::getRefreshIntervalAB() const
|
||||
{
|
||||
return tREFI;
|
||||
}
|
||||
|
||||
sc_time MemSpecGDDR5X::getRefreshIntervalPB() const
|
||||
{
|
||||
return tREFIPB;
|
||||
}
|
||||
|
||||
sc_time MemSpecGDDR5X::getExecutionTime(Command command, const tlm_generic_payload &payload) const
|
||||
{
|
||||
if (command == Command::PRE || command == Command::PREA)
|
||||
return tRP;
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
if (payload.get_command() == TLM_READ_COMMAND)
|
||||
return tRCDRD + clk;
|
||||
else
|
||||
return tRCDWR + clk;
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
return tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + getReadAccessTime();
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + getWriteAccessTime();
|
||||
else if (command == Command::REFA)
|
||||
return tRFC;
|
||||
else if (command == Command::REFB)
|
||||
return tRFCPB;
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("getExecutionTime",
|
||||
"command not known or command doesn't have a fixed execution time");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecGDDR5X::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,
|
||||
sc_time_stamp() + tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + getReadAccessTime());
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI,
|
||||
sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + getWriteAccessTime());
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecGDDR5X", "Method was called with invalid argument");
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
90
DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h
Normal file
90
DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 MEMSPECGDDR5X_H
|
||||
#define MEMSPECGDDR5X_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
|
||||
struct MemSpecGDDR5X final : public MemSpec
|
||||
{
|
||||
// Memspec Variables:
|
||||
sc_time tRP;
|
||||
sc_time tRAS;
|
||||
sc_time tRC;
|
||||
sc_time tRCDRD;
|
||||
sc_time tRCDWR;
|
||||
sc_time tRTP;
|
||||
sc_time tRRDS;
|
||||
sc_time tRRDL;
|
||||
sc_time tCCDS;
|
||||
sc_time tCCDL;
|
||||
sc_time tRL;
|
||||
sc_time tWCK2CKPIN;
|
||||
sc_time tWCK2CK;
|
||||
sc_time tWCK2DQO;
|
||||
sc_time tRTW;
|
||||
sc_time tWL;
|
||||
sc_time tWCK2DQI;
|
||||
sc_time tWR;
|
||||
sc_time tWTRS;
|
||||
sc_time tWTRL;
|
||||
sc_time tCKE;
|
||||
sc_time tPD; // = tCKE;
|
||||
sc_time tXP;
|
||||
sc_time tREFI;
|
||||
sc_time tREFIPB;
|
||||
sc_time tRFC;
|
||||
sc_time tRFCPB;
|
||||
sc_time tRREFD;
|
||||
sc_time tXS;
|
||||
sc_time tFAW;
|
||||
sc_time t32AW;
|
||||
sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK;
|
||||
sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK;
|
||||
sc_time tPPD;
|
||||
sc_time tLK;
|
||||
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECGDDR5X_H
|
||||
88
DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp
Normal file
88
DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 "MemSpecGDDR6.h"
|
||||
|
||||
sc_time MemSpecGDDR6::getRefreshIntervalAB() const
|
||||
{
|
||||
return tREFI;
|
||||
}
|
||||
|
||||
sc_time MemSpecGDDR6::getRefreshIntervalPB() const
|
||||
{
|
||||
return tREFIPB;
|
||||
}
|
||||
|
||||
sc_time MemSpecGDDR6::getExecutionTime(Command command, const tlm_generic_payload &payload) const
|
||||
{
|
||||
if (command == Command::PRE || command == Command::PREA)
|
||||
return tRP;
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
if (payload.get_command() == TLM_READ_COMMAND)
|
||||
return tRCDRD + clk;
|
||||
else
|
||||
return tRCDWR + clk;
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
return tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + getReadAccessTime();
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + getWriteAccessTime();
|
||||
else if (command == Command::REFA)
|
||||
return tRFC;
|
||||
else if (command == Command::REFB)
|
||||
return tRFCPB;
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("getExecutionTime",
|
||||
"command not known or command doesn't have a fixed execution time");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecGDDR6::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,
|
||||
sc_time_stamp() + tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + getReadAccessTime());
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI,
|
||||
sc_time_stamp() + tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + getWriteAccessTime());
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecGDDR6", "Method was called with invalid argument");
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
93
DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h
Normal file
93
DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 MEMSPECGDDR6_H
|
||||
#define MEMSPECGDDR6_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
|
||||
struct MemSpecGDDR6 final : public MemSpec
|
||||
{
|
||||
// Memspec Variables:
|
||||
sc_time tRP;
|
||||
sc_time tRAS;
|
||||
sc_time tRC;
|
||||
sc_time tRCDRD;
|
||||
sc_time tRCDWR;
|
||||
sc_time tRTP;
|
||||
sc_time tRRDS;
|
||||
sc_time tRRDL;
|
||||
sc_time tCCDS;
|
||||
sc_time tCCDL;
|
||||
sc_time tRL;
|
||||
sc_time tWCK2CKPIN;
|
||||
sc_time tWCK2CK;
|
||||
sc_time tWCK2DQO;
|
||||
sc_time tRTW;
|
||||
sc_time tWL;
|
||||
sc_time tWCK2DQI;
|
||||
sc_time tWR;
|
||||
sc_time tWTRS;
|
||||
sc_time tWTRL;
|
||||
sc_time tCKE;
|
||||
sc_time tPD; // = tCKE;
|
||||
sc_time tCKESR;
|
||||
sc_time tXP;
|
||||
sc_time tREFI;
|
||||
sc_time tREFIPB;
|
||||
sc_time tRFC;
|
||||
sc_time tRFCPB;
|
||||
sc_time tRREFD;
|
||||
sc_time tXS;
|
||||
sc_time tFAW;
|
||||
sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK;
|
||||
sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK;
|
||||
sc_time tPPD;
|
||||
sc_time tLK;
|
||||
sc_time tACTPDE;
|
||||
sc_time tPREPDE;
|
||||
sc_time tREFPDE;
|
||||
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECGDDR6_H
|
||||
@@ -66,12 +66,12 @@ struct MemSpecHBM2 final : public MemSpec
|
||||
sc_time tRTW;
|
||||
sc_time tXP;
|
||||
sc_time tCKE;
|
||||
sc_time tPD = tCKE;
|
||||
sc_time tRDPDE = tRL + tPL + (BurstLength / 2) * clk + clk;
|
||||
sc_time tWRPDE = tWL + tPL + (BurstLength / 2) * clk + clk + tWR;
|
||||
sc_time tWRAPDE = tWL + tPL + (BurstLength / 2) * clk + clk + tWR;
|
||||
sc_time tCKESR = tCKE + clk;
|
||||
sc_time tRDSRE = tRL + tPL + (BurstLength / 2) * clk + clk;
|
||||
sc_time tPD; // = tCKE;
|
||||
sc_time tRDPDE; // = tRL + tPL + (BurstLength / DataRate) * clk + clk;
|
||||
sc_time tWRPDE; // = tWL + tPL + (BurstLength / DataRate) * clk + clk + tWR;
|
||||
sc_time tWRAPDE; // = tWL + tPL + (BurstLength / DataRate) * clk + clk + tWR;
|
||||
sc_time tCKESR; // = tCKE + clk;
|
||||
sc_time tRDSRE; // = tRL + tPL + (BurstLength / DataRate) * clk + clk;
|
||||
sc_time tXS;
|
||||
sc_time tRFC;
|
||||
sc_time tRFCSB;
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
#include "checker/CheckerLPDDR4.h"
|
||||
#include "checker/CheckerWideIO2.h"
|
||||
#include "checker/CheckerHBM2.h"
|
||||
#include "checker/CheckerGDDR5.h"
|
||||
#include "checker/CheckerGDDR5X.h"
|
||||
#include "checker/CheckerGDDR6.h"
|
||||
#include "refresh/RefreshManager.h"
|
||||
#include "refresh/RefreshManagerDummy.h"
|
||||
#include "refresh/RefreshManagerBankwise.h"
|
||||
@@ -74,6 +77,12 @@ Controller::Controller(sc_module_name name) :
|
||||
checker = new CheckerWideIO2();
|
||||
else if (memSpec->MemoryType == "HBM2")
|
||||
checker = new CheckerHBM2();
|
||||
else if (memSpec->MemoryType == "GDDR5")
|
||||
checker = new CheckerGDDR5();
|
||||
else if (memSpec->MemoryType == "GDDR5X")
|
||||
checker = new CheckerGDDR5X();
|
||||
else if (memSpec->MemoryType == "GDDR6")
|
||||
checker = new CheckerGDDR6();
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Unsupported DRAM type");
|
||||
|
||||
|
||||
@@ -58,9 +58,6 @@ private:
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_time>> lastActivates;
|
||||
|
||||
// PowerDown TODO: Implement this method?
|
||||
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
|
||||
};
|
||||
|
||||
#endif // CHECKERDDR3_H
|
||||
|
||||
@@ -61,9 +61,6 @@ private:
|
||||
std::vector<std::queue<sc_time>> lastActivates;
|
||||
|
||||
sc_time burstClocks;
|
||||
|
||||
// PowerDown TODO: Implement this method?
|
||||
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
|
||||
};
|
||||
|
||||
#endif // CHECKERDDR4_H
|
||||
|
||||
394
DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp
Normal file
394
DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp
Normal file
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 "CheckerGDDR5.h"
|
||||
|
||||
CheckerGDDR5::CheckerGDDR5()
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<MemSpecGDDR5 *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerGDDR5", "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);
|
||||
last32Activates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR5::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
|
||||
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->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + 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::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RD)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + std::max(memSpec->tWR - memSpec->tRTP, memSpec->tWTRL));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
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->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + 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::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFB)
|
||||
{
|
||||
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->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
// lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()];
|
||||
// if (lastCommandStart != SC_ZERO_TIME)
|
||||
// earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
{
|
||||
if (bankwiseRefreshCounter == 0)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
}
|
||||
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportFatal("CheckerGDDR5", "Unknown command!");
|
||||
}
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
}
|
||||
|
||||
void CheckerGDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerGDDR5", "Changing state on bank " + 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 || command == Command::REFB)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(lastCommandOnBus);
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
last32Activates[rank.ID()].pop();
|
||||
last32Activates[rank.ID()].push(lastCommandOnBus);
|
||||
}
|
||||
|
||||
if (command == Command::REFB)
|
||||
bankwiseRefreshCounter = (bankwiseRefreshCounter + 1) % memSpec->BanksPerRank;
|
||||
}
|
||||
69
DRAMSys/library/src/controller/checker/CheckerGDDR5.h
Normal file
69
DRAMSys/library/src/controller/checker/CheckerGDDR5.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 CHECKERGDDR5_H
|
||||
#define CHECKERGDDR5_H
|
||||
|
||||
#include "CheckerIF.h"
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include "../../configuration/memspec/MemSpecGDDR5.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
|
||||
class CheckerGDDR5 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR5();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
const MemSpecGDDR5 *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;
|
||||
|
||||
// 4 and 32 activate window
|
||||
std::vector<std::queue<sc_time>> last4Activates;
|
||||
std::vector<std::queue<sc_time>> last32Activates;
|
||||
|
||||
sc_time burstClocks;
|
||||
|
||||
unsigned bankwiseRefreshCounter = 0;
|
||||
};
|
||||
|
||||
#endif // CHECKERGDDR5_H
|
||||
394
DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp
Normal file
394
DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp
Normal file
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 "CheckerGDDR5X.h"
|
||||
|
||||
CheckerGDDR5X::CheckerGDDR5X()
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<MemSpecGDDR5X *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerGDDR5X", "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);
|
||||
last32Activates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR5X::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
|
||||
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->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + 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::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RD)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + std::max(memSpec->tWR - memSpec->tRTP, memSpec->tWTRL));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
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->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + 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::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFB)
|
||||
{
|
||||
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->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
// lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()];
|
||||
// if (lastCommandStart != SC_ZERO_TIME)
|
||||
// earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
{
|
||||
if (bankwiseRefreshCounter == 0)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
}
|
||||
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportFatal("CheckerGDDR5X", "Unknown command!");
|
||||
}
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
}
|
||||
|
||||
void CheckerGDDR5X::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerGDDR5X", "Changing state on bank " + 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 || command == Command::REFB)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(lastCommandOnBus);
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
last32Activates[rank.ID()].pop();
|
||||
last32Activates[rank.ID()].push(lastCommandOnBus);
|
||||
}
|
||||
|
||||
if (command == Command::REFB)
|
||||
bankwiseRefreshCounter = (bankwiseRefreshCounter + 1) % memSpec->BanksPerRank;
|
||||
}
|
||||
69
DRAMSys/library/src/controller/checker/CheckerGDDR5X.h
Normal file
69
DRAMSys/library/src/controller/checker/CheckerGDDR5X.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 CHECKERGDDR5X_H
|
||||
#define CHECKERGDDR5X_H
|
||||
|
||||
#include "CheckerIF.h"
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include "../../configuration/memspec/MemSpecGDDR5X.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
|
||||
class CheckerGDDR5X final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR5X();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
const MemSpecGDDR5X *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;
|
||||
|
||||
// 4 and 32 activate window
|
||||
std::vector<std::queue<sc_time>> last4Activates;
|
||||
std::vector<std::queue<sc_time>> last32Activates;
|
||||
|
||||
sc_time burstClocks;
|
||||
|
||||
unsigned bankwiseRefreshCounter = 0;
|
||||
};
|
||||
|
||||
#endif // CHECKERGDDR5X_H
|
||||
383
DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp
Normal file
383
DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp
Normal file
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 "CheckerGDDR6.h"
|
||||
|
||||
CheckerGDDR6::CheckerGDDR6()
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<MemSpecGDDR6 *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerGDDR6", "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());
|
||||
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
|
||||
burstClocks = (memSpec->BurstLength / memSpec->DataRate) * memSpec->clk;
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR6::delayToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
|
||||
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->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + 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::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
if (lastActivates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RD)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + std::max(memSpec->tWR - memSpec->tRTP, memSpec->tWTRL));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWTRS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
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->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + 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::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else if (command == Command::REFB)
|
||||
{
|
||||
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->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + burstClocks + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
// lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()];
|
||||
// if (lastCommandStart != SC_ZERO_TIME)
|
||||
// earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
{
|
||||
if (bankwiseRefreshCounter == 0)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
}
|
||||
|
||||
if (lastActivates[rank.ID()].size() == 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->clk);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportFatal("CheckerGDDR6", "Unknown command!");
|
||||
}
|
||||
|
||||
return (earliestTimeToStart - sc_time_stamp());
|
||||
}
|
||||
|
||||
void CheckerGDDR6::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerGDDR6", "Changing state on bank " + 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 || command == Command::REFB)
|
||||
{
|
||||
if (lastActivates[rank.ID()].size() == 4)
|
||||
lastActivates[rank.ID()].pop();
|
||||
lastActivates[rank.ID()].push(lastCommandOnBus);
|
||||
}
|
||||
|
||||
if (command == Command::REFB)
|
||||
bankwiseRefreshCounter = (bankwiseRefreshCounter + 1) % memSpec->BanksPerRank;
|
||||
}
|
||||
68
DRAMSys/library/src/controller/checker/CheckerGDDR6.h
Normal file
68
DRAMSys/library/src/controller/checker/CheckerGDDR6.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 CHECKERGDDR6_H
|
||||
#define CHECKERGDDR6_H
|
||||
|
||||
#include "CheckerIF.h"
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include "../../configuration/memspec/MemSpecGDDR6.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
|
||||
class CheckerGDDR6 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR6();
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
const MemSpecGDDR6 *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>> lastActivates;
|
||||
|
||||
sc_time burstClocks;
|
||||
|
||||
unsigned bankwiseRefreshCounter = 0;
|
||||
};
|
||||
|
||||
#endif // CHECKERGDDR6_H
|
||||
@@ -64,9 +64,6 @@ private:
|
||||
sc_time burstClocks;
|
||||
|
||||
unsigned bankwiseRefreshCounter = 0;
|
||||
|
||||
// PowerDown TODO: Implement this method?
|
||||
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
|
||||
};
|
||||
|
||||
#endif // CHECKERHBM2_H
|
||||
|
||||
@@ -48,9 +48,6 @@ public:
|
||||
|
||||
virtual sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const = 0;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) = 0;
|
||||
|
||||
// PowerDown TODO: Implement this method?
|
||||
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
|
||||
};
|
||||
|
||||
#endif // CHECKERIF_H
|
||||
|
||||
@@ -58,9 +58,6 @@ private:
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_time>> lastActivates;
|
||||
|
||||
// PowerDown TODO: Implement this method?
|
||||
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
|
||||
};
|
||||
|
||||
#endif // CHECKERLPDDR4_H
|
||||
|
||||
@@ -60,9 +60,6 @@ private:
|
||||
std::vector<std::queue<sc_time>> lastActivates;
|
||||
|
||||
sc_time burstClocks;
|
||||
|
||||
// PowerDown TODO: Implement this method?
|
||||
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
|
||||
};
|
||||
|
||||
#endif // CHECKERWIDEIO_H
|
||||
|
||||
@@ -58,9 +58,6 @@ private:
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_time>> lastActivates;
|
||||
|
||||
// PowerDown TODO: Implement this method?
|
||||
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
|
||||
};
|
||||
|
||||
#endif // CHECKERWIDEIO2_H
|
||||
|
||||
@@ -59,6 +59,9 @@
|
||||
#include "dram/DramLPDDR4.h"
|
||||
#include "dram/DramWideIO2.h"
|
||||
#include "dram/DramHBM2.h"
|
||||
#include "dram/DramGDDR5.h"
|
||||
#include "dram/DramGDDR5X.h"
|
||||
#include "dram/DramGDDR6.h"
|
||||
#include "../controller/Controller.h"
|
||||
#include "../controller/ControllerRecordable.h"
|
||||
|
||||
@@ -306,6 +309,27 @@ void DRAMSys::instantiateModules(const string &traceName,
|
||||
else
|
||||
dram = new DramHBM2(str.c_str());
|
||||
}
|
||||
else if (memoryType == "GDDR5")
|
||||
{
|
||||
if (recordingEnabled)
|
||||
dram = new DramRecordable<DramGDDR5>(str.c_str(), tlmRecorders[i]);
|
||||
else
|
||||
dram = new DramGDDR5(str.c_str());
|
||||
}
|
||||
else if (memoryType == "GDDR5X")
|
||||
{
|
||||
if (recordingEnabled)
|
||||
dram = new DramRecordable<DramGDDR5X>(str.c_str(), tlmRecorders[i]);
|
||||
else
|
||||
dram = new DramGDDR5X(str.c_str());
|
||||
}
|
||||
else if (memoryType == "GDDR6")
|
||||
{
|
||||
if (recordingEnabled)
|
||||
dram = new DramRecordable<DramGDDR6>(str.c_str(), tlmRecorders[i]);
|
||||
else
|
||||
dram = new DramGDDR6(str.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("DRAMSys", "Unsupported DRAM type");
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#define DRAMDDR3_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "Dram.h"
|
||||
|
||||
class DramDDR3 : public Dram
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#define DRAMDDR4_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "Dram.h"
|
||||
|
||||
class DramDDR4 : public Dram
|
||||
|
||||
57
DRAMSys/library/src/simulation/dram/DramGDDR5.cpp
Normal file
57
DRAMSys/library/src/simulation/dram/DramGDDR5.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 "DramGDDR5.h"
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
#include "../../configuration/memspec/MemSpecGDDR5.h"
|
||||
|
||||
DramGDDR5::DramGDDR5(sc_module_name name) : Dram(name)
|
||||
{
|
||||
if (StoreMode == StorageMode::ErrorModel)
|
||||
SC_REPORT_FATAL("DramGDDR5", "Error Model not supported for GDDR5");
|
||||
|
||||
// Parameters for DRAMPower
|
||||
MemSpecGDDR5 *memSpec = dynamic_cast<MemSpecGDDR5 *>(this->memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("DramGDDR5", "Wrong MemSpec chosen");
|
||||
|
||||
if (Configuration::getInstance().PowerAnalysis)
|
||||
SC_REPORT_FATAL("DramGDDR5", "DRAMPower not supported for GDDR5");
|
||||
else
|
||||
DRAMPower = new libDRAMPowerDummy();
|
||||
}
|
||||
50
DRAMSys/library/src/simulation/dram/DramGDDR5.h
Normal file
50
DRAMSys/library/src/simulation/dram/DramGDDR5.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 DRAMGDDR5_H
|
||||
#define DRAMGDDR5_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include "Dram.h"
|
||||
|
||||
class DramGDDR5 : public Dram
|
||||
{
|
||||
public:
|
||||
DramGDDR5(sc_module_name);
|
||||
SC_HAS_PROCESS(DramGDDR5);
|
||||
virtual ~DramGDDR5() {}
|
||||
};
|
||||
|
||||
#endif // DRAMGDDR5_H
|
||||
57
DRAMSys/library/src/simulation/dram/DramGDDR5X.cpp
Normal file
57
DRAMSys/library/src/simulation/dram/DramGDDR5X.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 "DramGDDR5X.h"
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
#include "../../configuration/memspec/MemSpecGDDR5X.h"
|
||||
|
||||
DramGDDR5X::DramGDDR5X(sc_module_name name) : Dram(name)
|
||||
{
|
||||
if (StoreMode == StorageMode::ErrorModel)
|
||||
SC_REPORT_FATAL("DramGDDR5X", "Error Model not supported for GDDR5X");
|
||||
|
||||
// Parameters for DRAMPower
|
||||
MemSpecGDDR5X *memSpec = dynamic_cast<MemSpecGDDR5X *>(this->memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("DramGDDR5X", "Wrong MemSpec chosen");
|
||||
|
||||
if (Configuration::getInstance().PowerAnalysis)
|
||||
SC_REPORT_FATAL("DramGDDR5X", "DRAMPower not supported for GDDR5X");
|
||||
else
|
||||
DRAMPower = new libDRAMPowerDummy();
|
||||
}
|
||||
50
DRAMSys/library/src/simulation/dram/DramGDDR5X.h
Normal file
50
DRAMSys/library/src/simulation/dram/DramGDDR5X.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 DRAMGDDR5X_H
|
||||
#define DRAMGDDR5X_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include "Dram.h"
|
||||
|
||||
class DramGDDR5X : public Dram
|
||||
{
|
||||
public:
|
||||
DramGDDR5X(sc_module_name);
|
||||
SC_HAS_PROCESS(DramGDDR5X);
|
||||
virtual ~DramGDDR5X() {}
|
||||
};
|
||||
|
||||
#endif // DRAMGDDR5X_H
|
||||
57
DRAMSys/library/src/simulation/dram/DramGDDR6.cpp
Normal file
57
DRAMSys/library/src/simulation/dram/DramGDDR6.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 "DramGDDR6.h"
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
#include "../../configuration/memspec/MemSpecGDDR6.h"
|
||||
|
||||
DramGDDR6::DramGDDR6(sc_module_name name) : Dram(name)
|
||||
{
|
||||
if (StoreMode == StorageMode::ErrorModel)
|
||||
SC_REPORT_FATAL("DramGDDR6", "Error Model not supported for GDDR6");
|
||||
|
||||
// Parameters for DRAMPower
|
||||
MemSpecGDDR6 *memSpec = dynamic_cast<MemSpecGDDR6 *>(this->memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("DramGDDR6", "Wrong MemSpec chosen");
|
||||
|
||||
if (Configuration::getInstance().PowerAnalysis)
|
||||
SC_REPORT_FATAL("DramGDDR6", "DRAMPower not supported for GDDR6");
|
||||
else
|
||||
DRAMPower = new libDRAMPowerDummy();
|
||||
}
|
||||
51
DRAMSys/library/src/simulation/dram/DramGDDR6.h
Normal file
51
DRAMSys/library/src/simulation/dram/DramGDDR6.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2019, University of 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 DRAMGDDR6_H
|
||||
#define DRAMGDDR6_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include "Dram.h"
|
||||
|
||||
class DramGDDR6 : public Dram
|
||||
{
|
||||
public:
|
||||
DramGDDR6(sc_module_name);
|
||||
SC_HAS_PROCESS(DramGDDR6);
|
||||
virtual ~DramGDDR6() {}
|
||||
};
|
||||
|
||||
|
||||
#endif // DRAMGDDR6_H
|
||||
@@ -51,9 +51,7 @@ DramHBM2::DramHBM2(sc_module_name name) : Dram(name)
|
||||
SC_REPORT_FATAL("DramHBM2", "Wrong MemSpec chosen");
|
||||
|
||||
if (Configuration::getInstance().PowerAnalysis)
|
||||
{
|
||||
SC_REPORT_FATAL("DramHBM2", "DRAMPower not supported for HBM2");
|
||||
}
|
||||
else
|
||||
DRAMPower = new libDRAMPowerDummy();
|
||||
}
|
||||
|
||||
@@ -37,11 +37,8 @@
|
||||
#define DRAMHBM2_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "Dram.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class DramHBM2 : public Dram
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
|
||||
#include "DramLPDDR4.h"
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
#include "../../configuration/memspec/MemSpecLPDDR4.h"
|
||||
|
||||
DramLPDDR4::DramLPDDR4(sc_module_name name) : Dram(name)
|
||||
@@ -48,9 +51,7 @@ DramLPDDR4::DramLPDDR4(sc_module_name name) : Dram(name)
|
||||
SC_REPORT_FATAL("DramLPDDR4", "Wrong MemSpec chosen");
|
||||
|
||||
if (Configuration::getInstance().PowerAnalysis)
|
||||
{
|
||||
SC_REPORT_FATAL("DramLPDDR4", "DRAMPower not supported for LPDDR4");
|
||||
}
|
||||
else
|
||||
DRAMPower = new libDRAMPowerDummy();
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#define DRAMLPDDR4_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "Dram.h"
|
||||
|
||||
class DramLPDDR4 : public Dram
|
||||
|
||||
@@ -45,6 +45,9 @@
|
||||
#include "DramLPDDR4.h"
|
||||
#include "DramWideIO2.h"
|
||||
#include "DramHBM2.h"
|
||||
#include "DramGDDR5.h"
|
||||
#include "DramGDDR5X.h"
|
||||
#include "DramGDDR6.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
@@ -149,4 +152,7 @@ template class DramRecordable<DramWideIO>;
|
||||
template class DramRecordable<DramLPDDR4>;
|
||||
template class DramRecordable<DramWideIO2>;
|
||||
template class DramRecordable<DramHBM2>;
|
||||
template class DramRecordable<DramGDDR5>;
|
||||
template class DramRecordable<DramGDDR5X>;
|
||||
template class DramRecordable<DramGDDR6>;
|
||||
|
||||
|
||||
@@ -51,9 +51,7 @@ DramWideIO2::DramWideIO2(sc_module_name name) : Dram(name)
|
||||
SC_REPORT_FATAL("DramWideIO2", "Wrong MemSpec chosen");
|
||||
|
||||
if (Configuration::getInstance().PowerAnalysis)
|
||||
{
|
||||
SC_REPORT_FATAL("DramWideIO2", "DRAMPower not supported for WideIO2");
|
||||
}
|
||||
else
|
||||
DRAMPower = new libDRAMPowerDummy();
|
||||
}
|
||||
|
||||
@@ -37,11 +37,8 @@
|
||||
#define DRAMWIDEIO2_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include <tlm.h>
|
||||
#include "Dram.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class DramWideIO2 : public Dram
|
||||
{
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user