Merge branch 'DDR5' into 'develop'

Rambus Analysis Features

See merge request ems/astdm/dram.sys!270
This commit is contained in:
Lukas Steiner
2020-11-23 13:24:44 +01:00
150 changed files with 5909 additions and 1666 deletions

View File

@@ -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

View File

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

View File

@@ -0,0 +1,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
]
}
}

View File

@@ -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
]
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -0,0 +1,19 @@
{
"simconfig": {
"AddressOffset": 0,
"CheckTLM2Protocol": false,
"DatabaseRecording": true,
"Debug": false,
"ECCControllerMode": "Disabled",
"EnableWindowing": false,
"ErrorCSVFile": "",
"ErrorChipSeed": 42,
"PowerAnalysis": false,
"SimulationName": "ddr5",
"SimulationProgressBar": true,
"StoreMode": "NoStorage",
"ThermalSimulation": false,
"UseMalloc": false,
"WindowSize": 1000
}
}

View File

@@ -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);

View 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"
}
]
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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()

View File

@@ -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;
};

View File

@@ -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));
}

View File

@@ -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

View File

@@ -43,6 +43,7 @@
#include "Configuration.h"
#include "memspec/MemSpecDDR3.h"
#include "memspec/MemSpecDDR4.h"
#include "memspec/MemSpecDDR5.h"
#include "memspec/MemSpecWideIO.h"
#include "memspec/MemSpecLPDDR4.h"
#include "memspec/MemSpecWideIO2.h"
@@ -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")

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View 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;
}

View 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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -39,6 +39,7 @@
#include "Command.h"
#include "checker/CheckerDDR3.h"
#include "checker/CheckerDDR4.h"
#include "checker/CheckerDDR5.h"
#include "checker/CheckerWideIO.h"
#include "checker/CheckerLPDDR4.h"
#include "checker/CheckerWideIO2.h"
@@ -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)

View File

@@ -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;
};

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -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;

View 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);
}
}

View 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

View File

@@ -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;

View File

@@ -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))

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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()

View File

@@ -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;
}

View File

@@ -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

View File

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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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

View File

@@ -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(

View File

@@ -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

View File

@@ -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