Merge remote-tracking branch 'origin/develop' into work/tracegenerator
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -24,3 +24,5 @@ DRAMSys/analyzer/scripts/__pycache__/
|
||||
DRAMSys/gem5/boot_linux/linux-aarch32-ael.img
|
||||
DRAMSys/docs/doxygen
|
||||
/.vscode
|
||||
/cmake-build*
|
||||
/.idea
|
||||
|
||||
@@ -97,6 +97,7 @@ add_library(DRAMSysLibrary
|
||||
src/configuration/memspec/MemSpecGDDR5X.cpp
|
||||
src/configuration/memspec/MemSpecGDDR6.cpp
|
||||
src/configuration/memspec/MemSpecHBM2.cpp
|
||||
src/configuration/memspec/MemSpecSTTMRAM.cpp
|
||||
|
||||
src/controller/BankMachine.cpp
|
||||
src/controller/Command.cpp
|
||||
@@ -114,6 +115,7 @@ add_library(DRAMSysLibrary
|
||||
src/controller/checker/CheckerGDDR5X.cpp
|
||||
src/controller/checker/CheckerGDDR6.cpp
|
||||
src/controller/checker/CheckerHBM2.cpp
|
||||
src/controller/checker/CheckerSTTMRAM.cpp
|
||||
|
||||
src/controller/cmdmux/CmdMuxIF.h
|
||||
src/controller/cmdmux/CmdMuxOldest.cpp
|
||||
@@ -168,6 +170,7 @@ add_library(DRAMSysLibrary
|
||||
src/simulation/dram/DramGDDR5X.cpp
|
||||
src/simulation/dram/DramGDDR6.cpp
|
||||
src/simulation/dram/DramHBM2.cpp
|
||||
src/simulation/dram/DramSTTMRAM.cpp
|
||||
|
||||
${RECORDING_SOURCES}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"BANK_BIT": [
|
||||
13,
|
||||
14,
|
||||
15
|
||||
],
|
||||
"BYTE_BIT": [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
"COLUMN_BIT": [
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12
|
||||
],
|
||||
"ROW_BIT": [
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"mcconfig": {
|
||||
"PagePolicy": "Open",
|
||||
"Scheduler": "FrFcfs",
|
||||
"SchedulerBuffer": "Bankwise",
|
||||
"RequestBufferSize": 8,
|
||||
"CmdMux": "Oldest",
|
||||
"RespQueue": "Fifo",
|
||||
"RefreshPolicy": "NoRefresh",
|
||||
"RefreshMaxPostponed": 0,
|
||||
"RefreshMaxPulledin": 0,
|
||||
"PowerDownPolicy": "NoPowerDown",
|
||||
"Arbiter": "Simple",
|
||||
"MaxActiveTransactions": 128
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,8 @@
|
||||
"WPST": 0,
|
||||
"WR": 48,
|
||||
"CCD_L_slr": 8,
|
||||
"CCD_L_WR_slr": 16,
|
||||
"CCD_L_WR_slr": 32,
|
||||
"CCD_L_WR2_slr": 16,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 1600
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
"WPST": 0,
|
||||
"WR": 54,
|
||||
"CCD_L_slr": 9,
|
||||
"CCD_L_WR_slr": 18,
|
||||
"CCD_L_WR_slr": 36,
|
||||
"CCD_L_WR2_slr": 18,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 1800
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
"WPST": 0,
|
||||
"WR": 60,
|
||||
"CCD_L_slr": 10,
|
||||
"CCD_L_WR_slr": 20,
|
||||
"CCD_L_WR_slr": 40,
|
||||
"CCD_L_WR2_slr": 20,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 2000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
"WPST": 0,
|
||||
"WR": 66,
|
||||
"CCD_L_slr": 11,
|
||||
"CCD_L_WR_slr": 22,
|
||||
"CCD_L_WR_slr": 44,
|
||||
"CCD_L_WR2_slr": 22,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 2200
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
"WPST": 0,
|
||||
"WR": 72,
|
||||
"CCD_L_slr": 12,
|
||||
"CCD_L_WR_slr": 24,
|
||||
"CCD_L_WR_slr": 48,
|
||||
"CCD_L_WR2_slr": 24,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 2400
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
"WPST": 0,
|
||||
"WR": 78,
|
||||
"CCD_L_slr": 13,
|
||||
"CCD_L_WR_slr": 26,
|
||||
"CCD_L_WR_slr": 52,
|
||||
"CCD_L_WR2_slr": 26,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 2600
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
"WPST": 0,
|
||||
"WR": 84,
|
||||
"CCD_L_slr": 14,
|
||||
"CCD_L_WR_slr": 28,
|
||||
"CCD_L_WR_slr": 56,
|
||||
"CCD_L_WR2_slr": 28,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 2800
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
"WPST": 0,
|
||||
"WR": 90,
|
||||
"CCD_L_slr": 15,
|
||||
"CCD_L_WR_slr": 30,
|
||||
"CCD_L_WR_slr": 60,
|
||||
"CCD_L_WR2_slr": 30,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 3000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
"WPST": 0,
|
||||
"WR": 96,
|
||||
"CCD_L_slr": 16,
|
||||
"CCD_L_WR_slr": 32,
|
||||
"CCD_L_WR_slr": 64,
|
||||
"CCD_L_WR2_slr": 32,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 3200
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"WR": 48,
|
||||
"CCD_L_slr": 8,
|
||||
"CCD_L_WR_slr": 32,
|
||||
"CCD_L_WR2_slr": 16,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 1600
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"WR": 54,
|
||||
"CCD_L_slr": 9,
|
||||
"CCD_L_WR_slr": 36,
|
||||
"CCD_L_WR2_slr": 18,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 1800
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"WR": 60,
|
||||
"CCD_L_slr": 10,
|
||||
"CCD_L_WR_slr": 40,
|
||||
"CCD_L_WR2_slr": 20,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 2000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"WR": 66,
|
||||
"CCD_L_slr": 11,
|
||||
"CCD_L_WR_slr": 44,
|
||||
"CCD_L_WR2_slr": 22,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 2200
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"WR": 72,
|
||||
"CCD_L_slr": 12,
|
||||
"CCD_L_WR_slr": 48,
|
||||
"CCD_L_WR2_slr": 24,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 2400
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"WR": 78,
|
||||
"CCD_L_slr": 13,
|
||||
"CCD_L_WR_slr": 52,
|
||||
"CCD_L_WR2_slr": 26,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 2600
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"WR": 84,
|
||||
"CCD_L_slr": 14,
|
||||
"CCD_L_WR_slr": 56,
|
||||
"CCD_L_WR2_slr": 28,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 2800
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"WR": 90,
|
||||
"CCD_L_slr": 15,
|
||||
"CCD_L_WR_slr": 60,
|
||||
"CCD_L_WR2_slr": 30,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 3000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"WR": 96,
|
||||
"CCD_L_slr": 16,
|
||||
"CCD_L_WR_slr": 64,
|
||||
"CCD_L_WR2_slr": 32,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
@@ -70,4 +71,4 @@
|
||||
"clkMhz": 3200
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"WR": 48,
|
||||
"CCD_L_slr": 8,
|
||||
"CCD_L_WR_slr": 32,
|
||||
"CCD_L_WR2_slr": 16,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 8,
|
||||
|
||||
16
DRAMSys/library/resources/configs/memspecs/README.md
Normal file
16
DRAMSys/library/resources/configs/memspecs/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
*The following copyright notice only applies to the files "STT-MRAM-1.2x.json", "STT-MRAM-1.5x.json" and "STT-MRAM-2.0x.json".*
|
||||
|
||||
|
||||
(C) Copyright 2006-2018 Barcelona Supercomputing Center (BSC)
|
||||
|
||||
The copyright holder is BSC-CNS, and the authorship correspond to Kazi Asifuzzaman, Rommel Sanchez Verdejo, and Petar Radojkovic. The complete explanation of the derivation of the data can be found in the following study: Kazi Asifuzzaman, Rommel Sanchez Verdejo, and Petar Radojkovic. 2017. Enabling a reliable STT-MRAM main memory simulation. In Proceedings of the International Symposium on Memory Systems (MEMSYS '17). Washington DC, USA, 283-292. DOI: https://doi.org/10.1145/3132402.3132416
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.”
|
||||
|
||||
The configuration files list detailed timing parameters for STT-MRAM main memory, specifying a 1.2x/1.5x/2.0x deviation from respective DRAM timing parameters.
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 8,
|
||||
"dataRate": 2,
|
||||
"nbrOfBanks": 8,
|
||||
"nbrOfColumns": 1024,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfRows": 32768,
|
||||
"width": 8,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 1
|
||||
},
|
||||
"memoryId": "STT-MRAM-1.2x",
|
||||
"memoryType": "STT-MRAM",
|
||||
"memtimingspec": {
|
||||
"AL": 0,
|
||||
"CCD": 4,
|
||||
"CKE": 4,
|
||||
"CKESR": 7,
|
||||
"CL": 11,
|
||||
"DQSCK": 0,
|
||||
"FAW": 29,
|
||||
"RAS": 20,
|
||||
"RC": 34,
|
||||
"RCD": 14,
|
||||
"RL": 11,
|
||||
"RP": 14,
|
||||
"RRD": 6,
|
||||
"RTP": 6,
|
||||
"WL": 11,
|
||||
"WR": 12,
|
||||
"WTR": 2,
|
||||
"XP": 5,
|
||||
"XPDLL": 325,
|
||||
"XS": 324,
|
||||
"XSDLL": 512,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"RTRS": 1,
|
||||
"clkMhz": 800
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 8,
|
||||
"dataRate": 2,
|
||||
"nbrOfBanks": 8,
|
||||
"nbrOfColumns": 1024,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfRows": 32768,
|
||||
"width": 8,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 1
|
||||
},
|
||||
"memoryId": "STT-MRAM-1.5x",
|
||||
"memoryType": "STT-MRAM",
|
||||
"memtimingspec": {
|
||||
"AL": 0,
|
||||
"CCD": 4,
|
||||
"CKE": 4,
|
||||
"CKESR": 7,
|
||||
"CL": 11,
|
||||
"DQSCK": 0,
|
||||
"FAW": 36,
|
||||
"RAS": 23,
|
||||
"RC": 40,
|
||||
"RCD": 14,
|
||||
"RL": 11,
|
||||
"RP": 17,
|
||||
"RRD": 8,
|
||||
"RTP": 6,
|
||||
"WL": 11,
|
||||
"WR": 12,
|
||||
"WTR": 6,
|
||||
"XP": 5,
|
||||
"XPDLL": 325,
|
||||
"XS": 324,
|
||||
"XSDLL": 512,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"RTRS": 1,
|
||||
"clkMhz": 800
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 8,
|
||||
"dataRate": 2,
|
||||
"nbrOfBanks": 8,
|
||||
"nbrOfColumns": 1024,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfRows": 32768,
|
||||
"width": 8,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 1
|
||||
},
|
||||
"memoryId": "STT-MRAM-2.0x",
|
||||
"memoryType": "STT-MRAM",
|
||||
"memtimingspec": {
|
||||
"AL": 0,
|
||||
"CCD": 4,
|
||||
"CKE": 4,
|
||||
"CKESR": 7,
|
||||
"CL": 11,
|
||||
"DQSCK": 0,
|
||||
"FAW": 36,
|
||||
"RAS": 28,
|
||||
"RC": 50,
|
||||
"RCD": 14,
|
||||
"RL": 11,
|
||||
"RP": 22,
|
||||
"RRD": 10,
|
||||
"RTP": 6,
|
||||
"WL": 11,
|
||||
"WR": 48,
|
||||
"WTR": 6,
|
||||
"XP": 5,
|
||||
"XPDLL": 325,
|
||||
"XS": 324,
|
||||
"XSDLL": 512,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"RTRS": 1,
|
||||
"clkMhz": 800
|
||||
}
|
||||
}
|
||||
}
|
||||
19
DRAMSys/library/resources/configs/simulator/stt-mram.json
Normal file
19
DRAMSys/library/resources/configs/simulator/stt-mram.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": "stt-mram",
|
||||
"SimulationProgressBar": true,
|
||||
"StoreMode": "NoStorage",
|
||||
"ThermalSimulation": false,
|
||||
"UseMalloc": false,
|
||||
"WindowSize": 1000
|
||||
}
|
||||
}
|
||||
16
DRAMSys/library/resources/simulations/stt-mram-example.json
Normal file
16
DRAMSys/library/resources/simulations/stt-mram-example.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"simulation": {
|
||||
"addressmapping": "am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json",
|
||||
"mcconfig": "fr_fcfs_noref.json",
|
||||
"memspec": "STT-MRAM-1.2x.json",
|
||||
"simconfig": "stt-mram.json",
|
||||
"simulationid": "stt-mram-example",
|
||||
"thermalconfig": "config.json",
|
||||
"tracesetup": [
|
||||
{
|
||||
"clkMhz": 800,
|
||||
"name": "ddr3_example.stl"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -162,7 +162,7 @@ void TlmRecorder::introduceTransactionSystem(tlm_generic_payload &trans)
|
||||
currentTransactionsInSystem[&trans].cmd = trans.get_command() ==
|
||||
tlm::TLM_READ_COMMAND ? "R" : "W";
|
||||
currentTransactionsInSystem[&trans].address = trans.get_address();
|
||||
currentTransactionsInSystem[&trans].burstlength = trans.get_streaming_width();
|
||||
currentTransactionsInSystem[&trans].burstLength = DramExtension::getBurstLength(trans);
|
||||
currentTransactionsInSystem[&trans].dramExtension = DramExtension::getExtension(trans);
|
||||
currentTransactionsInSystem[&trans].timeOfGeneration = GenerationExtension::getTimeOfGeneration(trans);
|
||||
|
||||
@@ -406,7 +406,7 @@ void TlmRecorder::insertTransactionInDB(Transaction &recordingData)
|
||||
sqlite3_bind_int(insertTransactionStatement, 1, static_cast<int>(recordingData.id));
|
||||
sqlite3_bind_int(insertTransactionStatement, 2, static_cast<int>(recordingData.id));
|
||||
sqlite3_bind_int64(insertTransactionStatement, 3, static_cast<int64_t>(recordingData.address));
|
||||
sqlite3_bind_int(insertTransactionStatement, 4, static_cast<int>(recordingData.burstlength));
|
||||
sqlite3_bind_int(insertTransactionStatement, 4, static_cast<int>(recordingData.burstLength));
|
||||
sqlite3_bind_int(insertTransactionStatement, 5,
|
||||
static_cast<int>(recordingData.dramExtension.getThread().ID()));
|
||||
sqlite3_bind_int(insertTransactionStatement, 6,
|
||||
|
||||
@@ -92,7 +92,7 @@ private:
|
||||
|
||||
uint64_t id;
|
||||
uint64_t address;
|
||||
unsigned int burstlength;
|
||||
unsigned int burstLength;
|
||||
std::string cmd;
|
||||
DramExtension dramExtension;
|
||||
sc_time timeOfGeneration;
|
||||
|
||||
@@ -44,21 +44,21 @@ using namespace tlm;
|
||||
|
||||
DramExtension::DramExtension() :
|
||||
thread(0), channel(0), rank(0), bankgroup(0), bank(0),
|
||||
row(0), column(0), burstlength(0),
|
||||
row(0), column(0), burstLength(0),
|
||||
threadPayloadID(0), channelPayloadID(0) {}
|
||||
|
||||
DramExtension::DramExtension(Thread thread, Channel channel, Rank rank,
|
||||
BankGroup bankgroup, Bank bank, Row row,
|
||||
Column column, unsigned int burstlength,
|
||||
Column column, unsigned int burstLength,
|
||||
uint64_t threadPayloadID, uint64_t channelPayloadID) :
|
||||
thread(thread), channel(channel), rank(rank), bankgroup(bankgroup), bank(bank),
|
||||
row(row), column(column), burstlength(burstlength),
|
||||
row(row), column(column), burstLength(burstLength),
|
||||
threadPayloadID(threadPayloadID), channelPayloadID(channelPayloadID) {}
|
||||
|
||||
void DramExtension::setExtension(tlm::tlm_generic_payload *payload,
|
||||
Thread thread, Channel channel, Rank rank,
|
||||
BankGroup bankgroup, Bank bank, Row row,
|
||||
Column column, unsigned int burstlength,
|
||||
Column column, unsigned int burstLength,
|
||||
uint64_t threadPayloadID, uint64_t channelPayloadID)
|
||||
{
|
||||
DramExtension *extension = nullptr;
|
||||
@@ -73,14 +73,14 @@ void DramExtension::setExtension(tlm::tlm_generic_payload *payload,
|
||||
extension->bank = bank;
|
||||
extension->row = row;
|
||||
extension->column = column;
|
||||
extension->burstlength = burstlength;
|
||||
extension->burstLength = burstLength;
|
||||
extension->threadPayloadID = threadPayloadID;
|
||||
extension->channelPayloadID = channelPayloadID;
|
||||
}
|
||||
else
|
||||
{
|
||||
extension = new DramExtension(thread, channel, rank, bankgroup,
|
||||
bank, row, column, burstlength,
|
||||
bank, row, column, burstLength,
|
||||
threadPayloadID, channelPayloadID);
|
||||
payload->set_auto_extension(extension);
|
||||
}
|
||||
@@ -89,11 +89,11 @@ void DramExtension::setExtension(tlm::tlm_generic_payload *payload,
|
||||
void DramExtension::setExtension(tlm::tlm_generic_payload &payload,
|
||||
Thread thread, Channel channel, Rank rank,
|
||||
BankGroup bankgroup, Bank bank, Row row,
|
||||
Column column, unsigned int burstlength,
|
||||
Column column, unsigned int burstLength,
|
||||
uint64_t threadPayloadID, uint64_t channelPayloadID)
|
||||
{
|
||||
setExtension(&payload, thread, channel, rank, bankgroup,
|
||||
bank, row, column, burstlength,
|
||||
bank, row, column, burstLength,
|
||||
threadPayloadID, channelPayloadID);
|
||||
}
|
||||
|
||||
@@ -194,6 +194,16 @@ Column DramExtension::getColumn(const tlm_generic_payload &payload)
|
||||
return DramExtension::getColumn(&payload);
|
||||
}
|
||||
|
||||
unsigned DramExtension::getBurstLength(const tlm_generic_payload *payload)
|
||||
{
|
||||
return DramExtension::getExtension(payload).getBurstLength();
|
||||
}
|
||||
|
||||
unsigned DramExtension::getBurstLength(const tlm_generic_payload &payload)
|
||||
{
|
||||
return DramExtension::getBurstLength(&payload);
|
||||
}
|
||||
|
||||
uint64_t DramExtension::getThreadPayloadID(const tlm_generic_payload *payload)
|
||||
{
|
||||
return DramExtension::getExtension(payload).getThreadPayloadID();
|
||||
@@ -217,7 +227,7 @@ uint64_t DramExtension::getChannelPayloadID(const tlm_generic_payload &payload)
|
||||
tlm_extension_base *DramExtension::clone() const
|
||||
{
|
||||
return new DramExtension(thread, channel, rank, bankgroup, bank, row, column,
|
||||
burstlength, threadPayloadID, channelPayloadID);
|
||||
burstLength, threadPayloadID, channelPayloadID);
|
||||
}
|
||||
|
||||
void DramExtension::copy_from(const tlm_extension_base &ext)
|
||||
@@ -230,7 +240,7 @@ void DramExtension::copy_from(const tlm_extension_base &ext)
|
||||
bank = cpyFrom.bank;
|
||||
row = cpyFrom.row;
|
||||
column = cpyFrom.column;
|
||||
burstlength = cpyFrom.burstlength;
|
||||
burstLength = cpyFrom.burstLength;
|
||||
}
|
||||
|
||||
Thread DramExtension::getThread() const
|
||||
@@ -268,9 +278,9 @@ Column DramExtension::getColumn() const
|
||||
return column;
|
||||
}
|
||||
|
||||
unsigned int DramExtension::getBurstlength() const
|
||||
unsigned int DramExtension::getBurstLength() const
|
||||
{
|
||||
return burstlength;
|
||||
return burstLength;
|
||||
}
|
||||
|
||||
uint64_t DramExtension::getThreadPayloadID() const
|
||||
|
||||
@@ -165,7 +165,7 @@ public:
|
||||
DramExtension();
|
||||
DramExtension(Thread thread, Channel channel, Rank rank,
|
||||
BankGroup bankgroup, Bank bank, Row row,
|
||||
Column column, unsigned int burstlength,
|
||||
Column column, unsigned int burstLength,
|
||||
uint64_t threadPayloadID, uint64_t channelPayloadID);
|
||||
|
||||
virtual tlm::tlm_extension_base *clone() const;
|
||||
@@ -174,12 +174,12 @@ public:
|
||||
static void setExtension(tlm::tlm_generic_payload *payload,
|
||||
Thread thread, Channel channel, Rank rank,
|
||||
BankGroup bankgroup, Bank bank, Row row,
|
||||
Column column, unsigned int burstlength,
|
||||
Column column, unsigned int burstLength,
|
||||
uint64_t threadPayloadID, uint64_t channelPayloadID);
|
||||
static void setExtension(tlm::tlm_generic_payload &payload,
|
||||
Thread thread, Channel channel, Rank rank,
|
||||
BankGroup bankgroup, Bank bank, Row row,
|
||||
Column column, unsigned int burstlength,
|
||||
Column column, unsigned int burstLength,
|
||||
uint64_t threadPayloadID, uint64_t channelPayloadID);
|
||||
|
||||
static DramExtension &getExtension(const tlm::tlm_generic_payload *payload);
|
||||
@@ -205,6 +205,8 @@ public:
|
||||
static Row getRow(const tlm::tlm_generic_payload &payload);
|
||||
static Column getColumn(const tlm::tlm_generic_payload *payload);
|
||||
static Column getColumn(const tlm::tlm_generic_payload &payload);
|
||||
static unsigned getBurstLength(const tlm::tlm_generic_payload *payload);
|
||||
static unsigned getBurstLength(const tlm::tlm_generic_payload &payload);
|
||||
static uint64_t getThreadPayloadID(const tlm::tlm_generic_payload *payload);
|
||||
static uint64_t getThreadPayloadID(const tlm::tlm_generic_payload &payload);
|
||||
static uint64_t getChannelPayloadID(const tlm::tlm_generic_payload *payload);
|
||||
@@ -218,7 +220,7 @@ public:
|
||||
Row getRow() const;
|
||||
Column getColumn() const;
|
||||
|
||||
unsigned int getBurstlength() const;
|
||||
unsigned int getBurstLength() const;
|
||||
uint64_t getThreadPayloadID() const;
|
||||
uint64_t getChannelPayloadID() const;
|
||||
void incrementRow();
|
||||
@@ -231,7 +233,7 @@ private:
|
||||
Bank bank;
|
||||
Row row;
|
||||
Column column;
|
||||
unsigned int burstlength;
|
||||
unsigned int burstLength;
|
||||
uint64_t threadPayloadID;
|
||||
uint64_t channelPayloadID;
|
||||
};
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "memspec/MemSpecGDDR5.h"
|
||||
#include "memspec/MemSpecGDDR5X.h"
|
||||
#include "memspec/MemSpecGDDR6.h"
|
||||
#include "memspec/MemSpecSTTMRAM.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
@@ -357,6 +358,8 @@ void Configuration::loadMemSpec(Configuration &config, std::string memspecUri)
|
||||
memSpec = new MemSpecGDDR5X(jMemSpec);
|
||||
else if (memoryType == "GDDR6")
|
||||
memSpec = new MemSpecGDDR6(jMemSpec);
|
||||
else if (memoryType == "STT-MRAM")
|
||||
memSpec = new MemSpecSTTMRAM(jMemSpec);
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported DRAM type");
|
||||
}
|
||||
|
||||
@@ -69,7 +69,8 @@ public:
|
||||
const sc_time tCK;
|
||||
|
||||
const std::string memoryId;
|
||||
const enum class MemoryType {DDR3, DDR4, DDR5, LPDDR4, WideIO, WideIO2, GDDR5, GDDR5X, GDDR6, HBM2} memoryType;
|
||||
const enum class MemoryType {DDR3, DDR4, DDR5, LPDDR4, WideIO,
|
||||
WideIO2, GDDR5, GDDR5X, GDDR6, HBM2, STTMRAM} memoryType;
|
||||
|
||||
virtual ~MemSpec() {}
|
||||
|
||||
@@ -79,8 +80,8 @@ public:
|
||||
|
||||
virtual bool hasRasAndCasBus() const;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const = 0;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const = 0;
|
||||
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const = 0;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const = 0;
|
||||
|
||||
sc_time getCommandLength(Command) const;
|
||||
virtual uint64_t getSimMemSizeInBytes() const = 0;
|
||||
|
||||
@@ -120,7 +120,7 @@ sc_time MemSpecDDR3::getExecutionTime(Command command, const tlm_generic_payload
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecDDR3::getIntervalOnDataStrobe(Command command) const
|
||||
TimeInterval MemSpecDDR3::getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(tRL, tRL + burstDuration);
|
||||
|
||||
@@ -89,8 +89,8 @@ public:
|
||||
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
|
||||
virtual uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
@@ -139,7 +139,7 @@ sc_time MemSpecDDR4::getExecutionTime(Command command, const tlm_generic_payload
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecDDR4::getIntervalOnDataStrobe(Command command) const
|
||||
TimeInterval MemSpecDDR4::getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(tRL, tRL + burstDuration);
|
||||
|
||||
@@ -97,8 +97,8 @@ public:
|
||||
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
|
||||
virtual uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
@@ -59,56 +59,59 @@ MemSpecDDR5::MemSpecDDR5(json &memspec)
|
||||
numberOfLogicalRanks(logicalRanksPerPhysicalRank * numberOfPhysicalRanks),
|
||||
cmdMode(parseUint(memspec["memarchitecturespec"]["cmdMode"], "cmdMode")),
|
||||
refMode(parseUint(memspec["memarchitecturespec"]["refMode"], "refMode")),
|
||||
tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")),
|
||||
tPPD (tCK * parseUint(memspec["memtimingspec"]["PPD"], "PPD")),
|
||||
tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")),
|
||||
tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")),
|
||||
tRC (tRAS + tRP),
|
||||
tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")),
|
||||
tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")),
|
||||
tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")),
|
||||
tRPST (tCK * parseUint(memspec["memtimingspec"]["RPST"], "RPST")),
|
||||
tRDDQS (tCK * parseUint(memspec["memtimingspec"]["RDDQS"], "RDDQS")),
|
||||
tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")),
|
||||
tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")),
|
||||
tWPST (tCK * parseUint(memspec["memtimingspec"]["WPST"], "WPST")),
|
||||
tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")),
|
||||
tCCD_L_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_slr"], "CCD_L_slr")),
|
||||
tCCD_L_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_WR_slr"], "CCD_L_WR_slr")),
|
||||
tCCD_S_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_slr"], "CCD_S_slr")),
|
||||
tCCD_S_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_WR_slr"], "CCD_S_WR_slr")),
|
||||
tCCD_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_dlr"], "CCD_dlr")),
|
||||
tCCD_WR_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dlr"], "CCD_WR_dlr")),
|
||||
tCCD_WR_dpr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dpr"], "CCD_WR_dpr")),
|
||||
tRRD_L_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_L_slr"], "RRD_L_slr")),
|
||||
tRRD_S_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_S_slr"], "RRD_S_slr")),
|
||||
tRRD_dlr (tCK * parseUint(memspec["memtimingspec"]["RRD_dlr"], "RRD_dlr")),
|
||||
tFAW_slr (tCK * parseUint(memspec["memtimingspec"]["FAW_slr"], "FAW_slr")),
|
||||
tFAW_dlr (tCK * parseUint(memspec["memtimingspec"]["FAW_dlr"], "FAW_dlr")),
|
||||
tWTR_L (tCK * parseUint(memspec["memtimingspec"]["WTR_L"], "WTR_L")),
|
||||
tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")),
|
||||
tRFC_slr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_slr"], "RFC1_slr")
|
||||
: tCK * parseUint(memspec["memtimingspec"]["RFC2_slr"], "RFC2_slr")),
|
||||
tRFC_dlr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dlr"], "RFC1_dlr")
|
||||
: tCK * parseUint(memspec["memtimingspec"]["RFC2_dlr"], "RFC2_dlr")),
|
||||
tRFC_dpr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dpr"], "RFC1_dpr")
|
||||
: tCK * parseUint(memspec["memtimingspec"]["RFC2_dpr"], "RFC2_dpr")),
|
||||
tRFCsb_slr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_slr"], "RFCsb_slr")),
|
||||
tRFCsb_dlr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_dlr"], "RFCsb_dlr")),
|
||||
tREFI ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["REFI1"], "REFI1")
|
||||
: tCK * parseUint(memspec["memtimingspec"]["REFI2"], "REFI2")),
|
||||
tREFIsb (tCK * parseUint(memspec["memtimingspec"]["REFISB"], "REFISB")),
|
||||
tREFSBRD_slr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_slr"], "REFSBRD_slr")),
|
||||
tREFSBRD_dlr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_dlr"], "REFSBRD_dlr")),
|
||||
tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")),
|
||||
tCPDED (tCK * parseUint(memspec["memtimingspec"]["CPDED"], "CPDED")),
|
||||
tPD (tCK * parseUint(memspec["memtimingspec"]["PD"], "PD")),
|
||||
tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")),
|
||||
tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")),
|
||||
tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")),
|
||||
tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")),
|
||||
cmdOffset_S (cmdMode == 2 ? 1 * tCK : 0 * tCK),
|
||||
cmdOffset_L (cmdMode == 2 ? 3 * tCK : 1 * tCK)
|
||||
tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")),
|
||||
tPPD (tCK * parseUint(memspec["memtimingspec"]["PPD"], "PPD")),
|
||||
tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")),
|
||||
tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")),
|
||||
tRC (tRAS + tRP),
|
||||
tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")),
|
||||
tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")),
|
||||
tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")),
|
||||
tRPST (tCK * parseUint(memspec["memtimingspec"]["RPST"], "RPST")),
|
||||
tRDDQS (tCK * parseUint(memspec["memtimingspec"]["RDDQS"], "RDDQS")),
|
||||
tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")),
|
||||
tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")),
|
||||
tWPST (tCK * parseUint(memspec["memtimingspec"]["WPST"], "WPST")),
|
||||
tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")),
|
||||
tCCD_L_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_slr"], "CCD_L_slr")),
|
||||
tCCD_L_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_WR_slr"], "CCD_L_WR_slr")),
|
||||
tCCD_L_WR2_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_WR2_slr"], "CCD_L_WR2_slr")),
|
||||
tCCD_S_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_slr"], "CCD_S_slr")),
|
||||
tCCD_S_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_WR_slr"], "CCD_S_WR_slr")),
|
||||
tCCD_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_dlr"], "CCD_dlr")),
|
||||
tCCD_WR_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dlr"], "CCD_WR_dlr")),
|
||||
tCCD_WR_dpr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dpr"], "CCD_WR_dpr")),
|
||||
tRRD_L_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_L_slr"], "RRD_L_slr")),
|
||||
tRRD_S_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_S_slr"], "RRD_S_slr")),
|
||||
tRRD_dlr (tCK * parseUint(memspec["memtimingspec"]["RRD_dlr"], "RRD_dlr")),
|
||||
tFAW_slr (tCK * parseUint(memspec["memtimingspec"]["FAW_slr"], "FAW_slr")),
|
||||
tFAW_dlr (tCK * parseUint(memspec["memtimingspec"]["FAW_dlr"], "FAW_dlr")),
|
||||
tWTR_L (tCK * parseUint(memspec["memtimingspec"]["WTR_L"], "WTR_L")),
|
||||
tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")),
|
||||
tRFC_slr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_slr"], "RFC1_slr")
|
||||
: tCK * parseUint(memspec["memtimingspec"]["RFC2_slr"], "RFC2_slr")),
|
||||
tRFC_dlr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dlr"], "RFC1_dlr")
|
||||
: tCK * parseUint(memspec["memtimingspec"]["RFC2_dlr"], "RFC2_dlr")),
|
||||
tRFC_dpr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dpr"], "RFC1_dpr")
|
||||
: tCK * parseUint(memspec["memtimingspec"]["RFC2_dpr"], "RFC2_dpr")),
|
||||
tRFCsb_slr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_slr"], "RFCsb_slr")),
|
||||
tRFCsb_dlr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_dlr"], "RFCsb_dlr")),
|
||||
tREFI ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["REFI1"], "REFI1")
|
||||
: tCK * parseUint(memspec["memtimingspec"]["REFI2"], "REFI2")),
|
||||
tREFIsb (tCK * parseUint(memspec["memtimingspec"]["REFISB"], "REFISB")),
|
||||
tREFSBRD_slr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_slr"], "REFSBRD_slr")),
|
||||
tREFSBRD_dlr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_dlr"], "REFSBRD_dlr")),
|
||||
tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")),
|
||||
tCPDED (tCK * parseUint(memspec["memtimingspec"]["CPDED"], "CPDED")),
|
||||
tPD (tCK * parseUint(memspec["memtimingspec"]["PD"], "PD")),
|
||||
tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")),
|
||||
tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")),
|
||||
tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")),
|
||||
tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")),
|
||||
shortCmdOffset (cmdMode == 2 ? 1 * tCK : 0 * tCK),
|
||||
longCmdOffset (cmdMode == 2 ? 3 * tCK : 1 * tCK),
|
||||
tBURST16(tCK * 8),
|
||||
tBURST32(tCK * 16)
|
||||
{
|
||||
if (cmdMode == 1)
|
||||
{
|
||||
@@ -156,24 +159,39 @@ sc_time MemSpecDDR5::getRefreshIntervalSB() const
|
||||
}
|
||||
|
||||
// Returns the execution time for commands that have a fixed execution time
|
||||
sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload &) const
|
||||
sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload &payload) const
|
||||
{
|
||||
if (command == Command::PRE || command == Command::PREA || command == Command::PRESB)
|
||||
return tRP + cmdOffset_S;
|
||||
return tRP + shortCmdOffset;
|
||||
else if (command == Command::ACT)
|
||||
return tRCD + cmdOffset_L;
|
||||
return tRCD + longCmdOffset;
|
||||
else if (command == Command::RD)
|
||||
return tRL + burstDuration + cmdOffset_L;
|
||||
{
|
||||
if (DramExtension::getBurstLength(payload) == 32)
|
||||
return tRL + tBURST32 + longCmdOffset;
|
||||
else
|
||||
return tRL + tBURST16 + longCmdOffset;
|
||||
}
|
||||
else if (command == Command::RDA)
|
||||
return tRTP + tRP + cmdOffset_L;
|
||||
return tRTP + tRP + longCmdOffset;
|
||||
else if (command == Command::WR)
|
||||
return tWL + burstDuration + cmdOffset_L;
|
||||
{
|
||||
if (DramExtension::getBurstLength(payload) == 32)
|
||||
return tWL + tBURST32 + longCmdOffset;
|
||||
else
|
||||
return tWL + tBURST16 + longCmdOffset;
|
||||
}
|
||||
else if (command == Command::WRA)
|
||||
return tWL + burstDuration + tWR + tRP + cmdOffset_L;
|
||||
{
|
||||
if (DramExtension::getBurstLength(payload) == 32)
|
||||
return tWL + tBURST32 + tWR + tRP + longCmdOffset;
|
||||
else
|
||||
return tWL + tBURST16 + tWR + tRP + longCmdOffset;
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
return tRFC_slr + cmdOffset_S;
|
||||
return tRFC_slr + shortCmdOffset;
|
||||
else if (command == Command::REFSB)
|
||||
return tRFCsb_slr + cmdOffset_S;
|
||||
return tRFCsb_slr + shortCmdOffset;
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("getExecutionTime",
|
||||
@@ -182,12 +200,22 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command) const
|
||||
TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &payload) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(tRL + cmdOffset_L, tRL + burstDuration + cmdOffset_L);
|
||||
{
|
||||
if (DramExtension::getBurstLength(payload) == 32)
|
||||
return TimeInterval(tRL + longCmdOffset, tRL + tBURST32 + longCmdOffset);
|
||||
else
|
||||
return TimeInterval(tRL + longCmdOffset, tRL + tBURST16 + longCmdOffset);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(tWL + cmdOffset_L, tWL + burstDuration + cmdOffset_L);
|
||||
{
|
||||
if (DramExtension::getBurstLength(payload) == 32)
|
||||
return TimeInterval(tWL + longCmdOffset, tWL + tBURST32 + longCmdOffset);
|
||||
else
|
||||
return TimeInterval(tWL + longCmdOffset, tWL + tBURST16 + longCmdOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");
|
||||
|
||||
@@ -69,6 +69,7 @@ public:
|
||||
const sc_time tWR;
|
||||
const sc_time tCCD_L_slr;
|
||||
const sc_time tCCD_L_WR_slr;
|
||||
const sc_time tCCD_L_WR2_slr;
|
||||
const sc_time tCCD_S_slr;
|
||||
const sc_time tCCD_S_WR_slr;
|
||||
const sc_time tCCD_dlr;
|
||||
@@ -99,8 +100,11 @@ public:
|
||||
const sc_time tPRPDEN;
|
||||
const sc_time tREFPDEN;
|
||||
|
||||
const sc_time cmdOffset_S;
|
||||
const sc_time cmdOffset_L;
|
||||
const sc_time shortCmdOffset;
|
||||
const sc_time longCmdOffset;
|
||||
|
||||
const sc_time tBURST16;
|
||||
const sc_time tBURST32;
|
||||
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
@@ -108,8 +112,8 @@ public:
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalSB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
|
||||
virtual uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
@@ -128,7 +128,7 @@ sc_time MemSpecGDDR5::getExecutionTime(Command command, const tlm_generic_payloa
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecGDDR5::getIntervalOnDataStrobe(Command command) const
|
||||
TimeInterval MemSpecGDDR5::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,
|
||||
|
||||
@@ -88,8 +88,8 @@ public:
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
|
||||
virtual uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
@@ -128,7 +128,7 @@ sc_time MemSpecGDDR5X::getExecutionTime(Command command, const tlm_generic_paylo
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecGDDR5X::getIntervalOnDataStrobe(Command command) const
|
||||
TimeInterval MemSpecGDDR5X::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,
|
||||
|
||||
@@ -88,8 +88,8 @@ public:
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
|
||||
virtual uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
@@ -130,7 +130,7 @@ sc_time MemSpecGDDR6::getExecutionTime(Command command, const tlm_generic_payloa
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecGDDR6::getIntervalOnDataStrobe(Command command) const
|
||||
TimeInterval MemSpecGDDR6::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,
|
||||
|
||||
@@ -90,8 +90,8 @@ public:
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
|
||||
virtual uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
@@ -130,7 +130,7 @@ sc_time MemSpecHBM2::getExecutionTime(Command command, const tlm_generic_payload
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecHBM2::getIntervalOnDataStrobe(Command command) const
|
||||
TimeInterval MemSpecHBM2::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(tRL + tDQSCK, tRL + tDQSCK + burstDuration);
|
||||
|
||||
@@ -85,8 +85,8 @@ public:
|
||||
|
||||
virtual bool hasRasAndCasBus() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
|
||||
virtual uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
@@ -132,7 +132,7 @@ sc_time MemSpecLPDDR4::getExecutionTime(Command command, const tlm_generic_paylo
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecLPDDR4::getIntervalOnDataStrobe(Command command) const
|
||||
TimeInterval MemSpecLPDDR4::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(tRL + tDQSCK + 3 * tCK,
|
||||
|
||||
@@ -83,8 +83,8 @@ public:
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
|
||||
virtual uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
136
DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp
Normal file
136
DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "MemSpecSTTMRAM.h"
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecSTTMRAM::MemSpecSTTMRAM(json &memspec)
|
||||
: MemSpec(memspec, MemoryType::STTMRAM,
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
|
||||
1,
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks")
|
||||
* parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfDevicesOnDIMM"],"nbrOfDevicesOnDIMM")),
|
||||
tCKE (tCK * parseUint(memspec["memtimingspec"]["CKE"], "CKE")),
|
||||
tPD (tCKE),
|
||||
tCKESR (tCK * parseUint(memspec["memtimingspec"]["CKESR"], "CKESR")),
|
||||
tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")),
|
||||
tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")),
|
||||
tRC (tCK * parseUint(memspec["memtimingspec"]["RC"], "RC")),
|
||||
tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")),
|
||||
tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")),
|
||||
tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")),
|
||||
tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")),
|
||||
tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")),
|
||||
tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")),
|
||||
tXS (tCK * parseUint(memspec["memtimingspec"]["XS"], "XS")),
|
||||
tCCD (tCK * parseUint(memspec["memtimingspec"]["CCD"], "CCD")),
|
||||
tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")),
|
||||
tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")),
|
||||
tRRD (tCK * parseUint(memspec["memtimingspec"]["RRD"], "RRD")),
|
||||
tWTR (tCK * parseUint(memspec["memtimingspec"]["WTR"], "WTR")),
|
||||
tAL (tCK * parseUint(memspec["memtimingspec"]["AL"], "AL")),
|
||||
tXPDLL (tCK * parseUint(memspec["memtimingspec"]["XPDLL"], "XPDLL")),
|
||||
tXSDLL (tCK * parseUint(memspec["memtimingspec"]["XSDLL"], "XSDLL")),
|
||||
tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")),
|
||||
tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")),
|
||||
tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS"))
|
||||
{}
|
||||
|
||||
// Returns the execution time for commands that have a fixed execution time
|
||||
sc_time MemSpecSTTMRAM::getExecutionTime(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::PRE || command == Command::PREA)
|
||||
return tRP;
|
||||
else if (command == Command::ACT)
|
||||
return tRCD;
|
||||
else if (command == Command::RD)
|
||||
return tRL + burstDuration;
|
||||
else if (command == Command::RDA)
|
||||
return tRTP + tRP;
|
||||
else if (command == Command::WR)
|
||||
return tWL + burstDuration;
|
||||
else if (command == Command::WRA)
|
||||
return tWL + burstDuration + tWR + tRP;
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("getExecutionTime",
|
||||
"command not known or command doesn't have a fixed execution time");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecSTTMRAM::getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(tRL, tRL + burstDuration);
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(tWL, tWL + burstDuration);
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MemSpecSTTMRAM::getSimMemSizeInBytes() const
|
||||
{
|
||||
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
|
||||
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
||||
uint64_t memorySizeBytes = deviceSizeBytes * numberOfDevicesOnDIMM * numberOfRanks;
|
||||
|
||||
std::cout << headline << std::endl;
|
||||
std::cout << "Per Channel Configuration:" << std::endl << std::endl;
|
||||
std::cout << " Memory type: " << "STT-MRAM" << std::endl;
|
||||
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
|
||||
std::cout << " Ranks: " << numberOfRanks << std::endl;
|
||||
std::cout << " Banks per rank: " << banksPerRank << std::endl;
|
||||
std::cout << " Rows per bank: " << numberOfRows << std::endl;
|
||||
std::cout << " Columns per row: " << numberOfColumns << std::endl;
|
||||
std::cout << " Device width in bits: " << bitWidth << std::endl;
|
||||
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
|
||||
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
|
||||
std::cout << " Devices on DIMM: " << numberOfDevicesOnDIMM << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
assert(memorySizeBytes > 0);
|
||||
return memorySizeBytes;
|
||||
}
|
||||
82
DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h
Normal file
82
DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef MEMSPECSTTMRAM_H
|
||||
#define MEMSPECSTTMRAM_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
class MemSpecSTTMRAM final : public MemSpec
|
||||
{
|
||||
public:
|
||||
MemSpecSTTMRAM(nlohmann::json &memspec);
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_time tCKE;
|
||||
const sc_time tPD;
|
||||
const sc_time tCKESR;
|
||||
const sc_time tRAS;
|
||||
const sc_time tRC;
|
||||
const sc_time tRCD;
|
||||
const sc_time tRL;
|
||||
const sc_time tRTP;
|
||||
const sc_time tWL;
|
||||
const sc_time tWR;
|
||||
const sc_time tXP;
|
||||
const sc_time tXS;
|
||||
const sc_time tRP;
|
||||
const sc_time tDQSCK;
|
||||
const sc_time tCCD;
|
||||
const sc_time tFAW;
|
||||
const sc_time tRRD;
|
||||
const sc_time tWTR;
|
||||
const sc_time tXPDLL;
|
||||
const sc_time tXSDLL;
|
||||
const sc_time tAL;
|
||||
const sc_time tACTPDEN;
|
||||
const sc_time tPRPDEN;
|
||||
const sc_time tRTRS;
|
||||
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
|
||||
virtual uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECSTTMRAM_H
|
||||
@@ -126,7 +126,7 @@ sc_time MemSpecWideIO::getExecutionTime(Command command, const tlm_generic_paylo
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecWideIO::getIntervalOnDataStrobe(Command command) const
|
||||
TimeInterval MemSpecWideIO::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(tRL + tAC, tRL + tAC + burstDuration);
|
||||
|
||||
@@ -95,8 +95,8 @@ public:
|
||||
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
|
||||
virtual uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
@@ -117,7 +117,7 @@ sc_time MemSpecWideIO2::getExecutionTime(Command command, const tlm_generic_payl
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecWideIO2::getIntervalOnDataStrobe(Command command) const
|
||||
TimeInterval MemSpecWideIO2::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(tRL + tDQSCK, tRL + tDQSCK + burstDuration);
|
||||
|
||||
@@ -77,8 +77,8 @@ public:
|
||||
virtual sc_time getRefreshIntervalAB() const override;
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const override;
|
||||
virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
|
||||
|
||||
virtual uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
@@ -148,7 +148,8 @@ sc_time BankMachineOpen::start()
|
||||
else // row miss
|
||||
nextCommand = Command::PRE;
|
||||
}
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
|
||||
bankgroup, bank, DramExtension::getBurstLength(currentPayload));
|
||||
}
|
||||
}
|
||||
return timeToSchedule;
|
||||
@@ -178,7 +179,8 @@ sc_time BankMachineClosed::start()
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
}
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
|
||||
bankgroup, bank, DramExtension::getBurstLength(currentPayload));
|
||||
}
|
||||
}
|
||||
return timeToSchedule;
|
||||
@@ -225,7 +227,8 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
else // row miss
|
||||
nextCommand = Command::PRE;
|
||||
}
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
|
||||
bankgroup, bank, DramExtension::getBurstLength(currentPayload));
|
||||
}
|
||||
}
|
||||
return timeToSchedule;
|
||||
@@ -272,7 +275,8 @@ sc_time BankMachineClosedAdaptive::start()
|
||||
else // row miss, should never happen
|
||||
SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy");
|
||||
}
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
|
||||
bankgroup, bank, DramExtension::getBurstLength(currentPayload));
|
||||
}
|
||||
}
|
||||
return timeToSchedule;
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "checker/CheckerGDDR5.h"
|
||||
#include "checker/CheckerGDDR5X.h"
|
||||
#include "checker/CheckerGDDR6.h"
|
||||
#include "checker/CheckerSTTMRAM.h"
|
||||
#include "scheduler/SchedulerFifo.h"
|
||||
#include "scheduler/SchedulerFrFcfs.h"
|
||||
#include "scheduler/SchedulerFrFcfsGrp.h"
|
||||
@@ -102,6 +103,8 @@ Controller::Controller(sc_module_name name) :
|
||||
checker = new CheckerGDDR5X();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::GDDR6)
|
||||
checker = new CheckerGDDR6();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::STTMRAM)
|
||||
checker = new CheckerSTTMRAM();
|
||||
|
||||
// instantiate scheduler and command mux
|
||||
if (config.scheduler == Configuration::Scheduler::Fifo)
|
||||
@@ -287,6 +290,7 @@ void Controller::controllerMethod()
|
||||
Rank rank = DramExtension::getRank(payload);
|
||||
BankGroup bankgroup = DramExtension::getBankGroup(payload);
|
||||
Bank bank = DramExtension::getBank(payload);
|
||||
unsigned burstLength = DramExtension::getBurstLength(payload);
|
||||
|
||||
if (isRankCommand(command))
|
||||
{
|
||||
@@ -304,7 +308,7 @@ void Controller::controllerMethod()
|
||||
|
||||
refreshManagers[rank.ID()]->updateState(command);
|
||||
powerDownManagers[rank.ID()]->updateState(command);
|
||||
checker->insert(command, rank, bankgroup, bank);
|
||||
checker->insert(command, rank, bankgroup, bank, burstLength);
|
||||
|
||||
if (isCasCommand(command))
|
||||
{
|
||||
@@ -312,7 +316,7 @@ void Controller::controllerMethod()
|
||||
manageRequests(thinkDelayFw);
|
||||
respQueue->insertPayload(payload, sc_time_stamp()
|
||||
+ thinkDelayFw + phyDelayFw
|
||||
+ memSpec->getIntervalOnDataStrobe(command).end
|
||||
+ memSpec->getIntervalOnDataStrobe(command, *payload).end
|
||||
+ phyDelayBw + thinkDelayBw);
|
||||
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
@@ -437,9 +441,9 @@ void Controller::manageResponses()
|
||||
NDEBUG_UNUSED(uint64_t id) = DramExtension::getChannelPayloadID(transToRelease.payload);
|
||||
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system.");
|
||||
|
||||
numberOfBeatsServed += DramExtension::getBurstLength(transToRelease.payload);
|
||||
transToRelease.payload->release();
|
||||
transToRelease.payload = nullptr;
|
||||
numberOfTransactionsServed++;
|
||||
totalNumberOfPayloads--;
|
||||
|
||||
if (totalNumberOfPayloads == 0)
|
||||
|
||||
@@ -55,8 +55,7 @@ public:
|
||||
// Destructor
|
||||
virtual ~ControllerIF()
|
||||
{
|
||||
sc_time activeTime = numberOfTransactionsServed
|
||||
* Configuration::getInstance().memSpec->burstLength
|
||||
sc_time activeTime = numberOfBeatsServed
|
||||
/ Configuration::getInstance().memSpec->dataRate
|
||||
* Configuration::getInstance().memSpec->tCK;
|
||||
|
||||
@@ -143,7 +142,7 @@ protected:
|
||||
sc_time idleStart;
|
||||
} idleTimeCollector;
|
||||
|
||||
uint64_t numberOfTransactionsServed = 0;
|
||||
uint64_t numberOfBeatsServed = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payl
|
||||
{
|
||||
if (isCasCommand(command))
|
||||
{
|
||||
TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command);
|
||||
TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command, *payload);
|
||||
tlmRecorder->updateDataStrobe(sc_time_stamp() + delay + dataStrobe.start,
|
||||
sc_time_stamp() + delay + dataStrobe.end, *payload);
|
||||
}
|
||||
@@ -130,9 +130,9 @@ void ControllerRecordable::controllerMethod()
|
||||
|
||||
Controller::controllerMethod();
|
||||
|
||||
uint64_t windowNumberOfTransactionsServed = numberOfTransactionsServed - lastNumberOfTransactionsServed;
|
||||
lastNumberOfTransactionsServed = numberOfTransactionsServed;
|
||||
sc_time windowActiveTime = windowNumberOfTransactionsServed * activeTimeMultiplier;
|
||||
uint64_t windowNumberOfBeatsServed = numberOfBeatsServed - lastNumberOfBeatsServed;
|
||||
lastNumberOfBeatsServed = numberOfBeatsServed;
|
||||
sc_time windowActiveTime = windowNumberOfBeatsServed * activeTimeMultiplier;
|
||||
double windowAverageBandwidth = windowActiveTime / windowSizeTime;
|
||||
tlmRecorder->recordBandwidth(sc_time_stamp().to_seconds(), windowAverageBandwidth);
|
||||
}
|
||||
|
||||
@@ -66,10 +66,9 @@ private:
|
||||
std::vector<double> windowAverageBufferDepth;
|
||||
sc_time lastTimeCalled = SC_ZERO_TIME;
|
||||
|
||||
uint64_t lastNumberOfTransactionsServed = 0;
|
||||
sc_time activeTimeMultiplier = Configuration::getInstance().memSpec->burstLength
|
||||
/ Configuration::getInstance().memSpec->dataRate
|
||||
* Configuration::getInstance().memSpec->tCK;
|
||||
uint64_t lastNumberOfBeatsServed = 0;
|
||||
sc_time activeTimeMultiplier = Configuration::getInstance().memSpec->tCK
|
||||
/ Configuration::getInstance().memSpec->dataRate;
|
||||
};
|
||||
|
||||
#endif // CONTROLLERRECORDABLE_H
|
||||
|
||||
@@ -52,7 +52,7 @@ CheckerDDR3::CheckerDDR3()
|
||||
tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL;
|
||||
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL;
|
||||
tWRRD = memSpec->tWL + tBURST + memSpec->tWTR;
|
||||
tWRRD = memSpec->tWL + tBURST + memSpec->tWTR - memSpec->tAL;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK;
|
||||
@@ -60,7 +60,7 @@ CheckerDDR3::CheckerDDR3()
|
||||
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR + memSpec->tCK;
|
||||
}
|
||||
|
||||
sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -91,7 +91,7 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
@@ -412,7 +412,7 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerDDR3::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
void CheckerDDR3::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerDDR3", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + commandToString(command));
|
||||
|
||||
@@ -45,8 +45,9 @@ class CheckerDDR3 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerDDR3();
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
|
||||
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
|
||||
|
||||
private:
|
||||
const MemSpecDDR3 *memSpec;
|
||||
|
||||
@@ -54,8 +54,8 @@ CheckerDDR4::CheckerDDR4()
|
||||
tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + tBURST + memSpec->tCK - memSpec->tWL + memSpec->tWPRE;
|
||||
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL + memSpec->tWPRE;
|
||||
tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S;
|
||||
tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L;
|
||||
tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S - memSpec->tAL;
|
||||
tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L - memSpec->tAL;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL + memSpec->tRPRE;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK;
|
||||
@@ -63,7 +63,7 @@ CheckerDDR4::CheckerDDR4()
|
||||
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR;
|
||||
}
|
||||
|
||||
sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -102,7 +102,7 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
@@ -443,7 +443,7 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerDDR4", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + commandToString(command));
|
||||
|
||||
@@ -45,8 +45,9 @@ class CheckerDDR4 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerDDR4();
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
|
||||
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
|
||||
|
||||
private:
|
||||
const MemSpecDDR4 *memSpec;
|
||||
|
||||
@@ -41,7 +41,7 @@ CheckerDDR5::CheckerDDR5()
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerDDR5", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndDIMMRank = std::vector<std::vector<sc_time>>
|
||||
lastScheduledByCommandAndDimmRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfDIMMRanks, sc_max_time()));
|
||||
lastScheduledByCommandAndPhysicalRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfPhysicalRanks, sc_max_time()));
|
||||
@@ -56,40 +56,63 @@ CheckerDDR5::CheckerDDR5()
|
||||
lastScheduledByCommandAndBankInGroup = std::vector<std::vector<sc_time>>(numberOfCommands(),
|
||||
std::vector<sc_time>(memSpec->numberOfRanks * memSpec->banksPerGroup, sc_max_time()));
|
||||
lastCommandOnBus = sc_max_time();
|
||||
dummyCommandOnBus.start = sc_max_time();
|
||||
dummyCommandOnBus.end = sc_max_time();
|
||||
|
||||
last4ActivatesLogical = std::vector<std::queue<sc_time>>(memSpec->numberOfLogicalRanks);
|
||||
last4ActivatesPhysical = std::vector<std::queue<sc_time>>(memSpec->numberOfPhysicalRanks);
|
||||
|
||||
cmdOffset = memSpec->cmdMode * memSpec->tCK;
|
||||
lastBurstLengthByCommandAndDimmRank = std::vector<std::vector<uint8_t>>
|
||||
(4, std::vector<uint8_t>(memSpec->numberOfDIMMRanks));
|
||||
lastBurstLengthByCommandAndPhysicalRank = std::vector<std::vector<uint8_t>>
|
||||
(4, std::vector<uint8_t>(memSpec->numberOfPhysicalRanks));
|
||||
lastBurstLengthByCommandAndLogicalRank = std::vector<std::vector<uint8_t>>
|
||||
(4, std::vector<uint8_t>(memSpec->numberOfLogicalRanks));
|
||||
lastBurstLengthByCommandAndBankGroup = std::vector<std::vector<uint8_t>>
|
||||
(4, std::vector<uint8_t>(memSpec->numberOfBankGroups));
|
||||
lastBurstLengthByCommandAndBank = std::vector<std::vector<uint8_t>>
|
||||
(4, std::vector<uint8_t>(memSpec->numberOfBanks));
|
||||
lastBurstLengthByCommand = std::vector<uint8_t>(4);
|
||||
lastBurstLengthByCommandAndBankInGroup = std::vector<std::vector<uint8_t>>
|
||||
(4, std::vector<uint8_t>(memSpec->numberOfRanks * memSpec->banksPerGroup));
|
||||
|
||||
tRD_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tWR_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
cmdLengthDiff = memSpec->cmdMode * memSpec->tCK;
|
||||
|
||||
tBURST16 = 8 * memSpec->tCK;
|
||||
tBURST32 = 16 * memSpec->tCK;
|
||||
tWTRA = memSpec->tWR - memSpec->tRTP;
|
||||
tWRRDA = memSpec->tWL + tWR_BURST + tWTRA;
|
||||
tWRPRE = memSpec->tWL + tWR_BURST + memSpec->tWR;
|
||||
tWRRDA = memSpec->tWL + tBURST16 + tWTRA; // tWTRA = tWR - tRTP
|
||||
tWRPRE = memSpec->tWL + tBURST16 + memSpec->tWR;
|
||||
tRDAACT = memSpec->tRTP + memSpec->tRP;
|
||||
tWRAACT = tWRPRE + memSpec->tRP;
|
||||
tCCD_L_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
||||
tCCD_S_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
||||
tCCD_RTW_dlr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
||||
tRDRD_dpr = tRD_BURST + memSpec->tRTRS;
|
||||
tRDRD_ddr = tRD_BURST + memSpec->tRTRS;
|
||||
tRDWR_dpr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
||||
tRDWR_ddr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
||||
tCCD_L_WTR_slr = memSpec->tWL + tWR_BURST + memSpec->tWTR_L;
|
||||
tCCD_S_WTR_slr = memSpec->tWL + tWR_BURST + memSpec->tWTR_S;
|
||||
tCCD_WTR_dlr = memSpec->tWL + tWR_BURST + memSpec->tWTR_S;
|
||||
tWRWR_dpr = std::max(memSpec->tCCD_WR_dpr, tWR_BURST + memSpec->tRTRS);
|
||||
tWRWR_ddr = tWR_BURST + memSpec->tRTRS;
|
||||
tWRRD_dpr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE;
|
||||
tWRRD_ddr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE;
|
||||
tRDPDEN = memSpec->tRL + tRD_BURST + cmdOffset;
|
||||
tWRPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset;
|
||||
tWRAPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset;
|
||||
|
||||
// TODO: tRTP BL 32 (similar to LPDDR4)
|
||||
tCCD_L_RTW_slr = memSpec->tRL - memSpec->tWL + tBURST16 + 2 * memSpec->tCK
|
||||
- memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
||||
tCCD_S_RTW_slr = memSpec->tRL - memSpec->tWL + tBURST16 + 2 * memSpec->tCK
|
||||
- memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
||||
tCCD_RTW_dlr = memSpec->tRL - memSpec->tWL + tBURST16 + 2 * memSpec->tCK
|
||||
- memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
||||
tRDRD_dpr = tBURST16 + memSpec->tRTRS;
|
||||
tRDRD_ddr = tBURST16 + memSpec->tRTRS;
|
||||
tRDWR_dpr = memSpec->tRL - memSpec->tWL + tBURST16 + memSpec->tRTRS
|
||||
- memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
||||
tRDWR_ddr = memSpec->tRL - memSpec->tWL + tBURST16 + memSpec->tRTRS
|
||||
- memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
||||
tCCD_L_WTR_slr = memSpec->tWL + tBURST16 + memSpec->tWTR_L;
|
||||
tCCD_S_WTR_slr = memSpec->tWL + tBURST16 + memSpec->tWTR_S;
|
||||
tCCD_WTR_dlr = memSpec->tWL + tBURST16 + memSpec->tWTR_S;
|
||||
tWRWR_dpr = std::max(memSpec->tCCD_WR_dpr, tBURST16 + memSpec->tRTRS);
|
||||
tWRWR_ddr = tBURST16 + memSpec->tRTRS;
|
||||
tWRRD_dpr = memSpec->tWL - memSpec->tRL + tBURST16 + memSpec->tRTRS
|
||||
+ memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE;
|
||||
tWRRD_ddr = memSpec->tWL - memSpec->tRL + tBURST16 + memSpec->tRTRS
|
||||
+ memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE;
|
||||
tRDPDEN = memSpec->tRL + tBURST16 + cmdLengthDiff;
|
||||
tWRPDEN = memSpec->tWL + tBURST16 + memSpec->tWR + cmdLengthDiff;
|
||||
tWRAPDEN = memSpec->tWL + tBURST16 + memSpec->tWR + cmdLengthDiff;
|
||||
}
|
||||
|
||||
sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank,
|
||||
unsigned burstLength) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -116,15 +139,30 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
{
|
||||
if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST32);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()])
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) // different physical rank
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr);
|
||||
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RD][dimmrank.ID()]) // same DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommandAndDimmRank[Command::RD][dimmrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr);
|
||||
}
|
||||
else // different DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommand[Command::RD] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr);
|
||||
}
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
|
||||
@@ -137,64 +175,134 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
{
|
||||
if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST32);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()])
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) // different physical rank
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr);
|
||||
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RDA][dimmrank.ID()]) // same DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommandAndDimmRank[Command::RDA][dimmrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr);
|
||||
}
|
||||
else // different DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommand[Command::RDA] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr);
|
||||
}
|
||||
}
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA);
|
||||
}
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankgroup.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndPhysicalRank[Command::WR][physicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()])
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) // different physical rank
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr);
|
||||
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WR][dimmrank.ID()]) // same DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommandAndDimmRank[Command::WR][dimmrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr);
|
||||
}
|
||||
else // different DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommand[Command::WR] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr);
|
||||
}
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankgroup.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()])
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) // different physical rank
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr);
|
||||
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WRA][dimmrank.ID()]) // same DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommandAndDimmRank[Command::WRA][dimmrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr);
|
||||
}
|
||||
else // different DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommand[Command::WRA] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
@@ -205,49 +313,114 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::RD][bankgroup.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndLogicalRank[Command::RD][logicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()])
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) // different physical rank
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr);
|
||||
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RD][dimmrank.ID()]) // same DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommandAndDimmRank[Command::RD][dimmrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr);
|
||||
}
|
||||
else // different DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommand[Command::RD] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr);
|
||||
}
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankgroup.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndLogicalRank[Command::RDA][logicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()])
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) // different physical rank
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr);
|
||||
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RDA][dimmrank.ID()]) // same DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommandAndDimmRank[Command::RDA][dimmrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr);
|
||||
}
|
||||
else // different DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommand[Command::RDA] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr);
|
||||
}
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankgroup.ID()] == 32)
|
||||
{
|
||||
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR_slr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR2_slr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr);
|
||||
}
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
@@ -255,20 +428,50 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
{
|
||||
if (lastBurstLengthByCommandAndPhysicalRank[Command::WR][physicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST32);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()])
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) // different physical rank
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr);
|
||||
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WR][dimmrank.ID()]) // same DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommandAndDimmRank[Command::WR][dimmrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr);
|
||||
}
|
||||
else // different DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommand[Command::WR] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr);
|
||||
}
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankgroup.ID()] == 32)
|
||||
{
|
||||
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR_slr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR2_slr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr);
|
||||
}
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
@@ -276,15 +479,30 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
{
|
||||
if (lastBurstLengthByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST32);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()])
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) // different physical rank
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr);
|
||||
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WRA][dimmrank.ID()]) // same DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommandAndDimmRank[Command::WRA][dimmrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr);
|
||||
}
|
||||
else // different DIMM
|
||||
{
|
||||
if (lastBurstLengthByCommand[Command::WRA] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
@@ -311,61 +529,71 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::WRA][bank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + tBURST16);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PREA][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - cmdOffset);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - cmdLengthDiff);
|
||||
|
||||
// TODO: No tRFC_dlr and tRFC_dpr between REFA and ACT?
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::REFSB][bankInGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - cmdOffset);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - cmdLengthDiff);
|
||||
|
||||
// TODO: No tRFCsb_dlr between REFSB and ACT?
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_slr - cmdOffset);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_slr - cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFSB][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_dlr - cmdOffset);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_dlr - cmdLengthDiff);
|
||||
|
||||
if (last4ActivatesLogical[logicalrank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front()
|
||||
+ memSpec->tFAW_slr - memSpec->cmdOffset_L);
|
||||
+ memSpec->tFAW_slr - memSpec->longCmdOffset);
|
||||
|
||||
if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front()
|
||||
+ memSpec->tFAW_dlr - memSpec->cmdOffset_L);
|
||||
+ memSpec->tFAW_dlr - memSpec->longCmdOffset);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
@@ -383,23 +611,33 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
@@ -415,23 +653,33 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RD][bankInGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WR][bankInGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankInGroup[Command::WR][bankInGroup.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
@@ -447,15 +695,20 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP + memSpec->tCK);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + memSpec->tRP + cmdLengthDiff);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP + cmdLengthDiff);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PRE][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
@@ -473,7 +726,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndDimmRank[Command::REFA][dimmrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
|
||||
|
||||
@@ -484,19 +737,24 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + cmdLengthDiff);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + memSpec->tCK);
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + tBURST16 + cmdLengthDiff);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + cmdLengthDiff);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRE][bankInGroup.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
@@ -518,7 +776,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr);
|
||||
|
||||
// TODO: check this
|
||||
lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndDimmRank[Command::REFA][dimmrank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
|
||||
|
||||
@@ -532,11 +790,11 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
|
||||
if (last4ActivatesLogical[logicalrank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front()
|
||||
+ memSpec->tFAW_slr - memSpec->cmdOffset_S);
|
||||
+ memSpec->tFAW_slr - memSpec->shortCmdOffset);
|
||||
|
||||
if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front()
|
||||
+ memSpec->tFAW_dlr - memSpec->cmdOffset_S);
|
||||
+ memSpec->tFAW_dlr - memSpec->shortCmdOffset);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerDDR5", "Unknown command!");
|
||||
@@ -544,38 +802,62 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
if (lastCommandOnBus != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
|
||||
if (dummyCommandOnBus.start != sc_max_time())
|
||||
{
|
||||
TimeInterval currentCommandOnBus(earliestTimeToStart,
|
||||
earliestTimeToStart + memSpec->getCommandLength(command));
|
||||
if (currentCommandOnBus.intersects(dummyCommandOnBus))
|
||||
earliestTimeToStart = dummyCommandOnBus.end;
|
||||
}
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned burstLength)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerDDR5", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + commandToString(command));
|
||||
|
||||
Rank logicalrank = rank;
|
||||
Rank physicalrank = Rank(logicalrank.ID() / memSpec->logicalRanksPerPhysicalRank);
|
||||
Rank dimmrank = Rank(physicalrank.ID() / memSpec->physicalRanksPerDIMMRank);
|
||||
Rank logicalRank = rank;
|
||||
Rank physicalRank = Rank(logicalRank.ID() / memSpec->logicalRanksPerPhysicalRank);
|
||||
Rank dimmRank = Rank(physicalRank.ID() / memSpec->physicalRanksPerDIMMRank);
|
||||
Bank bankInGroup = Bank(rank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup);
|
||||
|
||||
lastScheduledByCommandAndDIMMRank[command][dimmrank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndPhysicalRank[command][physicalrank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndLogicalRank[command][logicalrank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndDimmRank[command][dimmRank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndPhysicalRank[command][physicalRank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndLogicalRank[command][logicalRank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankgroup.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankInGroup[command][bankInGroup.ID()] = sc_time_stamp();
|
||||
|
||||
if (isCasCommand(command))
|
||||
{
|
||||
lastBurstLengthByCommandAndDimmRank[command][dimmRank.ID()] = burstLength;
|
||||
lastBurstLengthByCommandAndPhysicalRank[command][physicalRank.ID()] = burstLength;
|
||||
lastBurstLengthByCommandAndLogicalRank[command][logicalRank.ID()] = burstLength;
|
||||
lastBurstLengthByCommandAndBankGroup[command][bankgroup.ID()] = burstLength;
|
||||
lastBurstLengthByCommandAndBank[command][bank.ID()] = burstLength;
|
||||
lastBurstLengthByCommand[command] = burstLength;
|
||||
lastBurstLengthByCommandAndBankInGroup[command][bankInGroup.ID()] = burstLength;
|
||||
|
||||
if (burstLength == 32)
|
||||
{
|
||||
dummyCommandOnBus.start = sc_time_stamp() + tBURST16;
|
||||
dummyCommandOnBus.end = sc_time_stamp() + tBURST16 + memSpec->getCommandLength(command);
|
||||
}
|
||||
}
|
||||
|
||||
lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK;
|
||||
|
||||
lastScheduledByCommandAndBankInGroup[command][rank.ID() * memSpec->banksPerGroup
|
||||
+ bank.ID() % memSpec->banksPerGroup] = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT || command == Command::REFSB)
|
||||
{
|
||||
if (last4ActivatesLogical[logicalrank.ID()].size() == 4)
|
||||
last4ActivatesLogical[logicalrank.ID()].pop();
|
||||
last4ActivatesLogical[logicalrank.ID()].push(lastCommandOnBus);
|
||||
if (last4ActivatesLogical[logicalRank.ID()].size() == 4)
|
||||
last4ActivatesLogical[logicalRank.ID()].pop();
|
||||
last4ActivatesLogical[logicalRank.ID()].push(lastCommandOnBus);
|
||||
|
||||
if (last4ActivatesPhysical[physicalrank.ID()].size() == 4)
|
||||
last4ActivatesPhysical[physicalrank.ID()].pop();
|
||||
last4ActivatesPhysical[physicalrank.ID()].push(lastCommandOnBus);
|
||||
if (last4ActivatesPhysical[physicalRank.ID()].size() == 4)
|
||||
last4ActivatesPhysical[physicalRank.ID()].pop();
|
||||
last4ActivatesPhysical[physicalRank.ID()].push(lastCommandOnBus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,34 +40,48 @@
|
||||
#include <vector>
|
||||
#include "../../configuration/memspec/MemSpecDDR5.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/utils.h"
|
||||
|
||||
class CheckerDDR5 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerDDR5();
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
|
||||
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
|
||||
|
||||
private:
|
||||
const MemSpecDDR5 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndDIMMRank;
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndDimmRank;
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndPhysicalRank;
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndLogicalRank;
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<sc_time> lastScheduledByCommand;
|
||||
sc_time lastCommandOnBus;
|
||||
TimeInterval dummyCommandOnBus;
|
||||
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankInGroup;
|
||||
|
||||
std::vector<std::queue<sc_time>> last4ActivatesPhysical;
|
||||
std::vector<std::queue<sc_time>> last4ActivatesLogical;
|
||||
|
||||
sc_time cmdOffset;
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndDimmRank;
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndPhysicalRank;
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndLogicalRank;
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndBankGroup;
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndBank;
|
||||
std::vector<uint8_t> lastBurstLengthByCommand;
|
||||
|
||||
sc_time tRD_BURST;
|
||||
sc_time tWR_BURST;
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndBankInGroup;
|
||||
|
||||
// TODO: store BL of last RD and WR globally or for each hierarchy?
|
||||
|
||||
sc_time cmdLengthDiff;
|
||||
|
||||
sc_time tBURST16;
|
||||
sc_time tBURST32;
|
||||
sc_time tWTRA;
|
||||
sc_time tWRRDA;
|
||||
sc_time tWRPRE;
|
||||
|
||||
@@ -64,7 +64,7 @@ CheckerGDDR5::CheckerGDDR5()
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -525,7 +525,7 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerGDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
void CheckerGDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerGDDR5", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + commandToString(command));
|
||||
|
||||
@@ -45,8 +45,9 @@ class CheckerGDDR5 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR5();
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
|
||||
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
|
||||
|
||||
private:
|
||||
const MemSpecGDDR5 *memSpec;
|
||||
|
||||
@@ -64,7 +64,7 @@ CheckerGDDR5X::CheckerGDDR5X()
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -525,7 +525,7 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerGDDR5X::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
void CheckerGDDR5X::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerGDDR5X", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + commandToString(command));
|
||||
|
||||
@@ -45,8 +45,9 @@ class CheckerGDDR5X final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR5X();
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
|
||||
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
|
||||
|
||||
private:
|
||||
const MemSpecGDDR5X *memSpec;
|
||||
|
||||
@@ -63,7 +63,7 @@ CheckerGDDR6::CheckerGDDR6()
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -546,7 +546,7 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerGDDR6::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
void CheckerGDDR6::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerGDDR6", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + commandToString(command));
|
||||
|
||||
@@ -45,8 +45,9 @@ class CheckerGDDR6 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerGDDR6();
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
|
||||
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
|
||||
|
||||
private:
|
||||
const MemSpecGDDR6 *memSpec;
|
||||
|
||||
@@ -64,7 +64,7 @@ CheckerHBM2::CheckerHBM2()
|
||||
tWRRDL = memSpec->tWL + tBURST + memSpec->tWTRL;
|
||||
}
|
||||
|
||||
sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -500,7 +500,7 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerHBM2::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
void CheckerHBM2::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerHBM2", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + commandToString(command));
|
||||
|
||||
@@ -45,8 +45,9 @@ class CheckerHBM2 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerHBM2();
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
|
||||
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
|
||||
|
||||
private:
|
||||
const MemSpecHBM2 *memSpec;
|
||||
|
||||
@@ -46,8 +46,9 @@ class CheckerIF
|
||||
public:
|
||||
virtual ~CheckerIF() {}
|
||||
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const = 0;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) = 0;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
|
||||
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const = 0;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) = 0;
|
||||
};
|
||||
|
||||
#endif // CHECKERIF_H
|
||||
|
||||
@@ -66,7 +66,7 @@ CheckerLPDDR4::CheckerLPDDR4()
|
||||
tREFPDEN = memSpec->tCK + memSpec->tCMDCKE;
|
||||
}
|
||||
|
||||
sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -496,7 +496,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerLPDDR4::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
void CheckerLPDDR4::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerLPDDR4", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + commandToString(command));
|
||||
|
||||
@@ -45,8 +45,9 @@ class CheckerLPDDR4 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerLPDDR4();
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
|
||||
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
|
||||
|
||||
private:
|
||||
const MemSpecLPDDR4 *memSpec;
|
||||
|
||||
388
DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp
Normal file
388
DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp
Normal file
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "CheckerSTTMRAM.h"
|
||||
|
||||
CheckerSTTMRAM::CheckerSTTMRAM()
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<const MemSpecSTTMRAM *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerSTTMRAM", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks, sc_max_time()));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks, sc_max_time()));
|
||||
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands(), sc_max_time());
|
||||
lastCommandOnBus = sc_max_time();
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
|
||||
tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL;
|
||||
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL;
|
||||
tWRRD = memSpec->tWL + tBURST + memSpec->tWTR - memSpec->tAL;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK;
|
||||
tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR + memSpec->tCK;
|
||||
}
|
||||
|
||||
sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ?
|
||||
lastScheduledByCommand[Command::RD] : sc_max_time();
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ?
|
||||
lastScheduledByCommand[Command::RDA] : sc_max_time();
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : sc_max_time();
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : sc_max_time();
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : sc_max_time();
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : sc_max_time();
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
|
||||
if (lastCommandStart != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerSTTMRAM", "Unknown command!");
|
||||
|
||||
if (lastCommandOnBus != sc_max_time())
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerSTTMRAM::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerSTTMRAM", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + commandToString(command));
|
||||
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
|
||||
lastCommandOnBus = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(sc_time_stamp());
|
||||
}
|
||||
}
|
||||
74
DRAMSys/library/src/controller/checker/CheckerSTTMRAM.h
Normal file
74
DRAMSys/library/src/controller/checker/CheckerSTTMRAM.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef CHECKERSTTMRAM_H
|
||||
#define CHECKERSTTMRAM_H
|
||||
|
||||
#include "CheckerIF.h"
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include "../../configuration/memspec/MemSpecSTTMRAM.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
|
||||
class CheckerSTTMRAM final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerSTTMRAM();
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
|
||||
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
|
||||
|
||||
private:
|
||||
const MemSpecSTTMRAM *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_time> lastScheduledByCommand;
|
||||
sc_time lastCommandOnBus;
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_time>> last4Activates;
|
||||
|
||||
sc_time tBURST;
|
||||
sc_time tRDWR;
|
||||
sc_time tRDWR_R;
|
||||
sc_time tWRRD;
|
||||
sc_time tWRPRE;
|
||||
sc_time tWRRD_R;
|
||||
sc_time tRDPDEN;
|
||||
sc_time tWRPDEN;
|
||||
sc_time tWRAPDEN;
|
||||
};
|
||||
|
||||
#endif // CHECKERSTTMRAM_H
|
||||
@@ -60,7 +60,7 @@ CheckerWideIO::CheckerWideIO()
|
||||
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR; // + memSpec->tCK; ??
|
||||
}
|
||||
|
||||
sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -385,7 +385,7 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, Bank
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerWideIO::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
void CheckerWideIO::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerWideIO", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + commandToString(command));
|
||||
|
||||
@@ -45,8 +45,9 @@ class CheckerWideIO final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerWideIO();
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
|
||||
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
|
||||
|
||||
private:
|
||||
const MemSpecWideIO *memSpec;
|
||||
|
||||
@@ -61,7 +61,7 @@ CheckerWideIO2::CheckerWideIO2()
|
||||
tWRRD_R = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tRTRS - memSpec->tRL;
|
||||
}
|
||||
|
||||
sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
@@ -463,7 +463,7 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, Ban
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerWideIO2::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
void CheckerWideIO2::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerWideIO2", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + commandToString(command));
|
||||
|
||||
@@ -45,8 +45,9 @@ class CheckerWideIO2 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerWideIO2();
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0),
|
||||
BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override;
|
||||
|
||||
private:
|
||||
const MemSpecWideIO2 *memSpec;
|
||||
|
||||
@@ -54,6 +54,8 @@ Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) :
|
||||
|
||||
addressDecoder = new AddressDecoder(pathToAddressMapping);
|
||||
addressDecoder->print();
|
||||
|
||||
bytesPerBeat = Configuration::getInstance().memSpec->dataBusWidth / 8;
|
||||
}
|
||||
|
||||
ArbiterSimple::ArbiterSimple(sc_module_name name, std::string pathToAddressMapping) :
|
||||
@@ -126,7 +128,8 @@ void ArbiterReorder::end_of_elaboration()
|
||||
tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload,
|
||||
tlm_phase &phase, sc_time &fwDelay)
|
||||
{
|
||||
sc_time notDelay = std::ceil((sc_time_stamp() + fwDelay) / tCK) * tCK - sc_time_stamp();
|
||||
sc_time clockOffset = (sc_time_stamp() + fwDelay) % tCK;
|
||||
sc_time notDelay = (clockOffset == SC_ZERO_TIME) ? fwDelay : (fwDelay + tCK - clockOffset);
|
||||
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
@@ -140,7 +143,7 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload,
|
||||
Channel(decodedAddress.channel), Rank(decodedAddress.rank),
|
||||
BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank),
|
||||
Row(decodedAddress.row), Column(decodedAddress.column),
|
||||
payload.get_streaming_width(), 0, 0);
|
||||
payload.get_data_length() / bytesPerBeat, 0, 0);
|
||||
payload.acquire();
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,8 @@ protected:
|
||||
sc_time tCK;
|
||||
sc_time arbitrationDelayFw;
|
||||
sc_time arbitrationDelayBw;
|
||||
|
||||
unsigned bytesPerBeat;
|
||||
};
|
||||
|
||||
class ArbiterSimple final : public Arbiter
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include "dram/DramGDDR5.h"
|
||||
#include "dram/DramGDDR5X.h"
|
||||
#include "dram/DramGDDR6.h"
|
||||
#include "dram/DramSTTMRAM.h"
|
||||
#include "../controller/Controller.h"
|
||||
|
||||
DRAMSys::DRAMSys(sc_module_name name,
|
||||
@@ -231,6 +232,8 @@ void DRAMSys::instantiateModules(const std::string &pathToResources,
|
||||
dram = new DramGDDR5X(str.c_str());
|
||||
else if (memoryType == MemSpec::MemoryType::GDDR6)
|
||||
dram = new DramGDDR6(str.c_str());
|
||||
else if (memoryType == MemSpec::MemoryType::STTMRAM)
|
||||
dram = new DramSTTMRAM(str.c_str());
|
||||
|
||||
drams.push_back(dram);
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "dram/DramGDDR5.h"
|
||||
#include "dram/DramGDDR5X.h"
|
||||
#include "dram/DramGDDR6.h"
|
||||
#include "dram/DramSTTMRAM.h"
|
||||
#include "../common/TlmRecorder.h"
|
||||
#include "../simulation/TemperatureController.h"
|
||||
#include "../error/ecchamming.h"
|
||||
@@ -172,6 +173,8 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName,
|
||||
dram = new DramRecordable<DramGDDR5X>(str.c_str(), tlmRecorders[i]);
|
||||
else if (memoryType == MemSpec::MemoryType::GDDR6)
|
||||
dram = new DramRecordable<DramGDDR6>(str.c_str(), tlmRecorders[i]);
|
||||
else if (memoryType == MemSpec::MemoryType::STTMRAM)
|
||||
dram = new DramRecordable<DramSTTMRAM>(str.c_str(), tlmRecorders[i]);
|
||||
|
||||
drams.push_back(dram);
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "DramGDDR5.h"
|
||||
#include "DramGDDR5X.h"
|
||||
#include "DramGDDR6.h"
|
||||
#include "DramSTTMRAM.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
@@ -156,3 +157,4 @@ template class DramRecordable<DramGDDR5>;
|
||||
template class DramRecordable<DramGDDR5X>;
|
||||
template class DramRecordable<DramGDDR6>;
|
||||
template class DramRecordable<DramHBM2>;
|
||||
template class DramRecordable<DramSTTMRAM>;
|
||||
|
||||
52
DRAMSys/library/src/simulation/dram/DramSTTMRAM.cpp
Normal file
52
DRAMSys/library/src/simulation/dram/DramSTTMRAM.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "DramSTTMRAM.h"
|
||||
|
||||
#include "Dram.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
#include "../../configuration/memspec/MemSpecSTTMRAM.h"
|
||||
|
||||
using namespace DRAMPower;
|
||||
|
||||
DramSTTMRAM::DramSTTMRAM(sc_module_name name) : Dram(name)
|
||||
{
|
||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||
SC_REPORT_FATAL("DramSTTMRAM", "Error Model not supported for STT-MRAM");
|
||||
|
||||
if (Configuration::getInstance().powerAnalysis)
|
||||
SC_REPORT_FATAL("DramSTTMRAM", "DRAMPower does not support STT-MRAM");
|
||||
}
|
||||
50
DRAMSys/library/src/simulation/dram/DramSTTMRAM.h
Normal file
50
DRAMSys/library/src/simulation/dram/DramSTTMRAM.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef DRAMSTTMRAM_H
|
||||
#define DRAMSTTMRAM_H
|
||||
|
||||
#include <systemc.h>
|
||||
#include "Dram.h"
|
||||
|
||||
class DramSTTMRAM : public Dram
|
||||
{
|
||||
public:
|
||||
DramSTTMRAM(sc_module_name);
|
||||
SC_HAS_PROCESS(DramSTTMRAM);
|
||||
virtual ~DramSTTMRAM() {}
|
||||
};
|
||||
|
||||
#endif // DRAMSTTMRAM_H
|
||||
@@ -42,6 +42,8 @@ project(DRAMSysSimulator)
|
||||
set(CMAKE_CXX_STANDARD 11 CACHE STRING "C++ Version")
|
||||
set(DCMAKE_SH="CMAKE_SH-NOTFOUND")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
add_executable(DRAMSys
|
||||
main.cpp
|
||||
ExampleInitiator.h
|
||||
@@ -62,4 +64,5 @@ target_include_directories(DRAMSys
|
||||
|
||||
target_link_libraries(DRAMSys
|
||||
PRIVATE DRAMSysLibrary
|
||||
PRIVATE Threads::Threads
|
||||
)
|
||||
|
||||
@@ -61,7 +61,7 @@ StlPlayer::StlPlayer(const sc_module_name &name,
|
||||
this->maxPendingWriteRequests = maxPendingWriteRequests;
|
||||
|
||||
this->playerClk = playerClk;
|
||||
burstlength = Configuration::getInstance().memSpec->burstLength;
|
||||
burstLength = Configuration::getInstance().memSpec->burstLength;
|
||||
dataLength = Configuration::getInstance().memSpec->bytesPerBurst;
|
||||
lineCnt = 0;
|
||||
|
||||
@@ -100,23 +100,23 @@ void StlPlayer::nextPayload()
|
||||
payload->set_response_status(TLM_INCOMPLETE_RESPONSE);
|
||||
payload->set_dmi_allowed(false);
|
||||
payload->set_byte_enable_length(0);
|
||||
payload->set_streaming_width(burstlength);
|
||||
payload->set_streaming_width(burstLength);
|
||||
payload->set_data_length(dataLength);
|
||||
payload->set_command(lineIterator->cmd);
|
||||
std::copy(lineIterator->data.begin(), lineIterator->data.end(), payload->get_data_ptr());
|
||||
|
||||
sc_time sendingOffset;
|
||||
sc_time sendingTime;
|
||||
sc_time sendingOffset;
|
||||
|
||||
if (lastEndReq == sc_time_stamp())
|
||||
sendingOffset = playerClk;
|
||||
else
|
||||
if (transactionsSent == 0)
|
||||
sendingOffset = SC_ZERO_TIME;
|
||||
else
|
||||
sendingOffset = playerClk - (sc_time_stamp() % playerClk);
|
||||
|
||||
if (!relative)
|
||||
sendingTime = std::max(sc_time_stamp() + sendingOffset, lineIterator->sendingTime);
|
||||
else
|
||||
sendingTime = sc_time_stamp() + std::max(sendingOffset, lineIterator->sendingTime);
|
||||
sendingTime = sc_time_stamp() + sendingOffset + lineIterator->sendingTime;
|
||||
|
||||
sendToTarget(*payload, BEGIN_REQ, sendingTime - sc_time_stamp());
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ private:
|
||||
std::ifstream file;
|
||||
uint64_t lineCnt;
|
||||
|
||||
unsigned int burstlength;
|
||||
unsigned int burstLength;
|
||||
unsigned int dataLength;
|
||||
sc_time playerClk; // May be different from the memory clock!
|
||||
|
||||
|
||||
@@ -92,10 +92,10 @@ void TrafficGenerator::nextPayload()
|
||||
payload->set_command(command);
|
||||
|
||||
sc_time sendingOffset;
|
||||
if (lastEndReq == sc_time_stamp())
|
||||
sendingOffset = tCK;
|
||||
else
|
||||
if (transactionsSent == 0)
|
||||
sendingOffset = SC_ZERO_TIME;
|
||||
else
|
||||
sendingOffset = tCK;
|
||||
|
||||
// TODO: do not send two requests in the same cycle
|
||||
sendToTarget(*payload, tlm::BEGIN_REQ, sendingOffset);
|
||||
|
||||
@@ -74,8 +74,6 @@ void TrafficInitiator::peqCallback(tlm_generic_payload &payload,
|
||||
{
|
||||
if (phase == END_REQ)
|
||||
{
|
||||
lastEndReq = sc_time_stamp();
|
||||
|
||||
if (nextPayloadSendable())
|
||||
nextPayload();
|
||||
else
|
||||
|
||||
@@ -75,7 +75,7 @@ protected:
|
||||
unsigned int maxPendingWriteRequests = 0;
|
||||
bool payloadPostponed = false;
|
||||
bool finished = false;
|
||||
sc_time lastEndReq = sc_max_time();
|
||||
|
||||
sc_event transactionFinished;
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user