Merge branch 'DDR5' into 'develop'
Rambus Analysis Features See merge request ems/astdm/dram.sys!270
This commit is contained in:
@@ -78,7 +78,6 @@ if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src/common/third_party/sqlite-amalgamation)
|
||||
endif()
|
||||
|
||||
add_library(DRAMSysLibrary
|
||||
src/common/AddressDecoder.cpp
|
||||
src/common/DebugManager.cpp
|
||||
src/common/dramExtensions.cpp
|
||||
src/common/tlm2_base_protocol_checker.h
|
||||
@@ -90,6 +89,7 @@ add_library(DRAMSysLibrary
|
||||
src/configuration/memspec/MemSpec.cpp
|
||||
src/configuration/memspec/MemSpecDDR3.cpp
|
||||
src/configuration/memspec/MemSpecDDR4.cpp
|
||||
src/configuration/memspec/MemSpecDDR5.cpp
|
||||
src/configuration/memspec/MemSpecLPDDR4.cpp
|
||||
src/configuration/memspec/MemSpecWideIO.cpp
|
||||
src/configuration/memspec/MemSpecWideIO2.cpp
|
||||
@@ -106,6 +106,7 @@ add_library(DRAMSysLibrary
|
||||
src/controller/checker/CheckerIF.h
|
||||
src/controller/checker/CheckerDDR3.cpp
|
||||
src/controller/checker/CheckerDDR4.cpp
|
||||
src/controller/checker/CheckerDDR5.cpp
|
||||
src/controller/checker/CheckerLPDDR4.cpp
|
||||
src/controller/checker/CheckerWideIO.cpp
|
||||
src/controller/checker/CheckerWideIO2.cpp
|
||||
@@ -126,6 +127,7 @@ add_library(DRAMSysLibrary
|
||||
src/controller/refresh/RefreshManagerDummy.cpp
|
||||
src/controller/refresh/RefreshManagerRankwise.cpp
|
||||
src/controller/refresh/RefreshManagerBankwise.cpp
|
||||
src/controller/refresh/RefreshManagerGroupwise.cpp
|
||||
|
||||
src/controller/respqueue/RespQueueIF.h
|
||||
src/controller/respqueue/RespQueueFifo.cpp
|
||||
@@ -135,6 +137,11 @@ add_library(DRAMSysLibrary
|
||||
src/controller/scheduler/SchedulerFifo.cpp
|
||||
src/controller/scheduler/SchedulerFrFcfs.cpp
|
||||
src/controller/scheduler/SchedulerFrFcfsGrp.cpp
|
||||
|
||||
src/controller/scheduler/BufferCounterIF.h
|
||||
src/controller/scheduler/BufferCounterBankwise.cpp
|
||||
src/controller/scheduler/BufferCounterReadWrite.cpp
|
||||
src/controller/scheduler/BufferCounterShared.cpp
|
||||
|
||||
src/error/eccbaseclass.cpp
|
||||
src/error/ecchamming.cpp
|
||||
@@ -145,6 +152,7 @@ add_library(DRAMSysLibrary
|
||||
src/error/ECC/Word.cpp
|
||||
|
||||
src/simulation/Arbiter.cpp
|
||||
src/simulation/AddressDecoder.cpp
|
||||
src/simulation/DRAMSys.cpp
|
||||
src/simulation/ReorderBuffer.h
|
||||
src/simulation/TemperatureController.cpp
|
||||
@@ -152,6 +160,7 @@ add_library(DRAMSysLibrary
|
||||
src/simulation/dram/Dram.cpp
|
||||
src/simulation/dram/DramDDR3.cpp
|
||||
src/simulation/dram/DramDDR4.cpp
|
||||
src/simulation/dram/DramDDR5.cpp
|
||||
src/simulation/dram/DramLPDDR4.cpp
|
||||
src/simulation/dram/DramWideIO.cpp
|
||||
src/simulation/dram/DramWideIO2.cpp
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"BYTE_BIT": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"COLUMN_BIT": [
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11
|
||||
],
|
||||
"BANKGROUP_BIT": [
|
||||
12,
|
||||
13,
|
||||
14
|
||||
],
|
||||
"BANK_BIT": [
|
||||
15
|
||||
],
|
||||
"ROW_BIT": [
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31
|
||||
],
|
||||
"CHANNEL_BIT": [
|
||||
32
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"BYTE_BIT": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"COLUMN_BIT": [
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12
|
||||
],
|
||||
"BANKGROUP_BIT": [
|
||||
13,
|
||||
14,
|
||||
15
|
||||
],
|
||||
"BANK_BIT": [
|
||||
16
|
||||
],
|
||||
"ROW_BIT": [
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32
|
||||
],
|
||||
"CHANNEL_BIT": [
|
||||
33
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"BYTE_BIT": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"COLUMN_BIT": [
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12
|
||||
],
|
||||
"BANKGROUP_BIT": [
|
||||
13,
|
||||
14,
|
||||
15
|
||||
],
|
||||
"BANK_BIT": [
|
||||
16
|
||||
],
|
||||
"ROW_BIT": [
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32
|
||||
],
|
||||
"RANK_BIT": [
|
||||
33,
|
||||
34,
|
||||
35
|
||||
],
|
||||
"CHANNEL_BIT": [
|
||||
36
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 1024,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 8,
|
||||
"nbrOfDevicesOnDIMM": 4,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x4x1Gbx8_DDR5-3200A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 22,
|
||||
"PPD": 2,
|
||||
"RP": 22,
|
||||
"RAS": 52,
|
||||
"RL": 22,
|
||||
"RTP": 12,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 20,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 48,
|
||||
"CCD_L_slr": 8,
|
||||
"CCD_L_WR_slr": 16,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 8,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 16,
|
||||
"WTR_S": 4,
|
||||
"RFC1_slr": 312,
|
||||
"RFC2_slr": 208,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 184,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 6240,
|
||||
"REFI2": 3120,
|
||||
"REFISB": 1560,
|
||||
"REFSBRD_slr": 48,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 8,
|
||||
"PD": 12,
|
||||
"XP": 12,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 1600
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 1024,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 8,
|
||||
"nbrOfDevicesOnDIMM": 4,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x4x1Gbx8_DDR5-3600A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 26,
|
||||
"PPD": 2,
|
||||
"RP": 26,
|
||||
"RAS": 58,
|
||||
"RL": 26,
|
||||
"RTP": 14,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 24,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 54,
|
||||
"CCD_L_slr": 9,
|
||||
"CCD_L_WR_slr": 18,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 9,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 18,
|
||||
"WTR_S": 5,
|
||||
"RFC1_slr": 351,
|
||||
"RFC2_slr": 234,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 207,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 7020,
|
||||
"REFI2": 3510,
|
||||
"REFISB": 1755,
|
||||
"REFSBRD_slr": 54,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 9,
|
||||
"PD": 14,
|
||||
"XP": 14,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 1800
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 1024,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 8,
|
||||
"nbrOfDevicesOnDIMM": 4,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x4x1Gbx8_DDR5-4000A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 28,
|
||||
"PPD": 2,
|
||||
"RP": 28,
|
||||
"RAS": 64,
|
||||
"RL": 28,
|
||||
"RTP": 15,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 26,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 60,
|
||||
"CCD_L_slr": 10,
|
||||
"CCD_L_WR_slr": 20,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 10,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 20,
|
||||
"WTR_S": 5,
|
||||
"RFC1_slr": 390,
|
||||
"RFC2_slr": 260,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 230,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 7800,
|
||||
"REFI2": 3900,
|
||||
"REFISB": 1950,
|
||||
"REFSBRD_slr": 60,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 10,
|
||||
"PD": 15,
|
||||
"XP": 15,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 2000
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 1024,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 8,
|
||||
"nbrOfDevicesOnDIMM": 4,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x4x1Gbx8_DDR5-4400A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 32,
|
||||
"PPD": 2,
|
||||
"RP": 32,
|
||||
"RAS": 71,
|
||||
"RL": 32,
|
||||
"RTP": 17,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 30,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 66,
|
||||
"CCD_L_slr": 11,
|
||||
"CCD_L_WR_slr": 22,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 11,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 22,
|
||||
"WTR_S": 6,
|
||||
"RFC_slr": 429,
|
||||
"RFC_slr": 286,
|
||||
"RFC_dlr": 0,
|
||||
"RFC_dlr": 0,
|
||||
"RFC_dpr": 0,
|
||||
"RFC_dpr": 0,
|
||||
"RFCsb_slr": 253,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 8580,
|
||||
"REFI2": 4290,
|
||||
"REFISB": 2145,
|
||||
"REFSBRD_slr": 66,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 11,
|
||||
"PD": 17,
|
||||
"XP": 17,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 2200
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 1024,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 8,
|
||||
"nbrOfDevicesOnDIMM": 4,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x4x1Gbx8_DDR5-4800A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 34,
|
||||
"PPD": 2,
|
||||
"RP": 34,
|
||||
"RAS": 77,
|
||||
"RL": 34,
|
||||
"RTP": 18,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 32,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 72,
|
||||
"CCD_L_slr": 12,
|
||||
"CCD_L_WR_slr": 24,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 12,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 24,
|
||||
"WTR_S": 6,
|
||||
"RFC1_slr": 468,
|
||||
"RFC2_slr": 312,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 276,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 9360,
|
||||
"REFI2": 4680,
|
||||
"REFISB": 2340,
|
||||
"REFSBRD_slr": 72,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 12,
|
||||
"PD": 18,
|
||||
"XP": 18,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 2400
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 1024,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 8,
|
||||
"nbrOfDevicesOnDIMM": 4,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x4x1Gbx8_DDR5-5200A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 38,
|
||||
"PPD": 2,
|
||||
"RP": 38,
|
||||
"RAS": 84,
|
||||
"RL": 38,
|
||||
"RTP": 20,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 36,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 78,
|
||||
"CCD_L_slr": 13,
|
||||
"CCD_L_WR_slr": 26,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 13,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 26,
|
||||
"WTR_S": 7,
|
||||
"RFC1_slr": 507,
|
||||
"RFC2_slr": 338,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 299,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 10140,
|
||||
"REFI2": 5070,
|
||||
"REFISB": 2535,
|
||||
"REFSBRD_slr": 78,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 13,
|
||||
"PD": 20,
|
||||
"XP": 20,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 2600
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 1024,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 8,
|
||||
"nbrOfDevicesOnDIMM": 4,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x4x1Gbx8_DDR5-5600A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 40,
|
||||
"PPD": 2,
|
||||
"RP": 40,
|
||||
"RAS": 90,
|
||||
"RL": 40,
|
||||
"RTP": 21,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 38,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 84,
|
||||
"CCD_L_slr": 14,
|
||||
"CCD_L_WR_slr": 28,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 14,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 28,
|
||||
"WTR_S": 7,
|
||||
"RFC1_slr": 546,
|
||||
"RFC2_slr": 364,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 322,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 10920,
|
||||
"REFI2": 5460,
|
||||
"REFISB": 2730,
|
||||
"REFSBRD_slr": 84,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 14,
|
||||
"PD": 21,
|
||||
"XP": 21,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 2800
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 1024,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 8,
|
||||
"nbrOfDevicesOnDIMM": 4,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x4x1Gbx8_DDR5-6000A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 42,
|
||||
"PPD": 2,
|
||||
"RP": 42,
|
||||
"RAS": 96,
|
||||
"RL": 42,
|
||||
"RTP": 23,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 40,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 90,
|
||||
"CCD_L_slr": 15,
|
||||
"CCD_L_WR_slr": 30,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 15,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 30,
|
||||
"WTR_S": 8,
|
||||
"RFC1_slr": 585,
|
||||
"RFC2_slr": 390,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 345,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 11700,
|
||||
"REFI2": 5850,
|
||||
"REFISB": 2925,
|
||||
"REFSBRD_slr": 90,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 15,
|
||||
"PD": 23,
|
||||
"XP": 23,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 3000
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 1024,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 8,
|
||||
"nbrOfDevicesOnDIMM": 4,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x4x1Gbx8_DDR5-6400A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 46,
|
||||
"PPD": 2,
|
||||
"RP": 46,
|
||||
"RAS": 103,
|
||||
"RL": 46,
|
||||
"RTP": 24,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 44,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 96,
|
||||
"CCD_L_slr": 16,
|
||||
"CCD_L_WR_slr": 32,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 16,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 32,
|
||||
"WTR_S": 8,
|
||||
"RFC1_slr": 624,
|
||||
"RFC2_slr": 416,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 368,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 12480,
|
||||
"REFI2": 6240,
|
||||
"REFISB": 3120,
|
||||
"REFSBRD_slr": 96,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 16,
|
||||
"PD": 24,
|
||||
"XP": 24,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 3200
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 2048,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 4,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x8x2Gbx4_DDR5-3200A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 22,
|
||||
"PPD": 2,
|
||||
"RP": 22,
|
||||
"RAS": 52,
|
||||
"RL": 22,
|
||||
"RTP": 12,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 20,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 48,
|
||||
"CCD_L_slr": 8,
|
||||
"CCD_L_WR_slr": 32,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 8,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 16,
|
||||
"WTR_S": 4,
|
||||
"RFC1_slr": 312,
|
||||
"RFC2_slr": 208,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 184,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 6240,
|
||||
"REFI2": 3120,
|
||||
"REFISB": 1560,
|
||||
"REFSBRD_slr": 48,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 8,
|
||||
"PD": 12,
|
||||
"XP": 12,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 1600
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 2048,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 4,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x8x2Gbx4_DDR5-3600A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 26,
|
||||
"PPD": 2,
|
||||
"RP": 26,
|
||||
"RAS": 58,
|
||||
"RL": 26,
|
||||
"RTP": 14,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 24,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 54,
|
||||
"CCD_L_slr": 9,
|
||||
"CCD_L_WR_slr": 36,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 9,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 18,
|
||||
"WTR_S": 5,
|
||||
"RFC1_slr": 351,
|
||||
"RFC2_slr": 234,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 207,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 7020,
|
||||
"REFI2": 3510,
|
||||
"REFISB": 1755,
|
||||
"REFSBRD_slr": 54,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 9,
|
||||
"PD": 14,
|
||||
"XP": 14,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 1800
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 2048,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 4,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x8x2Gbx4_DDR5-4000A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 28,
|
||||
"PPD": 2,
|
||||
"RP": 28,
|
||||
"RAS": 64,
|
||||
"RL": 28,
|
||||
"RTP": 15,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 26,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 60,
|
||||
"CCD_L_slr": 10,
|
||||
"CCD_L_WR_slr": 40,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 10,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 20,
|
||||
"WTR_S": 5,
|
||||
"RFC1_slr": 390,
|
||||
"RFC2_slr": 260,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 230,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 7800,
|
||||
"REFI2": 3900,
|
||||
"REFISB": 1950,
|
||||
"REFSBRD_slr": 60,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 10,
|
||||
"PD": 15,
|
||||
"XP": 15,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 2000
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 2048,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 4,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x8x2Gbx4_DDR5-4400A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 32,
|
||||
"PPD": 2,
|
||||
"RP": 32,
|
||||
"RAS": 71,
|
||||
"RL": 32,
|
||||
"RTP": 17,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 30,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 66,
|
||||
"CCD_L_slr": 11,
|
||||
"CCD_L_WR_slr": 44,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 11,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 22,
|
||||
"WTR_S": 6,
|
||||
"RFC_slr": 429,
|
||||
"RFC_slr": 286,
|
||||
"RFC_dlr": 0,
|
||||
"RFC_dlr": 0,
|
||||
"RFC_dpr": 0,
|
||||
"RFC_dpr": 0,
|
||||
"RFCsb_slr": 253,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 8580,
|
||||
"REFI2": 4290,
|
||||
"REFISB": 2145,
|
||||
"REFSBRD_slr": 66,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 11,
|
||||
"PD": 17,
|
||||
"XP": 17,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 2200
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 2048,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 4,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x8x2Gbx4_DDR5-4800A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 34,
|
||||
"PPD": 2,
|
||||
"RP": 34,
|
||||
"RAS": 77,
|
||||
"RL": 34,
|
||||
"RTP": 18,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 32,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 72,
|
||||
"CCD_L_slr": 12,
|
||||
"CCD_L_WR_slr": 48,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 12,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 24,
|
||||
"WTR_S": 6,
|
||||
"RFC1_slr": 468,
|
||||
"RFC2_slr": 312,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 276,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 9360,
|
||||
"REFI2": 4680,
|
||||
"REFISB": 2340,
|
||||
"REFSBRD_slr": 72,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 12,
|
||||
"PD": 18,
|
||||
"XP": 18,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 2400
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 2048,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 4,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x8x2Gbx4_DDR5-5200A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 38,
|
||||
"PPD": 2,
|
||||
"RP": 38,
|
||||
"RAS": 84,
|
||||
"RL": 38,
|
||||
"RTP": 20,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 36,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 78,
|
||||
"CCD_L_slr": 13,
|
||||
"CCD_L_WR_slr": 52,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 13,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 26,
|
||||
"WTR_S": 7,
|
||||
"RFC1_slr": 507,
|
||||
"RFC2_slr": 338,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 299,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 10140,
|
||||
"REFI2": 5070,
|
||||
"REFISB": 2535,
|
||||
"REFSBRD_slr": 78,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 13,
|
||||
"PD": 20,
|
||||
"XP": 20,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 2600
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 2048,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 4,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x8x2Gbx4_DDR5-5600A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 40,
|
||||
"PPD": 2,
|
||||
"RP": 40,
|
||||
"RAS": 90,
|
||||
"RL": 40,
|
||||
"RTP": 21,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 38,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 84,
|
||||
"CCD_L_slr": 14,
|
||||
"CCD_L_WR_slr": 56,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 14,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 28,
|
||||
"WTR_S": 7,
|
||||
"RFC1_slr": 546,
|
||||
"RFC2_slr": 364,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 322,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 10920,
|
||||
"REFI2": 5460,
|
||||
"REFISB": 2730,
|
||||
"REFSBRD_slr": 84,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 14,
|
||||
"PD": 21,
|
||||
"XP": 21,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 2800
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 2048,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 4,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x8x2Gbx4_DDR5-6000A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 42,
|
||||
"PPD": 2,
|
||||
"RP": 42,
|
||||
"RAS": 96,
|
||||
"RL": 42,
|
||||
"RTP": 23,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 40,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 90,
|
||||
"CCD_L_slr": 15,
|
||||
"CCD_L_WR_slr": 60,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 15,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 30,
|
||||
"WTR_S": 8,
|
||||
"RFC1_slr": 585,
|
||||
"RFC2_slr": 390,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 345,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 11700,
|
||||
"REFI2": 5850,
|
||||
"REFISB": 2925,
|
||||
"REFSBRD_slr": 90,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 15,
|
||||
"PD": 23,
|
||||
"XP": 23,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 3000
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 2048,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 4,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x8x2Gbx4_DDR5-6400A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 46,
|
||||
"PPD": 2,
|
||||
"RP": 46,
|
||||
"RAS": 103,
|
||||
"RL": 46,
|
||||
"RTP": 24,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 44,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 96,
|
||||
"CCD_L_slr": 16,
|
||||
"CCD_L_WR_slr": 64,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 0,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"RRD_L_slr": 16,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 0,
|
||||
"WTR_L": 32,
|
||||
"WTR_S": 8,
|
||||
"RFC1_slr": 624,
|
||||
"RFC2_slr": 416,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFCsb_slr": 368,
|
||||
"RFCsb_dlr": 0,
|
||||
"REFI1": 12480,
|
||||
"REFI2": 6240,
|
||||
"REFISB": 3120,
|
||||
"REFSBRD_slr": 96,
|
||||
"REFSBRD_dlr": 0,
|
||||
"RTRS": 2,
|
||||
"CPDED": 16,
|
||||
"PD": 24,
|
||||
"XP": 24,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 3200
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"burstLength": 16,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfColumns": 2048,
|
||||
"nbrOfRanks": 8,
|
||||
"nbrOfDIMMRanks": 2,
|
||||
"nbrOfPhysicalRanks": 2,
|
||||
"nbrOfLogicalRanks": 2,
|
||||
"nbrOfRows": 65536,
|
||||
"width": 4,
|
||||
"nbrOfDevicesOnDIMM": 8,
|
||||
"nbrOfChannels": 2,
|
||||
"cmdMode": 1,
|
||||
"refMode": 1
|
||||
},
|
||||
"memoryId": "JEDEC_2x8x8x8Gbx4_DDR5-3200A_4bit",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"RCD": 22,
|
||||
"PPD": 2,
|
||||
"RP": 22,
|
||||
"RAS": 52,
|
||||
"RL": 22,
|
||||
"RTP": 12,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RDDQS": 0,
|
||||
"WL": 20,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 48,
|
||||
"CCD_L_slr": 8,
|
||||
"CCD_L_WR_slr": 32,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_dlr": 8,
|
||||
"CCD_WR_dlr": 8,
|
||||
"CCD_WR_dpr": 8,
|
||||
"RRD_L_slr": 8,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 4,
|
||||
"FAW_slr": 32,
|
||||
"FAW_dlr": 16,
|
||||
"WTR_L": 16,
|
||||
"WTR_S": 4,
|
||||
"RFC1_slr": 312,
|
||||
"RFC2_slr": 208,
|
||||
"RFC1_dlr": 104,
|
||||
"RFC2_dlr": 70,
|
||||
"RFC1_dpr": 104,
|
||||
"RFC2_dpr": 70,
|
||||
"RFCsb_slr": 184,
|
||||
"RFCsb_dlr": 62,
|
||||
"REFI1": 6240,
|
||||
"REFI2": 3120,
|
||||
"REFISB": 1560,
|
||||
"REFSBRD_slr": 48,
|
||||
"REFSBRD_dlr": 24,
|
||||
"RTRS": 2,
|
||||
"CPDED": 8,
|
||||
"PD": 12,
|
||||
"XP": 12,
|
||||
"ACTPDEN": 2,
|
||||
"PRPDEN": 2,
|
||||
"REFPDEN": 2,
|
||||
"clkMhz": 1600
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,11 +49,13 @@
|
||||
"RFC2": 150,
|
||||
"RFC4": 103,
|
||||
"RL": 13,
|
||||
"RPRE": 1,
|
||||
"RP": 13,
|
||||
"RRD_L": 5,
|
||||
"RRD_S": 4,
|
||||
"RTP": 8,
|
||||
"WL": 12,
|
||||
"WPRE": 1,
|
||||
"WR": 14,
|
||||
"WTR_L": 7,
|
||||
"WTR_S": 3,
|
||||
|
||||
@@ -49,11 +49,13 @@
|
||||
"RFC2": 192,
|
||||
"RFC4": 132,
|
||||
"RL": 16,
|
||||
"RPRE": 1,
|
||||
"RP": 16,
|
||||
"RRD_L": 6,
|
||||
"RRD_S": 4,
|
||||
"RTP": 12,
|
||||
"WL": 16,
|
||||
"WPRE": 1,
|
||||
"WR": 18,
|
||||
"WTR_L": 9,
|
||||
"WTR_S": 3,
|
||||
|
||||
@@ -47,11 +47,13 @@
|
||||
"REFI": 3644,
|
||||
"RFC": 243,
|
||||
"RL": 13,
|
||||
"RPRE": 1,
|
||||
"RP": 13,
|
||||
"RRD_L": 5,
|
||||
"RRD_S": 4,
|
||||
"RTP": 8,
|
||||
"WL": 12,
|
||||
"WPRE": 1,
|
||||
"WR": 14,
|
||||
"WTR_L": 7,
|
||||
"WTR_S": 3,
|
||||
|
||||
@@ -47,11 +47,13 @@
|
||||
"REFI": 4680,
|
||||
"RFC": 313,
|
||||
"RL": 16,
|
||||
"RPRE": 1,
|
||||
"RP": 16,
|
||||
"RRD_L": 6,
|
||||
"RRD_S": 4,
|
||||
"RTP": 12,
|
||||
"WL": 16,
|
||||
"WPRE": 1,
|
||||
"WR": 18,
|
||||
"WTR_L": 9,
|
||||
"WTR_S": 3,
|
||||
|
||||
19
DRAMSys/library/resources/configs/simulator/ddr5.json
Normal file
19
DRAMSys/library/resources/configs/simulator/ddr5.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": "ddr5",
|
||||
"SimulationProgressBar": true,
|
||||
"StoreMode": "NoStorage",
|
||||
"ThermalSimulation": false,
|
||||
"UseMalloc": false,
|
||||
"WindowSize": 1000
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
DROP TABLE IF EXISTS Phases;
|
||||
DROP TABLE IF EXISTS GeneralInfo;
|
||||
DROP TABLE IF EXISTS CommandLengths;
|
||||
DROP TABLE IF EXISTS Comments;
|
||||
DROP TABLE IF EXISTS ranges;
|
||||
DROP TABLE IF EXISTS Transactions;
|
||||
DROP TABLE IF EXISTS DebugMessages;
|
||||
DROP TABLE IF EXISTS Power;
|
||||
|
||||
CREATE TABLE Phases(
|
||||
ID INTEGER PRIMARY KEY,
|
||||
PhaseName TEXT,
|
||||
PhaseBegin INTEGER,
|
||||
PhaseEnd INTEGER,
|
||||
Transact INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE GeneralInfo(
|
||||
NumberOfTransactions INTEGER,
|
||||
TraceEnd INTEGER,
|
||||
NumberOfRanks INTEGER,
|
||||
NumberOfBanks INTEGER,
|
||||
clk INTEGER,
|
||||
UnitOfTime TEXT,
|
||||
MCconfig TEXT,
|
||||
Memspec TEXT,
|
||||
Traces TEXT,
|
||||
WindowSize INTEGER,
|
||||
FlexibleRefresh INTEGER,
|
||||
MaxRefBurst INTEGER,
|
||||
ControllerThread INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE CommandLengths(
|
||||
ACT INTEGER,
|
||||
PRE INTEGER,
|
||||
PREA INTEGER,
|
||||
RD INTEGER,
|
||||
RDA INTEGER,
|
||||
WR INTEGER,
|
||||
WRA INTEGER,
|
||||
REFA INTEGER,
|
||||
REFB INTEGER,
|
||||
PDEA INTEGER,
|
||||
PDXA INTEGER,
|
||||
PDEP INTEGER,
|
||||
PDXP INTEGER,
|
||||
SREFEN INTEGER,
|
||||
SREFEX INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE Power(
|
||||
time DOUBLE,
|
||||
AveragePower DOUBLE
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE Comments(
|
||||
Time INTEGER,
|
||||
Text TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE DebugMessages(
|
||||
Time INTEGER,
|
||||
Message TEXT
|
||||
);
|
||||
|
||||
-- use SQLITE R* TREE Module to make queries on timespans effecient (see http://www.sqlite.org/rtree.html)
|
||||
CREATE VIRTUAL TABLE ranges USING rtree(
|
||||
id,
|
||||
begin, end
|
||||
);
|
||||
|
||||
CREATE TABLE Transactions(
|
||||
ID INTEGER,
|
||||
Range INTEGER,
|
||||
Address INTEGER,
|
||||
Burstlength INTEGER,
|
||||
TThread INTEGER,
|
||||
TChannel INTEGER,
|
||||
TRank INTEGER,
|
||||
TBankgroup INTEGER,
|
||||
TBank INTEGER,
|
||||
TRow INTEGER,
|
||||
TColumn INTEGER,
|
||||
DataStrobeBegin INTEGER,
|
||||
DataStrobeEnd INTEGER,
|
||||
TimeOfGeneration INTEGER,
|
||||
Command TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX ranges_index ON Transactions(Range);
|
||||
CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC);
|
||||
CREATE INDEX "messageTimes" ON "DebugMessages" ("Time" ASC);
|
||||
16
DRAMSys/library/resources/simulations/ddr5-example.json
Normal file
16
DRAMSys/library/resources/simulations/ddr5-example.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"simulation": {
|
||||
"addressmapping": "am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json",
|
||||
"mcconfig": "fr_fcfs.json",
|
||||
"memspec": "JEDEC_2x8x2Gbx4_DDR5-3200A.json",
|
||||
"simconfig": "ddr5.json",
|
||||
"simulationid": "ddr5-example",
|
||||
"thermalconfig": "config.json",
|
||||
"tracesetup": [
|
||||
{
|
||||
"clkMhz": 2000,
|
||||
"name": "ddr3_example.stl"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -46,8 +46,8 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
TlmRecorder::TlmRecorder(std::string name, std::string uri, std::string dbname) :
|
||||
name(name), sqlScriptURI(uri), dbName(dbname),
|
||||
TlmRecorder::TlmRecorder(std::string name, std::string dbname) :
|
||||
dbName(dbname), name(name),
|
||||
totalNumTransactions(1), simulationTimeCoveredByRecording(SC_ZERO_TIME)
|
||||
{
|
||||
recordedData.reserve(transactionCommitRate);
|
||||
@@ -60,7 +60,7 @@ TlmRecorder::TlmRecorder(std::string name, std::string uri, std::string dbname)
|
||||
sqlite3_exec(db, "PRAGMA main.synchronous=OFF", NULL, NULL, &sErrMsg);
|
||||
sqlite3_exec(db, "PRAGMA journal_mode = OFF", NULL, NULL, &sErrMsg);
|
||||
|
||||
createTables(TlmRecorder::sqlScriptURI);
|
||||
executeInitialSqlCommand();
|
||||
prepareSqlStatements();
|
||||
|
||||
PRINTDEBUGMESSAGE(name, "Starting new database transaction");
|
||||
@@ -80,6 +80,8 @@ TlmRecorder::~TlmRecorder()
|
||||
sqlite3_finalize(insertDebugMessageStatement);
|
||||
sqlite3_finalize(updateDataStrobeStatement);
|
||||
sqlite3_finalize(insertPowerStatement);
|
||||
sqlite3_finalize(insertBufferDepthStatement);
|
||||
sqlite3_finalize(insertBandwidthStatement);
|
||||
}
|
||||
|
||||
void TlmRecorder::recordPower(double timeInSeconds, double averagePower)
|
||||
@@ -89,6 +91,24 @@ void TlmRecorder::recordPower(double timeInSeconds, double averagePower)
|
||||
executeSqlStatement(insertPowerStatement);
|
||||
}
|
||||
|
||||
void TlmRecorder::recordBufferDepth(double timeInSeconds, const std::vector<double> &averageBufferDepth)
|
||||
{
|
||||
for (size_t index = 0; index < averageBufferDepth.size(); index++)
|
||||
{
|
||||
sqlite3_bind_double(insertBufferDepthStatement, 1, timeInSeconds);
|
||||
sqlite3_bind_int(insertBufferDepthStatement, 2, index);
|
||||
sqlite3_bind_double(insertBufferDepthStatement, 3, averageBufferDepth[index]);
|
||||
executeSqlStatement(insertBufferDepthStatement);
|
||||
}
|
||||
}
|
||||
|
||||
void TlmRecorder::recordBandwidth(double timeInSeconds, double averageBandwidth)
|
||||
{
|
||||
sqlite3_bind_double(insertBandwidthStatement, 1, timeInSeconds);
|
||||
sqlite3_bind_double(insertBandwidthStatement, 2, averageBandwidth);
|
||||
executeSqlStatement(insertBandwidthStatement);
|
||||
}
|
||||
|
||||
void TlmRecorder::recordPhase(tlm_generic_payload &trans,
|
||||
tlm_phase phase, sc_time time)
|
||||
{
|
||||
@@ -186,7 +206,11 @@ void TlmRecorder::commitRecordedDataToDB()
|
||||
}
|
||||
|
||||
sc_time rangeBegin = recordingData.recordedPhases.front().interval.start;
|
||||
sc_time rangeEnd = recordingData.recordedPhases.back().interval.end;
|
||||
sc_time rangeEnd = rangeBegin;
|
||||
for (auto &it : recordingData.recordedPhases)
|
||||
{
|
||||
rangeEnd = std::max(rangeEnd, it.interval.end);
|
||||
}
|
||||
insertRangeInDB(recordingData.id, rangeBegin, rangeEnd);
|
||||
}
|
||||
|
||||
@@ -232,23 +256,6 @@ void TlmRecorder::openDB(std::string name)
|
||||
}
|
||||
}
|
||||
|
||||
void TlmRecorder::createTables(std::string pathToURI)
|
||||
{
|
||||
std::string initial;
|
||||
ifstream in(pathToURI.c_str(), ios::in | ios::binary);
|
||||
|
||||
if (!in)
|
||||
SC_REPORT_FATAL("Error loading file", ("Could not load textfile from " + pathToURI).c_str());
|
||||
|
||||
in.seekg(0, ios::end);
|
||||
initial.resize(in.tellg());
|
||||
in.seekg(0, ios::beg);
|
||||
in.read(&initial[0], initial.size());
|
||||
in.close();
|
||||
|
||||
executeSqlCommand(initial);
|
||||
}
|
||||
|
||||
void TlmRecorder::setUpTransactionTerminatingPhases()
|
||||
{
|
||||
transactionTerminatingPhases.push_back(END_RESP);
|
||||
@@ -261,6 +268,10 @@ void TlmRecorder::setUpTransactionTerminatingPhases()
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm_phase>
|
||||
(END_REFB));
|
||||
|
||||
// Refresh Same Bank
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm_phase>
|
||||
(END_REFSB));
|
||||
|
||||
// Phases for Power Down
|
||||
transactionTerminatingPhases.push_back(static_cast<const tlm_phase>
|
||||
(END_PDNA));
|
||||
@@ -275,86 +286,91 @@ void TlmRecorder::prepareSqlStatements()
|
||||
insertTransactionString =
|
||||
"INSERT INTO Transactions VALUES (:id,:rangeID,:address,:burstlength,:thread,:channel,:rank,"
|
||||
":bankgroup,:bank,:row,:column,:dataStrobeBegin,:dataStrobeEnd, :timeOfGeneration,:command)";
|
||||
|
||||
insertRangeString = "INSERT INTO Ranges VALUES (:id,:begin,:end)";
|
||||
|
||||
updateRangeString = "UPDATE Ranges SET End = :end WHERE ID = :id";
|
||||
|
||||
updateDataStrobeString =
|
||||
"UPDATE Transactions SET DataStrobeBegin = :begin, DataStrobeEnd = :end WHERE ID = :id";
|
||||
|
||||
insertPhaseString =
|
||||
"INSERT INTO Phases (PhaseName,PhaseBegin,PhaseEnd,Transact) VALUES (:name,:begin,:end,:transaction)";
|
||||
|
||||
updatePhaseString =
|
||||
"UPDATE Phases SET PhaseEnd = :end WHERE Transact = :trans AND PhaseName = :name";
|
||||
|
||||
insertGeneralInfoString =
|
||||
"INSERT INTO GeneralInfo VALUES"
|
||||
"(:numberOfTransactions,:end,:numberOfRanks,:numberOfBanks,:clk,:unitOfTime,:mcconfig,:memspec,"
|
||||
":traces,:windowSize, :flexibleRefresh, :maxRefBurst, :controllerThread)";
|
||||
"(:numberOfTransactions,:end,:numberOfRanks,:numberOfBankgroups,:numberOfBanks,:clk,:unitOfTime,:mcconfig,:memspec,"
|
||||
":traces,:windowSize, :flexibleRefresh, :maxRefBurst, :controllerThread, :maxBufferDepth)";
|
||||
|
||||
insertCommandLengthsString =
|
||||
"INSERT INTO CommandLengths VALUES"
|
||||
"(:ACT, :PRE, :PREA, :RD, :RDA, :WR, :WRA, :REFA, :REFB, :PDEA, :PDXA, :PDEP, :PDXP, :SREFEN, :SREFEX)";
|
||||
"(:NOP, :RD, :WR, :RDA, :WRA, :ACT, :PRE, :REFB, :PRESB, :REFSB, :PREA, :REFA, :PDEA, :PDXA, :PDEP, :PDXP, :SREFEN, :SREFEX)";
|
||||
|
||||
insertDebugMessageString =
|
||||
"INSERT INTO DebugMessages (Time,Message) Values (:time,:message)";
|
||||
insertPowerString = "INSERT INTO Power VALUES (:time,:averagePower)";
|
||||
|
||||
sqlite3_prepare_v2(db, insertTransactionString.c_str(), -1,
|
||||
&insertTransactionStatement, 0);
|
||||
insertPowerString = "INSERT INTO Power VALUES (:time,:averagePower)";
|
||||
insertBufferDepthString = "INSERT INTO BufferDepth VALUES (:time,:bufferNumber,:averageBufferDepth)";
|
||||
insertBandwidthString = "INSERT INTO Bandwidth VALUES (:time,:averageBandwidth)";
|
||||
|
||||
sqlite3_prepare_v2(db, insertTransactionString.c_str(), -1, &insertTransactionStatement, 0);
|
||||
sqlite3_prepare_v2(db, insertRangeString.c_str(), -1, &insertRangeStatement, 0);
|
||||
sqlite3_prepare_v2(db, updateRangeString.c_str(), -1, &updateRangeStatement, 0);
|
||||
sqlite3_prepare_v2(db, insertPhaseString.c_str(), -1, &insertPhaseStatement, 0);
|
||||
sqlite3_prepare_v2(db, updatePhaseString.c_str(), -1, &updatePhaseStatement, 0);
|
||||
sqlite3_prepare_v2(db, updateDataStrobeString.c_str(), -1,
|
||||
&updateDataStrobeStatement, 0);
|
||||
sqlite3_prepare_v2(db, insertGeneralInfoString.c_str(), -1,
|
||||
&insertGeneralInfoStatement, 0);
|
||||
sqlite3_prepare_v2(db, insertCommandLengthsString.c_str(), -1,
|
||||
&insertCommandLengthsStatement, 0);
|
||||
sqlite3_prepare_v2(db, insertDebugMessageString.c_str(), -1,
|
||||
&insertDebugMessageStatement, 0);
|
||||
sqlite3_prepare_v2(db, updateDataStrobeString.c_str(), -1, &updateDataStrobeStatement, 0);
|
||||
sqlite3_prepare_v2(db, insertGeneralInfoString.c_str(), -1, &insertGeneralInfoStatement, 0);
|
||||
sqlite3_prepare_v2(db, insertCommandLengthsString.c_str(), -1, &insertCommandLengthsStatement, 0);
|
||||
sqlite3_prepare_v2(db, insertDebugMessageString.c_str(), -1, &insertDebugMessageStatement, 0);
|
||||
sqlite3_prepare_v2(db, insertPowerString.c_str(), -1, &insertPowerStatement, 0);
|
||||
sqlite3_prepare_v2(db, insertBufferDepthString.c_str(), -1, &insertBufferDepthStatement, 0);
|
||||
sqlite3_prepare_v2(db, insertBandwidthString.c_str(), -1, &insertBandwidthStatement, 0);
|
||||
}
|
||||
|
||||
void TlmRecorder::insertDebugMessageInDB(std::string message, const sc_time &time)
|
||||
{
|
||||
sqlite3_bind_int64(insertDebugMessageStatement, 1, time.value());
|
||||
sqlite3_bind_text(insertDebugMessageStatement, 2, message.c_str(),
|
||||
message.length(), 0);
|
||||
sqlite3_bind_text(insertDebugMessageStatement, 2, message.c_str(), message.length(), 0);
|
||||
executeSqlStatement(insertDebugMessageStatement);
|
||||
}
|
||||
|
||||
void TlmRecorder::insertGeneralInfo()
|
||||
{
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 1, totalNumTransactions - 1);
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 2,
|
||||
simulationTimeCoveredByRecording.value());
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 3,
|
||||
Configuration::getInstance().memSpec->numberOfRanks);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 4,
|
||||
Configuration::getInstance().memSpec->numberOfBanks);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 5,
|
||||
Configuration::getInstance().memSpec->tCK.value());
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 6, "PS", 2, NULL);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 7, mcconfig.c_str(),
|
||||
mcconfig.length(), NULL);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 8, memspec.c_str(),
|
||||
memspec.length(), NULL);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 9, traces.c_str(),
|
||||
traces.length(), NULL);
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 2, simulationTimeCoveredByRecording.value());
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 3, Configuration::getInstance().memSpec->numberOfRanks);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 4, Configuration::getInstance().memSpec->numberOfBankGroups);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 5, Configuration::getInstance().memSpec->numberOfBanks);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 6, Configuration::getInstance().memSpec->tCK.value());
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 7, "PS", 2, NULL);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 8, mcconfig.c_str(), mcconfig.length(), NULL);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 9, memspec.c_str(), memspec.length(), NULL);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 10, traces.c_str(), traces.length(), NULL);
|
||||
if (!Configuration::getInstance().enableWindowing)
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 10, 0);
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 11, 0);
|
||||
else
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 10,
|
||||
(Configuration::getInstance().memSpec->tCK *
|
||||
Configuration::getInstance().windowSize).value());
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 11,
|
||||
(Configuration::getInstance().memSpec->tCK *
|
||||
Configuration::getInstance().windowSize).value());
|
||||
|
||||
if ((Configuration::getInstance().refreshMaxPostponed > 0)
|
||||
|| (Configuration::getInstance().refreshMaxPulledin > 0)) {
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 11, 1);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 12,
|
||||
std::max(Configuration::getInstance().refreshMaxPostponed,
|
||||
Configuration::getInstance().refreshMaxPulledin));
|
||||
} else {
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 11, 0);
|
||||
|| (Configuration::getInstance().refreshMaxPulledin > 0))
|
||||
{
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 12, 1);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 13,
|
||||
std::max(Configuration::getInstance().refreshMaxPostponed,
|
||||
Configuration::getInstance().refreshMaxPulledin));
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 12, 0);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 13, 0);
|
||||
}
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 13, UINT_MAX);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 14, UINT_MAX);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 15, Configuration::getInstance().requestBufferSize);
|
||||
executeSqlStatement(insertGeneralInfoStatement);
|
||||
}
|
||||
|
||||
@@ -362,21 +378,24 @@ void TlmRecorder::insertCommandLengths()
|
||||
{
|
||||
MemSpec *memSpec = Configuration::getInstance().memSpec;
|
||||
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 1, memSpec->getCommandLength(Command::ACT) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 2, memSpec->getCommandLength(Command::PRE) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 3, memSpec->getCommandLength(Command::PREA) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 4, memSpec->getCommandLength(Command::RD) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 5, memSpec->getCommandLength(Command::RDA) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 6, memSpec->getCommandLength(Command::WR) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 7, memSpec->getCommandLength(Command::WRA) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 8, memSpec->getCommandLength(Command::REFA) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 9, memSpec->getCommandLength(Command::REFB) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 10, memSpec->getCommandLength(Command::PDEA) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 11, memSpec->getCommandLength(Command::PDXA) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 12, memSpec->getCommandLength(Command::PDEP) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 13, memSpec->getCommandLength(Command::PDXP) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 14, memSpec->getCommandLength(Command::SREFEN) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 15, memSpec->getCommandLength(Command::SREFEX) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 1, memSpec->getCommandLength(Command::NOP) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 2, memSpec->getCommandLength(Command::RD) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 3, memSpec->getCommandLength(Command::WR) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 4, memSpec->getCommandLength(Command::RDA) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 5, memSpec->getCommandLength(Command::WRA) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 6, memSpec->getCommandLength(Command::ACT) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 7, memSpec->getCommandLength(Command::PRE) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 8, memSpec->getCommandLength(Command::REFB) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 9, memSpec->getCommandLength(Command::PRESB) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 10, memSpec->getCommandLength(Command::REFSB) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 11, memSpec->getCommandLength(Command::PREA) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 12, memSpec->getCommandLength(Command::REFA) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 13, memSpec->getCommandLength(Command::PDEA) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 14, memSpec->getCommandLength(Command::PDXA) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 15, memSpec->getCommandLength(Command::PDEP) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 16, memSpec->getCommandLength(Command::PDXP) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 17, memSpec->getCommandLength(Command::SREFEN) / memSpec->tCK);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 18, memSpec->getCommandLength(Command::SREFEX) / memSpec->tCK);
|
||||
|
||||
executeSqlStatement(insertCommandLengthsStatement);
|
||||
}
|
||||
@@ -411,7 +430,6 @@ void TlmRecorder::insertTransactionInDB(Transaction &recordingData)
|
||||
recordingData.cmd.c_str(), recordingData.cmd.length(), NULL);
|
||||
|
||||
executeSqlStatement(insertTransactionStatement);
|
||||
|
||||
}
|
||||
|
||||
void TlmRecorder::insertRangeInDB(unsigned int id, const sc_time &begin,
|
||||
@@ -445,12 +463,12 @@ void TlmRecorder::executeSqlStatement(sqlite3_stmt *statement)
|
||||
sqlite3_reset(statement);
|
||||
}
|
||||
|
||||
void TlmRecorder::executeSqlCommand(std::string command)
|
||||
void TlmRecorder::executeInitialSqlCommand()
|
||||
{
|
||||
PRINTDEBUGMESSAGE(name, "Creating database by running provided sql script");
|
||||
|
||||
char *errMsg = 0;
|
||||
int rc = sqlite3_exec(db, command.c_str(), NULL, 0, &errMsg);
|
||||
int rc = sqlite3_exec(db, initialCommand.c_str(), NULL, 0, &errMsg);
|
||||
if (rc != SQLITE_OK) {
|
||||
SC_REPORT_FATAL("SQLITE Error", errMsg);
|
||||
sqlite3_free(errMsg);
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
std::string sqlScriptURI;
|
||||
std::string dbName;
|
||||
|
||||
TlmRecorder(std::string name, std::string uri, std::string dbname);
|
||||
TlmRecorder(std::string name, std::string dbname);
|
||||
~TlmRecorder();
|
||||
|
||||
void recordMCconfig(std::string mcconfig)
|
||||
@@ -77,13 +77,16 @@ public:
|
||||
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase,
|
||||
sc_time time);
|
||||
void recordPower(double timeInSeconds, double averagePower);
|
||||
void recordBufferDepth(double timeInSeconds, const std::vector<double> &averageBufferDepth);
|
||||
void recordBandwidth(double timeInSeconds, double averageBandwidth);
|
||||
void recordDebugMessage(std::string message, sc_time time);
|
||||
void updateDataStrobe(const sc_time &begin, const sc_time &end,
|
||||
tlm::tlm_generic_payload &trans);
|
||||
void closeConnection();
|
||||
|
||||
private:
|
||||
struct Transaction {
|
||||
struct Transaction
|
||||
{
|
||||
Transaction() {}
|
||||
Transaction(unsigned int id): id(id) {}
|
||||
|
||||
@@ -95,7 +98,8 @@ private:
|
||||
sc_time timeOfGeneration;
|
||||
TimeInterval timeOnDataStrobe;
|
||||
|
||||
struct Phase {
|
||||
struct Phase
|
||||
{
|
||||
Phase(std::string name, sc_time begin): name(name), interval(begin, SC_ZERO_TIME) {}
|
||||
std::string name;
|
||||
TimeInterval interval;
|
||||
@@ -111,11 +115,10 @@ private:
|
||||
std::string mcconfig, memspec, traces;
|
||||
|
||||
void prepareSqlStatements();
|
||||
void executeSqlCommand(std::string command);
|
||||
void executeInitialSqlCommand();
|
||||
void executeSqlStatement(sqlite3_stmt *statement);
|
||||
|
||||
void openDB(std::string name);
|
||||
void createTables(std::string pathToURI);
|
||||
void setUpTransactionTerminatingPhases();
|
||||
|
||||
void introduceTransactionSystem(tlm::tlm_generic_payload &trans);
|
||||
@@ -142,10 +145,125 @@ private:
|
||||
sqlite3_stmt *insertTransactionStatement, *insertRangeStatement,
|
||||
*updateRangeStatement, *insertPhaseStatement, *updatePhaseStatement,
|
||||
*insertGeneralInfoStatement, *insertCommandLengthsStatement,
|
||||
*insertDebugMessageStatement, *updateDataStrobeStatement, *insertPowerStatement;
|
||||
*insertDebugMessageStatement, *updateDataStrobeStatement,
|
||||
*insertPowerStatement, *insertBufferDepthStatement, *insertBandwidthStatement;
|
||||
std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString,
|
||||
updatePhaseString, insertGeneralInfoString, insertCommandLengthsString,
|
||||
insertDebugMessageString, updateDataStrobeString, insertPowerString;
|
||||
insertDebugMessageString, updateDataStrobeString, insertPowerString,
|
||||
insertBufferDepthString, insertBandwidthString;
|
||||
|
||||
std::string initialCommand =
|
||||
"DROP TABLE IF EXISTS Phases; \n"
|
||||
"DROP TABLE IF EXISTS GeneralInfo; \n"
|
||||
"DROP TABLE IF EXISTS CommandLengths; \n"
|
||||
"DROP TABLE IF EXISTS Comments; \n"
|
||||
"DROP TABLE IF EXISTS ranges; \n"
|
||||
"DROP TABLE IF EXISTS Transactions; \n"
|
||||
"DROP TABLE IF EXISTS DebugMessages; \n"
|
||||
"DROP TABLE IF EXISTS Power; \n"
|
||||
"DROP TABLE IF EXISTS BufferDepth; \n"
|
||||
"DROP TABLE IF EXISTS Bandwidth; \n"
|
||||
" \n"
|
||||
"CREATE TABLE Phases( \n"
|
||||
" ID INTEGER PRIMARY KEY, \n"
|
||||
" PhaseName TEXT, \n"
|
||||
" PhaseBegin INTEGER, \n"
|
||||
" PhaseEnd INTEGER, \n"
|
||||
" Transact INTEGER \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE GeneralInfo( \n"
|
||||
" NumberOfTransactions INTEGER, \n"
|
||||
" TraceEnd INTEGER, \n"
|
||||
" NumberOfRanks INTEGER, \n"
|
||||
" NumberOfBankgroups INTEGER, \n"
|
||||
" NumberOfBanks INTEGER, \n"
|
||||
" clk INTEGER, \n"
|
||||
" UnitOfTime TEXT, \n"
|
||||
" MCconfig TEXT, \n"
|
||||
" Memspec TEXT, \n"
|
||||
" Traces TEXT, \n"
|
||||
" WindowSize INTEGER, \n"
|
||||
" FlexibleRefresh INTEGER, \n"
|
||||
" MaxRefBurst INTEGER, \n"
|
||||
" ControllerThread INTEGER, \n"
|
||||
" MaxBufferDepth INTEGER \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE CommandLengths( \n"
|
||||
" NOP INTEGER, \n"
|
||||
" RD INTEGER, \n"
|
||||
" WR INTEGER, \n"
|
||||
" RDA INTEGER, \n"
|
||||
" WRA INTEGER, \n"
|
||||
" ACT INTEGER, \n"
|
||||
" PRE INTEGER, \n"
|
||||
" REFB INTEGER, \n"
|
||||
" PRESB INTEGER, \n"
|
||||
" REFSB INTEGER, \n"
|
||||
" PREA INTEGER, \n"
|
||||
" REFA INTEGER, \n"
|
||||
" PDEA INTEGER, \n"
|
||||
" PDXA INTEGER, \n"
|
||||
" PDEP INTEGER, \n"
|
||||
" PDXP INTEGER, \n"
|
||||
" SREFEN INTEGER, \n"
|
||||
" SREFEX INTEGER \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE Power( \n"
|
||||
" time DOUBLE, \n"
|
||||
" AveragePower DOUBLE \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE BufferDepth( \n"
|
||||
" Time DOUBLE, \n"
|
||||
" BufferNumber INTEGER, \n"
|
||||
" AverageBufferDepth DOUBLE \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE Bandwidth( \n"
|
||||
" Time DOUBLE, \n"
|
||||
" AverageBandwidth DOUBLE \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE Comments( \n"
|
||||
" Time INTEGER, \n"
|
||||
" Text TEXT \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE DebugMessages( \n"
|
||||
" Time INTEGER, \n"
|
||||
" Message TEXT \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"-- use SQLITE R* TREE Module to make queries on timespans effecient (see http://www.sqlite.org/rtree.html)\n"
|
||||
"CREATE VIRTUAL TABLE ranges USING rtree( \n"
|
||||
" id, \n"
|
||||
" begin, end \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE Transactions( \n"
|
||||
" ID INTEGER, \n"
|
||||
" Range INTEGER, \n"
|
||||
" Address INTEGER, \n"
|
||||
" Burstlength INTEGER, \n"
|
||||
" TThread INTEGER, \n"
|
||||
" TChannel INTEGER, \n"
|
||||
" TRank INTEGER, \n"
|
||||
" TBankgroup INTEGER, \n"
|
||||
" TBank INTEGER, \n"
|
||||
" TRow INTEGER, \n"
|
||||
" TColumn INTEGER, \n"
|
||||
" DataStrobeBegin INTEGER, \n"
|
||||
" DataStrobeEnd INTEGER, \n"
|
||||
" TimeOfGeneration INTEGER, \n"
|
||||
" Command TEXT \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE INDEX ranges_index ON Transactions(Range); \n"
|
||||
"CREATE INDEX \"phasesTransactions\" ON \"Phases\" (\"Transact\" ASC); \n"
|
||||
"CREATE INDEX \"messageTimes\" ON \"DebugMessages\" (\"Time\" ASC); \n";
|
||||
};
|
||||
|
||||
#endif // TLMRECORDER_H
|
||||
|
||||
@@ -44,24 +44,22 @@ using namespace tlm;
|
||||
|
||||
DramExtension::DramExtension() :
|
||||
thread(0), channel(0), rank(0), bankgroup(0), bank(0),
|
||||
row(0), column(0), burstlength(0), payloadID(0) {}
|
||||
|
||||
DramExtension::DramExtension(Thread thread, Rank rank, BankGroup bankgroup,
|
||||
Bank bank, Row row, Column column,
|
||||
unsigned int burstlength, uint64_t payloadID) :
|
||||
thread(thread), channel(0), rank(rank), bankgroup(bankgroup), bank(bank),
|
||||
row(row), column(column), burstlength(burstlength), payloadID(payloadID) {}
|
||||
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, uint64_t payloadID) :
|
||||
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), payloadID(payloadID) {}
|
||||
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, uint64_t payloadID)
|
||||
Column column, unsigned int burstlength,
|
||||
uint64_t threadPayloadID, uint64_t channelPayloadID)
|
||||
{
|
||||
DramExtension *extension = nullptr;
|
||||
payload->get_extension(extension);
|
||||
@@ -76,12 +74,14 @@ void DramExtension::setExtension(tlm::tlm_generic_payload *payload,
|
||||
extension->row = row;
|
||||
extension->column = column;
|
||||
extension->burstlength = burstlength;
|
||||
extension->payloadID = payloadID;
|
||||
extension->threadPayloadID = threadPayloadID;
|
||||
extension->channelPayloadID = channelPayloadID;
|
||||
}
|
||||
else
|
||||
{
|
||||
extension = new DramExtension(thread, channel, rank, bankgroup,
|
||||
bank, row, column, burstlength, payloadID);
|
||||
bank, row, column, burstlength,
|
||||
threadPayloadID, channelPayloadID);
|
||||
payload->set_auto_extension(extension);
|
||||
}
|
||||
}
|
||||
@@ -89,10 +89,25 @@ 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, uint64_t payloadID)
|
||||
Column column, unsigned int burstlength,
|
||||
uint64_t threadPayloadID, uint64_t channelPayloadID)
|
||||
{
|
||||
setExtension(&payload, thread, channel, rank, bankgroup,
|
||||
bank, row, column, burstlength, payloadID);
|
||||
bank, row, column, burstlength,
|
||||
threadPayloadID, channelPayloadID);
|
||||
}
|
||||
|
||||
void DramExtension::setPayloadIDs(tlm::tlm_generic_payload *payload, uint64_t threadPayloadID, uint64_t channelPayloadID)
|
||||
{
|
||||
DramExtension *extension;
|
||||
payload->get_extension(extension);
|
||||
extension->threadPayloadID = threadPayloadID;
|
||||
extension->channelPayloadID = channelPayloadID;
|
||||
}
|
||||
|
||||
void DramExtension::setPayloadIDs(tlm::tlm_generic_payload &payload, uint64_t threadPayloadID, uint64_t channelPayloadID)
|
||||
{
|
||||
DramExtension::setPayloadIDs(&payload, threadPayloadID, channelPayloadID);
|
||||
}
|
||||
|
||||
DramExtension &DramExtension::getExtension(const tlm_generic_payload *payload)
|
||||
@@ -179,19 +194,30 @@ Column DramExtension::getColumn(const tlm_generic_payload &payload)
|
||||
return DramExtension::getColumn(&payload);
|
||||
}
|
||||
|
||||
uint64_t DramExtension::getPayloadID(const tlm_generic_payload *payload)
|
||||
uint64_t DramExtension::getThreadPayloadID(const tlm_generic_payload *payload)
|
||||
{
|
||||
return DramExtension::getExtension(payload).getPayloadID();
|
||||
return DramExtension::getExtension(payload).getThreadPayloadID();
|
||||
}
|
||||
|
||||
uint64_t DramExtension::getPayloadID(const tlm_generic_payload &payload)
|
||||
uint64_t DramExtension::getThreadPayloadID(const tlm_generic_payload &payload)
|
||||
{
|
||||
return DramExtension::getPayloadID(&payload);
|
||||
return DramExtension::getThreadPayloadID(&payload);
|
||||
}
|
||||
|
||||
uint64_t DramExtension::getChannelPayloadID(const tlm_generic_payload *payload)
|
||||
{
|
||||
return DramExtension::getExtension(payload).getChannelPayloadID();
|
||||
}
|
||||
|
||||
uint64_t DramExtension::getChannelPayloadID(const tlm_generic_payload &payload)
|
||||
{
|
||||
return DramExtension::getChannelPayloadID(&payload);
|
||||
}
|
||||
|
||||
tlm_extension_base *DramExtension::clone() const
|
||||
{
|
||||
return new DramExtension(thread, channel, rank, bankgroup, bank, row, column, burstlength, payloadID);
|
||||
return new DramExtension(thread, channel, rank, bankgroup, bank, row, column,
|
||||
burstlength, threadPayloadID, channelPayloadID);
|
||||
}
|
||||
|
||||
void DramExtension::copy_from(const tlm_extension_base &ext)
|
||||
@@ -247,9 +273,14 @@ unsigned int DramExtension::getBurstlength() const
|
||||
return burstlength;
|
||||
}
|
||||
|
||||
uint64_t DramExtension::getPayloadID() const
|
||||
uint64_t DramExtension::getThreadPayloadID() const
|
||||
{
|
||||
return payloadID;
|
||||
return threadPayloadID;
|
||||
}
|
||||
|
||||
uint64_t DramExtension::getChannelPayloadID() const
|
||||
{
|
||||
return channelPayloadID;
|
||||
}
|
||||
|
||||
void DramExtension::incrementRow()
|
||||
|
||||
@@ -163,12 +163,10 @@ class DramExtension : public tlm::tlm_extension<DramExtension>
|
||||
{
|
||||
public:
|
||||
DramExtension();
|
||||
DramExtension(Thread thread, Rank rank, BankGroup bankgroup,
|
||||
Bank bank, Row row, Column column,
|
||||
unsigned int burstlength, uint64_t payloadID);
|
||||
DramExtension(Thread thread, Channel channel, Rank rank,
|
||||
BankGroup bankgroup, Bank bank, Row row,
|
||||
Column column, unsigned int burstlength, uint64_t payloadID);
|
||||
Column column, unsigned int burstlength,
|
||||
uint64_t threadPayloadID, uint64_t channelPayloadID);
|
||||
|
||||
virtual tlm::tlm_extension_base *clone() const;
|
||||
virtual void copy_from(const tlm::tlm_extension_base &ext);
|
||||
@@ -176,15 +174,22 @@ 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, uint64_t payloadID);
|
||||
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, uint64_t payloadID);
|
||||
Column column, unsigned int burstlength,
|
||||
uint64_t threadPayloadID, uint64_t channelPayloadID);
|
||||
|
||||
static DramExtension &getExtension(const tlm::tlm_generic_payload *payload);
|
||||
static DramExtension &getExtension(const tlm::tlm_generic_payload &payload);
|
||||
|
||||
static void setPayloadIDs(tlm::tlm_generic_payload *payload,
|
||||
uint64_t threadPayloadID, uint64_t channelPayloadID);
|
||||
static void setPayloadIDs(tlm::tlm_generic_payload &payload,
|
||||
uint64_t threadPayloadID, uint64_t channelPayloadID);
|
||||
|
||||
// Used for convience, caller could also use getExtension(..) to access these field
|
||||
static Thread getThread(const tlm::tlm_generic_payload *payload);
|
||||
static Thread getThread(const tlm::tlm_generic_payload &payload);
|
||||
@@ -200,8 +205,10 @@ 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 uint64_t getPayloadID(const tlm::tlm_generic_payload *payload);
|
||||
static uint64_t getPayloadID(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);
|
||||
static uint64_t getChannelPayloadID(const tlm::tlm_generic_payload &payload);
|
||||
|
||||
Thread getThread() const;
|
||||
Channel getChannel() const;
|
||||
@@ -212,7 +219,8 @@ public:
|
||||
Column getColumn() const;
|
||||
|
||||
unsigned int getBurstlength() const;
|
||||
uint64_t getPayloadID() const;
|
||||
uint64_t getThreadPayloadID() const;
|
||||
uint64_t getChannelPayloadID() const;
|
||||
void incrementRow();
|
||||
|
||||
private:
|
||||
@@ -224,7 +232,8 @@ private:
|
||||
Row row;
|
||||
Column column;
|
||||
unsigned int burstlength;
|
||||
uint64_t payloadID;
|
||||
uint64_t threadPayloadID;
|
||||
uint64_t channelPayloadID;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -74,18 +74,17 @@ std::string getPhaseName(tlm_phase phase)
|
||||
|
||||
json parseJSON(std::string path)
|
||||
{
|
||||
try
|
||||
std::ifstream file(path);
|
||||
if (file.is_open())
|
||||
{
|
||||
// parsing input with a syntax error
|
||||
json j = json::parse(std::ifstream(path));
|
||||
return j;
|
||||
}
|
||||
catch (json::parse_error& e)
|
||||
{
|
||||
// output exception information
|
||||
std::cout << "Error while trying to parse file: " << path << '\n'
|
||||
<< "message: " << e.what() << std::endl;
|
||||
json j = json::parse(file, nullptr, false);
|
||||
if (!j.is_discarded())
|
||||
return j;
|
||||
else
|
||||
throw std::invalid_argument("JSON parse error in file '" + path + "'.");
|
||||
}
|
||||
else
|
||||
throw std::invalid_argument("Failed to open file '" + path + "'.");
|
||||
}
|
||||
|
||||
bool parseBool(json &obj, std::string name)
|
||||
@@ -95,10 +94,10 @@ bool parseBool(json &obj, std::string name)
|
||||
if (obj.is_boolean())
|
||||
return obj;
|
||||
else
|
||||
throw std::invalid_argument("Expected type for '" + name + "': bool");
|
||||
throw std::invalid_argument("Expected type for parameter '" + name + "': bool");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str());
|
||||
throw std::invalid_argument("Parameter '" + name + "' does not exist.");
|
||||
}
|
||||
|
||||
unsigned int parseUint(json &obj, std::string name)
|
||||
@@ -108,10 +107,10 @@ unsigned int parseUint(json &obj, std::string name)
|
||||
if (obj.is_number_unsigned())
|
||||
return obj;
|
||||
else
|
||||
throw std::invalid_argument("Expected type for '" + name + "': unsigned int");
|
||||
throw std::invalid_argument("Expected type for parameter '" + name + "': unsigned int");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str());
|
||||
throw std::invalid_argument("Parameter '" + name + "' does not exist.");
|
||||
}
|
||||
|
||||
double parseUdouble(json &obj, std::string name)
|
||||
@@ -121,10 +120,10 @@ double parseUdouble(json &obj, std::string name)
|
||||
if (obj.is_number() && (obj > 0))
|
||||
return obj;
|
||||
else
|
||||
throw std::invalid_argument("Expected type for '" + name + "': positive double");
|
||||
throw std::invalid_argument("Expected type for parameter '" + name + "': positive double");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str());
|
||||
throw std::invalid_argument("Parameter '" + name + "' does not exist.");
|
||||
}
|
||||
|
||||
std::string parseString(json &obj, std::string name)
|
||||
@@ -134,13 +133,13 @@ std::string parseString(json &obj, std::string name)
|
||||
if (obj.is_string())
|
||||
return obj;
|
||||
else
|
||||
throw std::invalid_argument("Expected type for '" + name + "': string");
|
||||
throw std::invalid_argument("Expected type for parameter '" + name + "': string");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str());
|
||||
throw std::invalid_argument("Parameter '" + name + "' does not exist.");
|
||||
}
|
||||
|
||||
void setUpDummy(tlm_generic_payload &payload, uint64_t payloadID, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
void setUpDummy(tlm_generic_payload &payload, uint64_t channelPayloadID, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
{
|
||||
payload.set_address(bank.getStartAddress());
|
||||
payload.set_command(TLM_READ_COMMAND);
|
||||
@@ -149,6 +148,6 @@ void setUpDummy(tlm_generic_payload &payload, uint64_t payloadID, Rank rank, Ban
|
||||
payload.set_dmi_allowed(false);
|
||||
payload.set_byte_enable_length(0);
|
||||
payload.set_streaming_width(0);
|
||||
payload.set_extension(new DramExtension(Thread(UINT_MAX), rank, bankgroup,
|
||||
bank, Row(0), Column(0), 0, payloadID));
|
||||
payload.set_extension(new DramExtension(Thread(UINT_MAX), Channel(0), rank, bankgroup,
|
||||
bank, Row(0), Column(0), 0, 0, channelPayloadID));
|
||||
}
|
||||
|
||||
@@ -65,43 +65,6 @@ public:
|
||||
constexpr const char headline[] =
|
||||
"===========================================================================";
|
||||
|
||||
static inline void loadbar(unsigned int x,
|
||||
unsigned int n,
|
||||
unsigned int w = 50,
|
||||
unsigned int granularity = 1)
|
||||
{
|
||||
if ((n < 100) || ((x != n) && (x % (n / 100 * granularity) != 0)))
|
||||
return;
|
||||
|
||||
float ratio = x / (float) n;
|
||||
unsigned int c = (ratio * w);
|
||||
float rest = (ratio * w) - c;
|
||||
std::cout << std::setw(3) << round(ratio * 100) << "% |";
|
||||
for (unsigned int x = 0; x < c; x++)
|
||||
std::cout << "█";
|
||||
|
||||
if (rest >= 0 && rest < 0.125 && c != w)
|
||||
std::cout << " ";
|
||||
if (rest >= 0.125 && rest < 2 * 0.125)
|
||||
std::cout << "▏";
|
||||
if (rest >= 2 * 0.125 && rest < 3 * 0.125)
|
||||
std::cout << "▎";
|
||||
if (rest >= 3 * 0.125 && rest < 4 * 0.125)
|
||||
std::cout << "▍";
|
||||
if (rest >= 4 * 0.125 && rest < 5 * 0.125)
|
||||
std::cout << "▌";
|
||||
if (rest >= 5 * 0.125 && rest < 6 * 0.125)
|
||||
std::cout << "▋";
|
||||
if (rest >= 6 * 0.125 && rest < 7 * 0.125)
|
||||
std::cout << "▊";
|
||||
if (rest >= 7 * 0.125 && rest < 8 * 0.125)
|
||||
std::cout << "▉";
|
||||
|
||||
for (unsigned int x = c; x < (w - 1); x++)
|
||||
std::cout << " ";
|
||||
std::cout << "|\r" << std::flush;
|
||||
}
|
||||
|
||||
std::string getPhaseName(tlm::tlm_phase phase);
|
||||
|
||||
nlohmann::json parseJSON(std::string path);
|
||||
@@ -110,7 +73,8 @@ unsigned int parseUint(nlohmann::json &obj, std::string name);
|
||||
double parseUdouble(nlohmann::json &obj, std::string name);
|
||||
std::string parseString(nlohmann::json &obj, std::string name);
|
||||
|
||||
void setUpDummy(tlm::tlm_generic_payload &payload, uint64_t payloadID, Rank rank = Rank(0), BankGroup bankgroup = BankGroup(0), Bank bank = Bank(0));
|
||||
void setUpDummy(tlm::tlm_generic_payload &payload, uint64_t channelPayloadID,
|
||||
Rank rank = Rank(0), BankGroup bankgroup = BankGroup(0), Bank bank = Bank(0));
|
||||
|
||||
#endif // UTILS_H
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "Configuration.h"
|
||||
#include "memspec/MemSpecDDR3.h"
|
||||
#include "memspec/MemSpecDDR4.h"
|
||||
#include "memspec/MemSpecDDR5.h"
|
||||
#include "memspec/MemSpecWideIO.h"
|
||||
#include "memspec/MemSpecLPDDR4.h"
|
||||
#include "memspec/MemSpecWideIO2.h"
|
||||
@@ -81,25 +82,105 @@ void Configuration::setParameter(std::string name, nlohmann::json value)
|
||||
{
|
||||
// MCConfig
|
||||
if (name == "PagePolicy")
|
||||
pagePolicy = value;
|
||||
{
|
||||
if (value == "Open")
|
||||
pagePolicy = PagePolicy::Open;
|
||||
else if (value == "Closed")
|
||||
pagePolicy = PagePolicy::Closed;
|
||||
else if (value == "OpenAdaptive")
|
||||
pagePolicy = PagePolicy::OpenAdaptive;
|
||||
else if (value == "ClosedAdaptive")
|
||||
pagePolicy = PagePolicy::ClosedAdaptive;
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported page policy!");
|
||||
}
|
||||
else if (name == "Scheduler")
|
||||
scheduler = value;
|
||||
{
|
||||
if (value == "Fifo")
|
||||
scheduler = Scheduler::Fifo;
|
||||
else if (value == "FrFcfs")
|
||||
scheduler = Scheduler::FrFcfs;
|
||||
else if (value == "FrFcfsGrp")
|
||||
scheduler = Scheduler::FrFcfsGrp;
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported scheduler!");
|
||||
}
|
||||
else if (name == "SchedulerBuffer")
|
||||
{
|
||||
if (value == "Bankwise")
|
||||
schedulerBuffer = SchedulerBuffer::Bankwise;
|
||||
else if (value == "ReadWrite")
|
||||
schedulerBuffer = SchedulerBuffer::ReadWrite;
|
||||
else if (value == "Shared")
|
||||
schedulerBuffer = SchedulerBuffer::Shared;
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported scheduler buffer!");
|
||||
}
|
||||
else if (name == "RequestBufferSize")
|
||||
{
|
||||
requestBufferSize = value;
|
||||
if (requestBufferSize == 0)
|
||||
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
|
||||
}
|
||||
else if (name == "CmdMux")
|
||||
cmdMux = value;
|
||||
{
|
||||
if (value == "Oldest")
|
||||
cmdMux = CmdMux::Oldest;
|
||||
else if (value == "Strict")
|
||||
cmdMux = CmdMux::Strict;
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported cmd mux!");
|
||||
}
|
||||
else if (name == "RespQueue")
|
||||
respQueue = value;
|
||||
{
|
||||
if (value == "Fifo")
|
||||
respQueue = RespQueue::Fifo;
|
||||
else if (value == "Reorder")
|
||||
respQueue = RespQueue::Reorder;
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported response queue!");
|
||||
}
|
||||
else if (name == "Arbiter")
|
||||
{
|
||||
if (value == "Simple")
|
||||
arbiter = Arbiter::Simple;
|
||||
else if (value == "Fifo")
|
||||
arbiter = Arbiter::Fifo;
|
||||
else if (value == "Reorder")
|
||||
arbiter = Arbiter::Reorder;
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported arbiter!");
|
||||
}
|
||||
else if (name == "RefreshPolicy")
|
||||
refreshPolicy = value;
|
||||
{
|
||||
if (value == "NoRefresh")
|
||||
refreshPolicy = RefreshPolicy::NoRefresh;
|
||||
else if (value == "Rankwise")
|
||||
refreshPolicy = RefreshPolicy::Rankwise;
|
||||
else if (value == "Bankwise")
|
||||
refreshPolicy = RefreshPolicy::Bankwise;
|
||||
else if (value == "Groupwise")
|
||||
refreshPolicy = RefreshPolicy::Groupwise;
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported refresh policy!");
|
||||
}
|
||||
else if (name == "RefreshMaxPostponed")
|
||||
refreshMaxPostponed = value;
|
||||
else if (name == "RefreshMaxPulledin")
|
||||
refreshMaxPulledin = value;
|
||||
else if (name == "PowerDownPolicy")
|
||||
powerDownPolicy = value;
|
||||
{
|
||||
if (value == "NoPowerDown")
|
||||
powerDownPolicy = PowerDownPolicy::NoPowerDown;
|
||||
else if (value == "Staggered")
|
||||
powerDownPolicy = PowerDownPolicy::Staggered;
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported power down policy!");
|
||||
}
|
||||
else if (name == "PowerDownTimeout")
|
||||
powerDownTimeout = value;
|
||||
else if (name == "MaxActiveTransactions")
|
||||
maxActiveTransactions = value;
|
||||
//SimConfig------------------------------------------------
|
||||
else if (name == "SimulationName")
|
||||
simulationName = value;
|
||||
@@ -113,9 +194,7 @@ void Configuration::setParameter(std::string name, nlohmann::json value)
|
||||
{
|
||||
windowSize = value;
|
||||
if (windowSize == 0)
|
||||
SC_REPORT_FATAL("Configuration",
|
||||
("Invalid value for parameter " + name +
|
||||
". This parameter must be at least one.").c_str());
|
||||
SC_REPORT_FATAL("Configuration", "Minimum window size is 1");
|
||||
}
|
||||
else if (name == "Debug")
|
||||
debug = value;
|
||||
@@ -124,26 +203,37 @@ void Configuration::setParameter(std::string name, nlohmann::json value)
|
||||
else if (name == "SimulationProgressBar")
|
||||
simulationProgressBar = value;
|
||||
else if (name == "AddressOffset")
|
||||
{
|
||||
#ifdef DRAMSYS_GEM5
|
||||
addressOffset = value;
|
||||
#else
|
||||
addressOffset = 0;
|
||||
#endif
|
||||
}
|
||||
else if (name == "UseMalloc")
|
||||
useMalloc = value;
|
||||
else if (name == "CheckTLM2Protocol")
|
||||
checkTLM2Protocol = value;
|
||||
else if (name == "ECCControllerMode")
|
||||
ECCMode = value;
|
||||
{
|
||||
if (value == "Disabled")
|
||||
eccMode = ECCMode::Disabled;
|
||||
else if (value == "Hamming")
|
||||
eccMode = ECCMode::Hamming;
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported ECC mode!");
|
||||
}
|
||||
// Specification for ErrorChipSeed, ErrorCSVFile path and StoreMode
|
||||
else if (name == "ErrorChipSeed")
|
||||
errorChipSeed = value;
|
||||
else if (name == "ErrorCSVFile")
|
||||
errorCSVFile = value;
|
||||
else if (name == "StoreMode")
|
||||
storeMode = value;
|
||||
{
|
||||
if (value == "NoStorage")
|
||||
storeMode = StoreMode::NoStorage;
|
||||
else if (value == "Store")
|
||||
storeMode = StoreMode::Store;
|
||||
else if (value == "ErrorModel")
|
||||
storeMode = StoreMode::ErrorModel;
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported store mode!");
|
||||
}
|
||||
|
||||
// Temperature Simulation related
|
||||
else if (name == "TemperatureScale")
|
||||
{
|
||||
@@ -186,80 +276,24 @@ void Configuration::setPathToResources(std::string path)
|
||||
temperatureSim.setPathToResources(path);
|
||||
}
|
||||
|
||||
// Returns the total memory size in bytes
|
||||
std::uint64_t Configuration::getSimMemSizeInBytes()
|
||||
{
|
||||
// 1. Get number of banks, rows, columns and data width in bits for one die (or chip)
|
||||
std::string type = memSpec->memoryType;
|
||||
std::uint64_t ranks = memSpec->numberOfRanks;
|
||||
std::uint64_t bankgroups = memSpec->numberOfBankGroups;
|
||||
std::uint64_t banks = memSpec->numberOfBanks;
|
||||
std::uint64_t rows = memSpec->numberOfRows;
|
||||
std::uint64_t columns = memSpec->numberOfColumns;
|
||||
std::uint64_t bitWidth = memSpec->bitWidth;
|
||||
std::uint64_t devicesOnDIMM = memSpec->numberOfDevicesOnDIMM;
|
||||
// 2. Calculate size of one DRAM chip in bits
|
||||
std::uint64_t chipBitSize = banks * rows * columns * bitWidth;
|
||||
// 3. Calculate size of one DRAM chip in bytes
|
||||
std::uint64_t chipSize = chipBitSize / 8;
|
||||
// 4. Total memory size in Bytes of one DIMM (with only support of 1 rank on a DIMM)
|
||||
std::uint64_t memorySize = chipSize * memSpec->numberOfDevicesOnDIMM;
|
||||
|
||||
std::cout << headline << std::endl;
|
||||
std::cout << "Per Channel Configuration:" << std::endl << std::endl;
|
||||
std::cout << " Memory type: " << type << std::endl;
|
||||
std::cout << " Memory size in bytes: " << memorySize << std::endl;
|
||||
std::cout << " Number of ranks: " << ranks << std::endl;
|
||||
std::cout << " Number of bankgroups: " << bankgroups << std::endl;
|
||||
std::cout << " Number of banks: " << banks << std::endl;
|
||||
std::cout << " Number of rows: " << rows << std::endl;
|
||||
std::cout << " Number of columns: " << columns << std::endl;
|
||||
std::cout << " Chip data bus width: " << bitWidth << std::endl;
|
||||
std::cout << " Chip size in bits: " << chipBitSize << std::endl;
|
||||
std::cout << " Chip Size in bytes: " << chipSize << std::endl;
|
||||
std::cout << " Devices/Chips on DIMM: " << devicesOnDIMM << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
assert(memorySize > 0);
|
||||
return memorySize;
|
||||
}
|
||||
|
||||
// Returns the width of the data bus.
|
||||
// All DRAM chips on a DIMM operate in lockstep,
|
||||
// which constituing aggregate data bus width = chip's bus width * # locksteep-operated chips
|
||||
// The bus width is given in bits, e.g., 64-bit data bus, 128-bit data bus, etc.
|
||||
unsigned int Configuration::getDataBusWidth()
|
||||
{
|
||||
return memSpec->bitWidth * memSpec->numberOfDevicesOnDIMM;
|
||||
}
|
||||
|
||||
// Returns the number of bytes transfered in a burst
|
||||
unsigned int Configuration::getBytesPerBurst()
|
||||
{
|
||||
return (memSpec->burstLength * getDataBusWidth()) / 8;
|
||||
}
|
||||
|
||||
// Changes the number of bytes depeding on the ECC Controller. This function is needed for modules which get data directly or indirectly from the ECC Controller
|
||||
unsigned int Configuration::adjustNumBytesAfterECC(unsigned nBytes)
|
||||
{
|
||||
// Manipulate the number of bytes only if there is an ECC Controller selected
|
||||
if (ECCMode == "Disabled")
|
||||
if (eccMode == ECCMode::Disabled)
|
||||
return nBytes;
|
||||
else if (ECCMode == "Hamming")
|
||||
else // if (eccMode == ECCMode::Hamming)
|
||||
{
|
||||
assert(pECC != nullptr);
|
||||
return pECC->AllocationSize(nBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("Configuration", ("ECC mode " + ECCMode + " unsupported").c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::loadSimConfig(Configuration &config, std::string simconfigUri)
|
||||
{
|
||||
json doc = parseJSON(simconfigUri);
|
||||
if (doc["simconfig"].empty())
|
||||
SC_REPORT_FATAL("Configuration", "simconfig is empty.");
|
||||
for (auto& x : doc["simconfig"].items())
|
||||
config.setParameter(x.key(), x.value());
|
||||
}
|
||||
@@ -267,6 +301,8 @@ void Configuration::loadSimConfig(Configuration &config, std::string simconfigUr
|
||||
void Configuration::loadTemperatureSimConfig(Configuration &config, std::string thermalsimconfigUri)
|
||||
{
|
||||
json doc = parseJSON(thermalsimconfigUri);
|
||||
if (doc["thermalsimconfig"].empty())
|
||||
SC_REPORT_FATAL("Configuration", "thermalsimconfig is empty.");
|
||||
for (auto& x : doc["thermalsimconfig"].items())
|
||||
config.setParameter(x.key(), x.value());
|
||||
}
|
||||
@@ -275,6 +311,8 @@ void Configuration::loadMCConfig(Configuration &config, std::string mcconfigUri)
|
||||
{
|
||||
config.mcconfigUri = mcconfigUri;
|
||||
json doc = parseJSON(mcconfigUri);
|
||||
if (doc["mcconfig"].empty())
|
||||
SC_REPORT_FATAL("Configuration", "mcconfig is empty.");
|
||||
for (auto& x : doc["mcconfig"].items())
|
||||
config.setParameter(x.key(), x.value());
|
||||
}
|
||||
@@ -291,6 +329,8 @@ void Configuration::loadMemSpec(Configuration &config, std::string memspecUri)
|
||||
memSpec = new MemSpecDDR3(jMemSpec);
|
||||
else if (memoryType == "DDR4")
|
||||
memSpec = new MemSpecDDR4(jMemSpec);
|
||||
else if (memoryType == "DDR5")
|
||||
memSpec = new MemSpecDDR5(jMemSpec);
|
||||
else if (memoryType == "LPDDR4")
|
||||
memSpec = new MemSpecLPDDR4(jMemSpec);
|
||||
else if (memoryType == "WIDEIO_SDR")
|
||||
|
||||
@@ -69,16 +69,19 @@ public:
|
||||
std::string pathToResources;
|
||||
|
||||
// MCConfig:
|
||||
std::string pagePolicy = "Open";
|
||||
std::string scheduler = "Fifo";
|
||||
std::string cmdMux = "Oldest";
|
||||
std::string respQueue = "Fifo";
|
||||
enum class PagePolicy {Open, Closed, OpenAdaptive, ClosedAdaptive} pagePolicy;
|
||||
enum class Scheduler {Fifo, FrFcfs, FrFcfsGrp} scheduler;
|
||||
enum class SchedulerBuffer {Bankwise, ReadWrite, Shared} schedulerBuffer;
|
||||
enum class CmdMux {Oldest, Strict} cmdMux;
|
||||
enum class RespQueue {Fifo, Reorder} respQueue;
|
||||
enum class Arbiter {Simple, Fifo, Reorder} arbiter;
|
||||
unsigned int requestBufferSize = 8;
|
||||
std::string refreshPolicy = "Rankwise";
|
||||
enum class RefreshPolicy {NoRefresh, Rankwise, Bankwise, Groupwise} refreshPolicy;
|
||||
unsigned int refreshMaxPostponed = 0;
|
||||
unsigned int refreshMaxPulledin = 0;
|
||||
std::string powerDownPolicy = "NoPowerDown";
|
||||
enum class PowerDownPolicy {NoPowerDown, Staggered} powerDownPolicy;
|
||||
unsigned int powerDownTimeout = 3;
|
||||
unsigned int maxActiveTransactions = 64;
|
||||
|
||||
// SimConfig
|
||||
std::string simulationName = "default";
|
||||
@@ -90,7 +93,7 @@ public:
|
||||
bool thermalSimulation = false;
|
||||
bool simulationProgressBar = false;
|
||||
bool checkTLM2Protocol = false;
|
||||
std::string ECCMode = "Disabled";
|
||||
enum class ECCMode {Disabled, Hamming} eccMode;
|
||||
ECCBaseClass *pECC = nullptr;
|
||||
bool gem5 = false;
|
||||
bool useMalloc = false;
|
||||
@@ -104,14 +107,11 @@ public:
|
||||
//Configs for Seed, csv file and StorageMode
|
||||
unsigned int errorChipSeed;
|
||||
std::string errorCSVFile = "not defined.";
|
||||
std::string storeMode;
|
||||
enum class StoreMode {NoStorage, Store, ErrorModel} storeMode;
|
||||
|
||||
// Temperature Simulation related
|
||||
TemperatureSimConfig temperatureSim;
|
||||
|
||||
std::uint64_t getSimMemSizeInBytes();
|
||||
unsigned int getDataBusWidth();
|
||||
unsigned int getBytesPerBurst();
|
||||
unsigned int adjustNumBytesAfterECC(unsigned bytes);
|
||||
void setPathToResources(std::string path);
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpec::MemSpec(json &memspec, unsigned numberOfChannels,
|
||||
MemSpec::MemSpec(json &memspec, MemoryType memoryType,
|
||||
unsigned numberOfChannels,
|
||||
unsigned numberOfRanks, unsigned banksPerRank,
|
||||
unsigned groupsPerRank, unsigned banksPerGroup,
|
||||
unsigned numberOfBanks, unsigned numberOfBankGroups,
|
||||
@@ -61,10 +62,12 @@ MemSpec::MemSpec(json &memspec, unsigned numberOfChannels,
|
||||
burstLength(parseUint(memspec["memarchitecturespec"]["burstLength"],"burstLength")),
|
||||
dataRate(parseUint(memspec["memarchitecturespec"]["dataRate"],"dataRate")),
|
||||
bitWidth(parseUint(memspec["memarchitecturespec"]["width"],"width")),
|
||||
dataBusWidth(bitWidth * numberOfDevicesOnDIMM),
|
||||
bytesPerBurst((burstLength * dataBusWidth) / 8),
|
||||
fCKMHz(parseUdouble(memspec["memtimingspec"]["clkMhz"], "clkMhz")),
|
||||
tCK(sc_time(1.0 / fCKMHz, SC_US)),
|
||||
memoryId(parseString(memspec["memoryId"], "memoryId")),
|
||||
memoryType(parseString(memspec["memoryType"], "memoryType")),
|
||||
memoryType(memoryType),
|
||||
burstDuration(tCK * (burstLength / dataRate))
|
||||
{
|
||||
commandLengthInCycles = std::vector<unsigned>(numberOfCommands(), 1);
|
||||
@@ -74,3 +77,21 @@ sc_time MemSpec::getCommandLength(Command command) const
|
||||
{
|
||||
return tCK * commandLengthInCycles[command];
|
||||
}
|
||||
|
||||
sc_time MemSpec::getRefreshIntervalAB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "All bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
sc_time MemSpec::getRefreshIntervalPB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "Per bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
sc_time MemSpec::getRefreshIntervalSB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "Same bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
@@ -48,39 +48,44 @@
|
||||
class MemSpec
|
||||
{
|
||||
public:
|
||||
unsigned numberOfChannels;
|
||||
unsigned numberOfRanks;
|
||||
unsigned banksPerRank;
|
||||
unsigned groupsPerRank;
|
||||
unsigned banksPerGroup;
|
||||
unsigned numberOfBanks;
|
||||
unsigned numberOfBankGroups;
|
||||
unsigned numberOfDevicesOnDIMM;
|
||||
unsigned numberOfRows;
|
||||
unsigned numberOfColumns;
|
||||
unsigned burstLength;
|
||||
unsigned dataRate;
|
||||
unsigned bitWidth;
|
||||
const unsigned numberOfChannels;
|
||||
const unsigned numberOfRanks;
|
||||
const unsigned banksPerRank;
|
||||
const unsigned groupsPerRank;
|
||||
const unsigned banksPerGroup;
|
||||
const unsigned numberOfBanks;
|
||||
const unsigned numberOfBankGroups;
|
||||
const unsigned numberOfDevicesOnDIMM;
|
||||
const unsigned numberOfRows;
|
||||
const unsigned numberOfColumns;
|
||||
const unsigned burstLength;
|
||||
const unsigned dataRate;
|
||||
const unsigned bitWidth;
|
||||
const unsigned dataBusWidth;
|
||||
const unsigned bytesPerBurst;
|
||||
|
||||
// Clock
|
||||
double fCKMHz;
|
||||
sc_time tCK;
|
||||
const double fCKMHz;
|
||||
const sc_time tCK;
|
||||
|
||||
std::string memoryId;
|
||||
std::string memoryType;
|
||||
const std::string memoryId;
|
||||
const enum class MemoryType {DDR3, DDR4, DDR5, LPDDR4, WideIO, WideIO2, GDDR5, GDDR5X, GDDR6, HBM2} memoryType;
|
||||
|
||||
virtual ~MemSpec() {}
|
||||
|
||||
virtual sc_time getRefreshIntervalAB() const = 0;
|
||||
virtual sc_time getRefreshIntervalPB() const = 0;
|
||||
virtual sc_time getRefreshIntervalAB() const;
|
||||
virtual sc_time getRefreshIntervalPB() const;
|
||||
virtual sc_time getRefreshIntervalSB() const;
|
||||
|
||||
virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const = 0;
|
||||
virtual TimeInterval getIntervalOnDataStrobe(Command) const = 0;
|
||||
|
||||
sc_time getCommandLength(Command) const;
|
||||
virtual uint64_t getSimMemSizeInBytes() const = 0;
|
||||
|
||||
protected:
|
||||
MemSpec(nlohmann::json &memspec, unsigned numberOfChannels,
|
||||
MemSpec(nlohmann::json &memspec, MemoryType memoryType,
|
||||
unsigned numberOfChannels,
|
||||
unsigned numberOfRanks, unsigned banksPerRank,
|
||||
unsigned groupsPerRank, unsigned banksPerGroup,
|
||||
unsigned numberOfBanks, unsigned numberOfBankGroups,
|
||||
|
||||
@@ -39,7 +39,7 @@ using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecDDR3::MemSpecDDR3(json &memspec)
|
||||
: MemSpec(memspec,
|
||||
: MemSpec(memspec, MemoryType::DDR3,
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
|
||||
@@ -95,12 +95,6 @@ sc_time MemSpecDDR3::getRefreshIntervalAB() const
|
||||
return tREFI;
|
||||
}
|
||||
|
||||
sc_time MemSpecDDR3::getRefreshIntervalPB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecDDR3", "Per bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
// Returns the execution time for commands that have a fixed execution time
|
||||
sc_time MemSpecDDR3::getExecutionTime(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
@@ -138,3 +132,27 @@ TimeInterval MemSpecDDR3::getIntervalOnDataStrobe(Command command) const
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MemSpecDDR3::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: " << "DDR3" << 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;
|
||||
}
|
||||
|
||||
@@ -88,10 +88,11 @@ public:
|
||||
const double iDD3P1;
|
||||
|
||||
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 uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECDDR3_H
|
||||
|
||||
@@ -40,7 +40,7 @@ using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecDDR4::MemSpecDDR4(json &memspec)
|
||||
: MemSpec(memspec,
|
||||
: MemSpec(memspec, MemoryType::DDR4,
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
|
||||
@@ -55,19 +55,17 @@ MemSpecDDR4::MemSpecDDR4(json &memspec)
|
||||
tCKE (tCK * parseUint(memspec["memtimingspec"]["CKE"], "CKE")),
|
||||
tPD (tCKE),
|
||||
tCKESR (tCK * parseUint(memspec["memtimingspec"]["CKESR"], "CKESR")),
|
||||
tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")),
|
||||
tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")),
|
||||
tRC (tCK * parseUint(memspec["memtimingspec"]["RC"], "RC")),
|
||||
tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")),
|
||||
tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")),
|
||||
tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")),
|
||||
tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")),
|
||||
tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")),
|
||||
tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")),
|
||||
tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")),
|
||||
tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")),
|
||||
tXS (tCK * parseUint(memspec["memtimingspec"]["XS"], "XS")),
|
||||
tCCD_S (tCK * parseUint(memspec["memtimingspec"]["CCD_S"], "CCD_S")),
|
||||
tCCD_L (tCK * parseUint(memspec["memtimingspec"]["CCD_L"], "CCD_L")),
|
||||
tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")),
|
||||
tREFI ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 4) ?
|
||||
(tCK * (parseUint(memspec["memtimingspec"]["REFI"], "REFI") / 4)) :
|
||||
((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 2) ?
|
||||
@@ -79,6 +77,10 @@ MemSpecDDR4::MemSpecDDR4(json &memspec)
|
||||
(tCK * parseUint(memspec["memtimingspec"]["RFC2"], "RFC2")) :
|
||||
(tCK * parseUint(memspec["memtimingspec"]["RFC"], "RFC")))),
|
||||
tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")),
|
||||
tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")),
|
||||
tCCD_S (tCK * parseUint(memspec["memtimingspec"]["CCD_S"], "CCD_S")),
|
||||
tCCD_L (tCK * parseUint(memspec["memtimingspec"]["CCD_L"], "CCD_L")),
|
||||
tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")),
|
||||
tRRD_S (tCK * parseUint(memspec["memtimingspec"]["RRD_S"], "RRD_S")),
|
||||
tRRD_L (tCK * parseUint(memspec["memtimingspec"]["RRD_L"], "RRD_L")),
|
||||
tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")),
|
||||
@@ -112,12 +114,6 @@ sc_time MemSpecDDR4::getRefreshIntervalAB() const
|
||||
return tREFI;
|
||||
}
|
||||
|
||||
sc_time MemSpecDDR4::getRefreshIntervalPB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecDDR4", "Per bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
// Returns the execution time for commands that have a fixed execution time
|
||||
sc_time MemSpecDDR4::getExecutionTime(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
@@ -155,3 +151,28 @@ TimeInterval MemSpecDDR4::getIntervalOnDataStrobe(Command command) const
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MemSpecDDR4::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: " << "DDR4" << std::endl;
|
||||
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
|
||||
std::cout << " Ranks: " << numberOfRanks << std::endl;
|
||||
std::cout << " Bank groups per rank: " << groupsPerRank << 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;
|
||||
}
|
||||
|
||||
@@ -52,8 +52,10 @@ public:
|
||||
const sc_time tRC;
|
||||
const sc_time tRCD;
|
||||
const sc_time tRL;
|
||||
const sc_time tRPRE;
|
||||
const sc_time tRTP;
|
||||
const sc_time tWL;
|
||||
const sc_time tWPRE;
|
||||
const sc_time tWR;
|
||||
const sc_time tXP;
|
||||
const sc_time tXS;
|
||||
@@ -93,11 +95,12 @@ public:
|
||||
const double iDD62;
|
||||
const double vDD2;
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
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 uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECDDR4_H
|
||||
|
||||
224
DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp
Normal file
224
DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "MemSpecDDR5.h"
|
||||
#include "../Configuration.h"
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecDDR5::MemSpecDDR5(json &memspec)
|
||||
: MemSpec(memspec, MemoryType::DDR5,
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks")
|
||||
/ parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks")
|
||||
* parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups")
|
||||
* parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfDevicesOnDIMM"],"nbrOfDevicesOnDIMM")),
|
||||
numberOfDIMMRanks(parseUint(memspec["memarchitecturespec"]["nbrOfDIMMRanks"], "nbrOfDIMMRanks")),
|
||||
physicalRanksPerDIMMRank(parseUint(memspec["memarchitecturespec"]["nbrOfPhysicalRanks"], "nbrOfPhysicalRanks")),
|
||||
numberOfPhysicalRanks(physicalRanksPerDIMMRank * numberOfDIMMRanks),
|
||||
logicalRanksPerPhysicalRank(parseUint(memspec["memarchitecturespec"]["nbrOfLogicalRanks"], "nbrOfLogicalRanks")),
|
||||
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)
|
||||
{
|
||||
if (cmdMode == 1)
|
||||
{
|
||||
commandLengthInCycles[Command::ACT] = 2;
|
||||
commandLengthInCycles[Command::RD] = 2;
|
||||
commandLengthInCycles[Command::RDA] = 2;
|
||||
commandLengthInCycles[Command::WR] = 2;
|
||||
commandLengthInCycles[Command::WRA] = 2;
|
||||
}
|
||||
else if (cmdMode == 2)
|
||||
{
|
||||
commandLengthInCycles[Command::ACT] = 4;
|
||||
commandLengthInCycles[Command::PRE] = 2;
|
||||
commandLengthInCycles[Command::PREA] = 2;
|
||||
commandLengthInCycles[Command::PRESB] = 2;
|
||||
commandLengthInCycles[Command::RD] = 4;
|
||||
commandLengthInCycles[Command::RDA] = 4;
|
||||
commandLengthInCycles[Command::WR] = 4;
|
||||
commandLengthInCycles[Command::WRA] = 4;
|
||||
commandLengthInCycles[Command::REFA] = 2;
|
||||
commandLengthInCycles[Command::REFSB] = 2;
|
||||
commandLengthInCycles[Command::PDEA] = 2;
|
||||
commandLengthInCycles[Command::PDXA] = 2;
|
||||
commandLengthInCycles[Command::PDEP] = 2;
|
||||
commandLengthInCycles[Command::PDXP] = 2;
|
||||
commandLengthInCycles[Command::SREFEN] = 2;
|
||||
commandLengthInCycles[Command::SREFEX] = 2;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("MemSpecDDR5", "Invalid command mode!");
|
||||
|
||||
if (!(refMode == 1 || refMode == 2))
|
||||
SC_REPORT_FATAL("MemSpecDDR5", "Invalid refresh mode! "
|
||||
"Set 1 for normal or 2 for fine granularity refresh mode.");
|
||||
}
|
||||
|
||||
sc_time MemSpecDDR5::getRefreshIntervalAB() const
|
||||
{
|
||||
return tREFI;
|
||||
}
|
||||
|
||||
sc_time MemSpecDDR5::getRefreshIntervalSB() const
|
||||
{
|
||||
return tREFIsb;
|
||||
}
|
||||
|
||||
// Returns the execution time for commands that have a fixed execution time
|
||||
sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
if (command == Command::PRE || command == Command::PREA || command == Command::PRESB)
|
||||
return tRP + cmdOffset_S;
|
||||
else if (command == Command::ACT)
|
||||
return tRCD + cmdOffset_L;
|
||||
else if (command == Command::RD)
|
||||
return tRL + burstDuration + cmdOffset_L;
|
||||
else if (command == Command::RDA)
|
||||
return tRTP + tRP + cmdOffset_L;
|
||||
else if (command == Command::WR)
|
||||
return tWL + burstDuration + cmdOffset_L;
|
||||
else if (command == Command::WRA)
|
||||
return tWL + burstDuration + tWR + tRP + cmdOffset_L;
|
||||
else if (command == Command::REFA)
|
||||
return tRFC_slr + cmdOffset_S;
|
||||
else if (command == Command::REFSB)
|
||||
return tRFCsb_slr + cmdOffset_S;
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("getExecutionTime",
|
||||
"command not known or command doesn't have a fixed execution time");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command) const
|
||||
{
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
return TimeInterval(sc_time_stamp() + tRL + cmdOffset_L, sc_time_stamp() + tRL + burstDuration + cmdOffset_L);
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
return TimeInterval(sc_time_stamp() + tWL + cmdOffset_L, sc_time_stamp() + tWL + burstDuration + cmdOffset_L);
|
||||
else
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MemSpecDDR5::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: " << "DDR5" << std::endl;
|
||||
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
|
||||
std::cout << " DIMMs: " << numberOfDIMMRanks << std::endl;
|
||||
std::cout << " Physical Ranks per DIMM: " << physicalRanksPerDIMMRank << std::endl;
|
||||
std::cout << " Logical Ranks per device: " << logicalRanksPerPhysicalRank << std::endl;
|
||||
std::cout << " Ranks: " << numberOfRanks << std::endl;
|
||||
std::cout << " Bank groups per rank: " << groupsPerRank << 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;
|
||||
}
|
||||
117
DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h
Normal file
117
DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef MEMSPECDDR5_H
|
||||
#define MEMSPECDDR5_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
class MemSpecDDR5 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
MemSpecDDR5(nlohmann::json &memspec);
|
||||
|
||||
const unsigned numberOfDIMMRanks;
|
||||
const unsigned physicalRanksPerDIMMRank;
|
||||
const unsigned numberOfPhysicalRanks;
|
||||
const unsigned logicalRanksPerPhysicalRank;
|
||||
const unsigned numberOfLogicalRanks;
|
||||
const unsigned cmdMode;
|
||||
const unsigned refMode;
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_time tRCD;
|
||||
const sc_time tPPD;
|
||||
const sc_time tRP;
|
||||
const sc_time tRAS;
|
||||
const sc_time tRC;
|
||||
const sc_time tRL;
|
||||
const sc_time tRTP;
|
||||
const sc_time tRPRE;
|
||||
const sc_time tRPST;
|
||||
const sc_time tRDDQS;
|
||||
const sc_time tWL;
|
||||
const sc_time tWPRE;
|
||||
const sc_time tWPST;
|
||||
const sc_time tWR;
|
||||
const sc_time tCCD_L_slr;
|
||||
const sc_time tCCD_L_WR_slr;
|
||||
const sc_time tCCD_S_slr;
|
||||
const sc_time tCCD_S_WR_slr;
|
||||
const sc_time tCCD_dlr;
|
||||
const sc_time tCCD_WR_dlr;
|
||||
const sc_time tCCD_WR_dpr;
|
||||
const sc_time tRRD_L_slr;
|
||||
const sc_time tRRD_S_slr;
|
||||
const sc_time tRRD_dlr;
|
||||
const sc_time tFAW_slr;
|
||||
const sc_time tFAW_dlr;
|
||||
const sc_time tWTR_L;
|
||||
const sc_time tWTR_S;
|
||||
const sc_time tRFC_slr;
|
||||
const sc_time tRFC_dlr;
|
||||
const sc_time tRFC_dpr;
|
||||
const sc_time tRFCsb_slr;
|
||||
const sc_time tRFCsb_dlr;
|
||||
const sc_time tREFI;
|
||||
const sc_time tREFIsb;
|
||||
const sc_time tREFSBRD_slr;
|
||||
const sc_time tREFSBRD_dlr;
|
||||
const sc_time tRTRS;
|
||||
|
||||
const sc_time tCPDED;
|
||||
const sc_time tPD;
|
||||
const sc_time tXP;
|
||||
const sc_time tACTPDEN;
|
||||
const sc_time tPRPDEN;
|
||||
const sc_time tREFPDEN;
|
||||
|
||||
const sc_time cmdOffset_S;
|
||||
const sc_time cmdOffset_L;
|
||||
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
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 uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECDDR5_H
|
||||
@@ -39,7 +39,7 @@ using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecGDDR5::MemSpecGDDR5(json &memspec)
|
||||
: MemSpec(memspec,
|
||||
: MemSpec(memspec, MemoryType::GDDR5,
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
|
||||
@@ -142,3 +142,27 @@ TimeInterval MemSpecGDDR5::getIntervalOnDataStrobe(Command command) const
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MemSpecGDDR5::getSimMemSizeInBytes() const
|
||||
{
|
||||
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
|
||||
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
||||
uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks;
|
||||
|
||||
std::cout << headline << std::endl;
|
||||
std::cout << "Per Channel Configuration:" << std::endl << std::endl;
|
||||
std::cout << " Memory type: " << "GDDR5" << std::endl;
|
||||
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
|
||||
std::cout << " Ranks: " << numberOfRanks << std::endl;
|
||||
std::cout << " Bank groups per rank: " << groupsPerRank << 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 << std::endl;
|
||||
|
||||
assert(memorySizeBytes > 0);
|
||||
return memorySizeBytes;
|
||||
}
|
||||
|
||||
@@ -85,11 +85,13 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
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 uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECGDDR5_H
|
||||
|
||||
@@ -39,7 +39,7 @@ using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecGDDR5X::MemSpecGDDR5X(json &memspec)
|
||||
: MemSpec(memspec,
|
||||
: MemSpec(memspec, MemoryType::GDDR5X,
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
|
||||
@@ -142,3 +142,27 @@ TimeInterval MemSpecGDDR5X::getIntervalOnDataStrobe(Command command) const
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MemSpecGDDR5X::getSimMemSizeInBytes() const
|
||||
{
|
||||
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
|
||||
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
||||
uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks;
|
||||
|
||||
std::cout << headline << std::endl;
|
||||
std::cout << "Per Channel Configuration:" << std::endl << std::endl;
|
||||
std::cout << " Memory type: " << "GDDR5X" << std::endl;
|
||||
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
|
||||
std::cout << " Ranks: " << numberOfRanks << std::endl;
|
||||
std::cout << " Bank groups per rank: " << groupsPerRank << 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 << std::endl;
|
||||
|
||||
assert(memorySizeBytes > 0);
|
||||
return memorySizeBytes;
|
||||
}
|
||||
|
||||
@@ -85,11 +85,13 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
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 uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECGDDR5X_H
|
||||
|
||||
@@ -39,7 +39,7 @@ using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecGDDR6::MemSpecGDDR6(json &memspec)
|
||||
: MemSpec(memspec,
|
||||
: MemSpec(memspec, MemoryType::GDDR6,
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
|
||||
@@ -144,3 +144,27 @@ TimeInterval MemSpecGDDR6::getIntervalOnDataStrobe(Command command) const
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MemSpecGDDR6::getSimMemSizeInBytes() const
|
||||
{
|
||||
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
|
||||
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
||||
uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks;
|
||||
|
||||
std::cout << headline << std::endl;
|
||||
std::cout << "Per Channel Configuration:" << std::endl << std::endl;
|
||||
std::cout << " Memory type: " << "GDDR6" << std::endl;
|
||||
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
|
||||
std::cout << " Ranks: " << numberOfRanks << std::endl;
|
||||
std::cout << " Bank groups per rank: " << groupsPerRank << 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 << std::endl;
|
||||
|
||||
assert(memorySizeBytes > 0);
|
||||
return memorySizeBytes;
|
||||
}
|
||||
|
||||
@@ -87,11 +87,13 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
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 uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECGDDR6_H
|
||||
|
||||
@@ -39,7 +39,7 @@ using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecHBM2::MemSpecHBM2(json &memspec)
|
||||
: MemSpec(memspec,
|
||||
: MemSpec(memspec, MemoryType::HBM2,
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
|
||||
@@ -139,3 +139,27 @@ TimeInterval MemSpecHBM2::getIntervalOnDataStrobe(Command command) const
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MemSpecHBM2::getSimMemSizeInBytes() const
|
||||
{
|
||||
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
|
||||
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
||||
uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks;
|
||||
|
||||
std::cout << headline << std::endl;
|
||||
std::cout << "Per Channel Configuration:" << std::endl << std::endl;
|
||||
std::cout << " Memory type: " << "HBM2" << std::endl;
|
||||
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
|
||||
std::cout << " Ranks: " << numberOfRanks << std::endl;
|
||||
std::cout << " Bank groups per rank: " << groupsPerRank << 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 << std::endl;
|
||||
|
||||
assert(memorySizeBytes > 0);
|
||||
return memorySizeBytes;
|
||||
}
|
||||
|
||||
@@ -80,11 +80,13 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
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 uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECHBM2_H
|
||||
|
||||
@@ -39,7 +39,7 @@ using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecLPDDR4::MemSpecLPDDR4(json &memspec)
|
||||
: MemSpec(memspec,
|
||||
: MemSpec(memspec, MemoryType::LPDDR4,
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
|
||||
@@ -147,3 +147,26 @@ TimeInterval MemSpecLPDDR4::getIntervalOnDataStrobe(Command command) const
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MemSpecLPDDR4::getSimMemSizeInBytes() const
|
||||
{
|
||||
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
|
||||
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
||||
uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks;
|
||||
|
||||
std::cout << headline << std::endl;
|
||||
std::cout << "Per Channel Configuration:" << std::endl << std::endl;
|
||||
std::cout << " Memory type: " << "GDDR5" << 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 << std::endl;
|
||||
|
||||
assert(memorySizeBytes > 0);
|
||||
return memorySizeBytes;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,11 +80,13 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
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 uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECLPDDR4_H
|
||||
|
||||
@@ -39,7 +39,7 @@ using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecWideIO::MemSpecWideIO(json &memspec)
|
||||
: MemSpec(memspec,
|
||||
: MemSpec(memspec, MemoryType::WideIO,
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
|
||||
@@ -101,12 +101,6 @@ sc_time MemSpecWideIO::getRefreshIntervalAB() const
|
||||
return tREFI;
|
||||
}
|
||||
|
||||
sc_time MemSpecWideIO::getRefreshIntervalPB() const
|
||||
{
|
||||
SC_REPORT_FATAL("MemSpecWideIO", "Per bank refresh not supported");
|
||||
return SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
// Returns the execution time for commands that have a fixed execution time
|
||||
sc_time MemSpecWideIO::getExecutionTime(Command command, const tlm_generic_payload &) const
|
||||
{
|
||||
@@ -146,3 +140,26 @@ TimeInterval MemSpecWideIO::getIntervalOnDataStrobe(Command command) const
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MemSpecWideIO::getSimMemSizeInBytes() const
|
||||
{
|
||||
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
|
||||
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
||||
uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks;
|
||||
|
||||
std::cout << headline << std::endl;
|
||||
std::cout << "Per Channel Configuration:" << std::endl << std::endl;
|
||||
std::cout << " Memory type: " << "GDDR5" << 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 << std::endl;
|
||||
|
||||
assert(memorySizeBytes > 0);
|
||||
return memorySizeBytes;
|
||||
}
|
||||
|
||||
@@ -93,11 +93,12 @@ public:
|
||||
const double iDD62;
|
||||
const double vDD2;
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
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 uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECWIDEIO_H
|
||||
|
||||
@@ -39,7 +39,7 @@ using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecWideIO2::MemSpecWideIO2(json &memspec)
|
||||
: MemSpec(memspec,
|
||||
: MemSpec(memspec, MemoryType::WideIO2,
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
|
||||
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
|
||||
@@ -69,9 +69,9 @@ MemSpecWideIO2::MemSpecWideIO2(json &memspec)
|
||||
tWTR (tCK * parseUint(memspec["memtimingspec"]["WTR"], "WTR")),
|
||||
tRRD (tCK * parseUint(memspec["memtimingspec"]["RRD"], "RRD")),
|
||||
tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")),
|
||||
tREFI (tCK * (unsigned)(parseUint(memspec["memtimingspec"]["REFI"], "REFI")
|
||||
tREFI (tCK * static_cast<unsigned>(parseUint(memspec["memtimingspec"]["REFI"], "REFI")
|
||||
* parseUdouble(memspec["memtimingspec"]["REFM"], "REFM"))),
|
||||
tREFIpb (tCK * (unsigned)(parseUint(memspec["memtimingspec"]["REFIPB"], "REFIPB")
|
||||
tREFIpb (tCK * static_cast<unsigned>(parseUint(memspec["memtimingspec"]["REFIPB"], "REFIPB")
|
||||
* parseUdouble(memspec["memtimingspec"]["REFM"], "REFM"))),
|
||||
tRFCab (tCK * parseUint(memspec["memtimingspec"]["RFCAB"], "RFCAB")),
|
||||
tRFCpb (tCK * parseUint(memspec["memtimingspec"]["RFCPB"], "RFCPB")),
|
||||
@@ -131,3 +131,26 @@ TimeInterval MemSpecWideIO2::getIntervalOnDataStrobe(Command command) const
|
||||
return TimeInterval();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MemSpecWideIO2::getSimMemSizeInBytes() const
|
||||
{
|
||||
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * numberOfRows * numberOfColumns * bitWidth;
|
||||
uint64_t deviceSizeBytes = deviceSizeBits / 8;
|
||||
uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks;
|
||||
|
||||
std::cout << headline << std::endl;
|
||||
std::cout << "Per Channel Configuration:" << std::endl << std::endl;
|
||||
std::cout << " Memory type: " << "GDDR5" << 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 << std::endl;
|
||||
|
||||
assert(memorySizeBytes > 0);
|
||||
return memorySizeBytes;
|
||||
}
|
||||
|
||||
@@ -74,11 +74,13 @@ public:
|
||||
// Currents and Voltages:
|
||||
// TODO: to be completed
|
||||
|
||||
virtual sc_time getRefreshIntervalPB() const override;
|
||||
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 uint64_t getSimMemSizeInBytes() const override;
|
||||
};
|
||||
|
||||
#endif // MEMSPECWIDEIO2_H
|
||||
|
||||
@@ -55,23 +55,23 @@ void BankMachine::updateState(Command command)
|
||||
switch (command)
|
||||
{
|
||||
case Command::ACT:
|
||||
currentState = BmState::Activated;
|
||||
currentRow = DramExtension::getRow(currentPayload);
|
||||
state = State::Activated;
|
||||
openRow = DramExtension::getRow(currentPayload);
|
||||
break;
|
||||
case Command::PRE: case Command::PREA:
|
||||
currentState = BmState::Precharged;
|
||||
case Command::PRE: case Command::PREA: case Command::PRESB:
|
||||
state = State::Precharged;
|
||||
break;
|
||||
case Command::RD: case Command::WR:
|
||||
currentPayload = nullptr;
|
||||
break;
|
||||
case Command::RDA: case Command::WRA:
|
||||
currentState = BmState::Precharged;
|
||||
state = State::Precharged;
|
||||
currentPayload = nullptr;
|
||||
break;
|
||||
case Command::PDEA: case Command::PDEP: case Command::SREFEN:
|
||||
sleeping = true;
|
||||
break;
|
||||
case Command::REFA: case Command::REFB:
|
||||
case Command::REFA: case Command::REFB: case Command::REFSB:
|
||||
sleeping = false;
|
||||
blocked = false;
|
||||
break;
|
||||
@@ -105,12 +105,12 @@ Bank BankMachine::getBank()
|
||||
|
||||
Row BankMachine::getOpenRow()
|
||||
{
|
||||
return currentRow;
|
||||
return openRow;
|
||||
}
|
||||
|
||||
BmState BankMachine::getState()
|
||||
BankMachine::State BankMachine::getState()
|
||||
{
|
||||
return currentState;
|
||||
return state;
|
||||
}
|
||||
|
||||
bool BankMachine::isIdle()
|
||||
@@ -133,14 +133,14 @@ sc_time BankMachineOpen::start()
|
||||
if (currentPayload == nullptr)
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
if (state == State::Precharged && !blocked) // row miss
|
||||
{
|
||||
nextCommand = Command::ACT;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
else if (state == State::Activated)
|
||||
{
|
||||
if (DramExtension::getRow(currentPayload) == currentRow) // row hit
|
||||
if (DramExtension::getRow(currentPayload) == openRow) // row hit
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
nextCommand = Command::RD;
|
||||
@@ -175,12 +175,12 @@ sc_time BankMachineClosed::start()
|
||||
if (currentPayload == nullptr)
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
if (state == State::Precharged && !blocked) // row miss
|
||||
{
|
||||
nextCommand = Command::ACT;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
else if (state == State::Activated)
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
nextCommand = Command::RDA;
|
||||
@@ -209,16 +209,16 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
if (currentPayload == nullptr)
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
if (state == State::Precharged && !blocked) // row miss
|
||||
{
|
||||
nextCommand = Command::ACT;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
else if (state == State::Activated)
|
||||
{
|
||||
if (DramExtension::getRow(currentPayload) == currentRow) // row hit
|
||||
if (DramExtension::getRow(currentPayload) == openRow) // row hit
|
||||
{
|
||||
if (scheduler->hasFurtherRequest(bank) && !scheduler->hasFurtherRowHit(bank, currentRow))
|
||||
if (scheduler->hasFurtherRequest(bank) && !scheduler->hasFurtherRowHit(bank, openRow))
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
nextCommand = Command::RDA;
|
||||
@@ -262,16 +262,16 @@ sc_time BankMachineClosedAdaptive::start()
|
||||
if (currentPayload == nullptr)
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
if (state == State::Precharged && !blocked) // row miss
|
||||
{
|
||||
nextCommand = Command::ACT;
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank);
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
else if (state == State::Activated)
|
||||
{
|
||||
if (DramExtension::getRow(currentPayload) == currentRow) // row hit
|
||||
if (DramExtension::getRow(currentPayload) == openRow) // row hit
|
||||
{
|
||||
if (scheduler->hasFurtherRowHit(bank, currentRow))
|
||||
if (scheduler->hasFurtherRowHit(bank, openRow))
|
||||
{
|
||||
if (currentPayload->get_command() == TLM_READ_COMMAND)
|
||||
nextCommand = Command::RD;
|
||||
|
||||
@@ -43,12 +43,6 @@
|
||||
#include "scheduler/SchedulerIF.h"
|
||||
#include "checker/CheckerIF.h"
|
||||
|
||||
enum class BmState
|
||||
{
|
||||
Precharged,
|
||||
Activated
|
||||
};
|
||||
|
||||
class BankMachine
|
||||
{
|
||||
public:
|
||||
@@ -58,11 +52,13 @@ public:
|
||||
void updateState(Command);
|
||||
void block();
|
||||
|
||||
enum class State {Precharged, Activated};
|
||||
|
||||
Rank getRank();
|
||||
BankGroup getBankGroup();
|
||||
Bank getBank();
|
||||
Row getOpenRow();
|
||||
BmState getState();
|
||||
State getState();
|
||||
bool isIdle();
|
||||
|
||||
protected:
|
||||
@@ -71,8 +67,8 @@ protected:
|
||||
SchedulerIF *scheduler;
|
||||
CheckerIF *checker;
|
||||
Command nextCommand = Command::NOP;
|
||||
BmState currentState = BmState::Precharged;
|
||||
Row currentRow;
|
||||
State state = State::Precharged;
|
||||
Row openRow;
|
||||
sc_time timeToSchedule = sc_max_time();
|
||||
Rank rank = Rank(0);
|
||||
BankGroup bankgroup = BankGroup(0);
|
||||
|
||||
@@ -44,95 +44,104 @@ using namespace DRAMPower;
|
||||
std::string commandToString(Command command)
|
||||
{
|
||||
assert(command >= Command::NOP && command <= Command::SREFEX);
|
||||
static std::array<std::string, 16> stringOfCommand =
|
||||
static std::array<std::string, 18> stringOfCommand =
|
||||
{"NOP",
|
||||
"RD",
|
||||
"WR",
|
||||
"RDA",
|
||||
"WRA",
|
||||
"PRE",
|
||||
"ACT",
|
||||
"REFB",
|
||||
"PREA",
|
||||
"REFA",
|
||||
"PDEA",
|
||||
"PDXA",
|
||||
"PDEP",
|
||||
"PDXP",
|
||||
"SREFEN",
|
||||
"SREFEX"};
|
||||
"RD",
|
||||
"WR",
|
||||
"RDA",
|
||||
"WRA",
|
||||
"ACT",
|
||||
"PRE",
|
||||
"REFB",
|
||||
"PRESB",
|
||||
"REFSB",
|
||||
"PREA",
|
||||
"REFA",
|
||||
"PDEA",
|
||||
"PDXA",
|
||||
"PDEP",
|
||||
"PDXP",
|
||||
"SREFEN",
|
||||
"SREFEX"};
|
||||
return stringOfCommand[command];
|
||||
}
|
||||
|
||||
unsigned numberOfCommands()
|
||||
{
|
||||
return 16;
|
||||
return 18;
|
||||
}
|
||||
|
||||
tlm_phase commandToPhase(Command command)
|
||||
{
|
||||
assert(command >= Command::NOP && command <= Command::SREFEX);
|
||||
static std::array<tlm_phase, 16> phaseOfCommand =
|
||||
static std::array<tlm_phase, 18> phaseOfCommand =
|
||||
{UNINITIALIZED_PHASE,
|
||||
BEGIN_RD,
|
||||
BEGIN_WR,
|
||||
BEGIN_RDA,
|
||||
BEGIN_WRA,
|
||||
BEGIN_PRE,
|
||||
BEGIN_ACT,
|
||||
BEGIN_REFB,
|
||||
BEGIN_PREA,
|
||||
BEGIN_REFA,
|
||||
BEGIN_PDNA,
|
||||
END_PDNA,
|
||||
BEGIN_PDNP,
|
||||
END_PDNP,
|
||||
BEGIN_SREF,
|
||||
END_SREF};
|
||||
BEGIN_RD,
|
||||
BEGIN_WR,
|
||||
BEGIN_RDA,
|
||||
BEGIN_WRA,
|
||||
BEGIN_ACT,
|
||||
BEGIN_PRE,
|
||||
BEGIN_REFB,
|
||||
BEGIN_PRESB,
|
||||
BEGIN_REFSB,
|
||||
BEGIN_PREA,
|
||||
BEGIN_REFA,
|
||||
BEGIN_PDNA,
|
||||
END_PDNA,
|
||||
BEGIN_PDNP,
|
||||
END_PDNP,
|
||||
BEGIN_SREF,
|
||||
END_SREF};
|
||||
return phaseOfCommand[command];
|
||||
}
|
||||
|
||||
Command phaseToCommand(tlm_phase phase)
|
||||
{
|
||||
assert(phase >= BEGIN_RD && phase <= END_SREF);
|
||||
static std::array<Command, 16> commandOfPhase =
|
||||
static std::array<Command, 18> commandOfPhase =
|
||||
{Command::RD,
|
||||
Command::WR,
|
||||
Command::RDA,
|
||||
Command::WRA,
|
||||
Command::PRE,
|
||||
Command::ACT,
|
||||
Command::REFB,
|
||||
Command::PREA,
|
||||
Command::REFA,
|
||||
Command::PDEA,
|
||||
Command::PDXA,
|
||||
Command::PDEP,
|
||||
Command::PDXP,
|
||||
Command::SREFEN,
|
||||
Command::SREFEX};
|
||||
Command::WR,
|
||||
Command::RDA,
|
||||
Command::WRA,
|
||||
Command::ACT,
|
||||
Command::PRE,
|
||||
Command::REFB,
|
||||
Command::PRESB,
|
||||
Command::REFSB,
|
||||
Command::PREA,
|
||||
Command::REFA,
|
||||
Command::PDEA,
|
||||
Command::PDXA,
|
||||
Command::PDEP,
|
||||
Command::PDXP,
|
||||
Command::SREFEN,
|
||||
Command::SREFEX};
|
||||
return commandOfPhase[phase - BEGIN_RD];
|
||||
}
|
||||
|
||||
MemCommand::cmds phaseToDRAMPowerCommand(tlm_phase phase)
|
||||
{
|
||||
// TODO: add correct phases when DRAMPower supports DDR5 same bank refresh
|
||||
assert(phase >= BEGIN_RD && phase <= END_SREF);
|
||||
static std::array<MemCommand::cmds, 16> phaseOfCommand =
|
||||
static std::array<MemCommand::cmds, 18> phaseOfCommand =
|
||||
{MemCommand::RD,
|
||||
MemCommand::WR,
|
||||
MemCommand::RDA,
|
||||
MemCommand::WRA,
|
||||
MemCommand::PRE,
|
||||
MemCommand::ACT,
|
||||
MemCommand::REFB,
|
||||
MemCommand::PREA,
|
||||
MemCommand::REF,
|
||||
MemCommand::PDN_S_ACT,
|
||||
MemCommand::PUP_ACT,
|
||||
MemCommand::PDN_S_PRE,
|
||||
MemCommand::PUP_PRE,
|
||||
MemCommand::SREN,
|
||||
MemCommand::SREX};
|
||||
MemCommand::WR,
|
||||
MemCommand::RDA,
|
||||
MemCommand::WRA,
|
||||
MemCommand::ACT,
|
||||
MemCommand::PRE,
|
||||
MemCommand::REFB,
|
||||
MemCommand::NOP,
|
||||
MemCommand::NOP,
|
||||
MemCommand::PREA,
|
||||
MemCommand::REF,
|
||||
MemCommand::PDN_S_ACT,
|
||||
MemCommand::PUP_ACT,
|
||||
MemCommand::PDN_S_PRE,
|
||||
MemCommand::PUP_PRE,
|
||||
MemCommand::SREN,
|
||||
MemCommand::SREX};
|
||||
return phaseOfCommand[phase - BEGIN_RD];
|
||||
}
|
||||
|
||||
@@ -144,7 +153,7 @@ bool phaseNeedsEnd(tlm_phase phase)
|
||||
tlm_phase getEndPhase(tlm_phase phase)
|
||||
{
|
||||
assert(phase >= BEGIN_RD && phase <= BEGIN_REFA);
|
||||
return (phase + 15);
|
||||
return (phase + 17);
|
||||
}
|
||||
|
||||
bool isBankCommand(Command command)
|
||||
@@ -153,6 +162,12 @@ bool isBankCommand(Command command)
|
||||
return (command <= Command::REFB);
|
||||
}
|
||||
|
||||
bool isGroupCommand(Command command)
|
||||
{
|
||||
assert(command >= Command::NOP && command <= Command::SREFEX);
|
||||
return (command >= Command::PRESB && command <= Command::REFSB);
|
||||
}
|
||||
|
||||
bool isRankCommand(Command command)
|
||||
{
|
||||
assert(command >= Command::NOP && command <= Command::SREFEX);
|
||||
@@ -168,5 +183,5 @@ bool isCasCommand(Command command)
|
||||
bool isRasCommand(Command command)
|
||||
{
|
||||
assert(command >= Command::NOP && command <= Command::SREFEX);
|
||||
return (command >= Command::PRE);
|
||||
return (command >= Command::ACT);
|
||||
}
|
||||
|
||||
@@ -46,31 +46,35 @@
|
||||
#include "../common/third_party/DRAMPower/src/MemCommand.h"
|
||||
|
||||
// DO NOT CHANGE THE ORDER!
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_RD); // 5
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_WR); // 6
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_RDA); // 7
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_WRA); // 8
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PRE); // 9
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_ACT); // 10
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_REFB); // 11
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PREA); // 12
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_REFA); // 13
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PDNA); // 14
|
||||
DECLARE_EXTENDED_PHASE(END_PDNA); // 15
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PDNP); // 16
|
||||
DECLARE_EXTENDED_PHASE(END_PDNP); // 17
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_SREF); // 18
|
||||
DECLARE_EXTENDED_PHASE(END_SREF); // 19
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_RD); // 5
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_WR); // 6
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_RDA); // 7
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_WRA); // 8
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_ACT); // 9
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PRE); // 10
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_REFB); // 11
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PRESB); // 12
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_REFSB); // 13
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PREA); // 14
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_REFA); // 15
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PDNA); // 16
|
||||
DECLARE_EXTENDED_PHASE(END_PDNA); // 17
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_PDNP); // 18
|
||||
DECLARE_EXTENDED_PHASE(END_PDNP); // 19
|
||||
DECLARE_EXTENDED_PHASE(BEGIN_SREF); // 20
|
||||
DECLARE_EXTENDED_PHASE(END_SREF); // 21
|
||||
|
||||
DECLARE_EXTENDED_PHASE(END_RD); // 20
|
||||
DECLARE_EXTENDED_PHASE(END_WR); // 21
|
||||
DECLARE_EXTENDED_PHASE(END_RDA); // 22
|
||||
DECLARE_EXTENDED_PHASE(END_WRA); // 23
|
||||
DECLARE_EXTENDED_PHASE(END_PRE); // 24
|
||||
DECLARE_EXTENDED_PHASE(END_ACT); // 25
|
||||
DECLARE_EXTENDED_PHASE(END_REFB); // 26
|
||||
DECLARE_EXTENDED_PHASE(END_PREA); // 27
|
||||
DECLARE_EXTENDED_PHASE(END_REFA); // 28
|
||||
DECLARE_EXTENDED_PHASE(END_RD); // 22
|
||||
DECLARE_EXTENDED_PHASE(END_WR); // 23
|
||||
DECLARE_EXTENDED_PHASE(END_RDA); // 24
|
||||
DECLARE_EXTENDED_PHASE(END_WRA); // 25
|
||||
DECLARE_EXTENDED_PHASE(END_ACT); // 26
|
||||
DECLARE_EXTENDED_PHASE(END_PRE); // 27
|
||||
DECLARE_EXTENDED_PHASE(END_REFB); // 28
|
||||
DECLARE_EXTENDED_PHASE(END_PRESB); // 29
|
||||
DECLARE_EXTENDED_PHASE(END_REFSB); // 30
|
||||
DECLARE_EXTENDED_PHASE(END_PREA); // 31
|
||||
DECLARE_EXTENDED_PHASE(END_REFA); // 32
|
||||
|
||||
enum Command
|
||||
{
|
||||
@@ -79,9 +83,11 @@ enum Command
|
||||
WR,
|
||||
RDA,
|
||||
WRA,
|
||||
PRE,
|
||||
ACT,
|
||||
PRE,
|
||||
REFB,
|
||||
PRESB,
|
||||
REFSB,
|
||||
PREA,
|
||||
REFA,
|
||||
PDEA,
|
||||
@@ -100,6 +106,7 @@ bool phaseNeedsEnd(tlm::tlm_phase);
|
||||
tlm::tlm_phase getEndPhase(tlm::tlm_phase);
|
||||
unsigned numberOfCommands();
|
||||
bool isBankCommand(Command);
|
||||
bool isGroupCommand(Command);
|
||||
bool isRankCommand(Command);
|
||||
bool isCasCommand(Command);
|
||||
bool isRasCommand(Command);
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "Command.h"
|
||||
#include "checker/CheckerDDR3.h"
|
||||
#include "checker/CheckerDDR4.h"
|
||||
#include "checker/CheckerDDR5.h"
|
||||
#include "checker/CheckerWideIO.h"
|
||||
#include "checker/CheckerLPDDR4.h"
|
||||
#include "checker/CheckerWideIO2.h"
|
||||
@@ -53,9 +54,10 @@
|
||||
#include "cmdmux/CmdMuxOldest.h"
|
||||
#include "respqueue/RespQueueFifo.h"
|
||||
#include "respqueue/RespQueueReorder.h"
|
||||
#include "refresh/RefreshManagerRankwise.h"
|
||||
#include "refresh/RefreshManagerDummy.h"
|
||||
#include "refresh/RefreshManagerRankwise.h"
|
||||
#include "refresh/RefreshManagerBankwise.h"
|
||||
#include "refresh/RefreshManagerGroupwise.h"
|
||||
#include "powerdown/PowerDownManagerStaggered.h"
|
||||
#include "powerdown/PowerDownManagerDummy.h"
|
||||
|
||||
@@ -75,74 +77,66 @@ Controller::Controller(sc_module_name name) :
|
||||
readyCommands.reserve(memSpec->numberOfBanks);
|
||||
|
||||
// instantiate timing checker
|
||||
if (memSpec->memoryType == "DDR3")
|
||||
if (memSpec->memoryType == MemSpec::MemoryType::DDR3)
|
||||
checker = new CheckerDDR3();
|
||||
else if (memSpec->memoryType == "DDR4")
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::DDR4)
|
||||
checker = new CheckerDDR4();
|
||||
else if (memSpec->memoryType == "WIDEIO_SDR")
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::DDR5)
|
||||
checker = new CheckerDDR5();
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::WideIO)
|
||||
checker = new CheckerWideIO();
|
||||
else if (memSpec->memoryType == "LPDDR4")
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::LPDDR4)
|
||||
checker = new CheckerLPDDR4();
|
||||
else if (memSpec->memoryType == "WIDEIO2")
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::WideIO2)
|
||||
checker = new CheckerWideIO2();
|
||||
else if (memSpec->memoryType == "HBM2")
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::HBM2)
|
||||
checker = new CheckerHBM2();
|
||||
else if (memSpec->memoryType == "GDDR5")
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::GDDR5)
|
||||
checker = new CheckerGDDR5();
|
||||
else if (memSpec->memoryType == "GDDR5X")
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::GDDR5X)
|
||||
checker = new CheckerGDDR5X();
|
||||
else if (memSpec->memoryType == "GDDR6")
|
||||
else if (memSpec->memoryType == MemSpec::MemoryType::GDDR6)
|
||||
checker = new CheckerGDDR6();
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Unsupported DRAM type!");
|
||||
|
||||
// instantiate scheduler and command mux
|
||||
if (config.scheduler == "Fifo")
|
||||
if (config.scheduler == Configuration::Scheduler::Fifo)
|
||||
scheduler = new SchedulerFifo();
|
||||
else if (config.scheduler == "FrFcfs")
|
||||
else if (config.scheduler == Configuration::Scheduler::FrFcfs)
|
||||
scheduler = new SchedulerFrFcfs();
|
||||
else if (config.scheduler == "FrFcfsGrp")
|
||||
else if (config.scheduler == Configuration::Scheduler::FrFcfsGrp)
|
||||
scheduler = new SchedulerFrFcfsGrp();
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Selected scheduler not supported!");
|
||||
|
||||
if (config.cmdMux == "Oldest")
|
||||
if (config.cmdMux == Configuration::CmdMux::Oldest)
|
||||
cmdMux = new CmdMuxOldest();
|
||||
else if (config.cmdMux == "Strict")
|
||||
else if (config.cmdMux == Configuration::CmdMux::Strict)
|
||||
cmdMux = new CmdMuxStrict();
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Selected cmdmux not supported!");
|
||||
|
||||
if (config.respQueue == "Fifo")
|
||||
if (config.respQueue == Configuration::RespQueue::Fifo)
|
||||
respQueue = new RespQueueFifo();
|
||||
else if (config.respQueue == "Reorder")
|
||||
else if (config.respQueue == Configuration::RespQueue::Reorder)
|
||||
respQueue = new RespQueueReorder();
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Selected respqueue not supported!");
|
||||
|
||||
// instantiate bank machines (one per bank)
|
||||
if (config.pagePolicy == "Open")
|
||||
if (config.pagePolicy == Configuration::PagePolicy::Open)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineOpen(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == "OpenAdaptive")
|
||||
else if (config.pagePolicy == Configuration::PagePolicy::OpenAdaptive)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineOpenAdaptive(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == "Closed")
|
||||
else if (config.pagePolicy == Configuration::PagePolicy::Closed)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineClosed(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == "ClosedAdaptive")
|
||||
else if (config.pagePolicy == Configuration::PagePolicy::ClosedAdaptive)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineClosedAdaptive(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Selected page policy not supported!");
|
||||
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
@@ -151,7 +145,7 @@ Controller::Controller(sc_module_name name) :
|
||||
}
|
||||
|
||||
// instantiate power-down managers (one per rank)
|
||||
if (config.powerDownPolicy == "NoPowerDown")
|
||||
if (config.powerDownPolicy == Configuration::PowerDownPolicy::NoPowerDown)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
@@ -159,7 +153,7 @@ Controller::Controller(sc_module_name name) :
|
||||
powerDownManagers.push_back(manager);
|
||||
}
|
||||
}
|
||||
else if (config.powerDownPolicy == "Staggered")
|
||||
else if (config.powerDownPolicy == Configuration::PowerDownPolicy::Staggered)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
@@ -167,16 +161,14 @@ Controller::Controller(sc_module_name name) :
|
||||
powerDownManagers.push_back(manager);
|
||||
}
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Selected power-down mode not supported!");
|
||||
|
||||
// instantiate refresh managers (one per rank)
|
||||
if (config.refreshPolicy == "NoRefresh")
|
||||
if (config.refreshPolicy == Configuration::RefreshPolicy::NoRefresh)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
refreshManagers.push_back(new RefreshManagerDummy());
|
||||
}
|
||||
else if (config.refreshPolicy == "Rankwise")
|
||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::Rankwise)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
@@ -185,7 +177,16 @@ Controller::Controller(sc_module_name name) :
|
||||
refreshManagers.push_back(manager);
|
||||
}
|
||||
}
|
||||
else if (config.refreshPolicy == "Bankwise")
|
||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::Groupwise)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
RefreshManagerIF *manager = new RefreshManagerGroupwise
|
||||
(bankMachinesOnRank[rankID], powerDownManagers[rankID], Rank(rankID), checker);
|
||||
refreshManagers.push_back(manager);
|
||||
}
|
||||
}
|
||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::Bankwise)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
@@ -280,6 +281,12 @@ void Controller::controllerMethod()
|
||||
for (auto it : bankMachinesOnRank[rank.ID()])
|
||||
it->updateState(command);
|
||||
}
|
||||
else if (isGroupCommand(command))
|
||||
{
|
||||
for (unsigned bankID = (bank.ID() % memSpec->banksPerGroup);
|
||||
bankID < memSpec->banksPerRank; bankID += memSpec->banksPerGroup)
|
||||
bankMachinesOnRank[rank.ID()][bankID]->updateState(command);
|
||||
}
|
||||
else
|
||||
bankMachines[bank.ID()]->updateState(command);
|
||||
|
||||
@@ -347,7 +354,7 @@ tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &trans,
|
||||
SC_REPORT_FATAL("Controller", "nb_transport_fw in controller was triggered with unknown phase");
|
||||
|
||||
PRINTDEBUGMESSAGE(name(), "[fw] " + getPhaseName(phase) + " notification in " +
|
||||
notificationDelay.to_string());
|
||||
delay.to_string());
|
||||
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
@@ -368,7 +375,7 @@ void Controller::finishBeginReq()
|
||||
{
|
||||
if (transToAcquire.payload != nullptr && transToAcquire.time <= sc_time_stamp())
|
||||
{
|
||||
NDEBUG_UNUSED(uint64_t id) = DramExtension::getPayloadID(transToAcquire.payload);
|
||||
NDEBUG_UNUSED(uint64_t id) = DramExtension::getChannelPayloadID(transToAcquire.payload);
|
||||
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system.");
|
||||
|
||||
if (totalNumberOfPayloads == 0)
|
||||
@@ -415,6 +422,7 @@ void Controller::startBeginResp()
|
||||
{
|
||||
transToRelease.time = sc_max_time();
|
||||
sendToFrontend(transToRelease.payload, BEGIN_RESP);
|
||||
numberOfTransactionsServed++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -429,12 +437,11 @@ void Controller::finishEndResp()
|
||||
{
|
||||
if (transToRelease.payload != nullptr && transToRelease.time <= sc_time_stamp())
|
||||
{
|
||||
NDEBUG_UNUSED(uint64_t id) = DramExtension::getPayloadID(transToRelease.payload);
|
||||
NDEBUG_UNUSED(uint64_t id) = DramExtension::getChannelPayloadID(transToRelease.payload);
|
||||
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system.");
|
||||
|
||||
transToRelease.payload->release();
|
||||
transToRelease.payload = nullptr;
|
||||
numberOfTransactionsServed++;
|
||||
|
||||
totalNumberOfPayloads--;
|
||||
if (totalNumberOfPayloads == 0)
|
||||
|
||||
@@ -62,7 +62,7 @@ class Controller : public ControllerIF
|
||||
public:
|
||||
Controller(sc_module_name);
|
||||
SC_HAS_PROCESS(Controller);
|
||||
virtual ~Controller();
|
||||
virtual ~Controller() override;
|
||||
|
||||
protected:
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &) override;
|
||||
@@ -72,17 +72,19 @@ protected:
|
||||
virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase);
|
||||
virtual void sendToDram(Command, tlm::tlm_generic_payload *);
|
||||
|
||||
virtual void controllerMethod();
|
||||
|
||||
SchedulerIF *scheduler;
|
||||
MemSpec *memSpec;
|
||||
|
||||
private:
|
||||
unsigned totalNumberOfPayloads = 0;
|
||||
std::vector<unsigned> ranksNumberOfPayloads;
|
||||
ReadyCommands readyCommands;
|
||||
|
||||
MemSpec *memSpec;
|
||||
|
||||
std::vector<BankMachine *> bankMachines;
|
||||
std::vector<std::vector<BankMachine *>> bankMachinesOnRank;
|
||||
CmdMuxIF *cmdMux;
|
||||
SchedulerIF *scheduler;
|
||||
CheckerIF *checker;
|
||||
RespQueueIF *respQueue;
|
||||
std::vector<RefreshManagerIF *> refreshManagers;
|
||||
@@ -99,7 +101,6 @@ private:
|
||||
void startBeginResp();
|
||||
void finishEndResp();
|
||||
|
||||
void controllerMethod();
|
||||
sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent;
|
||||
};
|
||||
|
||||
|
||||
@@ -37,6 +37,20 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
ControllerRecordable::ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder)
|
||||
: Controller(name), tlmRecorder(tlmRecorder)
|
||||
{
|
||||
if (Configuration::getInstance().enableWindowing)
|
||||
{
|
||||
sensitive << windowEvent;
|
||||
windowSizeTime = Configuration::getInstance().windowSize * memSpec->tCK;
|
||||
slidingAverageBufferDepth = std::vector<sc_time>(scheduler->getBufferDepth().size());
|
||||
windowAverageBufferDepth = std::vector<double>(scheduler->getBufferDepth().size());
|
||||
windowEvent.notify(windowSizeTime);
|
||||
nextWindowEventTime = windowSizeTime;
|
||||
}
|
||||
}
|
||||
|
||||
tlm_sync_enum ControllerRecordable::nb_transport_fw(tlm_generic_payload &trans,
|
||||
tlm_phase &phase, sc_time &delay)
|
||||
{
|
||||
@@ -65,7 +79,10 @@ void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payl
|
||||
TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command);
|
||||
tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, *payload);
|
||||
}
|
||||
Controller::sendToDram(command, payload);
|
||||
sc_time delay = SC_ZERO_TIME;
|
||||
tlm_phase phase = commandToPhase(command);
|
||||
|
||||
iSocket->nb_transport_fw(*payload, phase, delay);
|
||||
}
|
||||
|
||||
void ControllerRecordable::recordPhase(tlm_generic_payload &trans, tlm_phase phase, sc_time delay)
|
||||
@@ -78,7 +95,7 @@ void ControllerRecordable::recordPhase(tlm_generic_payload &trans, tlm_phase pha
|
||||
NDEBUG_UNUSED(unsigned bank) = DramExtension::getExtension(trans).getBank().ID();
|
||||
NDEBUG_UNUSED(unsigned row) = DramExtension::getExtension(trans).getRow().ID();
|
||||
NDEBUG_UNUSED(unsigned col) = DramExtension::getExtension(trans).getColumn().ID();
|
||||
NDEBUG_UNUSED(uint64_t id) = DramExtension::getExtension(trans).getPayloadID();
|
||||
NDEBUG_UNUSED(uint64_t id) = DramExtension::getExtension(trans).getChannelPayloadID();
|
||||
|
||||
PRINTDEBUGMESSAGE(name(), "Recording " + getPhaseName(phase) + " thread " +
|
||||
std::to_string(thr) + " channel " + std::to_string(ch) + " bank group " + std::to_string(
|
||||
@@ -87,3 +104,46 @@ void ControllerRecordable::recordPhase(tlm_generic_payload &trans, tlm_phase pha
|
||||
|
||||
tlmRecorder->recordPhase(trans, phase, recTime);
|
||||
}
|
||||
|
||||
void ControllerRecordable::controllerMethod()
|
||||
{
|
||||
if (Configuration::getInstance().enableWindowing)
|
||||
{
|
||||
sc_time timeDiff = sc_time_stamp() - lastTimeCalled;
|
||||
lastTimeCalled = sc_time_stamp();
|
||||
const std::vector<unsigned> &bufferDepth = scheduler->getBufferDepth();
|
||||
|
||||
for (size_t index = 0; index < slidingAverageBufferDepth.size(); index++)
|
||||
slidingAverageBufferDepth[index] += bufferDepth[index] * timeDiff;
|
||||
|
||||
if (sc_time_stamp() == nextWindowEventTime)
|
||||
{
|
||||
windowEvent.notify(windowSizeTime);
|
||||
nextWindowEventTime += windowSizeTime;
|
||||
|
||||
for (size_t index = 0; index < slidingAverageBufferDepth.size(); index++)
|
||||
{
|
||||
windowAverageBufferDepth[index] = slidingAverageBufferDepth[index] / windowSizeTime;
|
||||
slidingAverageBufferDepth[index] = SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
tlmRecorder->recordBufferDepth(sc_time_stamp().to_seconds(), windowAverageBufferDepth);
|
||||
|
||||
Controller::controllerMethod();
|
||||
|
||||
uint64_t windowNumberOfTransactionsServed = numberOfTransactionsServed - lastNumberOfTransactionsServed;
|
||||
lastNumberOfTransactionsServed = numberOfTransactionsServed;
|
||||
sc_time windowActiveTime = windowNumberOfTransactionsServed * activeTimeMultiplier;
|
||||
double windowAverageBandwidth = windowActiveTime / windowSizeTime;
|
||||
tlmRecorder->recordBandwidth(sc_time_stamp().to_seconds(), windowAverageBandwidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
Controller::controllerMethod();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Controller::controllerMethod();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@
|
||||
class ControllerRecordable final : public Controller
|
||||
{
|
||||
public:
|
||||
ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder) :
|
||||
Controller(name), tlmRecorder(tlmRecorder) {}
|
||||
ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder);
|
||||
virtual ~ControllerRecordable() override {}
|
||||
|
||||
protected:
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans,
|
||||
@@ -53,9 +53,23 @@ protected:
|
||||
virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase) override;
|
||||
virtual void sendToDram(Command, tlm::tlm_generic_payload *) override;
|
||||
|
||||
virtual void controllerMethod() override;
|
||||
|
||||
private:
|
||||
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time delay);
|
||||
TlmRecorder *tlmRecorder;
|
||||
|
||||
sc_event windowEvent;
|
||||
sc_time windowSizeTime;
|
||||
sc_time nextWindowEventTime;
|
||||
std::vector<sc_time> slidingAverageBufferDepth;
|
||||
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;
|
||||
};
|
||||
|
||||
#endif // CONTROLLERRECORDABLE_H
|
||||
|
||||
@@ -52,11 +52,11 @@ CheckerDDR4::CheckerDDR4()
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
||||
|
||||
tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + tBURST - memSpec->tWL + 2 * memSpec->tCK;
|
||||
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL;
|
||||
tRDWR = memSpec->tRL + tBURST + memSpec->tCK - memSpec->tWL + memSpec->tWPRE;
|
||||
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL + memSpec->tWPRE;
|
||||
tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S;
|
||||
tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL + memSpec->tRPRE;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK;
|
||||
tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
|
||||
581
DRAMSys/library/src/controller/checker/CheckerDDR5.cpp
Normal file
581
DRAMSys/library/src/controller/checker/CheckerDDR5.cpp
Normal file
@@ -0,0 +1,581 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "CheckerDDR5.h"
|
||||
|
||||
CheckerDDR5::CheckerDDR5()
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = dynamic_cast<MemSpecDDR5 *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerDDR5", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndDIMMRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfDIMMRanks));
|
||||
lastScheduledByCommandAndPhysicalRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfPhysicalRanks));
|
||||
lastScheduledByCommandAndLogicalRank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfLogicalRanks));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBankGroups));
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
||||
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
|
||||
|
||||
// Required for Same Bank Refresh
|
||||
lastScheduledByCommandAndBankInGroup = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks * memSpec->banksPerGroup));
|
||||
|
||||
last4ActivatesLogical = std::vector<std::queue<sc_time>>(memSpec->numberOfLogicalRanks);
|
||||
last4ActivatesPhysical = std::vector<std::queue<sc_time>>(memSpec->numberOfPhysicalRanks);
|
||||
|
||||
cmdOffset = memSpec->cmdMode * memSpec->tCK;
|
||||
|
||||
tRD_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tWR_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tWTRA = memSpec->tWR - memSpec->tRTP;
|
||||
tWRRDA = memSpec->tWL + tWR_BURST + tWTRA;
|
||||
tWRPRE = memSpec->tWL + tWR_BURST + 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)
|
||||
}
|
||||
|
||||
sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
|
||||
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);
|
||||
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()])
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()])
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr);
|
||||
}
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()])
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()])
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr);
|
||||
}
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()])
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()])
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()])
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()])
|
||||
{
|
||||
if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()])
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr);
|
||||
}
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankgroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_S_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::ACT][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_dlr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PREA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - cmdOffset);
|
||||
|
||||
// TODO: No tRFC_dlr and tRFC_dpr between REFA and ACT?
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::REFSB][bankInGroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - cmdOffset);
|
||||
|
||||
// TODO: No tRFCsb_dlr between REFSB and ACT?
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_slr - cmdOffset);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFSB][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_dlr - cmdOffset);
|
||||
|
||||
if (last4ActivatesLogical[logicalrank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front()
|
||||
+ memSpec->tFAW_slr - memSpec->cmdOffset_L);
|
||||
|
||||
if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front()
|
||||
+ memSpec->tFAW_dlr - memSpec->cmdOffset_L);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PREA][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRESB][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PREA][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
// PRESB tPPD
|
||||
}
|
||||
else if (command == Command::PRESB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RD][bankInGroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WR][bankInGroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
// PREA tRP
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRESB][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PRE][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PREA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFA][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
|
||||
|
||||
// REFSB tRFCsb_slr/dlr
|
||||
// PRESB tRP
|
||||
}
|
||||
else if (command == Command::REFSB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRE][bankInGroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
// PREA tRP
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroup.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr);
|
||||
|
||||
// TODO: check this
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFA][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr);
|
||||
|
||||
// TODO: check this
|
||||
lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFSB][physicalrank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_dlr);
|
||||
|
||||
if (last4ActivatesLogical[logicalrank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front()
|
||||
+ memSpec->tFAW_slr - memSpec->cmdOffset_S);
|
||||
|
||||
if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front()
|
||||
+ memSpec->tFAW_dlr - memSpec->cmdOffset_S);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerDDR5", "Unknown command!");
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank)
|
||||
{
|
||||
PRINTDEBUGMESSAGE("CheckerDDR5", "Changing state on bank " + std::to_string(bank.ID())
|
||||
+ " command is " + commandToString(command));
|
||||
|
||||
Rank logicalrank = rank;
|
||||
Rank physicalrank = Rank(logicalrank.ID() / memSpec->logicalRanksPerPhysicalRank);
|
||||
Rank dimmrank = Rank(physicalrank.ID() / memSpec->physicalRanksPerDIMMRank);
|
||||
|
||||
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();
|
||||
|
||||
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 (last4ActivatesPhysical[physicalrank.ID()].size() == 4)
|
||||
last4ActivatesPhysical[physicalrank.ID()].pop();
|
||||
last4ActivatesPhysical[physicalrank.ID()].push(lastCommandOnBus);
|
||||
}
|
||||
}
|
||||
95
DRAMSys/library/src/controller/checker/CheckerDDR5.h
Normal file
95
DRAMSys/library/src/controller/checker/CheckerDDR5.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef CHECKERDDR5_H
|
||||
#define CHECKERDDR5_H
|
||||
|
||||
#include "CheckerIF.h"
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include "../../configuration/memspec/MemSpecDDR5.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
|
||||
class CheckerDDR5 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerDDR5();
|
||||
virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override;
|
||||
virtual void insert(Command, Rank, BankGroup, Bank) override;
|
||||
|
||||
private:
|
||||
const MemSpecDDR5 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_time>> 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;
|
||||
|
||||
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankInGroup;
|
||||
|
||||
std::vector<std::queue<sc_time>> last4ActivatesPhysical;
|
||||
std::vector<std::queue<sc_time>> last4ActivatesLogical;
|
||||
|
||||
sc_time cmdOffset;
|
||||
|
||||
sc_time tRD_BURST;
|
||||
sc_time tWR_BURST;
|
||||
sc_time tWTRA;
|
||||
sc_time tWRRDA;
|
||||
sc_time tWRPRE;
|
||||
sc_time tRDAACT;
|
||||
sc_time tWRAACT;
|
||||
sc_time tCCD_L_RTW_slr;
|
||||
sc_time tCCD_S_RTW_slr;
|
||||
sc_time tCCD_RTW_dlr;
|
||||
sc_time tRDRD_dpr;
|
||||
sc_time tRDRD_ddr;
|
||||
sc_time tRDWR_dpr;
|
||||
sc_time tRDWR_ddr;
|
||||
sc_time tCCD_L_WTR_slr;
|
||||
sc_time tCCD_S_WTR_slr;
|
||||
sc_time tCCD_WTR_dlr;
|
||||
sc_time tWRWR_dpr;
|
||||
sc_time tWRWR_ddr;
|
||||
sc_time tWRRD_dpr;
|
||||
sc_time tWRRD_ddr;
|
||||
sc_time tRDPDEN;
|
||||
sc_time tWRPDEN;
|
||||
sc_time tWRAPDEN;
|
||||
};
|
||||
|
||||
#endif // CHECKERDDR5_H
|
||||
@@ -49,7 +49,7 @@ CommandTuple::Type CmdMuxOldest::selectCommand(ReadyCommands &readyCommands)
|
||||
{
|
||||
if (std::get<CommandTuple::Timestamp>(*it) == sc_time_stamp())
|
||||
{
|
||||
newPayloadID = DramExtension::getPayloadID(std::get<CommandTuple::Payload>(*it));
|
||||
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
|
||||
if (newPayloadID < lastPayloadID)
|
||||
{
|
||||
lastPayloadID = newPayloadID;
|
||||
|
||||
@@ -49,7 +49,7 @@ CommandTuple::Type CmdMuxStrict::selectCommand(ReadyCommands &readyCommands)
|
||||
{
|
||||
if (std::get<CommandTuple::Timestamp>(*it) == sc_time_stamp())
|
||||
{
|
||||
newPayloadID = DramExtension::getPayloadID(std::get<CommandTuple::Payload>(*it));
|
||||
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
|
||||
if (isCasCommand(std::get<CommandTuple::Command>(*it)))
|
||||
{
|
||||
if ((newPayloadID < lastPayloadID) && (newPayloadID == nextPayloadID))
|
||||
|
||||
@@ -47,7 +47,7 @@ void PowerDownManagerStaggered::triggerEntry()
|
||||
{
|
||||
controllerIdle = true;
|
||||
|
||||
if (state == PdmState::Idle)
|
||||
if (state == State::Idle)
|
||||
entryTriggered = true;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ void PowerDownManagerStaggered::triggerExit()
|
||||
enterSelfRefresh = false;
|
||||
entryTriggered = false;
|
||||
|
||||
if (state != PdmState::Idle)
|
||||
if (state != State::Idle)
|
||||
exitTriggered = true;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ void PowerDownManagerStaggered::triggerInterruption()
|
||||
{
|
||||
entryTriggered = false;
|
||||
|
||||
if (state != PdmState::Idle)
|
||||
if (state != State::Idle)
|
||||
exitTriggered = true;
|
||||
}
|
||||
|
||||
@@ -81,13 +81,13 @@ sc_time PowerDownManagerStaggered::start()
|
||||
|
||||
if (exitTriggered)
|
||||
{
|
||||
if (state == PdmState::ActivePdn)
|
||||
if (state == State::ActivePdn)
|
||||
nextCommand = Command::PDXA;
|
||||
else if (state == PdmState::PrechargePdn)
|
||||
else if (state == State::PrechargePdn)
|
||||
nextCommand = Command::PDXP;
|
||||
else if (state == PdmState::SelfRefresh)
|
||||
else if (state == State::SelfRefresh)
|
||||
nextCommand = Command::SREFEX;
|
||||
else if (state == PdmState::ExtraRefresh)
|
||||
else if (state == State::ExtraRefresh)
|
||||
nextCommand = Command::REFA;
|
||||
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0));
|
||||
@@ -124,35 +124,35 @@ void PowerDownManagerStaggered::updateState(Command command)
|
||||
activatedBanks = 0;
|
||||
break;
|
||||
case Command::PDEA:
|
||||
state = PdmState::ActivePdn;
|
||||
state = State::ActivePdn;
|
||||
entryTriggered = false;
|
||||
break;
|
||||
case Command::PDEP:
|
||||
state = PdmState::PrechargePdn;
|
||||
state = State::PrechargePdn;
|
||||
entryTriggered = false;
|
||||
break;
|
||||
case Command::SREFEN:
|
||||
state = PdmState::SelfRefresh;
|
||||
state = State::SelfRefresh;
|
||||
entryTriggered = false;
|
||||
enterSelfRefresh = false;
|
||||
break;
|
||||
case Command::PDXA:
|
||||
state = PdmState::Idle;
|
||||
state = State::Idle;
|
||||
exitTriggered = false;
|
||||
break;
|
||||
case Command::PDXP:
|
||||
state = PdmState::Idle;
|
||||
state = State::Idle;
|
||||
exitTriggered = false;
|
||||
if (controllerIdle)
|
||||
enterSelfRefresh = true;
|
||||
break;
|
||||
case Command::SREFEX:
|
||||
state = PdmState::ExtraRefresh;
|
||||
state = State::ExtraRefresh;
|
||||
break;
|
||||
case Command::REFA:
|
||||
if (state == PdmState::ExtraRefresh)
|
||||
if (state == State::ExtraRefresh)
|
||||
{
|
||||
state = PdmState::Idle;
|
||||
state = State::Idle;
|
||||
exitTriggered = false;
|
||||
}
|
||||
else if (controllerIdle)
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
virtual sc_time start() override;
|
||||
|
||||
private:
|
||||
enum class PdmState {Idle, ActivePdn, PrechargePdn, SelfRefresh, ExtraRefresh} state = PdmState::Idle;
|
||||
enum class State {Idle, ActivePdn, PrechargePdn, SelfRefresh, ExtraRefresh} state = State::Idle;
|
||||
tlm::tlm_generic_payload powerDownPayload;
|
||||
Rank rank;
|
||||
CheckerIF *checker;
|
||||
|
||||
@@ -39,9 +39,9 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankMachines,
|
||||
RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankMachinesOnRank,
|
||||
PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker)
|
||||
: bankMachinesOnRank(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
: bankMachinesOnRank(bankMachinesOnRank), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = config.memSpec;
|
||||
@@ -50,8 +50,9 @@ RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankM
|
||||
refreshPayloads = std::vector<tlm_generic_payload>(memSpec->banksPerRank);
|
||||
for (unsigned bankID = 0; bankID < memSpec->banksPerRank; bankID++)
|
||||
{
|
||||
setUpDummy(refreshPayloads[bankID], 0, rank, bankMachines[bankID]->getBankGroup(), bankMachines[bankID]->getBank());
|
||||
allBankMachines.push_back(bankMachines[bankID]);
|
||||
setUpDummy(refreshPayloads[bankID], 0, rank, bankMachinesOnRank[bankID]->getBankGroup(),
|
||||
bankMachinesOnRank[bankID]->getBank());
|
||||
allBankMachines.push_back(bankMachinesOnRank[bankID]);
|
||||
}
|
||||
remainingBankMachines = allBankMachines;
|
||||
currentBankMachine = *remainingBankMachines.begin();
|
||||
@@ -80,10 +81,10 @@ sc_time RefreshManagerBankwise::start()
|
||||
if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalPB())
|
||||
{
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
||||
state = RmState::Regular;
|
||||
state = State::Regular;
|
||||
}
|
||||
|
||||
if (state == RmState::Regular)
|
||||
if (state == State::Regular)
|
||||
{
|
||||
bool forcedRefresh = (flexibilityCounter == maxPostponed);
|
||||
bool allBanksBusy = true;
|
||||
@@ -113,7 +114,7 @@ sc_time RefreshManagerBankwise::start()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentBankMachine->getState() == BmState::Activated)
|
||||
if (currentBankMachine->getState() == BankMachine::State::Activated)
|
||||
nextCommand = Command::PRE;
|
||||
else
|
||||
{
|
||||
@@ -148,13 +149,13 @@ sc_time RefreshManagerBankwise::start()
|
||||
|
||||
if (allBanksBusy)
|
||||
{
|
||||
state = RmState::Regular;
|
||||
state = State::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentBankMachine->getState() == BmState::Activated)
|
||||
if (currentBankMachine->getState() == BankMachine::State::Activated)
|
||||
nextCommand = Command::PRE;
|
||||
else
|
||||
nextCommand = Command::REFB;
|
||||
@@ -178,20 +179,20 @@ void RefreshManagerBankwise::updateState(Command command)
|
||||
if (remainingBankMachines.empty())
|
||||
remainingBankMachines = allBankMachines;
|
||||
|
||||
if (state == RmState::Pulledin)
|
||||
if (state == State::Pulledin)
|
||||
flexibilityCounter--;
|
||||
else
|
||||
state = RmState::Pulledin;
|
||||
state = State::Pulledin;
|
||||
|
||||
if (flexibilityCounter == maxPulledin)
|
||||
{
|
||||
state = RmState::Regular;
|
||||
state = State::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalPB();
|
||||
}
|
||||
break;
|
||||
case Command::REFA:
|
||||
// Refresh command after SREFEX
|
||||
state = RmState::Regular; // TODO: check if this assignment is necessary
|
||||
state = State::Regular; // TODO: check if this assignment is necessary
|
||||
timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalPB();
|
||||
sleeping = false;
|
||||
break;
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
virtual void updateState(Command) override;
|
||||
|
||||
private:
|
||||
enum class RmState {Regular, Pulledin} state = RmState::Regular;
|
||||
enum class State {Regular, Pulledin} state = State::Regular;
|
||||
const MemSpec *memSpec;
|
||||
std::vector<BankMachine *> &bankMachinesOnRank;
|
||||
PowerDownManagerIF *powerDownManager;
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "RefreshManagerGroupwise.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/utils.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManagerGroupwise::RefreshManagerGroupwise(std::vector<BankMachine *> &bankMachinesOnRank,
|
||||
PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker)
|
||||
: bankMachinesOnRank(bankMachinesOnRank), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = config.memSpec;
|
||||
timeForNextTrigger = memSpec->getRefreshIntervalSB();
|
||||
|
||||
refreshPayloads = std::vector<tlm_generic_payload>(memSpec->banksPerGroup);
|
||||
for (unsigned bankID = 0; bankID < memSpec->banksPerGroup; bankID++)
|
||||
{
|
||||
setUpDummy(refreshPayloads[bankID], 0, rank, bankMachinesOnRank[bankID]->getBankGroup(),
|
||||
bankMachinesOnRank[bankID]->getBank());
|
||||
allBankMachines.push_back(std::vector<BankMachine *>(memSpec->groupsPerRank));
|
||||
}
|
||||
|
||||
std::list<std::vector<BankMachine *>>::iterator it = allBankMachines.begin();
|
||||
for (unsigned bankID = 0; bankID < memSpec->banksPerGroup; bankID++)
|
||||
{
|
||||
for (unsigned groupID = 0; groupID < memSpec->groupsPerRank; groupID++)
|
||||
(*it)[groupID] = bankMachinesOnRank[groupID * memSpec->banksPerGroup + bankID];
|
||||
it++;
|
||||
}
|
||||
|
||||
remainingBankMachines = allBankMachines;
|
||||
currentIterator = remainingBankMachines.begin();
|
||||
|
||||
maxPostponed = static_cast<int>(config.refreshMaxPostponed * memSpec->banksPerGroup);
|
||||
maxPulledin = -static_cast<int>(config.refreshMaxPulledin * memSpec->banksPerGroup);
|
||||
}
|
||||
|
||||
CommandTuple::Type RefreshManagerGroupwise::getNextCommand()
|
||||
{
|
||||
return CommandTuple::Type
|
||||
(nextCommand, &refreshPayloads[currentIterator->front()->getBank().ID()
|
||||
% memSpec->banksPerGroup], timeToSchedule);
|
||||
}
|
||||
|
||||
sc_time RefreshManagerGroupwise::start()
|
||||
{
|
||||
timeToSchedule = sc_max_time();
|
||||
nextCommand = Command::NOP;
|
||||
|
||||
if (sc_time_stamp() >= timeForNextTrigger)
|
||||
{
|
||||
powerDownManager->triggerInterruption();
|
||||
if (sleeping)
|
||||
return timeToSchedule;
|
||||
|
||||
if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalSB())
|
||||
{
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalSB();
|
||||
state = State::Regular;
|
||||
}
|
||||
|
||||
if (state == State::Regular)
|
||||
{
|
||||
bool forcedRefresh = (flexibilityCounter == maxPostponed);
|
||||
bool allBanksBusy = true;
|
||||
|
||||
if (!skipSelection)
|
||||
{
|
||||
currentIterator = remainingBankMachines.begin();
|
||||
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
|
||||
{
|
||||
bool groupIsBusy = false;
|
||||
for (auto groupIt : *bankIt)
|
||||
{
|
||||
if (!groupIt->isIdle())
|
||||
{
|
||||
groupIsBusy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!groupIsBusy)
|
||||
{
|
||||
allBanksBusy = false;
|
||||
currentIterator = bankIt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allBanksBusy && !forcedRefresh)
|
||||
{
|
||||
flexibilityCounter++;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalSB();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextCommand = Command::REFSB;
|
||||
for (auto it : *currentIterator)
|
||||
{
|
||||
if (it->getState() == BankMachine::State::Activated)
|
||||
{
|
||||
nextCommand = Command::PRESB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nextCommand == Command::REFSB && forcedRefresh)
|
||||
{
|
||||
for (auto it : *currentIterator)
|
||||
it->block();
|
||||
skipSelection = true;
|
||||
}
|
||||
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
|
||||
currentIterator->front()->getBankGroup(), currentIterator->front()->getBank());
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
else // if (state == RmState::Pulledin)
|
||||
{
|
||||
bool allBanksBusy = true;
|
||||
|
||||
currentIterator = remainingBankMachines.begin();
|
||||
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
|
||||
{
|
||||
bool groupIsBusy = false;
|
||||
for (auto groupIt : *bankIt)
|
||||
{
|
||||
if (!groupIt->isIdle())
|
||||
{
|
||||
groupIsBusy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!groupIsBusy)
|
||||
{
|
||||
allBanksBusy = false;
|
||||
currentIterator = bankIt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (allBanksBusy)
|
||||
{
|
||||
state = State::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalSB();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextCommand = Command::REFSB;
|
||||
for (auto it : *currentIterator)
|
||||
{
|
||||
if (it->getState() == BankMachine::State::Activated)
|
||||
{
|
||||
nextCommand = Command::PRESB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
|
||||
currentIterator->front()->getBankGroup(), currentIterator->front()->getBank());
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
|
||||
void RefreshManagerGroupwise::updateState(Command command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case Command::REFSB:
|
||||
skipSelection = false;
|
||||
remainingBankMachines.erase(currentIterator);
|
||||
if (remainingBankMachines.empty())
|
||||
remainingBankMachines = allBankMachines;
|
||||
currentIterator = remainingBankMachines.begin();
|
||||
|
||||
if (state == State::Pulledin)
|
||||
flexibilityCounter--;
|
||||
else
|
||||
state = State::Pulledin;
|
||||
|
||||
if (flexibilityCounter == maxPulledin)
|
||||
{
|
||||
state = State::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalSB();
|
||||
}
|
||||
break;
|
||||
case Command::REFA:
|
||||
// Refresh command after SREFEX
|
||||
state = State::Regular; // TODO: check if this assignment is necessary
|
||||
timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalSB();
|
||||
sleeping = false;
|
||||
break;
|
||||
case Command::PDEA: case Command::PDEP:
|
||||
sleeping = true;
|
||||
break;
|
||||
case Command::SREFEN:
|
||||
sleeping = true;
|
||||
timeForNextTrigger = sc_max_time();
|
||||
break;
|
||||
case Command::PDXA: case Command::PDXP:
|
||||
sleeping = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef REFRESHMANAGERGROUPWISE_H
|
||||
#define REFRESHMANAGERGROUPWISE_H
|
||||
|
||||
#include "RefreshManagerIF.h"
|
||||
#include "../../configuration/memspec/MemSpec.h"
|
||||
#include "../BankMachine.h"
|
||||
#include "../powerdown/PowerDownManagerIF.h"
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <list>
|
||||
|
||||
class RefreshManagerGroupwise final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerGroupwise(std::vector<BankMachine *> &, PowerDownManagerIF *, Rank, CheckerIF *);
|
||||
|
||||
virtual CommandTuple::Type getNextCommand() override;
|
||||
virtual sc_time start() override;
|
||||
virtual void updateState(Command) override;
|
||||
|
||||
private:
|
||||
enum class State {Regular, Pulledin} state = State::Regular;
|
||||
const MemSpec *memSpec;
|
||||
std::vector<BankMachine *> &bankMachinesOnRank;
|
||||
PowerDownManagerIF *powerDownManager;
|
||||
std::vector<tlm::tlm_generic_payload> refreshPayloads;
|
||||
sc_time timeForNextTrigger = sc_max_time();
|
||||
sc_time timeToSchedule = sc_max_time();
|
||||
Rank rank;
|
||||
CheckerIF *checker;
|
||||
Command nextCommand = Command::NOP;
|
||||
|
||||
std::list<std::vector<BankMachine *>> remainingBankMachines;
|
||||
std::list<std::vector<BankMachine *>> allBankMachines;
|
||||
std::list<std::vector<BankMachine *>>::iterator currentIterator;
|
||||
|
||||
int flexibilityCounter = 0;
|
||||
int maxPostponed = 0;
|
||||
int maxPulledin = 0;
|
||||
|
||||
bool sleeping = false;
|
||||
bool skipSelection = false;
|
||||
};
|
||||
|
||||
#endif // REFRESHMANAGERGROUPWISE_H
|
||||
@@ -39,9 +39,9 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
RefreshManagerRankwise::RefreshManagerRankwise(std::vector<BankMachine *> &bankMachines,
|
||||
RefreshManagerRankwise::RefreshManagerRankwise(std::vector<BankMachine *> &bankMachinesOnRank,
|
||||
PowerDownManagerIF *powerDownManager, Rank rank, CheckerIF *checker)
|
||||
: bankMachinesOnRank(bankMachines), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
: bankMachinesOnRank(bankMachinesOnRank), powerDownManager(powerDownManager), rank(rank), checker(checker)
|
||||
{
|
||||
Configuration &config = Configuration::getInstance();
|
||||
memSpec = config.memSpec;
|
||||
@@ -71,10 +71,10 @@ sc_time RefreshManagerRankwise::start()
|
||||
if (sc_time_stamp() >= timeForNextTrigger + memSpec->getRefreshIntervalAB())
|
||||
{
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
||||
state = RmState::Regular;
|
||||
state = State::Regular;
|
||||
}
|
||||
|
||||
if (state == RmState::Regular)
|
||||
if (state == State::Regular)
|
||||
{
|
||||
if (flexibilityCounter == maxPostponed) // forced refresh
|
||||
{
|
||||
@@ -122,7 +122,7 @@ sc_time RefreshManagerRankwise::start()
|
||||
|
||||
if (controllerBusy)
|
||||
{
|
||||
state = RmState::Regular;
|
||||
state = State::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
||||
return timeForNextTrigger;
|
||||
}
|
||||
@@ -155,20 +155,20 @@ void RefreshManagerRankwise::updateState(Command command)
|
||||
if (sleeping)
|
||||
{
|
||||
// Refresh command after SREFEX
|
||||
state = RmState::Regular; // TODO: check if this assignment is necessary
|
||||
state = State::Regular; // TODO: check if this assignment is necessary
|
||||
timeForNextTrigger = sc_time_stamp() + memSpec->getRefreshIntervalAB();
|
||||
sleeping = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state == RmState::Pulledin)
|
||||
if (state == State::Pulledin)
|
||||
flexibilityCounter--;
|
||||
else
|
||||
state = RmState::Pulledin;
|
||||
state = State::Pulledin;
|
||||
|
||||
if (flexibilityCounter == maxPulledin)
|
||||
{
|
||||
state = RmState::Regular;
|
||||
state = State::Regular;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
virtual void updateState(Command) override;
|
||||
|
||||
private:
|
||||
enum class RmState {Regular, Pulledin} state = RmState::Regular;
|
||||
enum class State {Regular, Pulledin} state = State::Regular;
|
||||
const MemSpec *memSpec;
|
||||
std::vector<BankMachine *> &bankMachinesOnRank;
|
||||
PowerDownManagerIF *powerDownManager;
|
||||
|
||||
@@ -39,7 +39,7 @@ using namespace tlm;
|
||||
|
||||
void RespQueueReorder::insertPayload(tlm_generic_payload *payload, sc_time strobeEnd)
|
||||
{
|
||||
buffer[DramExtension::getPayloadID(payload)] = {payload, strobeEnd};
|
||||
buffer[DramExtension::getChannelPayloadID(payload)] = {payload, strobeEnd};
|
||||
}
|
||||
|
||||
tlm_generic_payload *RespQueueReorder::nextPayload()
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "BufferCounterBankwise.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
|
||||
BufferCounterBankwise::BufferCounterBankwise(unsigned requestBufferSize, unsigned numberOfBanks)
|
||||
: requestBufferSize(requestBufferSize)
|
||||
{
|
||||
numRequestsOnBank = std::vector<unsigned>(numberOfBanks, 0);
|
||||
}
|
||||
|
||||
bool BufferCounterBankwise::hasBufferSpace() const
|
||||
{
|
||||
return (numRequestsOnBank[lastBankID] < requestBufferSize);
|
||||
}
|
||||
|
||||
void BufferCounterBankwise::storeRequest(tlm::tlm_generic_payload *payload)
|
||||
{
|
||||
lastBankID = DramExtension::getBank(payload).ID();
|
||||
numRequestsOnBank[lastBankID]++;
|
||||
}
|
||||
|
||||
void BufferCounterBankwise::removeRequest(tlm::tlm_generic_payload *payload)
|
||||
{
|
||||
numRequestsOnBank[DramExtension::getBank(payload).ID()]--;
|
||||
}
|
||||
|
||||
const std::vector<unsigned> &BufferCounterBankwise::getBufferDepth() const
|
||||
{
|
||||
return numRequestsOnBank;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef BUFFERCOUNTERBANKWISE_H
|
||||
#define BUFFERCOUNTERBANKWISE_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "BufferCounterIF.h"
|
||||
|
||||
class BufferCounterBankwise final : public BufferCounterIF
|
||||
{
|
||||
public:
|
||||
BufferCounterBankwise(unsigned requestBufferSize, unsigned numberOfBanks);
|
||||
virtual bool hasBufferSpace() const override;
|
||||
virtual void storeRequest(tlm::tlm_generic_payload *payload) override;
|
||||
virtual void removeRequest(tlm::tlm_generic_payload *payload) override;
|
||||
virtual const std::vector<unsigned> &getBufferDepth() const override;
|
||||
|
||||
private:
|
||||
const unsigned requestBufferSize;
|
||||
std::vector<unsigned> numRequestsOnBank;
|
||||
unsigned lastBankID;
|
||||
};
|
||||
|
||||
#endif // BUFFERCOUNTERBANKWISE_H
|
||||
50
DRAMSys/library/src/controller/scheduler/BufferCounterIF.h
Normal file
50
DRAMSys/library/src/controller/scheduler/BufferCounterIF.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef BUFFERCOUNTERIF_H
|
||||
#define BUFFERCOUNTERIF_H
|
||||
|
||||
#include <tlm.h>
|
||||
|
||||
class BufferCounterIF
|
||||
{
|
||||
public:
|
||||
virtual ~BufferCounterIF() = default;
|
||||
virtual bool hasBufferSpace() const = 0;
|
||||
virtual void storeRequest(tlm::tlm_generic_payload *payload) = 0;
|
||||
virtual void removeRequest(tlm::tlm_generic_payload *payload) = 0;
|
||||
virtual const std::vector<unsigned> &getBufferDepth() const = 0;
|
||||
};
|
||||
|
||||
#endif // BUFFERCOUNTERIF_H
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "BufferCounterReadWrite.h"
|
||||
|
||||
BufferCounterReadWrite::BufferCounterReadWrite(unsigned requestBufferSize)
|
||||
: requestBufferSize(requestBufferSize)
|
||||
{
|
||||
numReadWriteRequests = std::vector<unsigned>(2);
|
||||
}
|
||||
|
||||
bool BufferCounterReadWrite::hasBufferSpace() const
|
||||
{
|
||||
return (numReadWriteRequests[0] < requestBufferSize && numReadWriteRequests[1] < requestBufferSize);
|
||||
}
|
||||
|
||||
void BufferCounterReadWrite::storeRequest(tlm::tlm_generic_payload *payload)
|
||||
{
|
||||
if (payload->is_read())
|
||||
numReadWriteRequests[0]++;
|
||||
else
|
||||
numReadWriteRequests[1]++;
|
||||
}
|
||||
|
||||
void BufferCounterReadWrite::removeRequest(tlm::tlm_generic_payload *payload)
|
||||
{
|
||||
if (payload->is_read())
|
||||
numReadWriteRequests[0]--;
|
||||
else
|
||||
numReadWriteRequests[1]--;
|
||||
}
|
||||
|
||||
const std::vector<unsigned> &BufferCounterReadWrite::getBufferDepth() const
|
||||
{
|
||||
return numReadWriteRequests;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef BUFFERCOUNTERREADWRITE_H
|
||||
#define BUFFERCOUNTERREADWRITE_H
|
||||
|
||||
#include "BufferCounterIF.h"
|
||||
|
||||
class BufferCounterReadWrite final : public BufferCounterIF
|
||||
{
|
||||
public:
|
||||
BufferCounterReadWrite(unsigned requestBufferSize);
|
||||
virtual bool hasBufferSpace() const override;
|
||||
virtual void storeRequest(tlm::tlm_generic_payload *payload) override;
|
||||
virtual void removeRequest(tlm::tlm_generic_payload *payload) override;
|
||||
virtual const std::vector<unsigned> &getBufferDepth() const override;
|
||||
|
||||
private:
|
||||
const unsigned requestBufferSize;
|
||||
std::vector<unsigned> numReadWriteRequests;
|
||||
};
|
||||
|
||||
#endif // BUFFERCOUNTERREADWRITE_H
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#include "BufferCounterShared.h"
|
||||
|
||||
BufferCounterShared::BufferCounterShared(unsigned requestBufferSize)
|
||||
: requestBufferSize(requestBufferSize)
|
||||
{
|
||||
numRequests = std::vector<unsigned>(1);
|
||||
}
|
||||
|
||||
bool BufferCounterShared::hasBufferSpace() const
|
||||
{
|
||||
return (numRequests[0] < requestBufferSize);
|
||||
}
|
||||
|
||||
void BufferCounterShared::storeRequest(tlm::tlm_generic_payload *)
|
||||
{
|
||||
numRequests[0]++;
|
||||
}
|
||||
|
||||
void BufferCounterShared::removeRequest(tlm::tlm_generic_payload *)
|
||||
{
|
||||
numRequests[0]--;
|
||||
}
|
||||
|
||||
const std::vector<unsigned> &BufferCounterShared::getBufferDepth() const
|
||||
{
|
||||
return numRequests;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Technische Universität Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
*/
|
||||
|
||||
#ifndef BUFFERCOUNTERSHARED_H
|
||||
#define BUFFERCOUNTERSHARED_H
|
||||
|
||||
#include "BufferCounterIF.h"
|
||||
|
||||
class BufferCounterShared final : public BufferCounterIF
|
||||
{
|
||||
public:
|
||||
BufferCounterShared(unsigned requestBufferSize);
|
||||
virtual bool hasBufferSpace() const override;
|
||||
virtual void storeRequest(tlm::tlm_generic_payload *payload) override;
|
||||
virtual void removeRequest(tlm::tlm_generic_payload *payload) override;
|
||||
virtual const std::vector<unsigned> &getBufferDepth() const override;
|
||||
|
||||
private:
|
||||
const unsigned requestBufferSize;
|
||||
std::vector<unsigned> numRequests;
|
||||
};
|
||||
|
||||
#endif // BUFFERCOUNTERSHARED_H
|
||||
@@ -34,36 +34,48 @@
|
||||
|
||||
#include "SchedulerFifo.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "BufferCounterBankwise.h"
|
||||
#include "BufferCounterReadWrite.h"
|
||||
#include "BufferCounterShared.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
SchedulerFifo::SchedulerFifo()
|
||||
{
|
||||
buffer = std::vector<std::deque<tlm_generic_payload *>>
|
||||
(Configuration::getInstance().memSpec->numberOfBanks);
|
||||
requestBufferSize = Configuration::getInstance().requestBufferSize;
|
||||
Configuration &config = Configuration::getInstance();
|
||||
buffer = std::vector<std::deque<tlm_generic_payload *>>(config.memSpec->numberOfBanks);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
|
||||
bufferCounter = new BufferCounterReadWrite(config.requestBufferSize);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
|
||||
bufferCounter = new BufferCounterShared(config.requestBufferSize);
|
||||
}
|
||||
|
||||
bool SchedulerFifo::hasBufferSpace()
|
||||
SchedulerFifo::~SchedulerFifo()
|
||||
{
|
||||
if (buffer[lastBankID].size() < requestBufferSize)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
delete bufferCounter;
|
||||
}
|
||||
|
||||
bool SchedulerFifo::hasBufferSpace() const
|
||||
{
|
||||
return bufferCounter->hasBufferSpace();
|
||||
}
|
||||
|
||||
void SchedulerFifo::storeRequest(tlm_generic_payload *payload)
|
||||
{
|
||||
lastBankID = DramExtension::getBank(payload).ID();
|
||||
buffer[lastBankID].push_back(payload);
|
||||
buffer[DramExtension::getBank(payload).ID()].push_back(payload);
|
||||
bufferCounter->storeRequest(payload);
|
||||
}
|
||||
|
||||
void SchedulerFifo::removeRequest(tlm_generic_payload *payload)
|
||||
{
|
||||
buffer[DramExtension::getBank(payload).ID()].pop_front();
|
||||
bufferCounter->removeRequest(payload);
|
||||
}
|
||||
|
||||
tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine)
|
||||
tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) const
|
||||
{
|
||||
unsigned bankID = bankMachine->getBank().ID();
|
||||
if (!buffer[bankID].empty())
|
||||
@@ -72,7 +84,7 @@ tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row)
|
||||
bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) const
|
||||
{
|
||||
if (buffer[bank.ID()].size() >= 2)
|
||||
{
|
||||
@@ -83,10 +95,15 @@ bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SchedulerFifo::hasFurtherRequest(Bank bank)
|
||||
bool SchedulerFifo::hasFurtherRequest(Bank bank) const
|
||||
{
|
||||
if (buffer[bank.ID()].size() >= 2)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::vector<unsigned> &SchedulerFifo::getBufferDepth() const
|
||||
{
|
||||
return bufferCounter->getBufferDepth();
|
||||
}
|
||||
|
||||
@@ -38,24 +38,28 @@
|
||||
#include <tlm.h>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
|
||||
#include "SchedulerIF.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../BankMachine.h"
|
||||
#include "BufferCounterIF.h"
|
||||
|
||||
class SchedulerFifo : public SchedulerIF
|
||||
class SchedulerFifo final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
SchedulerFifo();
|
||||
virtual bool hasBufferSpace() override;
|
||||
virtual ~SchedulerFifo() override;
|
||||
virtual bool hasBufferSpace() const override;
|
||||
virtual void storeRequest(tlm::tlm_generic_payload *) override;
|
||||
virtual void removeRequest(tlm::tlm_generic_payload *) override;
|
||||
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) override;
|
||||
virtual bool hasFurtherRowHit(Bank, Row) override;
|
||||
virtual bool hasFurtherRequest(Bank) override;
|
||||
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override;
|
||||
virtual bool hasFurtherRowHit(Bank, Row) const override;
|
||||
virtual bool hasFurtherRequest(Bank) const override;
|
||||
virtual const std::vector<unsigned> &getBufferDepth() const override;
|
||||
|
||||
private:
|
||||
std::vector<std::deque<tlm::tlm_generic_payload *>> buffer;
|
||||
unsigned requestBufferSize;
|
||||
unsigned lastBankID;
|
||||
BufferCounterIF *bufferCounter;
|
||||
};
|
||||
|
||||
#endif // SCHEDULERFIFO_H
|
||||
|
||||
@@ -33,53 +33,62 @@
|
||||
*/
|
||||
|
||||
#include "SchedulerFrFcfs.h"
|
||||
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include <systemc.h>
|
||||
#include "BufferCounterBankwise.h"
|
||||
#include "BufferCounterReadWrite.h"
|
||||
#include "BufferCounterShared.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
SchedulerFrFcfs::SchedulerFrFcfs()
|
||||
{
|
||||
buffer = std::vector<std::list<tlm_generic_payload *>>
|
||||
(Configuration::getInstance().memSpec->numberOfBanks);
|
||||
requestBufferSize = Configuration::getInstance().requestBufferSize;
|
||||
Configuration &config = Configuration::getInstance();
|
||||
buffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->numberOfBanks);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
|
||||
bufferCounter = new BufferCounterReadWrite(config.requestBufferSize);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
|
||||
bufferCounter = new BufferCounterShared(config.requestBufferSize);
|
||||
}
|
||||
|
||||
bool SchedulerFrFcfs::hasBufferSpace()
|
||||
SchedulerFrFcfs::~SchedulerFrFcfs()
|
||||
{
|
||||
if (buffer[lastBankID].size() < requestBufferSize)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
delete bufferCounter;
|
||||
}
|
||||
|
||||
bool SchedulerFrFcfs::hasBufferSpace() const
|
||||
{
|
||||
return bufferCounter->hasBufferSpace();
|
||||
}
|
||||
|
||||
void SchedulerFrFcfs::storeRequest(tlm_generic_payload *payload)
|
||||
{
|
||||
lastBankID = DramExtension::getBank(payload).ID();
|
||||
buffer[lastBankID].push_back(payload);
|
||||
buffer[DramExtension::getBank(payload).ID()].push_back(payload);
|
||||
bufferCounter->storeRequest(payload);
|
||||
}
|
||||
|
||||
void SchedulerFrFcfs::removeRequest(tlm_generic_payload *payload)
|
||||
{
|
||||
bufferCounter->removeRequest(payload);
|
||||
unsigned bankID = DramExtension::getBank(payload).ID();
|
||||
for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++)
|
||||
{
|
||||
if (*it == payload)
|
||||
{
|
||||
buffer[bankID].erase(it);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SC_REPORT_FATAL("SchedulerFrFcfs", "removeRequest failed!");
|
||||
}
|
||||
|
||||
tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine)
|
||||
tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) const
|
||||
{
|
||||
unsigned bankID = bankMachine->getBank().ID();
|
||||
if (!buffer[bankID].empty())
|
||||
{
|
||||
if (bankMachine->getState() == BmState::Activated)
|
||||
if (bankMachine->getState() == BankMachine::State::Activated)
|
||||
{
|
||||
// Search for row hit
|
||||
Row openRow = bankMachine->getOpenRow();
|
||||
@@ -95,7 +104,7 @@ tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row)
|
||||
bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) const
|
||||
{
|
||||
unsigned rowHitCounter = 0;
|
||||
for (auto it = buffer[bank.ID()].begin(); it != buffer[bank.ID()].end(); it++)
|
||||
@@ -110,7 +119,12 @@ bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SchedulerFrFcfs::hasFurtherRequest(Bank bank)
|
||||
bool SchedulerFrFcfs::hasFurtherRequest(Bank bank) const
|
||||
{
|
||||
return (buffer[bank.ID()].size() >= 2);
|
||||
}
|
||||
|
||||
const std::vector<unsigned> &SchedulerFrFcfs::getBufferDepth() const
|
||||
{
|
||||
return bufferCounter->getBufferDepth();
|
||||
}
|
||||
|
||||
@@ -38,24 +38,28 @@
|
||||
#include <tlm.h>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include "SchedulerIF.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../BankMachine.h"
|
||||
#include "BufferCounterIF.h"
|
||||
|
||||
class SchedulerFrFcfs : public SchedulerIF
|
||||
class SchedulerFrFcfs final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
SchedulerFrFcfs();
|
||||
virtual bool hasBufferSpace() override;
|
||||
virtual ~SchedulerFrFcfs() override;
|
||||
virtual bool hasBufferSpace() const override;
|
||||
virtual void storeRequest(tlm::tlm_generic_payload *) override;
|
||||
virtual void removeRequest(tlm::tlm_generic_payload *) override;
|
||||
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) override;
|
||||
virtual bool hasFurtherRowHit(Bank, Row) override;
|
||||
virtual bool hasFurtherRequest(Bank) override;
|
||||
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override;
|
||||
virtual bool hasFurtherRowHit(Bank, Row) const override;
|
||||
virtual bool hasFurtherRequest(Bank) const override;
|
||||
virtual const std::vector<unsigned> &getBufferDepth() const override;
|
||||
|
||||
private:
|
||||
std::vector<std::list<tlm::tlm_generic_payload *>> buffer;
|
||||
unsigned requestBufferSize;
|
||||
unsigned lastBankID;
|
||||
BufferCounterIF *bufferCounter;
|
||||
};
|
||||
|
||||
#endif // SCHEDULERFRFCFS_H
|
||||
|
||||
@@ -34,32 +34,44 @@
|
||||
|
||||
#include "SchedulerFrFcfsGrp.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "BufferCounterBankwise.h"
|
||||
#include "BufferCounterReadWrite.h"
|
||||
#include "BufferCounterShared.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
SchedulerFrFcfsGrp::SchedulerFrFcfsGrp()
|
||||
{
|
||||
buffer = std::vector<std::list<tlm_generic_payload *>>
|
||||
(Configuration::getInstance().memSpec->numberOfBanks);
|
||||
requestBufferSize = Configuration::getInstance().requestBufferSize;
|
||||
Configuration &config = Configuration::getInstance();
|
||||
buffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->numberOfBanks);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
|
||||
bufferCounter = new BufferCounterReadWrite(config.requestBufferSize);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
|
||||
bufferCounter = new BufferCounterShared(config.requestBufferSize);
|
||||
}
|
||||
|
||||
bool SchedulerFrFcfsGrp::hasBufferSpace()
|
||||
SchedulerFrFcfsGrp::~SchedulerFrFcfsGrp()
|
||||
{
|
||||
if (buffer[lastBankID].size() < requestBufferSize)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
delete bufferCounter;
|
||||
}
|
||||
|
||||
bool SchedulerFrFcfsGrp::hasBufferSpace() const
|
||||
{
|
||||
return bufferCounter->hasBufferSpace();
|
||||
}
|
||||
|
||||
void SchedulerFrFcfsGrp::storeRequest(tlm_generic_payload *payload)
|
||||
{
|
||||
lastBankID = DramExtension::getBank(payload).ID();
|
||||
buffer[lastBankID].push_back(payload);
|
||||
buffer[DramExtension::getBank(payload).ID()].push_back(payload);
|
||||
bufferCounter->storeRequest(payload);
|
||||
}
|
||||
|
||||
void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload *payload)
|
||||
{
|
||||
bufferCounter->removeRequest(payload);
|
||||
lastCommand = payload->get_command();
|
||||
unsigned bankID = DramExtension::getBank(payload).ID();
|
||||
for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++)
|
||||
@@ -67,18 +79,17 @@ void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload *payload)
|
||||
if (*it == payload)
|
||||
{
|
||||
buffer[bankID].erase(it);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SC_REPORT_FATAL("SchedulerFrFcfs", "removeRequest failed!");
|
||||
}
|
||||
|
||||
tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine)
|
||||
tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine) const
|
||||
{
|
||||
unsigned bankID = bankMachine->getBank().ID();
|
||||
if (!buffer[bankID].empty())
|
||||
{
|
||||
if (bankMachine->getState() == BmState::Activated)
|
||||
if (bankMachine->getState() == BankMachine::State::Activated)
|
||||
{
|
||||
// Filter all row hits
|
||||
Row openRow = bankMachine->getOpenRow();
|
||||
@@ -118,7 +129,7 @@ tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row)
|
||||
bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) const
|
||||
{
|
||||
unsigned rowHitCounter = 0;
|
||||
for (auto it = buffer[bank.ID()].begin(); it != buffer[bank.ID()].end(); it++)
|
||||
@@ -133,10 +144,15 @@ bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank)
|
||||
bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank) const
|
||||
{
|
||||
if (buffer[bank.ID()].size() >= 2)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::vector<unsigned> &SchedulerFrFcfsGrp::getBufferDepth() const
|
||||
{
|
||||
return bufferCounter->getBufferDepth();
|
||||
}
|
||||
|
||||
@@ -42,22 +42,25 @@
|
||||
#include "SchedulerIF.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../BankMachine.h"
|
||||
#include "BufferCounterIF.h"
|
||||
|
||||
class SchedulerFrFcfsGrp : public SchedulerIF
|
||||
class SchedulerFrFcfsGrp final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
SchedulerFrFcfsGrp();
|
||||
virtual bool hasBufferSpace() override;
|
||||
virtual ~SchedulerFrFcfsGrp() override;
|
||||
virtual bool hasBufferSpace() const override;
|
||||
virtual void storeRequest(tlm::tlm_generic_payload *) override;
|
||||
virtual void removeRequest(tlm::tlm_generic_payload *) override;
|
||||
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) override;
|
||||
virtual bool hasFurtherRowHit(Bank, Row) override;
|
||||
virtual bool hasFurtherRequest(Bank) override;
|
||||
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override;
|
||||
virtual bool hasFurtherRowHit(Bank, Row) const override;
|
||||
virtual bool hasFurtherRequest(Bank) const override;
|
||||
virtual const std::vector<unsigned> &getBufferDepth() const override;
|
||||
|
||||
private:
|
||||
std::vector<std::list<tlm::tlm_generic_payload *>> buffer;
|
||||
unsigned requestBufferSize;
|
||||
tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND;
|
||||
unsigned lastBankID;
|
||||
BufferCounterIF *bufferCounter;
|
||||
};
|
||||
|
||||
#endif // SCHEDULERFRFCFSGRP_H
|
||||
|
||||
@@ -36,22 +36,23 @@
|
||||
#define SCHEDULERIF_H
|
||||
|
||||
#include <tlm.h>
|
||||
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../../common/DebugManager.h"
|
||||
|
||||
enum class BmState;
|
||||
class BankMachine;
|
||||
|
||||
class SchedulerIF
|
||||
{
|
||||
public:
|
||||
virtual ~SchedulerIF() {}
|
||||
virtual bool hasBufferSpace() = 0;
|
||||
virtual ~SchedulerIF() = default;
|
||||
virtual bool hasBufferSpace() const = 0;
|
||||
virtual void storeRequest(tlm::tlm_generic_payload *) = 0;
|
||||
virtual void removeRequest(tlm::tlm_generic_payload *) = 0;
|
||||
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) = 0;
|
||||
virtual bool hasFurtherRowHit(Bank, Row) = 0;
|
||||
virtual bool hasFurtherRequest(Bank) = 0;
|
||||
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const = 0;
|
||||
virtual bool hasFurtherRowHit(Bank, Row) const = 0;
|
||||
virtual bool hasFurtherRequest(Bank) const = 0;
|
||||
virtual const std::vector<unsigned> &getBufferDepth() const = 0;
|
||||
};
|
||||
|
||||
#endif // SCHEDULERIF_H
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "errormodel.h"
|
||||
#include "../common/DebugManager.h"
|
||||
#include "../simulation/TemperatureController.h"
|
||||
#include "../common/AddressDecoder.h"
|
||||
#include "../simulation/AddressDecoder.h"
|
||||
#include "../common/dramExtensions.h"
|
||||
|
||||
#include <random>
|
||||
@@ -51,7 +51,7 @@ void errorModel::init()
|
||||
// Get Configuration parameters:
|
||||
burstLenght = Configuration::getInstance().memSpec->burstLength;
|
||||
numberOfColumns = Configuration::getInstance().memSpec->numberOfColumns;
|
||||
bytesPerColumn = std::log2(Configuration::getInstance().getDataBusWidth());
|
||||
bytesPerColumn = std::log2(Configuration::getInstance().memSpec->dataBusWidth);
|
||||
|
||||
// Adjust number of bytes per column dynamically to the selected ecc controller
|
||||
bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC(
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <iostream>
|
||||
#include <systemc.h>
|
||||
#include "../configuration/Configuration.h"
|
||||
#include "../common/AddressDecoder.h"
|
||||
#include "../simulation/AddressDecoder.h"
|
||||
#include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
|
||||
|
||||
class errorModel : public sc_module
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <bitset>
|
||||
|
||||
#include "AddressDecoder.h"
|
||||
#include "utils.h"
|
||||
#include "../common/utils.h"
|
||||
#include "../configuration/Configuration.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user