Add skeleton for HBM3 implementation
This commit is contained in:
@@ -98,6 +98,7 @@ add_library(DRAMSysLibrary
|
||||
src/configuration/memspec/MemSpecGDDR5X.cpp
|
||||
src/configuration/memspec/MemSpecGDDR6.cpp
|
||||
src/configuration/memspec/MemSpecHBM2.cpp
|
||||
src/configuration/memspec/MemSpecHBM3.cpp
|
||||
src/configuration/memspec/MemSpecSTTMRAM.cpp
|
||||
|
||||
src/controller/BankMachine.cpp
|
||||
@@ -117,6 +118,7 @@ add_library(DRAMSysLibrary
|
||||
src/controller/checker/CheckerGDDR5X.cpp
|
||||
src/controller/checker/CheckerGDDR6.cpp
|
||||
src/controller/checker/CheckerHBM2.cpp
|
||||
src/controller/checker/CheckerHBM3.cpp
|
||||
src/controller/checker/CheckerSTTMRAM.cpp
|
||||
|
||||
src/controller/cmdmux/CmdMuxIF.h
|
||||
@@ -176,6 +178,7 @@ add_library(DRAMSysLibrary
|
||||
src/simulation/dram/DramGDDR5X.cpp
|
||||
src/simulation/dram/DramGDDR6.cpp
|
||||
src/simulation/dram/DramHBM2.cpp
|
||||
src/simulation/dram/DramHBM3.cpp
|
||||
src/simulation/dram/DramSTTMRAM.cpp
|
||||
|
||||
${RECORDING_SOURCES}
|
||||
@@ -187,6 +190,7 @@ add_library(DRAMSysLibrary
|
||||
resources/simulations/ddr3-gem5-se.json
|
||||
resources/simulations/ddr4-example.json
|
||||
resources/simulations/hbm2-example.json
|
||||
resources/simulations/hbm3-example.json
|
||||
resources/simulations/lpddr4-example.json
|
||||
resources/simulations/ranktest.json
|
||||
resources/simulations/wideio-example.json
|
||||
@@ -203,6 +207,7 @@ add_library(DRAMSysLibrary
|
||||
resources/configs/amconfigs/am_ddr3_x16_rbc.json
|
||||
resources/configs/amconfigs/am_ddr4_8x4Gbx8_dimm_p1KB_brc.json
|
||||
resources/configs/amconfigs/am_hbm2_8Gb_pc_brc.json
|
||||
resources/configs/amconfigs/am_hbm3_8Gb_pc_brc.json
|
||||
resources/configs/amconfigs/am_lpddr4_8Gbx16_brc.json
|
||||
resources/configs/amconfigs/am_ranktest.json
|
||||
resources/configs/amconfigs/am_wideio2_4x64_4x2Gb_brc.json
|
||||
@@ -226,6 +231,7 @@ add_library(DRAMSysLibrary
|
||||
|
||||
# Memspec Config Files
|
||||
resources/configs/memspecs/HBM2.json
|
||||
resources/configs/memspecs/HBM3.json
|
||||
resources/configs/memspecs/JEDEC_256Mb_WIDEIO-200_128bit.json
|
||||
resources/configs/memspecs/JEDEC_256Mb_WIDEIO-266_128bit.json
|
||||
resources/configs/memspecs/JEDEC_4Gb_DDR4-1866_8bit_A.json
|
||||
@@ -280,6 +286,7 @@ add_library(DRAMSysLibrary
|
||||
resources/configs/simulator/ddr3_gem5_se.json
|
||||
resources/configs/simulator/ddr4.json
|
||||
resources/configs/simulator/hbm2.json
|
||||
resources/configs/simulator/hbm3.json
|
||||
resources/configs/simulator/lpddr4.json
|
||||
resources/configs/simulator/wideio.json
|
||||
resources/configs/simulator/wideio_thermal.json
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"PSEUDOCHANNEL_BIT":[
|
||||
29
|
||||
],
|
||||
"BANKGROUP_BIT":[
|
||||
27,
|
||||
28
|
||||
],
|
||||
"BANK_BIT": [
|
||||
25,
|
||||
26
|
||||
],
|
||||
"BYTE_BIT": [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
"COLUMN_BIT": [
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"ROW_BIT": [
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24
|
||||
]
|
||||
}
|
||||
}
|
||||
61
DRAMSys/library/resources/configs/memspecs/HBM3.json
Normal file
61
DRAMSys/library/resources/configs/memspecs/HBM3.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 8,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 4,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 128,
|
||||
"nbrOfPseudoChannels": 2,
|
||||
"nbrOfRows": 32768,
|
||||
"width": 64,
|
||||
"nbrOfDevices": 1,
|
||||
"nbrOfChannels": 1
|
||||
},
|
||||
"memoryId": "",
|
||||
"memoryType": "HBM3",
|
||||
"memtimingspec": {
|
||||
"CCDL": 4,
|
||||
"CCDS": 2,
|
||||
"CKE": 8,
|
||||
"DQSCK": 1,
|
||||
"FAW": 16,
|
||||
"PL": 0,
|
||||
"PPD": 2,
|
||||
"RAS": 28,
|
||||
"RC": 42,
|
||||
"RCDRD": 12,
|
||||
"RCDWR": 6,
|
||||
"REFI": 3900,
|
||||
"REFIPB": 244,
|
||||
"RFC": 220,
|
||||
"RFCPB": 96,
|
||||
"RL": 17,
|
||||
"RP": 14,
|
||||
"RRDL": 6,
|
||||
"RRDS": 4,
|
||||
"RREFD": 8,
|
||||
"RTP": 5,
|
||||
"RTW": 18,
|
||||
"WL": 7,
|
||||
"WR": 14,
|
||||
"WTRL": 9,
|
||||
"WTRS": 4,
|
||||
"XP": 8,
|
||||
"XS": 216,
|
||||
"clkMhz": 1600
|
||||
},
|
||||
"memtimingspec_comments": {
|
||||
"CKE": "no entry in HBM3",
|
||||
"DQSCK": "?",
|
||||
"PL": "?",
|
||||
"PPD": "added",
|
||||
"REFIPB": "renamed from REFISB; value TODO",
|
||||
"RFC": "TODO",
|
||||
"RFCPB": "renamed from RFCSB to RFCPB; TODO",
|
||||
"RL": "?",
|
||||
"WL": "?",
|
||||
"XS": "TODO (tRFC(min) + 10)"
|
||||
}
|
||||
}
|
||||
}
|
||||
19
DRAMSys/library/resources/configs/simulator/hbm3.json
Normal file
19
DRAMSys/library/resources/configs/simulator/hbm3.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"simconfig": {
|
||||
"AddressOffset": 0,
|
||||
"CheckTLM2Protocol": false,
|
||||
"DatabaseRecording": true,
|
||||
"Debug": false,
|
||||
"ECCControllerMode": "Disabled",
|
||||
"EnableWindowing": false,
|
||||
"ErrorCSVFile": "",
|
||||
"ErrorChipSeed": 42,
|
||||
"PowerAnalysis": false,
|
||||
"SimulationName": "hbm3",
|
||||
"SimulationProgressBar": true,
|
||||
"StoreMode": "NoStorage",
|
||||
"ThermalSimulation": false,
|
||||
"UseMalloc": false,
|
||||
"WindowSize": 1000
|
||||
}
|
||||
}
|
||||
16
DRAMSys/library/resources/simulations/hbm3-example.json
Normal file
16
DRAMSys/library/resources/simulations/hbm3-example.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"simulation": {
|
||||
"addressmapping": "am_hbm3_8Gb_pc_brc.json",
|
||||
"mcconfig": "fr_fcfs.json",
|
||||
"memspec": "HBM3.json",
|
||||
"simconfig": "hbm3.json",
|
||||
"simulationid": "hbm3-example",
|
||||
"thermalconfig": "config.json",
|
||||
"tracesetup": [
|
||||
{
|
||||
"clkMhz": 1000,
|
||||
"name": "ddr3_example.stl"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -367,21 +367,14 @@ void TlmRecorder::insertGeneralInfo()
|
||||
|
||||
const MemSpec& memSpec = *config.memSpec;
|
||||
const auto memoryType = memSpec.memoryType;
|
||||
bool rowColumnCommandBus = [memoryType]() -> bool {
|
||||
if (memoryType == MemSpec::MemoryType::HBM2)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}();
|
||||
|
||||
bool rowColumnCommandBus = (memoryType == MemSpec::MemoryType::HBM2) || (memoryType == MemSpec::MemoryType::HBM3);
|
||||
|
||||
bool pseudoChannelMode = [&memSpec, memoryType]() -> bool {
|
||||
if (memoryType != MemSpec::MemoryType::HBM2)
|
||||
if (memoryType != MemSpec::MemoryType::HBM2 && memoryType != MemSpec::MemoryType::HBM3)
|
||||
return false;
|
||||
|
||||
if (memSpec.pseudoChannelsPerChannel != 1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return memSpec.pseudoChannelsPerChannel != 1;
|
||||
}();
|
||||
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 17, static_cast<int>(rowColumnCommandBus));
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "memspec/MemSpecLPDDR5.h"
|
||||
#include "memspec/MemSpecWideIO2.h"
|
||||
#include "memspec/MemSpecHBM2.h"
|
||||
#include "memspec/MemSpecHBM3.h"
|
||||
#include "memspec/MemSpecGDDR5.h"
|
||||
#include "memspec/MemSpecGDDR5X.h"
|
||||
#include "memspec/MemSpecGDDR6.h"
|
||||
@@ -337,6 +338,8 @@ void Configuration::loadMemSpec(const DRAMSysConfiguration::MemSpec &memSpecConf
|
||||
memSpec = std::make_unique<const MemSpecWideIO2>(memSpecConfig);
|
||||
else if (memoryType == "HBM2")
|
||||
memSpec = std::make_unique<const MemSpecHBM2>(memSpecConfig);
|
||||
else if (memoryType == "HBM3")
|
||||
memSpec = std::make_unique<const MemSpecHBM3>(memSpecConfig);
|
||||
else if (memoryType == "GDDR5")
|
||||
memSpec = std::make_unique<const MemSpecGDDR5>(memSpecConfig);
|
||||
else if (memoryType == "GDDR5X")
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
|
||||
const std::string memoryId;
|
||||
const enum class MemoryType {DDR3, DDR4, DDR5, LPDDR4, LPDDR5, WideIO,
|
||||
WideIO2, GDDR5, GDDR5X, GDDR6, HBM2, STTMRAM} memoryType;
|
||||
WideIO2, GDDR5, GDDR5X, GDDR6, HBM2, HBM3, STTMRAM} memoryType;
|
||||
|
||||
virtual ~MemSpec() = default;
|
||||
|
||||
|
||||
168
DRAMSys/library/src/configuration/memspec/MemSpecHBM3.cpp
Normal file
168
DRAMSys/library/src/configuration/memspec/MemSpecHBM3.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Lukas Steiner
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../../common/utils.h"
|
||||
#include "MemSpecHBM3.h"
|
||||
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
MemSpecHBM3::MemSpecHBM3(const DRAMSysConfiguration::MemSpec &memSpec)
|
||||
: MemSpec(memSpec, MemoryType::HBM3,
|
||||
memSpec.memArchitectureSpec.entries.at("nbrOfChannels"),
|
||||
memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"),
|
||||
memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"),
|
||||
memSpec.memArchitectureSpec.entries.at("nbrOfBanks"),
|
||||
memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"),
|
||||
memSpec.memArchitectureSpec.entries.at("nbrOfBanks")
|
||||
/ memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"),
|
||||
memSpec.memArchitectureSpec.entries.at("nbrOfBanks")
|
||||
* memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"),
|
||||
memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups")
|
||||
* memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"),
|
||||
memSpec.memArchitectureSpec.entries.at("nbrOfDevices")),
|
||||
tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")),
|
||||
tRC (tCK * memSpec.memTimingSpec.entries.at("RC")),
|
||||
tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")),
|
||||
tRCDRD (tCK * memSpec.memTimingSpec.entries.at("RCDRD")),
|
||||
tRCDWR (tCK * memSpec.memTimingSpec.entries.at("RCDWR")),
|
||||
tRRDL (tCK * memSpec.memTimingSpec.entries.at("RRDL")),
|
||||
tRRDS (tCK * memSpec.memTimingSpec.entries.at("RRDS")),
|
||||
tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")),
|
||||
tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")),
|
||||
tRP (tCK * memSpec.memTimingSpec.entries.at("RP")),
|
||||
tRL (tCK * memSpec.memTimingSpec.entries.at("RL")),
|
||||
tWL (tCK * memSpec.memTimingSpec.entries.at("WL")),
|
||||
tPL (tCK * memSpec.memTimingSpec.entries.at("PL")),
|
||||
tWR (tCK * memSpec.memTimingSpec.entries.at("WR")),
|
||||
tCCDL (tCK * memSpec.memTimingSpec.entries.at("CCDL")),
|
||||
tCCDS (tCK * memSpec.memTimingSpec.entries.at("CCDS")),
|
||||
tWTRL (tCK * memSpec.memTimingSpec.entries.at("WTRL")),
|
||||
tWTRS (tCK * memSpec.memTimingSpec.entries.at("WTRS")),
|
||||
tRTW (tCK * memSpec.memTimingSpec.entries.at("RTW")),
|
||||
tXP (tCK * memSpec.memTimingSpec.entries.at("XP")),
|
||||
tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")),
|
||||
tPD (tCKE),
|
||||
tCKESR (tCKE + tCK),
|
||||
tXS (tCK * memSpec.memTimingSpec.entries.at("XS")),
|
||||
tRFC (tCK * memSpec.memTimingSpec.entries.at("RFC")),
|
||||
tRFCPB (tCK * memSpec.memTimingSpec.entries.at("RFCPB")),
|
||||
tRREFD (tCK * memSpec.memTimingSpec.entries.at("RREFD")),
|
||||
tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")),
|
||||
tREFIPB (tCK * memSpec.memTimingSpec.entries.at("REFIPB"))
|
||||
{
|
||||
commandLengthInCycles[Command::ACT] = 2; // TODO 1.5
|
||||
|
||||
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
|
||||
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
||||
memorySizeBytes = deviceSizeBytes * ranksPerChannel * numberOfChannels;
|
||||
|
||||
std::cout << headline << std::endl;
|
||||
std::cout << "Memory Configuration:" << std::endl << std::endl;
|
||||
std::cout << " Memory type: " << "HBM3" << std::endl;
|
||||
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
|
||||
std::cout << " Channels: " << numberOfChannels << std::endl;
|
||||
std::cout << " Pseudo channels per channel: " << ranksPerChannel << std::endl;
|
||||
std::cout << " Bank groups per pseudo channel: " << groupsPerRank << std::endl;
|
||||
std::cout << " Banks per pseudo channel: " << banksPerRank << std::endl;
|
||||
std::cout << " Rows per bank: " << rowsPerBank << std::endl;
|
||||
std::cout << " Columns per row: " << columnsPerRow << std::endl;
|
||||
std::cout << " Pseudo channel width in bits: " << bitWidth << std::endl;
|
||||
std::cout << " Pseudo channel size in bits: " << deviceSizeBits << std::endl;
|
||||
std::cout << " Pseudo channel size in bytes: " << deviceSizeBytes << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
sc_time MemSpecHBM3::getRefreshIntervalAB() const
|
||||
{
|
||||
return tREFI;
|
||||
}
|
||||
|
||||
sc_time MemSpecHBM3::getRefreshIntervalPB() const
|
||||
{
|
||||
return tREFIPB;
|
||||
}
|
||||
|
||||
bool MemSpecHBM3::hasRasAndCasBus() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
sc_time MemSpecHBM3::getExecutionTime(Command command, const tlm_generic_payload &payload) const
|
||||
{
|
||||
if (command == Command::PREPB || command == Command::PREAB)
|
||||
return tRP;
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
if (payload.get_command() == TLM_READ_COMMAND)
|
||||
return tRCDRD + tCK;
|
||||
else
|
||||
return tRCDWR + tCK;
|
||||
}
|
||||
else if (command == Command::RD)
|
||||
return tRL + tDQSCK + burstDuration;
|
||||
else if (command == Command::RDA)
|
||||
return tRTP + tRP;
|
||||
else if (command == Command::WR)
|
||||
return tWL + burstDuration;
|
||||
else if (command == Command::WRA)
|
||||
return tWL + burstDuration + tWR + tRP;
|
||||
else if (command == Command::REFAB)
|
||||
return tRFC;
|
||||
else if (command == Command::REFPB)
|
||||
return tRFCPB;
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("getExecutionTime",
|
||||
"command not known or command doesn't have a fixed execution time");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecHBM3::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return {tRL + tDQSCK, tRL + tDQSCK + burstDuration};
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return {tWL, tWL + burstDuration};
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecHBM3", "Method was called with invalid argument");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
93
DRAMSys/library/src/configuration/memspec/MemSpecHBM3.h
Normal file
93
DRAMSys/library/src/configuration/memspec/MemSpecHBM3.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Lukas Steiner
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#ifndef MemSpecHBM3_H
|
||||
#define MemSpecHBM3_H
|
||||
|
||||
#include <systemc>
|
||||
#include "MemSpec.h"
|
||||
|
||||
class MemSpecHBM3 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
explicit MemSpecHBM3(const DRAMSysConfiguration::MemSpec &memSpec);
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_core::sc_time tDQSCK;
|
||||
// sc_time tDQSQ; // TODO: check actual value of this parameter
|
||||
const sc_core::sc_time tRC;
|
||||
const sc_core::sc_time tRAS;
|
||||
const sc_core::sc_time tRCDRD;
|
||||
const sc_core::sc_time tRCDWR;
|
||||
const sc_core::sc_time tRRDL;
|
||||
const sc_core::sc_time tRRDS;
|
||||
const sc_core::sc_time tFAW;
|
||||
const sc_core::sc_time tRTP;
|
||||
const sc_core::sc_time tRP;
|
||||
const sc_core::sc_time tRL;
|
||||
const sc_core::sc_time tWL;
|
||||
const sc_core::sc_time tPL;
|
||||
const sc_core::sc_time tWR;
|
||||
const sc_core::sc_time tCCDL;
|
||||
const sc_core::sc_time tCCDS;
|
||||
// sc_time tCCDR; // TODO: consecutive reads to different stack IDs
|
||||
const sc_core::sc_time tWTRL;
|
||||
const sc_core::sc_time tWTRS;
|
||||
const sc_core::sc_time tRTW;
|
||||
const sc_core::sc_time tXP;
|
||||
const sc_core::sc_time tCKE;
|
||||
const sc_core::sc_time tPD; // = tCKE;
|
||||
const sc_core::sc_time tCKESR; // = tCKE + tCK;
|
||||
const sc_core::sc_time tXS;
|
||||
const sc_core::sc_time tRFC;
|
||||
const sc_core::sc_time tRFCPB;
|
||||
const sc_core::sc_time tRREFD;
|
||||
const sc_core::sc_time tREFI;
|
||||
const sc_core::sc_time tREFIPB;
|
||||
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
sc_core::sc_time getRefreshIntervalAB() const override;
|
||||
sc_core::sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
bool hasRasAndCasBus() const override;
|
||||
|
||||
sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
};
|
||||
|
||||
#endif // MemSpecHBM3_H
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "checker/CheckerLPDDR5.h"
|
||||
#include "checker/CheckerWideIO2.h"
|
||||
#include "checker/CheckerHBM2.h"
|
||||
#include "checker/CheckerHBM3.h"
|
||||
#include "checker/CheckerGDDR5.h"
|
||||
#include "checker/CheckerGDDR5X.h"
|
||||
#include "checker/CheckerGDDR6.h"
|
||||
@@ -98,6 +99,8 @@ Controller::Controller(const sc_module_name& name, const Configuration& config)
|
||||
checker = std::make_unique<CheckerWideIO2>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::HBM2)
|
||||
checker = std::make_unique<CheckerHBM2>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::HBM3)
|
||||
checker = std::make_unique<CheckerHBM3>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::GDDR5)
|
||||
checker = std::make_unique<CheckerGDDR5>(config);
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::GDDR5X)
|
||||
|
||||
549
DRAMSys/library/src/controller/checker/CheckerHBM3.cpp
Normal file
549
DRAMSys/library/src/controller/checker/CheckerHBM3.cpp
Normal file
@@ -0,0 +1,549 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "CheckerHBM3.h"
|
||||
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
CheckerHBM3::CheckerHBM3(const Configuration& config)
|
||||
{
|
||||
memSpec = dynamic_cast<const MemSpecHBM3 *>(config.memSpec.get());
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerHBM3", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, sc_max_time()));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->bankGroupsPerChannel, sc_max_time()));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, sc_max_time()));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), sc_max_time());
|
||||
lastCommandOnRasBus = sc_max_time();
|
||||
lastCommandOnCasBus = sc_max_time();
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
bankwiseRefreshCounter = std::vector<unsigned>(memSpec->ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDPDE = memSpec->tRL + memSpec->tPL + tBURST + memSpec->tCK;
|
||||
tRDSRE = tRDPDE;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tWRPDE = memSpec->tWL + memSpec->tPL + tBURST + memSpec->tCK + memSpec->tWR;
|
||||
tWRAPDE = memSpec->tWL + memSpec->tPL + tBURST + memSpec->tCK + memSpec->tWR;
|
||||
tWRRDS = memSpec->tWL + tBURST + memSpec->tWTRS;
|
||||
tWRRDL = memSpec->tWL + tBURST + memSpec->tWTRL;
|
||||
}
|
||||
|
||||
sc_time CheckerHBM3::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
|
||||
{
|
||||
Rank rank = DramExtension::getRank(payload);
|
||||
BankGroup bankGroup = DramExtension::getBankGroup(payload);
|
||||
Bank bank = DramExtension::getBank(payload);
|
||||
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
unsigned burstLength = DramExtension::getBurstLength(payload);
|
||||
assert(!(memSpec->ranksPerChannel == 1) || (burstLength == 2 || burstLength == 4)); // Legacy mode
|
||||
// assert(!(memSpec->ranksPerChannel == 2) || (burstLength == 4)); // Pseudo-channel mode
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
unsigned burstLength = DramExtension::getBurstLength(payload);
|
||||
assert(!(memSpec->ranksPerChannel == 1) || (burstLength == 2)); // Legacy mode
|
||||
// assert(!(memSpec->ranksPerChannel == 2) || (burstLength == 4)); // Pseudo-channel mode
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXP];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS - memSpec->tCK);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW - memSpec->tCK);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXP];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXP];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
{
|
||||
if (bankwiseRefreshCounter[rank.ID()] == 0)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDEA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXP];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDEP];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::ACT];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE));
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PREPB];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PREAB];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXP];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::REFAB];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::REFPB];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEN];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerHBM3", "Unknown command!");
|
||||
|
||||
if (command.isRasCommand())
|
||||
{
|
||||
if (lastCommandOnRasBus != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lastCommandOnCasBus != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
}
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerHBM3::insert(Command command, const tlm_generic_payload& payload)
|
||||
{
|
||||
Rank rank = DramExtension::getRank(payload);
|
||||
BankGroup bankGroup = DramExtension::getBankGroup(payload);
|
||||
Bank bank = DramExtension::getBank(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerHBM3", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + command.toString());
|
||||
|
||||
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();
|
||||
|
||||
if (command.isCasCommand())
|
||||
lastCommandOnCasBus = sc_time_stamp();
|
||||
else if (command == Command::ACT)
|
||||
lastCommandOnRasBus = sc_time_stamp() + memSpec->tCK;
|
||||
else
|
||||
lastCommandOnRasBus = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT || command == Command::REFPB)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(lastCommandOnRasBus);
|
||||
}
|
||||
|
||||
if (command == Command::REFPB)
|
||||
bankwiseRefreshCounter[rank.ID()] = (bankwiseRefreshCounter[rank.ID()] + 1) % memSpec->banksPerRank;
|
||||
}
|
||||
79
DRAMSys/library/src/controller/checker/CheckerHBM3.h
Normal file
79
DRAMSys/library/src/controller/checker/CheckerHBM3.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef CHECKERHBM3_H
|
||||
#define CHECKERHBM3_H
|
||||
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
#include "CheckerIF.h"
|
||||
#include "../../configuration/memspec/MemSpecHBM3.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
|
||||
class CheckerHBM3 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
explicit CheckerHBM3(const Configuration& config);
|
||||
sc_core::sc_time timeToSatisfyConstraints(Command command, const tlm::tlm_generic_payload& payload) const override;
|
||||
void insert(Command command, const tlm::tlm_generic_payload& payload) override;
|
||||
|
||||
private:
|
||||
const MemSpecHBM3 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
|
||||
sc_core::sc_time lastCommandOnRasBus;
|
||||
sc_core::sc_time lastCommandOnCasBus;
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_core::sc_time>> last4Activates;
|
||||
std::vector<unsigned> bankwiseRefreshCounter;
|
||||
|
||||
sc_core::sc_time tBURST;
|
||||
sc_core::sc_time tRDPDE;
|
||||
sc_core::sc_time tRDSRE;
|
||||
sc_core::sc_time tWRPRE;
|
||||
sc_core::sc_time tWRPDE;
|
||||
sc_core::sc_time tWRAPDE;
|
||||
sc_core::sc_time tRTWR;
|
||||
sc_core::sc_time tWRRDS;
|
||||
sc_core::sc_time tWRRDL;
|
||||
sc_core::sc_time tWRRDR;
|
||||
};
|
||||
|
||||
#endif // CHECKERHBM3_H
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "dram/DramLPDDR5.h"
|
||||
#include "dram/DramWideIO2.h"
|
||||
#include "dram/DramHBM2.h"
|
||||
#include "dram/DramHBM3.h"
|
||||
#include "dram/DramGDDR5.h"
|
||||
#include "dram/DramGDDR5X.h"
|
||||
#include "dram/DramGDDR6.h"
|
||||
@@ -191,6 +192,9 @@ void DRAMSys::instantiateModules(const DRAMSysConfiguration::AddressMapping &add
|
||||
else if (memoryType == MemSpec::MemoryType::HBM2)
|
||||
drams.emplace_back(std::make_unique<DramHBM2>(("dram" + std::to_string(i)).c_str(), config,
|
||||
*temperatureController));
|
||||
else if (memoryType == MemSpec::MemoryType::HBM3)
|
||||
drams.emplace_back(std::make_unique<DramHBM3>(("dram" + std::to_string(i)).c_str(), config,
|
||||
*temperatureController));
|
||||
else if (memoryType == MemSpec::MemoryType::GDDR5)
|
||||
drams.emplace_back(std::make_unique<DramGDDR5>(("dram" + std::to_string(i)).c_str(), config,
|
||||
*temperatureController));
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "dram/DramLPDDR5.h"
|
||||
#include "dram/DramWideIO2.h"
|
||||
#include "dram/DramHBM2.h"
|
||||
#include "dram/DramHBM3.h"
|
||||
#include "dram/DramGDDR5.h"
|
||||
#include "dram/DramGDDR5X.h"
|
||||
#include "dram/DramGDDR6.h"
|
||||
@@ -153,6 +154,9 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName,
|
||||
else if (memoryType == MemSpec::MemoryType::HBM2)
|
||||
drams.emplace_back(std::make_unique<DramRecordable<DramHBM2>>(("dram" + std::to_string(i)).c_str(),
|
||||
config, *temperatureController, tlmRecorders[i]));
|
||||
else if (memoryType == MemSpec::MemoryType::HBM3)
|
||||
drams.emplace_back(std::make_unique<DramRecordable<DramHBM3>>(("dram" + std::to_string(i)).c_str(),
|
||||
config, *temperatureController, tlmRecorders[i]));
|
||||
else if (memoryType == MemSpec::MemoryType::GDDR5)
|
||||
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR5>>(("dram" + std::to_string(i)).c_str(),
|
||||
config, *temperatureController, tlmRecorders[i]));
|
||||
|
||||
52
DRAMSys/library/src/simulation/dram/DramHBM3.cpp
Normal file
52
DRAMSys/library/src/simulation/dram/DramHBM3.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "DramHBM3.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
#include "../../configuration/memspec/MemSpecHBM3.h"
|
||||
|
||||
using namespace sc_core;
|
||||
|
||||
DramHBM3::DramHBM3(const sc_module_name& name, const Configuration& config,
|
||||
TemperatureController& temperatureController)
|
||||
: Dram(name, config)
|
||||
{
|
||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||
SC_REPORT_FATAL("DramHBM3", "Error Model not supported for HBM3");
|
||||
|
||||
if (powerAnalysis)
|
||||
SC_REPORT_FATAL("DramHBM3", "DRAMPower does not support HBM3");
|
||||
}
|
||||
52
DRAMSys/library/src/simulation/dram/DramHBM3.h
Normal file
52
DRAMSys/library/src/simulation/dram/DramHBM3.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef DRAMHBM3_H
|
||||
#define DRAMHBM3_H
|
||||
|
||||
#include <systemc>
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../TemperatureController.h"
|
||||
|
||||
class DramHBM3 : public Dram
|
||||
{
|
||||
public:
|
||||
DramHBM3(const sc_core::sc_module_name &name, const Configuration& config,
|
||||
TemperatureController& temperatureController);
|
||||
SC_HAS_PROCESS(DramHBM3);
|
||||
};
|
||||
|
||||
#endif // DRAMHBM3_H
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "DramLPDDR5.h"
|
||||
#include "DramWideIO2.h"
|
||||
#include "DramHBM2.h"
|
||||
#include "DramHBM3.h"
|
||||
#include "DramGDDR5.h"
|
||||
#include "DramGDDR5X.h"
|
||||
#include "DramGDDR6.h"
|
||||
@@ -162,4 +163,5 @@ template class DramRecordable<DramGDDR5>;
|
||||
template class DramRecordable<DramGDDR5X>;
|
||||
template class DramRecordable<DramGDDR6>;
|
||||
template class DramRecordable<DramHBM2>;
|
||||
template class DramRecordable<DramHBM3>;
|
||||
template class DramRecordable<DramSTTMRAM>;
|
||||
|
||||
Reference in New Issue
Block a user