Merge branch 'develop' into wip/unit_test_preps

# Conflicts:
#	extensions/standards/DDR5/DRAMSys/controller/checker/CheckerDDR5.cpp
This commit is contained in:
Lukas Steiner
2023-04-14 11:35:32 +02:00
174 changed files with 6822 additions and 3684 deletions

View File

@@ -77,7 +77,7 @@ endif()
set(DRAMSYS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src")
set(DRAMSYS_LIBRARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib")
set(DRAMSYS_TESTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tests")
set(DRAMSYS_RESOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/resources")
set(DRAMSYS_RESOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/configs")
set(DRAMSYS_EXTENSIONS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extensions")
### Build options ###
@@ -137,6 +137,7 @@ FetchContent_Declare(
GIT_REPOSITORY https://github.com/accellera-official/systemc.git
GIT_TAG 2.3.4)
set(DISABLE_COPYRIGHT_MESSAGE True)
FetchContent_MakeAvailable(systemc)
set_target_properties(systemc PROPERTIES FOLDER lib)

View File

@@ -19,7 +19,6 @@ The JSON code below shows an example configuration:
},
{
"clkMhz": 2000,
"type": "generator",
"name": "gen0",
"numRequests": 2000,
"rwRatio": 0.85,
@@ -32,7 +31,6 @@ The JSON code below shows an example configuration:
},
{
"clkMhz": 1000,
"type": "hammer",
"name": "ham0",
"numRequests": 4000,
"rowIncrement": 2097152
@@ -49,11 +47,58 @@ Field Descriptions:
- "mcconfig": memory controller configuration file
- "tracesetup": The trace setup is only used in standalone mode. In library mode or gem5 mode the trace setup is ignored. Each device should be added as a json object inside the "tracesetup" array.
Each **trace setup** device configuration can be a **trace player** ("type": "player"), a **traffic generator** ("type": "generator") or a **row hammer generator** ("type": "hammer"). By not specifing the **type** parameter, the device will act as a **trace player**.
Each **trace setup** device configuration can be a **trace player**, a **traffic generator** or a **row hammer generator**. The type will be automatically concluded based on the given parameters.
All device configurations must define a **clkMhz** (operation frequency of the **traffic initiator**) and a **name** (in case of a trace player this specifies the **trace file** to play; in case of a generator this field is only for identification purposes).
The **maxPendingReadRequests** and **maxPendingWriteRequests** parameters define the maximum number of outstanding read/write requests. The current implementation delays all memory accesses if one limit is reached. The default value (0) disables the limit.
A **traffic generator** can be configured to generate **numRequests** requests in total, of which the **rwRatio** field defines the probability of one request being a read request. The length of a request (in bytes) can be specified with the **dataLength** parameter. The **seed** parameter can be used to produce identical results for all simulations. **minAddress** and **maxAddress** specify the address range, by default the whole address range is used. The parameter **addressDistribution** can either be set to **random** or **sequential**. In case of **sequential** the additional **addressIncrement** field must be specified, defining the address increment after each request.
A **traffic generator** can be configured to generate **numRequests** requests in total, of which the **rwRatio** field defines the probability of one request being a read request. The length of a request (in bytes) can be specified with the **dataLength** parameter. The **seed** parameter can be used to produce identical results for all simulations. **minAddress** and **maxAddress** specify the address range, by default the whole address range is used. The parameter **addressDistribution** can either be set to **random** or **sequential**. In case of **sequential** the additional **addressIncrement** field must be specified, defining the address increment after each request. The address alignment of the random generator can be configured using the **dataAlignment** field. By default, the addresses will be naturally aligned at dataLength.
For more advanced use cases, the traffic generator is capable of acting as a state machine with multiple states that can be configured in the same manner as described earlier. Each state is specified as an element in the **states** array. Each state has to include an unique **id**. The **transitions** field describes all possible transitions from one state to another with their associated **probability**.
In the context of a state machine, there exists another type of generator: the idle generator. In an idle state no requests are issued. The parameter **idleClks** specifies the duration of the idle state.
An example of a state machine configuration with 3 states is shown below.
```json
{
"clkMhz": 100,
"maxPendingReadRequests": 8,
"name": "StateMachine",
"states": [
{
"addressDistribution": "sequential",
"addressIncrement": 256,
"id": 0,
"maxAddress": 1024,
"numRequests": 1000,
"rwRatio": 0.5
},
{
"id": 1,
"idleClks": 1000
},
{
"addressDistribution": "random",
"id": 2,
"maxAddress": 2048,
"minAddress": 1024,
"numRequests": 1000,
"rwRatio": 0.75
}
],
"transitions": [
{
"from": 0,
"probability": 1.0,
"to": 1
},
{
"from": 1,
"probability": 1.0,
"to": 2
}
]
}
```
The **row hammer generator** is a special traffic generator that mimics a row hammer attack. It generates **numRequests** alternating read requests to two different addresses. The first address is 0x0, the second address is specified by the **rowIncrement** parameter and should decode to a different row in the same bank. Since only one outstanding request is allowed, the controller cannot perform any reordering, forcing a row switch (precharge and activate) for each access. That way the number of activations on the target rows are maximized.
@@ -182,7 +227,7 @@ Used fields:
```json
{
"CONGEN": {
"addressmapping": {
"XOR": [
{
"FIRST": 13,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
28,
29,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
13,
14,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
27,
28,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
13,
14,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
28,
29,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
13,
14,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
26,
27,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
13,
14,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANKGROUP_BIT":[
28,
29

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0,
1

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0,
1

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0,
1

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0,
1

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"PSEUDOCHANNEL_BIT":[
29
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"PSEUDOCHANNEL_BIT":[
28
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
28,
29,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
11,
12,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
5,
6,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
27,
28,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
11,
12,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
5,
6,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
27,
28,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BYTE_BIT": [
0
],

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"RANK_BIT":[
30,
31

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
13,
14,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
25,
26,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
12,
13,

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
25,
26

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
11,
12

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
23,
24

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
11,
12

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
26,
27

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
11,
12

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
27,
28

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
12,
13

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
24,
25

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
11,
12

View File

@@ -1,5 +1,5 @@
{
"CONGEN": {
"addressmapping": {
"BANK_BIT": [
4,
5

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 8,
"CCD_L_WR_slr": 32,
"CCD_L_WR2_slr": 16,
"CCD_M_slr": 8,
"CCD_M_WR_slr": 32,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 16,
"WTR_M": 16,
"WTR_S": 4,
"RFC1_slr": 312,
"RFC2_slr": 208,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 8,
"CCD_L_WR_slr": 32,
"CCD_L_WR2_slr": 16,
"CCD_M_slr": 8,
"CCD_M_WR_slr": 32,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 16,
"WTR_M": 16,
"WTR_S": 4,
"RFC1_slr": 312,
"RFC2_slr": 208,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 9,
"CCD_L_WR_slr": 36,
"CCD_L_WR2_slr": 18,
"CCD_M_slr": 9,
"CCD_M_WR_slr": 36,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 18,
"WTR_M": 18,
"WTR_S": 5,
"RFC1_slr": 351,
"RFC2_slr": 234,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 10,
"CCD_L_WR_slr": 40,
"CCD_L_WR2_slr": 20,
"CCD_M_slr": 10,
"CCD_M_WR_slr": 40,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 20,
"WTR_M": 20,
"WTR_S": 5,
"RFC1_slr": 390,
"RFC2_slr": 260,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 11,
"CCD_L_WR_slr": 44,
"CCD_L_WR2_slr": 22,
"CCD_M_slr": 11,
"CCD_M_WR_slr": 44,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 22,
"WTR_M": 22,
"WTR_S": 6,
"RFC1_slr": 429,
"RFC2_slr": 286,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 12,
"CCD_L_WR_slr": 48,
"CCD_L_WR2_slr": 24,
"CCD_M_slr": 12,
"CCD_M_WR_slr": 48,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 24,
"WTR_M": 24,
"WTR_S": 6,
"RFC1_slr": 468,
"RFC2_slr": 312,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 13,
"CCD_L_WR_slr": 52,
"CCD_L_WR2_slr": 26,
"CCD_M_slr": 13,
"CCD_M_WR_slr": 52,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 26,
"WTR_M": 26,
"WTR_S": 7,
"RFC1_slr": 507,
"RFC2_slr": 338,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 14,
"CCD_L_WR_slr": 56,
"CCD_L_WR2_slr": 28,
"CCD_M_slr": 14,
"CCD_M_WR_slr": 56,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 28,
"WTR_M": 28,
"WTR_S": 7,
"RFC1_slr": 546,
"RFC2_slr": 364,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 15,
"CCD_L_WR_slr": 60,
"CCD_L_WR2_slr": 30,
"CCD_M_slr": 15,
"CCD_M_WR_slr": 60,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 30,
"WTR_M": 30,
"WTR_S": 8,
"RFC1_slr": 585,
"RFC2_slr": 390,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 16,
"CCD_L_WR_slr": 64,
"CCD_L_WR2_slr": 32,
"CCD_M_slr": 16,
"CCD_M_WR_slr": 64,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 32,
"WTR_M": 32,
"WTR_S": 8,
"RFC1_slr": 624,
"RFC2_slr": 416,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 8,
"CCD_L_WR_slr": 32,
"CCD_L_WR2_slr": 16,
"CCD_M_slr": 8,
"CCD_M_WR_slr": 32,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 16,
"WTR_M": 16,
"WTR_S": 4,
"RFC1_slr": 312,
"RFC2_slr": 208,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 9,
"CCD_L_WR_slr": 36,
"CCD_L_WR2_slr": 18,
"CCD_M_slr": 9,
"CCD_M_WR_slr": 36,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 18,
"WTR_M": 18,
"WTR_S": 5,
"RFC1_slr": 351,
"RFC2_slr": 234,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 10,
"CCD_L_WR_slr": 40,
"CCD_L_WR2_slr": 20,
"CCD_M_slr": 10,
"CCD_M_WR_slr": 40,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 20,
"WTR_M": 20,
"WTR_S": 5,
"RFC1_slr": 390,
"RFC2_slr": 260,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 11,
"CCD_L_WR_slr": 44,
"CCD_L_WR2_slr": 22,
"CCD_M_slr": 11,
"CCD_M_WR_slr": 44,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 22,
"WTR_M": 22,
"WTR_S": 6,
"RFC1_slr": 429,
"RFC2_slr": 286,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 12,
"CCD_L_WR_slr": 48,
"CCD_L_WR2_slr": 24,
"CCD_M_slr": 12,
"CCD_M_WR_slr": 48,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 24,
"WTR_M": 24,
"WTR_S": 6,
"RFC1_slr": 468,
"RFC2_slr": 312,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 13,
"CCD_L_WR_slr": 52,
"CCD_L_WR2_slr": 26,
"CCD_M_slr": 13,
"CCD_M_WR_slr": 52,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 26,
"WTR_M": 26,
"WTR_S": 7,
"RFC1_slr": 507,
"RFC2_slr": 338,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 14,
"CCD_L_WR_slr": 56,
"CCD_L_WR2_slr": 28,
"CCD_M_slr": 14,
"CCD_M_WR_slr": 56,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 28,
"WTR_M": 28,
"WTR_S": 7,
"RFC1_slr": 546,
"RFC2_slr": 364,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 15,
"CCD_L_WR_slr": 60,
"CCD_L_WR2_slr": 30,
"CCD_M_slr": 15,
"CCD_M_WR_slr": 60,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 30,
"WTR_M": 30,
"WTR_S": 8,
"RFC1_slr": 585,
"RFC2_slr": 390,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 16,
"CCD_L_WR_slr": 64,
"CCD_L_WR2_slr": 32,
"CCD_M_slr": 16,
"CCD_M_WR_slr": 64,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 0,
@@ -50,6 +52,7 @@
"FAW_slr": 32,
"FAW_dlr": 0,
"WTR_L": 32,
"WTR_M": 32,
"WTR_S": 8,
"RFC1_slr": 624,
"RFC2_slr": 416,

View File

@@ -39,6 +39,8 @@
"CCD_L_slr": 8,
"CCD_L_WR_slr": 32,
"CCD_L_WR2_slr": 16,
"CCD_M_slr": 8,
"CCD_M_WR_slr": 32,
"CCD_S_slr": 8,
"CCD_S_WR_slr": 8,
"CCD_dlr": 8,
@@ -49,7 +51,8 @@
"RRD_dlr": 4,
"FAW_slr": 32,
"FAW_dlr": 16,
"WTR_L": 16,
"WTR_L": 16,
"WTR_M": 16,
"WTR_S": 4,
"RFC1_slr": 312,
"RFC2_slr": 208,

View File

@@ -217,7 +217,7 @@ void SimulationDialog::saveConfiguration(QFile &file)
loadConfigurationFromTextFields();
std::string dump = DRAMSys::Config::dump(configuration, 4);
std::string dump = nlohmann::json(configuration).dump(4);
out << dump.c_str();
}
@@ -252,13 +252,13 @@ void SimulationDialog::loadConfigurationFromTextFields()
try
{
from_dump(ui->addressMappingTextEdit->toPlainText().toStdString(), addressMapping);
from_dump(ui->mcConfigTextEdit->toPlainText().toStdString(), mcConfig);
from_dump(ui->memSpecTextEdit->toPlainText().toStdString(), memSpec);
from_dump(ui->simConfigTextEdit->toPlainText().toStdString(), simConfig);
nlohmann::json::parse(ui->addressMappingTextEdit->toPlainText().toStdString()).get_to(addressMapping);
nlohmann::json::parse(ui->mcConfigTextEdit->toPlainText().toStdString()).get_to(mcConfig);
nlohmann::json::parse(ui->memSpecTextEdit->toPlainText().toStdString()).get_to(memSpec);
nlohmann::json::parse(ui->simConfigTextEdit->toPlainText().toStdString()).get_to(simConfig);
if (!ui->traceSetupTextEdit->toPlainText().toStdString().empty())
from_dump(ui->traceSetupTextEdit->toPlainText().toStdString(), traceSetup);
nlohmann::json::parse(ui->traceSetupTextEdit->toPlainText().toStdString()).get_to(traceSetup);
}
catch (const std::exception &e)
{
@@ -300,9 +300,9 @@ void SimulationDialog::loadConfiguration()
{
ui->simulationIdLabel->setEnabled(true);
ui->simulationId->setEnabled(true);
ui->simulationId->setText(configuration.simulationId.c_str());
ui->simulationId->setText(configuration.simulationid.c_str());
ui->simulationIdLineEdit->setText(configuration.simulationId.c_str());
ui->simulationIdLineEdit->setText(configuration.simulationid.c_str());
loadSimConfig();
loadMcConfig();
@@ -316,7 +316,7 @@ void SimulationDialog::loadSimConfig()
{
ui->simConfigTextEdit->clear();
std::string dump = DRAMSys::Config::dump(configuration.simConfig, 4);
std::string dump = nlohmann::json(configuration.simconfig).dump(4);
ui->simConfigTextEdit->setText(dump.c_str());
}
@@ -324,7 +324,7 @@ void SimulationDialog::loadMcConfig()
{
ui->mcConfigTextEdit->clear();
std::string dump = DRAMSys::Config::dump(configuration.mcConfig, 4);
std::string dump = nlohmann::json(configuration.mcconfig).dump(4);
ui->mcConfigTextEdit->setText(dump.c_str());
}
@@ -332,7 +332,7 @@ void SimulationDialog::loadMemSpec()
{
ui->memSpecTextEdit->clear();
std::string dump = DRAMSys::Config::dump(configuration.memSpec, 4);
std::string dump = nlohmann::json(configuration.memspec).dump(4);
ui->memSpecTextEdit->setText(dump.c_str());
}
@@ -340,7 +340,7 @@ void SimulationDialog::loadAddressMapping()
{
ui->addressMappingTextEdit->clear();
std::string dump = DRAMSys::Config::dump(configuration.addressMapping, 4);
std::string dump = nlohmann::json(configuration.addressmapping).dump(4);
ui->addressMappingTextEdit->setText(dump.c_str());
}
@@ -348,9 +348,9 @@ void SimulationDialog::loadTraceSetup()
{
ui->traceSetupTextEdit->clear();
if (const auto &traceSetup = configuration.traceSetup)
if (const auto &traceSetup = configuration.tracesetup)
{
std::string dump = DRAMSys::Config::dump(*traceSetup, 4);
std::string dump = nlohmann::json(*traceSetup).dump(4);
ui->traceSetupTextEdit->setText(dump.c_str());
}
}
@@ -359,7 +359,7 @@ void SimulationDialog::loadPreview()
{
ui->previewTextEdit->clear();
std::string dump = DRAMSys::Config::dump(configuration, 4);
std::string dump = nlohmann::json(configuration).dump(4);
ui->previewTextEdit->setText(dump.c_str());
}
@@ -372,7 +372,7 @@ QFileInfoList SimulationDialog::getSimulationResults()
for (const auto &fileInfo : baseDir.entryInfoList())
{
if (fileInfo.baseName().startsWith(configuration.simulationId.c_str()))
if (fileInfo.baseName().startsWith(configuration.simulationid.c_str()))
{
// Dont open tracefiles that are older than a few seconds
if (fileInfo.metadataChangeTime().secsTo(QDateTime::currentDateTime()) > 30)

View File

@@ -45,77 +45,80 @@ using namespace tlm;
MemSpecDDR5::MemSpecDDR5(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::DDR5,
memSpec.memArchitectureSpec.entries.at("nbrOfChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memArchitectureSpec.entries.at("nbrOfRanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks")
/ memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks")
* memSpec.memArchitectureSpec.entries.at("nbrOfRanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups")
* memSpec.memArchitectureSpec.entries.at("nbrOfRanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfDevices")),
dimmRanksPerChannel(memSpec.memArchitectureSpec.entries.at("nbrOfDIMMRanks")),
physicalRanksPerDimmRank(memSpec.memArchitectureSpec.entries.at("nbrOfPhysicalRanks")),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
/ memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
dimmRanksPerChannel(memSpec.memarchitecturespec.entries.at("nbrOfDIMMRanks")),
physicalRanksPerDimmRank(memSpec.memarchitecturespec.entries.at("nbrOfPhysicalRanks")),
physicalRanksPerChannel(physicalRanksPerDimmRank * dimmRanksPerChannel),
logicalRanksPerPhysicalRank(memSpec.memArchitectureSpec.entries.at("nbrOfLogicalRanks")),
logicalRanksPerPhysicalRank(memSpec.memarchitecturespec.entries.at("nbrOfLogicalRanks")),
logicalRanksPerChannel(logicalRanksPerPhysicalRank * physicalRanksPerChannel),
cmdMode(memSpec.memArchitectureSpec.entries.at("cmdMode")),
refMode(memSpec.memArchitectureSpec.entries.at("refMode")),
RAAIMT(memSpec.memArchitectureSpec.entries.at("RAAIMT")),
RAAMMT(memSpec.memArchitectureSpec.entries.at("RAAMMT")),
RAACDR(memSpec.memArchitectureSpec.entries.at("RAACDR")),
tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")),
tPPD (tCK * memSpec.memTimingSpec.entries.at("PPD")),
tRP (tCK * memSpec.memTimingSpec.entries.at("RP")),
tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")),
cmdMode(memSpec.memarchitecturespec.entries.at("cmdMode")),
refMode(memSpec.memarchitecturespec.entries.at("refMode")),
RAAIMT(memSpec.memarchitecturespec.entries.at("RAAIMT")),
RAAMMT(memSpec.memarchitecturespec.entries.at("RAAMMT")),
RAACDR(memSpec.memarchitecturespec.entries.at("RAACDR")),
tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")),
tPPD (tCK * memSpec.memtimingspec.entries.at("PPD")),
tRP (tCK * memSpec.memtimingspec.entries.at("RP")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC (tRAS + tRP),
tRL (tCK * memSpec.memTimingSpec.entries.at("RL")),
tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")),
tRPRE (tCK * memSpec.memTimingSpec.entries.at("RPRE")),
tRPST (tCK * memSpec.memTimingSpec.entries.at("RPST")),
tRDDQS (tCK * memSpec.memTimingSpec.entries.at("RDDQS")),
tWL (tCK * memSpec.memTimingSpec.entries.at("WL")),
tWPRE (tCK * memSpec.memTimingSpec.entries.at("WPRE")),
tWPST (tCK * memSpec.memTimingSpec.entries.at("WPST")),
tWR (tCK * memSpec.memTimingSpec.entries.at("WR")),
tCCD_L_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_L_slr")),
tCCD_L_WR_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_L_WR_slr")),
tCCD_L_WR2_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_L_WR2_slr")),
tCCD_S_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_S_slr")),
tCCD_S_WR_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_S_WR_slr")),
tCCD_dlr (tCK * memSpec.memTimingSpec.entries.at("CCD_dlr")),
tCCD_WR_dlr (tCK * memSpec.memTimingSpec.entries.at("CCD_WR_dlr")),
tCCD_WR_dpr (tCK * memSpec.memTimingSpec.entries.at("CCD_WR_dpr")),
tRRD_L_slr (tCK * memSpec.memTimingSpec.entries.at("RRD_L_slr")),
tRRD_S_slr (tCK * memSpec.memTimingSpec.entries.at("RRD_S_slr")),
tRRD_dlr (tCK * memSpec.memTimingSpec.entries.at("RRD_dlr")),
tFAW_slr (tCK * memSpec.memTimingSpec.entries.at("FAW_slr")),
tFAW_dlr (tCK * memSpec.memTimingSpec.entries.at("FAW_dlr")),
tWTR_L (tCK * memSpec.memTimingSpec.entries.at("WTR_L")),
tWTR_S (tCK * memSpec.memTimingSpec.entries.at("WTR_S")),
tRFC_slr ((refMode == 1) ? tCK * memSpec.memTimingSpec.entries.at("RFC1_slr")
: tCK * memSpec.memTimingSpec.entries.at("RFC2_slr")),
tRFC_dlr ((refMode == 1) ? tCK * memSpec.memTimingSpec.entries.at("RFC1_dlr")
: tCK * memSpec.memTimingSpec.entries.at("RFC2_dlr")),
tRFC_dpr ((refMode == 1) ? tCK * memSpec.memTimingSpec.entries.at("RFC1_dpr")
: tCK * memSpec.memTimingSpec.entries.at("RFC2_dpr")),
tRFCsb_slr (tCK * memSpec.memTimingSpec.entries.at("RFCsb_slr")),
tRFCsb_dlr (tCK * memSpec.memTimingSpec.entries.at("RFCsb_dlr")),
tREFI ((refMode == 1) ? tCK * memSpec.memTimingSpec.entries.at("REFI1")
: tCK * memSpec.memTimingSpec.entries.at("REFI2")),
tREFIsb (tCK * memSpec.memTimingSpec.entries.at("REFISB")),
tREFSBRD_slr (tCK * memSpec.memTimingSpec.entries.at("REFSBRD_slr")),
tREFSBRD_dlr (tCK * memSpec.memTimingSpec.entries.at("REFSBRD_dlr")),
tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")),
tCPDED (tCK * memSpec.memTimingSpec.entries.at("CPDED")),
tPD (tCK * memSpec.memTimingSpec.entries.at("PD")),
tXP (tCK * memSpec.memTimingSpec.entries.at("XP")),
tACTPDEN (tCK * memSpec.memTimingSpec.entries.at("ACTPDEN")),
tPRPDEN (tCK * memSpec.memTimingSpec.entries.at("PRPDEN")),
tREFPDEN (tCK * memSpec.memTimingSpec.entries.at("REFPDEN")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tRPRE (tCK * memSpec.memtimingspec.entries.at("RPRE")),
tRPST (tCK * memSpec.memtimingspec.entries.at("RPST")),
tRDDQS (tCK * memSpec.memtimingspec.entries.at("RDDQS")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tWPRE (tCK * memSpec.memtimingspec.entries.at("WPRE")),
tWPST (tCK * memSpec.memtimingspec.entries.at("WPST")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tCCD_L_slr (tCK * memSpec.memtimingspec.entries.at("CCD_L_slr")),
tCCD_L_WR_slr (tCK * memSpec.memtimingspec.entries.at("CCD_L_WR_slr")),
tCCD_L_WR2_slr (tCK * memSpec.memtimingspec.entries.at("CCD_L_WR2_slr")),
tCCD_M_slr (tCK * memSpec.memtimingspec.entries.at("CCD_M_slr")),
tCCD_M_WR_slr (tCK * memSpec.memtimingspec.entries.at("CCD_M_WR_slr")),
tCCD_S_slr (tCK * memSpec.memtimingspec.entries.at("CCD_S_slr")),
tCCD_S_WR_slr (tCK * memSpec.memtimingspec.entries.at("CCD_S_WR_slr")),
tCCD_dlr (tCK * memSpec.memtimingspec.entries.at("CCD_dlr")),
tCCD_WR_dlr (tCK * memSpec.memtimingspec.entries.at("CCD_WR_dlr")),
tCCD_WR_dpr (tCK * memSpec.memtimingspec.entries.at("CCD_WR_dpr")),
tRRD_L_slr (tCK * memSpec.memtimingspec.entries.at("RRD_L_slr")),
tRRD_S_slr (tCK * memSpec.memtimingspec.entries.at("RRD_S_slr")),
tRRD_dlr (tCK * memSpec.memtimingspec.entries.at("RRD_dlr")),
tFAW_slr (tCK * memSpec.memtimingspec.entries.at("FAW_slr")),
tFAW_dlr (tCK * memSpec.memtimingspec.entries.at("FAW_dlr")),
tWTR_L (tCK * memSpec.memtimingspec.entries.at("WTR_L")),
tWTR_M (tCK * memSpec.memtimingspec.entries.at("WTR_M")),
tWTR_S (tCK * memSpec.memtimingspec.entries.at("WTR_S")),
tRFC_slr ((refMode == 1) ? tCK * memSpec.memtimingspec.entries.at("RFC1_slr")
: tCK * memSpec.memtimingspec.entries.at("RFC2_slr")),
tRFC_dlr ((refMode == 1) ? tCK * memSpec.memtimingspec.entries.at("RFC1_dlr")
: tCK * memSpec.memtimingspec.entries.at("RFC2_dlr")),
tRFC_dpr ((refMode == 1) ? tCK * memSpec.memtimingspec.entries.at("RFC1_dpr")
: tCK * memSpec.memtimingspec.entries.at("RFC2_dpr")),
tRFCsb_slr (tCK * memSpec.memtimingspec.entries.at("RFCsb_slr")),
tRFCsb_dlr (tCK * memSpec.memtimingspec.entries.at("RFCsb_dlr")),
tREFI ((refMode == 1) ? tCK * memSpec.memtimingspec.entries.at("REFI1")
: tCK * memSpec.memtimingspec.entries.at("REFI2")),
tREFIsb (tCK * memSpec.memtimingspec.entries.at("REFISB")),
tREFSBRD_slr (tCK * memSpec.memtimingspec.entries.at("REFSBRD_slr")),
tREFSBRD_dlr (tCK * memSpec.memtimingspec.entries.at("REFSBRD_dlr")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")),
tCPDED (tCK * memSpec.memtimingspec.entries.at("CPDED")),
tPD (tCK * memSpec.memtimingspec.entries.at("PD")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tACTPDEN (tCK * memSpec.memtimingspec.entries.at("ACTPDEN")),
tPRPDEN (tCK * memSpec.memtimingspec.entries.at("PRPDEN")),
tREFPDEN (tCK * memSpec.memtimingspec.entries.at("REFPDEN")),
shortCmdOffset (cmdMode == 2 ? 1 * tCK : 0 * tCK),
longCmdOffset (cmdMode == 2 ? 3 * tCK : 1 * tCK),
tBURST16 (tCK * 8),

View File

@@ -74,6 +74,8 @@ public:
const sc_core::sc_time tCCD_L_slr;
const sc_core::sc_time tCCD_L_WR_slr;
const sc_core::sc_time tCCD_L_WR2_slr;
const sc_core::sc_time tCCD_M_slr;
const sc_core::sc_time tCCD_M_WR_slr;
const sc_core::sc_time tCCD_S_slr;
const sc_core::sc_time tCCD_S_WR_slr;
const sc_core::sc_time tCCD_dlr;
@@ -85,6 +87,7 @@ public:
const sc_core::sc_time tFAW_slr;
const sc_core::sc_time tFAW_dlr;
const sc_core::sc_time tWTR_L;
const sc_core::sc_time tWTR_M;
const sc_core::sc_time tWTR_S;
const sc_core::sc_time tRFC_slr;
const sc_core::sc_time tRFC_dlr;

View File

@@ -104,6 +104,7 @@ CheckerDDR5::CheckerDDR5(const Configuration& config)
tRDWR_ddr = memSpec->tRL - memSpec->tWL + tBURST16 + memSpec->tRTRS
- memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
tCCD_L_WTR_slr = memSpec->tWL + tBURST16 + memSpec->tWTR_L;
tCCD_M_WTR_slr = memSpec->tWL + tBURST16 + memSpec->tWTR_M; // tWTR_M is max(16nck, 10ns)
tCCD_S_WTR_slr = memSpec->tWL + tBURST16 + memSpec->tWTR_S;
tCCD_WTR_dlr = memSpec->tWL + tBURST16 + memSpec->tWTR_S;
tWRWR_dpr = std::max(memSpec->tCCD_WR_dpr, tBURST16 + memSpec->tRTRS);
@@ -140,10 +141,14 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic
if (lastCommandStart != scMaxTime)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
if (lastCommandStart != scMaxTime)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
if (lastCommandStart != scMaxTime)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_M_slr);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalRank.ID()];
if (lastCommandStart != scMaxTime)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr);
@@ -178,7 +183,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
if (lastCommandStart != scMaxTime)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_M_slr);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalRank.ID()];
if (lastCommandStart != scMaxTime)
@@ -224,13 +229,22 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic
}
}
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != scMaxTime)
{
if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
if (lastCommandStart != scMaxTime)
{
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_M_WTR_slr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_M_WTR_slr);
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalRank.ID()];
@@ -274,9 +288,9 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic
if (lastCommandStart != scMaxTime)
{
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_M_WTR_slr + tBURST16);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_M_WTR_slr);
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalRank.ID()];
@@ -419,22 +433,47 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
if (lastCommandStart != scMaxTime)
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
{
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup.ID()] == 32)
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != scMaxTime)
{
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32)
{
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR_slr);
}
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR2_slr);
}
else
{
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
{
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
if (lastCommandStart != lastScheduledByCommandAndBank[Command::WR][bank.ID()]) // different bank
{
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup.ID()] == 32)
{
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_M_WR_slr);
}
else
{
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_M_WR_slr);
}
}
}
else // no RMW
{
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
if (lastCommandStart != scMaxTime)
{
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup.ID()] == 32)
{
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR2_slr);
}
else
{
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr);
}
}
}
@@ -470,22 +509,34 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
if (lastCommandStart != scMaxTime)
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
{
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup.ID()] == 32)
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
if (lastCommandStart != scMaxTime)
{
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR_slr);
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup.ID()] == 32)
{
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_M_WR_slr);
}
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR2_slr);
{
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_M_WR_slr);
}
}
else
}
else // no RMW
{
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
if (lastCommandStart != scMaxTime)
{
if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup.ID()] == 32)
{
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR2_slr);
}
else
{
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr);
}
}
}

View File

@@ -96,6 +96,7 @@ private:
sc_core::sc_time tRDWR_dpr;
sc_core::sc_time tRDWR_ddr;
sc_core::sc_time tCCD_L_WTR_slr;
sc_core::sc_time tCCD_M_WTR_slr;
sc_core::sc_time tCCD_S_WTR_slr;
sc_core::sc_time tCCD_WTR_dlr;
sc_core::sc_time tWRWR_dpr;

View File

@@ -44,51 +44,51 @@ using namespace tlm;
MemSpecHBM3::MemSpecHBM3(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::HBM3,
memSpec.memArchitectureSpec.entries.at("nbrOfChannels"),
memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"),
memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks")
/ memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks")
* memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"),
memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups")
* memSpec.memArchitectureSpec.entries.at("nbrOfPseudoChannels"),
memSpec.memArchitectureSpec.entries.at("nbrOfDevices")),
RAAIMT(memSpec.memArchitectureSpec.entries.at("RAAIMT")),
RAAMMT(memSpec.memArchitectureSpec.entries.at("RAAMMT")),
RAACDR(memSpec.memArchitectureSpec.entries.at("RAACDR")),
tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")),
tRC (tCK * memSpec.memTimingSpec.entries.at("RC")),
tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")),
tRCDRD (tCK * memSpec.memTimingSpec.entries.at("RCDRD")),
tRCDWR (tCK * memSpec.memTimingSpec.entries.at("RCDWR")),
tRRDL (tCK * memSpec.memTimingSpec.entries.at("RRDL")),
tRRDS (tCK * memSpec.memTimingSpec.entries.at("RRDS")),
tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")),
tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")),
tRP (tCK * memSpec.memTimingSpec.entries.at("RP")),
tRL (tCK * memSpec.memTimingSpec.entries.at("RL")),
tWL (tCK * memSpec.memTimingSpec.entries.at("WL")),
tPL (tCK * memSpec.memTimingSpec.entries.at("PL")),
tWR (tCK * memSpec.memTimingSpec.entries.at("WR")),
tCCDL (tCK * memSpec.memTimingSpec.entries.at("CCDL")),
tCCDS (tCK * memSpec.memTimingSpec.entries.at("CCDS")),
tWTRL (tCK * memSpec.memTimingSpec.entries.at("WTRL")),
tWTRS (tCK * memSpec.memTimingSpec.entries.at("WTRS")),
tRTW (tCK * memSpec.memTimingSpec.entries.at("RTW")),
tXP (tCK * memSpec.memTimingSpec.entries.at("XP")),
tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")),
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
/ memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups")
* memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
RAAIMT(memSpec.memarchitecturespec.entries.at("RAAIMT")),
RAAMMT(memSpec.memarchitecturespec.entries.at("RAAMMT")),
RAACDR(memSpec.memarchitecturespec.entries.at("RAACDR")),
tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tRC (tCK * memSpec.memtimingspec.entries.at("RC")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRCDRD (tCK * memSpec.memtimingspec.entries.at("RCDRD")),
tRCDWR (tCK * memSpec.memtimingspec.entries.at("RCDWR")),
tRRDL (tCK * memSpec.memtimingspec.entries.at("RRDL")),
tRRDS (tCK * memSpec.memtimingspec.entries.at("RRDS")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tRP (tCK * memSpec.memtimingspec.entries.at("RP")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tPL (tCK * memSpec.memtimingspec.entries.at("PL")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tCCDL (tCK * memSpec.memtimingspec.entries.at("CCDL")),
tCCDS (tCK * memSpec.memtimingspec.entries.at("CCDS")),
tWTRL (tCK * memSpec.memtimingspec.entries.at("WTRL")),
tWTRS (tCK * memSpec.memtimingspec.entries.at("WTRS")),
tRTW (tCK * memSpec.memtimingspec.entries.at("RTW")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD (tCKE),
tCKESR (tCKE + tCK),
tXS (tCK * memSpec.memTimingSpec.entries.at("XS")),
tRFC (tCK * memSpec.memTimingSpec.entries.at("RFC")),
tRFCPB (tCK * memSpec.memTimingSpec.entries.at("RFCPB")),
tRREFD (tCK * memSpec.memTimingSpec.entries.at("RREFD")),
tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")),
tREFIPB (tCK * memSpec.memTimingSpec.entries.at("REFIPB")),
tPPD (tCK * memSpec.memTimingSpec.entries.at("PPD"))
tXS (tCK * memSpec.memtimingspec.entries.at("XS")),
tRFC (tCK * memSpec.memtimingspec.entries.at("RFC")),
tRFCPB (tCK * memSpec.memtimingspec.entries.at("RFCPB")),
tRREFD (tCK * memSpec.memtimingspec.entries.at("RREFD")),
tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")),
tREFIPB (tCK * memSpec.memtimingspec.entries.at("REFIPB")),
tPPD (tCK * memSpec.memtimingspec.entries.at("PPD"))
{
commandLengthInCycles[Command::ACT] = 1.5;
commandLengthInCycles[Command::PREPB] = 0.5;

View File

@@ -44,42 +44,42 @@ using namespace tlm;
MemSpecLPDDR5::MemSpecLPDDR5(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::LPDDR5,
memSpec.memArchitectureSpec.entries.at("nbrOfChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memArchitectureSpec.entries.at("nbrOfRanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks")
/ memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks")
* memSpec.memArchitectureSpec.entries.at("nbrOfRanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups")
* memSpec.memArchitectureSpec.entries.at("nbrOfRanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfDevices")),
per2BankOffset(memSpec.memArchitectureSpec.entries.at("per2BankOffset")),
tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")),
tREFIpb (tCK * memSpec.memTimingSpec.entries.at("REFIpb")),
tRFCab (tCK * memSpec.memTimingSpec.entries.at("RFCab")),
tRFCpb (tCK * memSpec.memTimingSpec.entries.at("RFCpb")),
tRPab (tCK * memSpec.memTimingSpec.entries.at("RPab")),
tRPpb (tCK * memSpec.memTimingSpec.entries.at("RPpb")),
tRCab (tCK * memSpec.memTimingSpec.entries.at("RCab")),
tRCpb (tCK * memSpec.memTimingSpec.entries.at("RCpb")),
tPPD (tCK * memSpec.memTimingSpec.entries.at("PPD")),
tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")),
tRCD_L (tCK * memSpec.memTimingSpec.entries.at("RCD_L")),
tRCD_S (tCK * memSpec.memTimingSpec.entries.at("RCD_S")),
tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")),
tRRD (tCK * memSpec.memTimingSpec.entries.at("RRD")),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
/ memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
per2BankOffset(memSpec.memarchitecturespec.entries.at("per2BankOffset")),
tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")),
tREFIpb (tCK * memSpec.memtimingspec.entries.at("REFIpb")),
tRFCab (tCK * memSpec.memtimingspec.entries.at("RFCab")),
tRFCpb (tCK * memSpec.memtimingspec.entries.at("RFCpb")),
tRPab (tCK * memSpec.memtimingspec.entries.at("RPab")),
tRPpb (tCK * memSpec.memtimingspec.entries.at("RPpb")),
tRCab (tCK * memSpec.memtimingspec.entries.at("RCab")),
tRCpb (tCK * memSpec.memtimingspec.entries.at("RCpb")),
tPPD (tCK * memSpec.memtimingspec.entries.at("PPD")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRCD_L (tCK * memSpec.memtimingspec.entries.at("RCD_L")),
tRCD_S (tCK * memSpec.memtimingspec.entries.at("RCD_S")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
tRRD (tCK * memSpec.memtimingspec.entries.at("RRD")),
//tCCD (tCK * parseUint(memspec["memtimingspec"], "CCD")),
tRL (tCK * memSpec.memTimingSpec.entries.at("RL")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
//tRPST (tCK * parseUint(memspec["memtimingspec"], "RPST")),
//tDQSCK (tCK * parseUint(memspec["memtimingspec"], "DQSCK")),
tRBTP (tCK * memSpec.memTimingSpec.entries.at("RBTP")),
tWL (tCK * memSpec.memTimingSpec.entries.at("WL")),
tRBTP (tCK * memSpec.memtimingspec.entries.at("RBTP")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
//tDQSS (tCK * parseUint(memspec["memtimingspec"], "DQSS")),
//tDQS2DQ (tCK * parseUint(memspec["memtimingspec"], "DQS2DQ")),
tWR (tCK * memSpec.memTimingSpec.entries.at("WR")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
//tWPRE (tCK * parseUint(memspec["memtimingspec"], "WPRE")),
//tWTR (tCK * parseUint(memspec["memtimingspec"], "WTR")),
//tXP (tCK * parseUint(memspec["memtimingspec"] "XP")),
@@ -88,20 +88,20 @@ MemSpecLPDDR5::MemSpecLPDDR5(const DRAMSys::Config::MemSpec &memSpec)
//tESCKE (tCK * parseUint(memspec["memtimingspec"], "ESCKE")),
//tCKE (tCK * parseUint(memspec["memtimingspec"], "CKE")),
//tCMDCKE (tCK * parseUint(memspec["memtimingspec"], "CMDCKE")),
BL_n_min_16(tCK * memSpec.memTimingSpec.entries.at("BL_n_min_16")),
BL_n_max_16(tCK * memSpec.memTimingSpec.entries.at("BL_n_max_16")),
BL_n_L_16(tCK * memSpec.memTimingSpec.entries.at("BL_n_L_16")),
BL_n_S_16(tCK * memSpec.memTimingSpec.entries.at("BL_n_S_16")),
BL_n_min_32(tCK * memSpec.memTimingSpec.entries.at("BL_n_min_32")),
BL_n_max_32(tCK * memSpec.memTimingSpec.entries.at("BL_n_max_32")),
BL_n_L_32(tCK * memSpec.memTimingSpec.entries.at("BL_n_L_32")),
BL_n_S_32(tCK * memSpec.memTimingSpec.entries.at("BL_n_S_32")),
tWTR_L (tCK * memSpec.memTimingSpec.entries.at("WTR_L")),
tWTR_S (tCK * memSpec.memTimingSpec.entries.at("WTR_S")),
tWCK2DQO(tCK * memSpec.memTimingSpec.entries.at("WCK2DQO")),
tpbR2act(tCK * memSpec.memTimingSpec.entries.at("pbR2act")),
tpbR2pbR(tCK * memSpec.memTimingSpec.entries.at("pbR2pbR")),
tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")),
BL_n_min_16(tCK * memSpec.memtimingspec.entries.at("BL_n_min_16")),
BL_n_max_16(tCK * memSpec.memtimingspec.entries.at("BL_n_max_16")),
BL_n_L_16(tCK * memSpec.memtimingspec.entries.at("BL_n_L_16")),
BL_n_S_16(tCK * memSpec.memtimingspec.entries.at("BL_n_S_16")),
BL_n_min_32(tCK * memSpec.memtimingspec.entries.at("BL_n_min_32")),
BL_n_max_32(tCK * memSpec.memtimingspec.entries.at("BL_n_max_32")),
BL_n_L_32(tCK * memSpec.memtimingspec.entries.at("BL_n_L_32")),
BL_n_S_32(tCK * memSpec.memtimingspec.entries.at("BL_n_S_32")),
tWTR_L (tCK * memSpec.memtimingspec.entries.at("WTR_L")),
tWTR_S (tCK * memSpec.memtimingspec.entries.at("WTR_S")),
tWCK2DQO(tCK * memSpec.memtimingspec.entries.at("WCK2DQO")),
tpbR2act(tCK * memSpec.memtimingspec.entries.at("pbR2act")),
tpbR2pbR(tCK * memSpec.memtimingspec.entries.at("pbR2pbR")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")),
tBURST16(tCK * 16 / dataRate),
tBURST32(tCK * 32 / dataRate),
bankMode(groupsPerRank != 1 ? BankMode::MBG : (banksPerRank == 16 ? BankMode::M16B : BankMode::M8B))

View File

@@ -1,122 +0,0 @@
/*
* Copyright (c) 2021, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#include "AddressMapping.h"
#include <iostream>
namespace DRAMSys::Config
{
void to_json(json_t &j, const AddressMapping &m)
{
auto congen = json_t{{"BYTE_BIT", m.byteBits},
{"COLUMN_BIT", m.columnBits},
{"ROW_BIT", m.rowBits},
{"BANK_BIT", m.bankBits},
{"BANKGROUP_BIT", m.bankGroupBits},
{"RANK_BIT", m.rankBits},
{"CHANNEL_BIT", m.channelBits},
{"XOR", m.xorBits}};
remove_null_values(congen);
j["CONGEN"] = congen;
}
void from_json(const json_t &j, AddressMapping &m)
{
json_t j_addressmapping = get_config_json(j, addressMappingPath, "CONGEN");
json_t congen;
if (j_addressmapping["CONGEN"].is_null())
congen = j_addressmapping;
else
congen = j_addressmapping["CONGEN"];
if (congen.contains("BYTE_BIT"))
congen.at("BYTE_BIT").get_to(m.byteBits);
if (congen.contains("COLUMN_BIT"))
congen.at("COLUMN_BIT").get_to(m.columnBits);
if (congen.contains("ROW_BIT"))
congen.at("ROW_BIT").get_to(m.rowBits);
if (congen.contains("BANK_BIT"))
congen.at("BANK_BIT").get_to(m.bankBits);
if (congen.contains("BANKGROUP_BIT"))
congen.at("BANKGROUP_BIT").get_to(m.bankGroupBits);
if (congen.contains("RANK_BIT"))
congen.at("RANK_BIT").get_to(m.rankBits);
// HBM pseudo channels are internally modelled as ranks
if (congen.contains("PSEUDOCHANNEL_BIT"))
congen.at("PSEUDOCHANNEL_BIT").get_to(m.rankBits);
if (congen.contains("CHANNEL_BIT"))
congen.at("CHANNEL_BIT").get_to(m.channelBits);
if (congen.contains("XOR"))
congen.at("XOR").get_to(m.xorBits);
}
void to_json(json_t &j, const XorPair &x)
{
j = json_t{{"FIRST", x.first}, {"SECOND", x.second}};
}
void from_json(const json_t &j, XorPair &x)
{
j.at("FIRST").get_to(x.first);
j.at("SECOND").get_to(x.second);
}
void from_dump(const std::string &dump, AddressMapping &c)
{
json_t json_addressmapping = json_t::parse(dump).at("addressmapping");
json_addressmapping.get_to(c);
}
std::string dump(const AddressMapping &c, unsigned int indentation)
{
json_t json_addressmapping;
json_addressmapping["addressmapping"] = c;
return json_addressmapping.dump(indentation);
}
} // namespace DRAMSys::Config

View File

@@ -36,40 +36,47 @@
#ifndef DRAMSYSCONFIGURATION_ADDRESSMAPPING_H
#define DRAMSYSCONFIGURATION_ADDRESSMAPPING_H
#include "DRAMSys/config/ConfigUtil.h"
#include "DRAMSys/util/json.h"
#include <optional>
namespace DRAMSys::Config
{
const std::string addressMappingPath = "addressmapping";
struct XorPair
{
unsigned int first;
unsigned int second;
unsigned int FIRST;
unsigned int SECOND;
};
void to_json(json_t &j, const XorPair &x);
void from_json(const json_t &j, XorPair &x);
NLOHMANN_JSONIFY_ALL_THINGS(XorPair, FIRST, SECOND)
struct AddressMapping
{
std::optional<std::vector<unsigned int>> byteBits;
std::optional<std::vector<unsigned int>> columnBits;
std::optional<std::vector<unsigned int>> rowBits;
std::optional<std::vector<unsigned int>> bankBits;
std::optional<std::vector<unsigned int>> bankGroupBits;
std::optional<std::vector<unsigned int>> rankBits;
std::optional<std::vector<unsigned int>> channelBits;
std::optional<std::vector<XorPair>> xorBits;
static constexpr std::string_view KEY = "addressmapping";
static constexpr std::string_view SUB_DIR = "addressmapping";
std::optional<std::vector<unsigned int>> BYTE_BIT;
std::optional<std::vector<unsigned int>> COLUMN_BIT;
std::optional<std::vector<unsigned int>> ROW_BIT;
std::optional<std::vector<unsigned int>> BANK_BIT;
std::optional<std::vector<unsigned int>> BANKGROUP_BIT;
std::optional<std::vector<unsigned int>> RANK_BIT;
std::optional<std::vector<unsigned int>> PSEUDOCHANNEL_BIT;
std::optional<std::vector<unsigned int>> CHANNEL_BIT;
std::optional<std::vector<XorPair>> XOR;
};
void to_json(json_t &j, const AddressMapping &m);
void from_json(const json_t &j, AddressMapping &m);
void from_dump(const std::string &dump, AddressMapping &c);
std::string dump(const AddressMapping &c, unsigned int indentation = -1);
NLOHMANN_JSONIFY_ALL_THINGS(AddressMapping,
BYTE_BIT,
COLUMN_BIT,
ROW_BIT,
BANK_BIT,
BANKGROUP_BIT,
RANK_BIT,
PSEUDOCHANNEL_BIT,
CHANNEL_BIT,
XOR)
} // namespace Configuration

View File

@@ -1,116 +0,0 @@
/*
* Copyright (c) 2021, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#ifndef DRAMSYSCONFIGURATION_UTIL_H
#define DRAMSYSCONFIGURATION_UTIL_H
#include "DRAMSys/util/json.h"
#include <optional>
#include <utility>
namespace DRAMSys::Config
{
//using json_t = nlohmann::json;
// template <typename T>
// class Optional : public std::pair<T, bool>
// {
// public:
// Optional() : std::pair<T, bool>{{}, false}
// {
// }
// Optional(const T &v) : std::pair<T, bool>{v, true}
// {
// }
// bool isValid() const
// {
// return this->second;
// }
// const T &getValue() const
// {
// assert(this->second == true);
// return this->first;
// }
// void setValue(const T &v)
// {
// this->first = v;
// this->second = true;
// }
// void invalidate()
// {
// this->second = false;
// }
// /**
// * This methods only purpose is to make a optional type
// * valid so that it can be written to by reference.
// */
// T &setByReference()
// {
// this->second = true;
// return this->first;
// }
// };
template <typename T>
void invalidateEnum(T& value)
{
if (value.has_value() && value.value() == T::value_type::Invalid)
value.reset();
}
json_t get_config_json(const json_t& j, const std::string& configPath, const std::string& objectName);
inline void remove_null_values(json_t& j)
{
std::vector<std::string> keysToRemove;
for (const auto& element : j.items())
{
if (element.value() == nullptr)
keysToRemove.emplace_back(element.key());
}
std::for_each(keysToRemove.begin(), keysToRemove.end(), [&](const std::string& key) { j.erase(key); });
}
} // namespace DRAMSys::Config
#endif // DRAMSYSCONFIGURATION_UTIL_H

View File

@@ -35,62 +35,97 @@
#include "DRAMSysConfiguration.h"
#include "DRAMSys/config/ConfigUtil.h"
#include <fstream>
#include <iostream>
namespace DRAMSys::Config
{
std::string Configuration::resourceDirectory;
void to_json(json_t &j, const Configuration &c)
Configuration from_path(std::string_view path, std::string_view resourceDirectory)
{
j = json_t{{"addressmapping", c.addressMapping}, {"mcconfig", c.mcConfig}, {"memspec", c.memSpec},
{"simulationid", c.simulationId}, {"simconfig", c.simConfig}, {"tracesetup", c.traceSetup}};
std::ifstream file(path.data());
remove_null_values(j);
}
void from_json(const json_t &j, Configuration &c)
{
j.at("addressmapping").get_to(c.addressMapping);
j.at("mcconfig").get_to(c.mcConfig);
j.at("memspec").get_to(c.memSpec);
j.at("simulationid").get_to(c.simulationId);
j.at("simconfig").get_to(c.simConfig);
if (j.contains("tracesetup"))
j.at("tracesetup").get_to(c.traceSetup);
}
void from_dump(const std::string &dump, Configuration &c)
{
json_t json_simulation = json_t::parse(dump).at("simulation");
json_simulation.get_to(c);
}
std::string dump(const Configuration &c, unsigned int indentation)
{
json_t json_simulation;
json_simulation["simulation"] = c;
return json_simulation.dump(indentation);
}
Configuration from_path(const std::string &path, const std::string &resourceDirectory)
{
Configuration::resourceDirectory = resourceDirectory;
std::ifstream file(path);
if (file.is_open())
enum class SubConfig
{
json_t simulation = json_t::parse(file).at("simulation");
MemSpec,
AddressMapping,
McConfig,
SimConfig,
TraceSetup,
Unkown
} current_sub_config;
// This custom parser callback is responsible to swap out the paths to the sub-config json files
// with the actual json data.
std::function<bool(int depth, nlohmann::detail::parse_event_t event, json_t &parsed)>
parser_callback;
parser_callback =
[&parser_callback, &current_sub_config, resourceDirectory](
int depth, nlohmann::detail::parse_event_t event, json_t &parsed) -> bool {
using nlohmann::detail::parse_event_t;
if (depth != 2)
return true;
if (event == parse_event_t::key) {
assert(parsed.is_string());
if (parsed == MemSpec::KEY)
current_sub_config = SubConfig::MemSpec;
else if (parsed == AddressMapping::KEY)
current_sub_config = SubConfig::AddressMapping;
else if (parsed == McConfig::KEY)
current_sub_config = SubConfig::McConfig;
else if (parsed == SimConfig::KEY)
current_sub_config = SubConfig::SimConfig;
else if (parsed == TraceSetupConstants::KEY)
current_sub_config = SubConfig::TraceSetup;
else
current_sub_config = SubConfig::Unkown;
}
// In case we have an value (string) instead of an object, replace the value with the loaded
// json object.
if (event == parse_event_t::value && current_sub_config != SubConfig::Unkown) {
// Replace name of json file with actual json data
auto parse_json = [&parser_callback,
resourceDirectory](std::string_view base_dir,
std::string_view sub_config_key,
const std::string &filename) -> json_t {
std::filesystem::path path(resourceDirectory);
path /= base_dir;
path /= filename;
std::ifstream json_file(path);
if (!json_file.is_open())
throw std::runtime_error("Failed to open file " + std::string(path));
json_t json =
json_t::parse(json_file, parser_callback, true, true).at(sub_config_key);
return json;
};
if (current_sub_config == SubConfig::MemSpec)
parsed = parse_json(MemSpec::SUB_DIR, MemSpec::KEY, parsed);
else if (current_sub_config == SubConfig::AddressMapping)
parsed = parse_json(AddressMapping::SUB_DIR, AddressMapping::KEY, parsed);
else if (current_sub_config == SubConfig::McConfig)
parsed = parse_json(McConfig::SUB_DIR, McConfig::KEY, parsed);
else if (current_sub_config == SubConfig::SimConfig)
parsed = parse_json(SimConfig::SUB_DIR, SimConfig::KEY, parsed);
else if (current_sub_config == SubConfig::TraceSetup)
parsed = parse_json(TraceSetupConstants::SUB_DIR, TraceSetupConstants::KEY, parsed);
}
return true;
};
if (file.is_open()) {
json_t simulation = json_t::parse(file, parser_callback, true, true).at(Configuration::KEY);
return simulation.get<DRAMSys::Config::Configuration>();
}
else
{
throw std::runtime_error("Failed to open file " + path);
} else {
throw std::runtime_error("Failed to open file " + std::string(path));
}
}

View File

@@ -41,42 +41,45 @@
#include "DRAMSys/config/SimConfig.h"
#include "DRAMSys/config/TraceSetup.h"
#include "DRAMSys/config/memspec/MemSpec.h"
#include "DRAMSys/config/ConfigUtil.h"
#include <optional>
#include <string>
/**
* To support polymorphic configurations, a Json "type" tag is used
* to determine the correct type before further parsing.
*
* To support optional values, std::optional is used. The default
* values will be provided by DRAMSys itself.
*
* To achieve static polymorphism, std::variant is used.
* To achieve static polymorphism, std::variant is used. The concrete
* type is determined by the provided fields automatically.
*
* To achieve backwards compatibility, this library manipulates the json
* data type as it is parsed in to substitute paths to sub-configurations
* with the actual json object that is stored at this path.
*/
namespace DRAMSys::Config {
struct Configuration
{
AddressMapping addressMapping;
McConfig mcConfig;
MemSpec memSpec;
SimConfig simConfig;
std::string simulationId;
std::optional<TraceSetup> traceSetup;
static std::string resourceDirectory;
static constexpr std::string_view KEY = "simulation";
AddressMapping addressmapping;
McConfig mcconfig;
MemSpec memspec;
SimConfig simconfig;
std::string simulationid;
std::optional<TraceSetup> tracesetup;
};
void to_json(json &j, const Configuration &p);
void from_json(const json &j, Configuration &p);
NLOHMANN_JSONIFY_ALL_THINGS(Configuration,
addressmapping,
mcconfig,
memspec,
simconfig,
simulationid,
tracesetup)
void from_dump(const std::string &dump, Configuration &c);
std::string dump(const Configuration &c, unsigned int indentation = -1);
Configuration from_path(const std::string &path, const std::string &resourceDirectory = DRAMSYS_RESOURCE_DIR);
Configuration from_path(std::string_view path, std::string_view resourceDirectory = DRAMSYS_RESOURCE_DIR);
} // namespace DRAMSys::Config

View File

@@ -38,162 +38,36 @@
namespace DRAMSys::Config
{
void to_json(json_t &j, const McConfig &c)
void to_json(json_t &j, const RefreshPolicyType &r)
{
j = json_t{{"PagePolicy", c.pagePolicy},
{"Scheduler", c.scheduler},
{"HighWatermark", c.highWatermark},
{"LowWatermark", c.lowWatermark},
{"SchedulerBuffer", c.schedulerBuffer},
{"RequestBufferSize", c.requestBufferSize},
{"CmdMux", c.cmdMux},
{"RespQueue", c.respQueue},
{"RefreshPolicy", c.refreshPolicy},
{"RefreshMaxPostponed", c.refreshMaxPostponed},
{"RefreshMaxPulledin", c.refreshMaxPulledin},
{"PowerDownPolicy", c.powerDownPolicy},
{"Arbiter", c.arbiter},
{"MaxActiveTransactions", c.maxActiveTransactions},
{"RefreshManagement", c.refreshManagement},
{"ArbitrationDelayFw", c.arbitrationDelayFw},
{"ArbitrationDelayBw", c.arbitrationDelayBw},
{"ThinkDelayFw", c.thinkDelayFw},
{"ThinkDelayBw", c.thinkDelayBw},
{"PhyDelayFw", c.phyDelayFw},
{"PhyDelayBw", c.phyDelayBw},
{"BlockingReadDelay", c.blockingReadDelay},
{"BlockingWriteDelay", c.blockingWriteDelay}};
remove_null_values(j);
}
void from_json(const json_t &j, McConfig &c)
{
json_t j_mcconfig = get_config_json(j, mcConfigPath, "mcconfig");
if (j_mcconfig.contains("PagePolicy"))
j_mcconfig.at("PagePolicy").get_to(c.pagePolicy);
if (j_mcconfig.contains("Scheduler"))
j_mcconfig.at("Scheduler").get_to(c.scheduler);
if (j_mcconfig.contains("HighWatermark"))
j_mcconfig.at("HighWatermark").get_to(c.highWatermark);
if (j_mcconfig.contains("LowWatermark"))
j_mcconfig.at("LowWatermark").get_to(c.lowWatermark);
if (j_mcconfig.contains("SchedulerBuffer"))
j_mcconfig.at("SchedulerBuffer").get_to(c.schedulerBuffer);
if (j_mcconfig.contains("RequestBufferSize"))
j_mcconfig.at("RequestBufferSize").get_to(c.requestBufferSize);
if (j_mcconfig.contains("CmdMux"))
j_mcconfig.at("CmdMux").get_to(c.cmdMux);
if (j_mcconfig.contains("RespQueue"))
j_mcconfig.at("RespQueue").get_to(c.respQueue);
if (j_mcconfig.contains("RefreshPolicy"))
j_mcconfig.at("RefreshPolicy").get_to(c.refreshPolicy);
if (j_mcconfig.contains("RefreshMaxPostponed"))
j_mcconfig.at("RefreshMaxPostponed").get_to(c.refreshMaxPostponed);
if (j_mcconfig.contains("RefreshMaxPulledin"))
j_mcconfig.at("RefreshMaxPulledin").get_to(c.refreshMaxPulledin);
if (j_mcconfig.contains("PowerDownPolicy"))
j_mcconfig.at("PowerDownPolicy").get_to(c.powerDownPolicy);
if (j_mcconfig.contains("Arbiter"))
j_mcconfig.at("Arbiter").get_to(c.arbiter);
if (j_mcconfig.contains("MaxActiveTransactions"))
j_mcconfig.at("MaxActiveTransactions").get_to(c.maxActiveTransactions);
if (j_mcconfig.contains("RefreshManagement"))
j_mcconfig.at("RefreshManagement").get_to(c.refreshManagement);
if (j_mcconfig.contains("ArbitrationDelayFw"))
j_mcconfig.at("ArbitrationDelayFw").get_to(c.arbitrationDelayFw);
if (j_mcconfig.contains("ArbitrationDelayBw"))
j_mcconfig.at("ArbitrationDelayBw").get_to(c.arbitrationDelayBw);
if (j_mcconfig.contains("ThinkDelayFw"))
j_mcconfig.at("ThinkDelayFw").get_to(c.thinkDelayFw);
if (j_mcconfig.contains("ThinkDelayBw"))
j_mcconfig.at("ThinkDelayBw").get_to(c.thinkDelayBw);
if (j_mcconfig.contains("PhyDelayFw"))
j_mcconfig.at("PhyDelayFw").get_to(c.phyDelayFw);
if (j_mcconfig.contains("PhyDelayBw"))
j_mcconfig.at("PhyDelayBw").get_to(c.phyDelayBw);
if (j_mcconfig.contains("BlockingReadDelay"))
j_mcconfig.at("BlockingReadDelay").get_to(c.blockingReadDelay);
if (j_mcconfig.contains("BlockingWriteDelay"))
j_mcconfig.at("BlockingWriteDelay").get_to(c.blockingWriteDelay);
invalidateEnum(c.pagePolicy);
invalidateEnum(c.scheduler);
invalidateEnum(c.schedulerBuffer);
invalidateEnum(c.cmdMux);
invalidateEnum(c.respQueue);
invalidateEnum(c.refreshPolicy);
invalidateEnum(c.respQueue);
invalidateEnum(c.powerDownPolicy);
invalidateEnum(c.arbiter);
}
void to_json(json_t &j, const RefreshPolicy &r)
{
if (r == RefreshPolicy::NoRefresh)
if (r == RefreshPolicyType::NoRefresh)
j = "NoRefresh";
else if (r == RefreshPolicy::AllBank)
else if (r == RefreshPolicyType::AllBank)
j = "AllBank";
else if (r == RefreshPolicy::PerBank)
else if (r == RefreshPolicyType::PerBank)
j = "PerBank";
else if (r == RefreshPolicy::Per2Bank)
else if (r == RefreshPolicyType::Per2Bank)
j = "Per2Bank";
else if (r == RefreshPolicy::SameBank)
else if (r == RefreshPolicyType::SameBank)
j = "SameBank";
else
j = nullptr;
}
void from_json(const json_t &j, RefreshPolicy &r)
void from_json(const json_t &j, RefreshPolicyType &r)
{
if (j == "NoRefresh")
r = RefreshPolicy::NoRefresh;
r = RefreshPolicyType::NoRefresh;
else if (j == "AllBank" || j == "Rankwise")
r = RefreshPolicy::AllBank;
r = RefreshPolicyType::AllBank;
else if (j == "PerBank" || j == "Bankwise")
r = RefreshPolicy::PerBank;
r = RefreshPolicyType::PerBank;
else if (j == "SameBank" || j == "Groupwise")
r = RefreshPolicy::SameBank;
r = RefreshPolicyType::SameBank;
else if (j == "Per2Bank")
r = RefreshPolicy::Per2Bank;
r = RefreshPolicyType::Per2Bank;
else
r = RefreshPolicy::Invalid;
}
void from_dump(const std::string &dump, McConfig &c)
{
json_t json_mcconfig = json_t::parse(dump).at("mcconfig");
json_mcconfig.get_to(c);
}
std::string dump(const McConfig &c, unsigned int indentation)
{
json_t json_mcconfig;
json_mcconfig["mcconfig"] = c;
return json_mcconfig.dump(indentation);
r = RefreshPolicyType::Invalid;
}
} // namespace DRAMSys::Config

View File

@@ -36,7 +36,7 @@
#ifndef DRAMSYSCONFIGURATION_MCCONFIG_H
#define DRAMSYSCONFIGURATION_MCCONFIG_H
#include "DRAMSys/config/ConfigUtil.h"
#include "DRAMSys/util/json.h"
#include <optional>
#include <utility>
@@ -44,9 +44,8 @@
namespace DRAMSys::Config
{
const std::string mcConfigPath = "mcconfig";
enum class PagePolicy
enum class PagePolicyType
{
Open,
OpenAdaptive,
@@ -55,15 +54,15 @@ enum class PagePolicy
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(PagePolicy, {
{PagePolicy::Invalid, nullptr},
{PagePolicy::Open, "Open"},
{PagePolicy::OpenAdaptive, "OpenAdaptive"},
{PagePolicy::Closed, "Closed"},
{PagePolicy::ClosedAdaptive, "ClosedAdaptive"},
NLOHMANN_JSON_SERIALIZE_ENUM(PagePolicyType, {
{PagePolicyType::Invalid, nullptr},
{PagePolicyType::Open, "Open"},
{PagePolicyType::OpenAdaptive, "OpenAdaptive"},
{PagePolicyType::Closed, "Closed"},
{PagePolicyType::ClosedAdaptive, "ClosedAdaptive"},
})
enum class Scheduler
enum class SchedulerType
{
Fifo,
FrFcfs,
@@ -73,14 +72,14 @@ enum class Scheduler
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(Scheduler, {{Scheduler::Invalid, nullptr},
{Scheduler::Fifo, "Fifo"},
{Scheduler::FrFcfs, "FrFcfs"},
{Scheduler::FrFcfsGrp, "FrFcfsGrp"},
{Scheduler::GrpFrFcfs, "GrpFrFcfs"},
{Scheduler::GrpFrFcfsWm, "GrpFrFcfsWm"}})
NLOHMANN_JSON_SERIALIZE_ENUM(SchedulerType, {{SchedulerType::Invalid, nullptr},
{SchedulerType::Fifo, "Fifo"},
{SchedulerType::FrFcfs, "FrFcfs"},
{SchedulerType::FrFcfsGrp, "FrFcfsGrp"},
{SchedulerType::GrpFrFcfs, "GrpFrFcfs"},
{SchedulerType::GrpFrFcfsWm, "GrpFrFcfsWm"}})
enum class SchedulerBuffer
enum class SchedulerBufferType
{
Bankwise,
ReadWrite,
@@ -88,33 +87,33 @@ enum class SchedulerBuffer
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(SchedulerBuffer, {{SchedulerBuffer::Invalid, nullptr},
{SchedulerBuffer::Bankwise, "Bankwise"},
{SchedulerBuffer::ReadWrite, "ReadWrite"},
{SchedulerBuffer::Shared, "Shared"}})
NLOHMANN_JSON_SERIALIZE_ENUM(SchedulerBufferType, {{SchedulerBufferType::Invalid, nullptr},
{SchedulerBufferType::Bankwise, "Bankwise"},
{SchedulerBufferType::ReadWrite, "ReadWrite"},
{SchedulerBufferType::Shared, "Shared"}})
enum class CmdMux
enum class CmdMuxType
{
Oldest,
Strict,
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(CmdMux,
{{CmdMux::Invalid, nullptr}, {CmdMux::Oldest, "Oldest"}, {CmdMux::Strict, "Strict"}})
NLOHMANN_JSON_SERIALIZE_ENUM(CmdMuxType,
{{CmdMuxType::Invalid, nullptr}, {CmdMuxType::Oldest, "Oldest"}, {CmdMuxType::Strict, "Strict"}})
enum class RespQueue
enum class RespQueueType
{
Fifo,
Reorder,
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(RespQueue, {{RespQueue::Invalid, nullptr},
{RespQueue::Fifo, "Fifo"},
{RespQueue::Reorder, "Reorder"}})
NLOHMANN_JSON_SERIALIZE_ENUM(RespQueueType, {{RespQueueType::Invalid, nullptr},
{RespQueueType::Fifo, "Fifo"},
{RespQueueType::Reorder, "Reorder"}})
enum class RefreshPolicy
enum class RefreshPolicyType
{
NoRefresh,
AllBank,
@@ -124,18 +123,18 @@ enum class RefreshPolicy
Invalid = -1
};
enum class PowerDownPolicy
enum class PowerDownPolicyType
{
NoPowerDown,
Staggered,
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(PowerDownPolicy, {{PowerDownPolicy::Invalid, nullptr},
{PowerDownPolicy::NoPowerDown, "NoPowerDown"},
{PowerDownPolicy::Staggered, "Staggered"}})
NLOHMANN_JSON_SERIALIZE_ENUM(PowerDownPolicyType, {{PowerDownPolicyType::Invalid, nullptr},
{PowerDownPolicyType::NoPowerDown, "NoPowerDown"},
{PowerDownPolicyType::Staggered, "Staggered"}})
enum class Arbiter
enum class ArbiterType
{
Simple,
Fifo,
@@ -143,46 +142,71 @@ enum class Arbiter
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(Arbiter, {{Arbiter::Invalid, nullptr},
{Arbiter::Simple, "Simple"},
{Arbiter::Fifo, "Fifo"},
{Arbiter::Reorder, "Reorder"}})
NLOHMANN_JSON_SERIALIZE_ENUM(ArbiterType, {{ArbiterType::Invalid, nullptr},
{ArbiterType::Simple, "Simple"},
{ArbiterType::Fifo, "Fifo"},
{ArbiterType::Reorder, "Reorder"}})
struct McConfig
{
std::optional<PagePolicy> pagePolicy;
std::optional<Scheduler> scheduler;
std::optional<unsigned int> highWatermark;
std::optional<unsigned int> lowWatermark;
std::optional<SchedulerBuffer> schedulerBuffer;
std::optional<unsigned int> requestBufferSize;
std::optional<CmdMux> cmdMux;
std::optional<RespQueue> respQueue;
std::optional<RefreshPolicy> refreshPolicy;
std::optional<unsigned int> refreshMaxPostponed;
std::optional<unsigned int> refreshMaxPulledin;
std::optional<PowerDownPolicy> powerDownPolicy;
std::optional<Arbiter> arbiter;
std::optional<unsigned int> maxActiveTransactions;
std::optional<bool> refreshManagement;
std::optional<unsigned int> arbitrationDelayFw;
std::optional<unsigned int> arbitrationDelayBw;
std::optional<unsigned int> thinkDelayFw;
std::optional<unsigned int> thinkDelayBw;
std::optional<unsigned int> phyDelayFw;
std::optional<unsigned int> phyDelayBw;
std::optional<unsigned int> blockingReadDelay;
std::optional<unsigned int> blockingWriteDelay;
static constexpr std::string_view KEY = "mcconfig";
static constexpr std::string_view SUB_DIR = "mcconfig";
std::optional<PagePolicyType> PagePolicy;
std::optional<SchedulerType> Scheduler;
std::optional<unsigned int> HighWatermark;
std::optional<unsigned int> LowWatermark;
std::optional<SchedulerBufferType> SchedulerBuffer;
std::optional<unsigned int> RequestBufferSize;
std::optional<CmdMuxType> CmdMux;
std::optional<RespQueueType> RespQueue;
std::optional<RefreshPolicyType> RefreshPolicy;
std::optional<unsigned int> RefreshMaxPostponed;
std::optional<unsigned int> RefreshMaxPulledin;
std::optional<PowerDownPolicyType> PowerDownPolicy;
std::optional<ArbiterType> Arbiter;
std::optional<unsigned int> MaxActiveTransactions;
std::optional<bool> RefreshManagement;
std::optional<unsigned int> ArbitrationDelayFw;
std::optional<unsigned int> ArbitrationDelayBw;
std::optional<unsigned int> ThinkDelayFw;
std::optional<unsigned int> ThinkDelayBw;
std::optional<unsigned int> PhyDelayFw;
std::optional<unsigned int> PhyDelayBw;
std::optional<unsigned int> BlockingReadDelay;
std::optional<unsigned int> BlockingWriteDelay;
};
void to_json(json_t &j, const McConfig &c);
void from_json(const json_t &j, McConfig &c);
NLOHMANN_JSONIFY_ALL_THINGS(McConfig,
PagePolicy,
Scheduler,
HighWatermark,
LowWatermark,
SchedulerBuffer,
RequestBufferSize,
CmdMux,
RespQueue,
RefreshPolicy,
RefreshMaxPostponed,
RefreshMaxPulledin,
PowerDownPolicy,
Arbiter,
MaxActiveTransactions,
RefreshManagement,
ArbitrationDelayFw,
ArbitrationDelayBw,
ThinkDelayFw,
ThinkDelayBw,
PhyDelayFw,
PhyDelayBw,
BlockingReadDelay,
BlockingWriteDelay)
void to_json(json_t &j, const RefreshPolicy &r);
void from_json(const json_t &j, RefreshPolicy &r);
void to_json(json_t &j, const RefreshPolicyType &r);
void from_json(const json_t &j, RefreshPolicyType &r);
void from_dump(const std::string &dump, McConfig &c);
std::string dump(const McConfig &c, unsigned int indentation = -1);
// void from_dump(const std::string &dump, McConfig &c);
// std::string dump(const McConfig &c, unsigned int indentation = -1);
} // namespace Configuration

View File

@@ -1,121 +0,0 @@
/*
* Copyright (c) 2021, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#include "SimConfig.h"
namespace DRAMSys::Config
{
void to_json(json_t &j, const SimConfig &c)
{
j = json_t{{"AddressOffset", c.addressOffset},
{"CheckTLM2Protocol", c.checkTLM2Protocol},
{"DatabaseRecording", c.databaseRecording},
{"Debug", c.debug},
{"EnableWindowing", c.enableWindowing},
{"ErrorCSVFile", c.errorCsvFile},
{"ErrorChipSeed", c.errorChipSeed},
{"PowerAnalysis", c.powerAnalysis},
{"SimulationName", c.simulationName},
{"SimulationProgressBar", c.simulationProgressBar},
{"StoreMode", c.storeMode},
{"ThermalSimulation", c.thermalSimulation},
{"UseMalloc", c.useMalloc},
{"WindowSize", c.windowSize}};
}
void from_json(const json_t &j, SimConfig &c)
{
json_t j_simconfig = get_config_json(j, simConfigPath, "simconfig");
if (j_simconfig.contains("AddressOffset"))
j_simconfig.at("AddressOffset").get_to(c.addressOffset);
if (j_simconfig.contains("CheckTLM2Protocol"))
j_simconfig.at("CheckTLM2Protocol").get_to(c.checkTLM2Protocol);
if (j_simconfig.contains("DatabaseRecording"))
j_simconfig.at("DatabaseRecording").get_to(c.databaseRecording);
if (j_simconfig.contains("Debug"))
j_simconfig.at("Debug").get_to(c.debug);
if (j_simconfig.contains("EnableWindowing"))
j_simconfig.at("EnableWindowing").get_to(c.enableWindowing);
if (j_simconfig.contains("ErrorCSVFile"))
j_simconfig.at("ErrorCSVFile").get_to(c.errorCsvFile);
if (j_simconfig.contains("ErrorChipSeed"))
j_simconfig.at("ErrorChipSeed").get_to(c.errorChipSeed);
if (j_simconfig.contains("PowerAnalysis"))
j_simconfig.at("PowerAnalysis").get_to(c.powerAnalysis);
if (j_simconfig.contains("SimulationName"))
j_simconfig.at("SimulationName").get_to(c.simulationName);
if (j_simconfig.contains("SimulationProgressBar"))
j_simconfig.at("SimulationProgressBar").get_to(c.simulationProgressBar);
if (j_simconfig.contains("StoreMode"))
j_simconfig.at("StoreMode").get_to(c.storeMode);
if (j_simconfig.contains("ThermalSimulation"))
j_simconfig.at("ThermalSimulation").get_to(c.thermalSimulation);
if (j_simconfig.contains("UseMalloc"))
j_simconfig.at("UseMalloc").get_to(c.useMalloc);
if (j_simconfig.contains("WindowSize"))
j_simconfig.at("WindowSize").get_to(c.windowSize);
invalidateEnum(c.storeMode);
}
void from_dump(const std::string &dump, SimConfig &c)
{
json_t json_simconfig = json_t::parse(dump).at("simconfig");
json_simconfig.get_to(c);
}
std::string dump(const SimConfig &c, unsigned int indentation)
{
json_t json_simconfig;
json_simconfig["simconfig"] = c;
return json_simconfig.dump(indentation);
}
} // namespace DRAMSys::Config

View File

@@ -36,15 +36,14 @@
#ifndef DRAMSYSCONFIGURATION_SIMCONFIG_H
#define DRAMSYSCONFIGURATION_SIMCONFIG_H
#include "DRAMSys/config/ConfigUtil.h"
#include "DRAMSys/util/json.h"
#include <optional>
namespace DRAMSys::Config
{
const std::string simConfigPath = "simconfig";
enum class StoreMode
enum class StoreModeType
{
NoStorage,
Store,
@@ -52,34 +51,47 @@ enum class StoreMode
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(StoreMode, {{StoreMode::Invalid, nullptr},
{StoreMode::NoStorage, "NoStorage"},
{StoreMode::Store, "Store"},
{StoreMode::ErrorModel, "ErrorModel"}})
NLOHMANN_JSON_SERIALIZE_ENUM(StoreModeType, {{StoreModeType::Invalid, nullptr},
{StoreModeType::NoStorage, "NoStorage"},
{StoreModeType::Store, "Store"},
{StoreModeType::ErrorModel, "ErrorModel"}})
struct SimConfig
{
std::optional<uint64_t> addressOffset;
std::optional<bool> checkTLM2Protocol;
std::optional<bool> databaseRecording;
std::optional<bool> debug;
std::optional<bool> enableWindowing;
std::optional<std::string> errorCsvFile;
std::optional<unsigned int> errorChipSeed;
std::optional<bool> powerAnalysis;
std::optional<std::string> simulationName;
std::optional<bool> simulationProgressBar;
std::optional<StoreMode> storeMode;
std::optional<bool> thermalSimulation;
std::optional<bool> useMalloc;
std::optional<unsigned int> windowSize;
static constexpr std::string_view KEY = "simconfig";
static constexpr std::string_view SUB_DIR = "simconfig";
std::optional<uint64_t> AddressOffset;
std::optional<bool> CheckTLM2Protocol;
std::optional<bool> DatabaseRecording;
std::optional<bool> Debug;
std::optional<bool> EnableWindowing;
std::optional<std::string> ErrorCSVFile;
std::optional<unsigned int> ErrorChipSeed;
std::optional<bool> PowerAnalysis;
std::optional<std::string> SimulationName;
std::optional<bool> SimulationProgressBar;
std::optional<StoreModeType> StoreMode;
std::optional<bool> ThermalSimulation;
std::optional<bool> UseMalloc;
std::optional<unsigned int> WindowSize;
};
void to_json(json_t &j, const SimConfig &c);
void from_json(const json_t &j, SimConfig &c);
void from_dump(const std::string &dump, SimConfig &c);
std::string dump(const SimConfig &c, unsigned int indentation = -1);
NLOHMANN_JSONIFY_ALL_THINGS(SimConfig,
AddressOffset,
CheckTLM2Protocol,
DatabaseRecording,
Debug,
EnableWindowing,
ErrorCSVFile,
ErrorChipSeed,
PowerAnalysis,
SimulationName,
SimulationProgressBar,
StoreMode,
ThermalSimulation,
UseMalloc,
WindowSize)
} // namespace Configuration

View File

@@ -1,314 +0,0 @@
/*
* Copyright (c) 2021, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#include "TraceSetup.h"
#include <variant>
namespace DRAMSys::Config
{
TrafficInitiator::~TrafficInitiator()
{
}
TraceGeneratorState::~TraceGeneratorState()
{
}
void to_json(json_t &j, const TraceSetup &c)
{
// Create an empty array
j = json_t::array();
for (const auto &initiator : c.initiators)
{
json_t initiator_j;
std::visit(
[&initiator_j](auto &&initiator)
{
initiator_j["name"] = initiator.name;
initiator_j["clkMhz"] = initiator.clkMhz;
initiator_j["maxPendingReadRequests"] = initiator.maxPendingReadRequests;
initiator_j["maxPendingWriteRequests"] = initiator.maxPendingWriteRequests;
using T = std::decay_t<decltype(initiator)>;
if constexpr (std::is_same_v<T, TraceGenerator>)
{
initiator_j["type"] = "generator";
initiator_j["seed"] = initiator.seed;
initiator_j["maxTransactions"] = initiator.maxTransactions;
initiator_j["idleUntil"] = initiator.idleUntil;
// When there are less than 2 states, flatten out the json.
if (initiator.states.size() == 1)
{
std::visit(
[&initiator_j](auto &&state)
{
using U = std::decay_t<decltype(state)>;
if constexpr (std::is_same_v<U, TraceGeneratorTrafficState>)
{
initiator_j["numRequests"] = state.numRequests;
initiator_j["rwRatio"] = state.rwRatio;
initiator_j["addressDistribution"] = state.addressDistribution;
initiator_j["addressIncrement"] = state.addressIncrement;
initiator_j["minAddress"] = state.minAddress;
initiator_j["maxAddress"] = state.maxAddress;
initiator_j["clksPerRequest"] = state.clksPerRequest;
initiator_j["notify"] = state.notify;
}
else // if constexpr (std::is_same_v<U, TraceGeneratorIdleState>)
{
initiator_j["idleClks"] = state.idleClks;
}
},
initiator.states.at(0));
}
else
{
json_t states_j = json_t::array();
for (const auto &state : initiator.states)
{
json_t state_j;
state_j["id"] = state.first;
std::visit(
[&state_j](auto &&state)
{
using U = std::decay_t<decltype(state)>;
if constexpr (std::is_same_v<U, TraceGeneratorTrafficState>)
{
state_j["numRequests"] = state.numRequests;
state_j["rwRatio"] = state.rwRatio;
state_j["addressDistribution"] = state.addressDistribution;
state_j["addressIncrement"] = state.addressIncrement;
state_j["minAddress"] = state.minAddress;
state_j["maxAddress"] = state.maxAddress;
state_j["clksPerRequest"] = state.clksPerRequest;
state_j["notify"] = state.notify;
}
else // if constexpr (std::is_same_v<U, TraceGeneratorIdleState>)
{
state_j["idleClks"] = state.idleClks;
}
},
state.second);
remove_null_values(state_j);
states_j.insert(states_j.end(), state_j);
}
initiator_j["states"] = states_j;
json_t transitions_j = json_t::array();
for (const auto &transition : initiator.transitions)
{
json_t transition_j;
transition_j["from"] = transition.first;
transition_j["to"] = transition.second.to;
transition_j["probability"] = transition.second.probability;
remove_null_values(transition_j);
transitions_j.insert(transitions_j.end(), transition_j);
}
initiator_j["transitions"] = transitions_j;
}
}
else if constexpr (std::is_same_v<T, TraceHammer>)
{
initiator_j["type"] = "hammer";
initiator_j["numRequests"] = initiator.numRequests;
initiator_j["rowIncrement"] = initiator.rowIncrement;
}
else // if constexpr (std::is_same_v<T, TracePlayer>)
{
initiator_j["type"] = "player";
}
},
initiator);
remove_null_values(initiator_j);
j.insert(j.end(), initiator_j);
}
}
void from_json(const json_t&j, TraceSetup &c)
{
for (const auto &initiator_j : j)
{
// Default to Player, when not specified
TrafficInitiatorType type = initiator_j.value("type", TrafficInitiatorType::Player);
std::variant<TracePlayer, TraceGenerator, TraceHammer> initiator;
if (type == TrafficInitiatorType::Player)
{
initiator = TracePlayer{};
}
else if (type == TrafficInitiatorType::Generator)
{
TraceGenerator generator;
auto process_state = [](const json_t&state_j)
-> std::pair<unsigned int, std::variant<TraceGeneratorIdleState, TraceGeneratorTrafficState>>
{
std::variant<TraceGeneratorIdleState, TraceGeneratorTrafficState> state;
if (state_j.contains("idleClks"))
{
// Idle state
TraceGeneratorIdleState idleState;
state_j.at("idleClks").get_to(idleState.idleClks);
state = std::move(idleState);
}
else
{
// Traffic state
TraceGeneratorTrafficState trafficState;
state_j.at("numRequests").get_to(trafficState.numRequests);
state_j.at("rwRatio").get_to(trafficState.rwRatio);
state_j.at("addressDistribution").get_to(trafficState.addressDistribution);
if (state_j.contains("addressIncrement"))
state_j.at("addressIncrement").get_to(trafficState.addressIncrement);
if (state_j.contains("minAddress"))
state_j.at("minAddress").get_to(trafficState.minAddress);
if (state_j.contains("maxAddress"))
state_j.at("maxAddress").get_to(trafficState.maxAddress);
if (state_j.contains("clksPerRequest"))
state_j.at("clksPerRequest").get_to(trafficState.clksPerRequest);
if (state_j.contains("notify"))
state_j.at("notify").get_to(trafficState.notify);
state = std::move(trafficState);
}
// Default to 0
unsigned int id = 0;
if (state_j.contains("id"))
id = state_j.at("id");
return {id, std::move(state)};
};
if (initiator_j.contains("states"))
{
for (const auto &state_j : initiator_j.at("states"))
{
auto state = process_state(state_j);
generator.states[state.first] = std::move(state.second);
}
for (const auto &transition_j : initiator_j.at("transitions"))
{
TraceGeneratorStateTransition transition;
unsigned int from = transition_j.at("from");
transition.to = transition_j.at("to");
transition.probability = transition_j.at("probability");
generator.transitions.emplace(from, transition);
}
}
else // Only one state will be created
{
auto state = process_state(initiator_j);
generator.states[state.first] = std::move(state.second);
}
if (initiator_j.contains("seed"))
initiator_j.at("seed").get_to(generator.seed);
if (initiator_j.contains("maxTransactions"))
initiator_j.at("maxTransactions").get_to(generator.maxTransactions);
if (initiator_j.contains("dataLength"))
initiator_j.at("dataLength").get_to(generator.dataLength);
if (initiator_j.contains("idleUntil"))
initiator_j.at("idleUntil").get_to(generator.idleUntil);
initiator = generator;
}
else if (type == TrafficInitiatorType::Hammer)
{
TraceHammer hammer;
initiator_j.at("numRequests").get_to(hammer.numRequests);
initiator_j.at("rowIncrement").get_to(hammer.rowIncrement);
initiator = hammer;
}
std::visit(
[&initiator_j](auto &&initiator)
{
initiator_j.at("name").get_to(initiator.name);
initiator_j.at("clkMhz").get_to(initiator.clkMhz);
if (initiator_j.contains("maxPendingReadRequests"))
initiator_j.at("maxPendingReadRequests").get_to(initiator.maxPendingReadRequests);
if (initiator_j.contains("maxPendingWriteRequests"))
initiator_j.at("maxPendingWriteRequests").get_to(initiator.maxPendingWriteRequests);
},
initiator);
c.initiators.emplace_back(std::move(initiator));
}
}
void from_dump(const std::string &dump, TraceSetup &c)
{
json_t json_tracesetup = json_t::parse(dump).at("tracesetup");
json_tracesetup.get_to(c);
}
std::string dump(const TraceSetup &c, unsigned int indentation)
{
json_t json_tracesetup;
json_tracesetup["tracesetup"] = c;
return json_tracesetup.dump(indentation);
}
} // namespace DRAMSys::Config

View File

@@ -36,7 +36,7 @@
#ifndef DRAMSYSCONFIGURATION_TRACESETUP_H
#define DRAMSYSCONFIGURATION_TRACESETUP_H
#include "DRAMSys/config/ConfigUtil.h"
#include "DRAMSys/util/json.h"
#include <optional>
#include <variant>
@@ -68,74 +68,141 @@ NLOHMANN_JSON_SERIALIZE_ENUM(AddressDistribution, {{AddressDistribution::Invalid
{AddressDistribution::Random, "random"},
{AddressDistribution::Sequential, "sequential"}})
struct TrafficInitiator
struct TracePlayer
{
virtual ~TrafficInitiator() = 0;
uint64_t clkMhz;
std::string name;
std::optional<unsigned int> maxPendingReadRequests;
std::optional<unsigned int> maxPendingWriteRequests;
};
struct TracePlayer : public TrafficInitiator
{
};
NLOHMANN_JSONIFY_ALL_THINGS(
TracePlayer, clkMhz, name, maxPendingReadRequests, maxPendingWriteRequests)
struct TraceGeneratorState
struct TrafficGeneratorActiveState
{
virtual ~TraceGeneratorState() = 0;
};
unsigned int id;
struct TraceGeneratorTrafficState : public TraceGeneratorState
{
uint64_t numRequests;
double rwRatio;
AddressDistribution addressDistribution;
std::optional<uint64_t> addressIncrement;
std::optional<uint64_t> minAddress;
std::optional<uint64_t> maxAddress;
std::optional<uint64_t> clksPerRequest;
std::optional<std::string> notify;
};
struct TraceGeneratorIdleState : public TraceGeneratorState
NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorActiveState,
id,
numRequests,
rwRatio,
addressDistribution,
addressIncrement,
minAddress,
maxAddress)
struct TrafficGeneratorIdleState
{
unsigned int id;
uint64_t idleClks;
};
struct TraceGeneratorStateTransition
NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorIdleState, id, idleClks)
struct TrafficGeneratorStateTransition
{
unsigned int from;
unsigned int to;
float probability;
};
struct TraceGenerator : public TrafficInitiator
NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorStateTransition, from, to, probability)
struct TrafficGenerator
{
uint64_t clkMhz;
std::string name;
std::optional<unsigned int> maxPendingReadRequests;
std::optional<unsigned int> maxPendingWriteRequests;
std::optional<uint64_t> seed;
std::optional<uint64_t> maxTransactions;
std::optional<unsigned> dataLength;
std::map<unsigned int, std::variant<TraceGeneratorIdleState, TraceGeneratorTrafficState>> states;
std::multimap<unsigned int, TraceGeneratorStateTransition> transitions;
std::optional<std::string> idleUntil;
std::optional<unsigned> dataAlignment;
uint64_t numRequests;
double rwRatio;
AddressDistribution addressDistribution;
std::optional<uint64_t> addressIncrement;
std::optional<uint64_t> minAddress;
std::optional<uint64_t> maxAddress;
};
struct TraceHammer : public TrafficInitiator
NLOHMANN_JSONIFY_ALL_THINGS(TrafficGenerator,
clkMhz,
name,
maxPendingReadRequests,
maxPendingWriteRequests,
seed,
maxTransactions,
dataLength,
dataAlignment,
numRequests,
rwRatio,
addressDistribution,
addressIncrement,
minAddress,
maxAddress)
struct TrafficGeneratorStateMachine
{
uint64_t clkMhz;
std::string name;
std::optional<unsigned int> maxPendingReadRequests;
std::optional<unsigned int> maxPendingWriteRequests;
std::optional<uint64_t> seed;
std::optional<uint64_t> maxTransactions;
std::optional<unsigned> dataLength;
std::optional<unsigned> dataAlignment;
std::vector<std::variant<TrafficGeneratorActiveState, TrafficGeneratorIdleState>> states;
std::vector<TrafficGeneratorStateTransition> transitions;
};
NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorStateMachine,
clkMhz,
name,
maxPendingReadRequests,
maxPendingWriteRequests,
seed,
maxTransactions,
dataLength,
dataAlignment,
states,
transitions)
struct RowHammer
{
uint64_t clkMhz;
std::string name;
std::optional<unsigned int> maxPendingReadRequests;
std::optional<unsigned int> maxPendingWriteRequests;
uint64_t numRequests;
uint64_t rowIncrement;
};
struct TraceSetup
NLOHMANN_JSONIFY_ALL_THINGS(
RowHammer, clkMhz, name, maxPendingReadRequests, maxPendingWriteRequests, numRequests, rowIncrement)
struct TraceSetupConstants
{
std::vector<std::variant<TracePlayer, TraceGenerator, TraceHammer>> initiators;
static constexpr std::string_view KEY = "tracesetup";
static constexpr std::string_view SUB_DIR = "tracesetup";
};
void to_json(json_t &j, const TraceSetup &c);
void from_json(const json_t &j, TraceSetup &c);
void from_dump(const std::string &dump, TraceSetup &c);
std::string dump(const TraceSetup &c, unsigned int indentation = -1);
using TraceSetup = std::vector<
std::variant<TracePlayer, TrafficGenerator, TrafficGeneratorStateMachine, RowHammer>>;
} // namespace Configuration

View File

@@ -38,7 +38,7 @@
namespace DRAMSys::Config
{
void to_json(json_t &j, const MemArchitectureSpec &c)
void to_json(json_t &j, const MemArchitectureSpecType &c)
{
j = json_t{};
@@ -48,7 +48,7 @@ void to_json(json_t &j, const MemArchitectureSpec &c)
}
}
void from_json(const json_t &j, MemArchitectureSpec &c)
void from_json(const json_t &j, MemArchitectureSpecType &c)
{
for (const auto &entry : j.items())
{

View File

@@ -36,20 +36,20 @@
#ifndef DRAMSYSCONFIGURATION_MEMARCHITECTURESPEC_H
#define DRAMSYSCONFIGURATION_MEMARCHITECTURESPEC_H
#include "DRAMSys/config/ConfigUtil.h"
#include "DRAMSys/util/json.h"
#include <unordered_map>
namespace DRAMSys::Config
{
struct MemArchitectureSpec
struct MemArchitectureSpecType
{
std::unordered_map<std::string, unsigned int> entries;
};
void to_json(json_t &j, const MemArchitectureSpec &c);
void from_json(const json_t &j, MemArchitectureSpec &c);
void to_json(json_t &j, const MemArchitectureSpecType &c);
void from_json(const json_t &j, MemArchitectureSpecType &c);
} // namespace Configuration

View File

@@ -36,7 +36,7 @@
#ifndef DRAMSYSCONFIGURATION_MEMPOWERSPEC_H
#define DRAMSYSCONFIGURATION_MEMPOWERSPEC_H
#include "DRAMSys/config/ConfigUtil.h"
#include "DRAMSys/util/json.h"
#include <unordered_map>

View File

@@ -36,7 +36,7 @@
#ifndef DRAMSYSCONFIGURATION_MEMSPEC_H
#define DRAMSYSCONFIGURATION_MEMSPEC_H
#include "DRAMSys/config/ConfigUtil.h"
#include "DRAMSys/util/json.h"
#include "DRAMSys/config/memspec/MemArchitectureSpec.h"
#include "DRAMSys/config/memspec/MemPowerSpec.h"
#include "DRAMSys/config/memspec/MemTimingSpec.h"
@@ -45,22 +45,20 @@
namespace DRAMSys::Config {
const std::string memSpecPath = "memspec";
struct MemSpec
{
MemArchitectureSpec memArchitectureSpec;
static constexpr std::string_view KEY = "memspec";
static constexpr std::string_view SUB_DIR = "memspec";
MemArchitectureSpecType memarchitecturespec;
std::string memoryId;
std::string memoryType;
MemTimingSpec memTimingSpec;
std::optional<MemPowerSpec> memPowerSpec;
MemTimingSpecType memtimingspec;
std::optional<MemPowerSpec> mempowerspec;
};
void to_json(json &j, const MemSpec &c);
void from_json(const json &j, MemSpec &c);
void from_dump(const std::string &dump, MemSpec &c);
std::string dump(const MemSpec &c, unsigned int indentation = -1);
NLOHMANN_JSONIFY_ALL_THINGS(
MemSpec, memarchitecturespec, memoryId, memoryType, memtimingspec, mempowerspec)
} // namespace Configuration

View File

@@ -38,7 +38,7 @@
namespace DRAMSys::Config
{
void to_json(json_t &j, const MemTimingSpec &c)
void to_json(json_t &j, const MemTimingSpecType &c)
{
j = json_t{};
@@ -48,7 +48,7 @@ void to_json(json_t &j, const MemTimingSpec &c)
}
}
void from_json(const json_t &j, MemTimingSpec &c)
void from_json(const json_t &j, MemTimingSpecType &c)
{
for (const auto &entry : j.items())
{

View File

@@ -36,7 +36,7 @@
#ifndef DRAMSYSCONFIGURATION_MEMTIMINGSPEC_H
#define DRAMSYSCONFIGURATION_MEMTIMINGSPEC_H
#include "DRAMSys/config/ConfigUtil.h"
#include "DRAMSys/util/json.h"
#include <unordered_map>
@@ -44,13 +44,13 @@ namespace DRAMSys::Config
{
using json = nlohmann::json;
struct MemTimingSpec
struct MemTimingSpecType
{
std::unordered_map<std::string, unsigned int> entries;
};
void to_json(json &j, const MemTimingSpec &c);
void from_json(const json &j, MemTimingSpec &c);
void to_json(json &j, const MemTimingSpecType &c);
void from_json(const json &j, MemTimingSpecType &c);
} // namespace Configuration

View File

@@ -288,4 +288,18 @@ public:
static bool notifyChildTransCompletion(tlm::tlm_generic_payload& trans);
};
class EccExtension : public tlm::tlm_extension<EccExtension>
{
public:
tlm_extension_base* clone() const override
{
return new EccExtension;
}
void copy_from(tlm_extension_base const &ext) override
{
auto const &cpyFrom = static_cast<EccExtension const &>(ext);
}
};
#endif // DRAMEXTENSIONS_H

View File

@@ -86,202 +86,232 @@ enum sc_time_unit string2TimeUnit(const std::string &s)
}
void Configuration::loadSimConfig(const DRAMSys::Config::SimConfig &simConfig)
{
if (const auto& _addressOffset = simConfig.addressOffset)
addressOffset = *_addressOffset;
{
addressOffset = simConfig.AddressOffset.value_or(addressOffset);
checkTLM2Protocol = simConfig.CheckTLM2Protocol.value_or(checkTLM2Protocol);
databaseRecording = simConfig.DatabaseRecording.value_or(databaseRecording);
debug = simConfig.Debug.value_or(debug);
enableWindowing = simConfig.EnableWindowing.value_or(enableWindowing);
simulationName = simConfig.SimulationName.value_or(simulationName);
simulationProgressBar = simConfig.SimulationProgressBar.value_or(simulationProgressBar);
useMalloc = simConfig.UseMalloc.value_or(useMalloc);
if (const auto& _checkTLM2Protocol = simConfig.checkTLM2Protocol)
checkTLM2Protocol = *_checkTLM2Protocol;
if (const auto& _databaseRecording = simConfig.databaseRecording)
databaseRecording = *_databaseRecording;
if (const auto& _debug = simConfig.debug)
debug = *_debug;
if (const auto& _enableWindowing = simConfig.enableWindowing)
enableWindowing = *_enableWindowing;
if (const auto& _powerAnalysis = simConfig.powerAnalysis)
{
powerAnalysis = *_powerAnalysis;
#ifndef DRAMPOWER
if (powerAnalysis)
SC_REPORT_FATAL("Configuration", "Power analysis is only supported with included DRAMPower library!");
#endif
}
if (const auto& _simulationName = simConfig.simulationName)
simulationName = *_simulationName;
if (const auto& _simulationProgressBar = simConfig.simulationProgressBar)
simulationProgressBar = *_simulationProgressBar;
if (const auto& _useMalloc = simConfig.useMalloc)
useMalloc = *_useMalloc;
if (const auto& _windowSize = simConfig.windowSize)
windowSize = *_windowSize;
if (const auto &_storeMode = simConfig.StoreMode)
storeMode = [=]
{
switch (*_storeMode)
{
case DRAMSys::Config::StoreModeType::NoStorage:
return StoreMode::NoStorage;
case DRAMSys::Config::StoreModeType::Store:
return StoreMode::Store;
default:
SC_REPORT_FATAL("Configuration", "Invalid StoreMode");
return StoreMode::NoStorage; // Silence Warning
}
}();
windowSize = simConfig.WindowSize.value_or(windowSize);
if (windowSize == 0)
SC_REPORT_FATAL("Configuration", "Minimum window size is 1");
if (const auto& _storeMode = simConfig.storeMode)
storeMode = [=] {
if (_storeMode == DRAMSys::Config::StoreMode::NoStorage)
return StoreMode::NoStorage;
else // (_storeMode == DRAMSys::Config::StoreMode::Store)
return StoreMode::Store;
}();
powerAnalysis = simConfig.PowerAnalysis.value_or(powerAnalysis);
#ifndef DRAMPOWER
if (powerAnalysis)
SC_REPORT_FATAL("Configuration", "Power analysis is only supported with included DRAMPower library!");
#endif
}
void Configuration::loadMCConfig(const DRAMSys::Config::McConfig &mcConfig)
{
if (const auto& _pagePolicy = mcConfig.pagePolicy)
pagePolicy = [=] {
if (_pagePolicy == DRAMSys::Config::PagePolicy::Open)
if (const auto &_pagePolicy = mcConfig.PagePolicy)
pagePolicy = [=]
{
switch (*_pagePolicy)
{
case DRAMSys::Config::PagePolicyType::Open:
return PagePolicy::Open;
else if (_pagePolicy == DRAMSys::Config::PagePolicy::OpenAdaptive)
case DRAMSys::Config::PagePolicyType::OpenAdaptive:
return PagePolicy::OpenAdaptive;
else if (_pagePolicy == DRAMSys::Config::PagePolicy::Closed)
case DRAMSys::Config::PagePolicyType::Closed:
return PagePolicy::Closed;
else
case DRAMSys::Config::PagePolicyType::ClosedAdaptive:
return PagePolicy::ClosedAdaptive;
default:
SC_REPORT_FATAL("Configuration", "Invalid PagePolicy");
return PagePolicy::Open; // Silence Warning
}
}();
if (const auto& _scheduler = mcConfig.scheduler)
scheduler = [=] {
if (_scheduler == DRAMSys::Config::Scheduler::Fifo)
return Scheduler::Fifo;
else if (_scheduler == DRAMSys::Config::Scheduler::FrFcfs)
return Scheduler::FrFcfs;
else if (_scheduler == DRAMSys::Config::Scheduler::FrFcfsGrp)
return Scheduler::FrFcfsGrp;
else if (_scheduler == DRAMSys::Config::Scheduler::GrpFrFcfs)
return Scheduler::GrpFrFcfs;
else
return Scheduler::GrpFrFcfsWm;
if (const auto &_scheduler = mcConfig.Scheduler)
scheduler = [=]
{
switch (*_scheduler)
{
case DRAMSys::Config::SchedulerType::Fifo:
return Scheduler::Fifo;
case DRAMSys::Config::SchedulerType::FrFcfs:
return Scheduler::FrFcfs;
case DRAMSys::Config::SchedulerType::FrFcfsGrp:
return Scheduler::FrFcfsGrp;
case DRAMSys::Config::SchedulerType::GrpFrFcfs:
return Scheduler::GrpFrFcfs;
case DRAMSys::Config::SchedulerType::GrpFrFcfsWm:
return Scheduler::GrpFrFcfsWm;
default:
SC_REPORT_FATAL("Configuration", "Invalid Scheduler");
return Scheduler::Fifo; // Silence Warning
}
}();
if (const auto& _highWatermark = mcConfig.highWatermark)
highWatermark = *mcConfig.highWatermark;
if (const auto& _lowWatermark = mcConfig.lowWatermark)
lowWatermark = *mcConfig.lowWatermark;
if (const auto& _schedulerBuffer = mcConfig.schedulerBuffer)
schedulerBuffer = [=] {
if (_schedulerBuffer == DRAMSys::Config::SchedulerBuffer::Bankwise)
if (const auto &_schedulerBuffer = mcConfig.SchedulerBuffer)
schedulerBuffer = [=]
{
switch (*_schedulerBuffer)
{
case DRAMSys::Config::SchedulerBufferType::Bankwise:
return SchedulerBuffer::Bankwise;
else if (_schedulerBuffer == DRAMSys::Config::SchedulerBuffer::ReadWrite)
case DRAMSys::Config::SchedulerBufferType::ReadWrite:
return SchedulerBuffer::ReadWrite;
else
case DRAMSys::Config::SchedulerBufferType::Shared:
return SchedulerBuffer::Shared;
default:
SC_REPORT_FATAL("Configuration", "Invalid SchedulerBuffer");
return SchedulerBuffer::Bankwise; // Silence Warning
}
}();
if (const auto& _requestBufferSize = mcConfig.requestBufferSize)
requestBufferSize = *mcConfig.requestBufferSize;
if (const auto &_cmdMux = mcConfig.CmdMux)
cmdMux = [=]
{
switch (*_cmdMux)
{
case DRAMSys::Config::CmdMuxType::Oldest:
return CmdMux::Oldest;
case DRAMSys::Config::CmdMuxType::Strict:
return CmdMux::Strict;
default:
SC_REPORT_FATAL("Configuration", "Invalid CmdMux");
return CmdMux::Oldest; // Silence Warning
}
}();
if (const auto &_respQueue = mcConfig.RespQueue)
respQueue = [=]
{
switch (*_respQueue)
{
case DRAMSys::Config::RespQueueType::Fifo:
return RespQueue::Fifo;
case DRAMSys::Config::RespQueueType::Reorder:
return RespQueue::Reorder;
default:
SC_REPORT_FATAL("Configuration", "Invalid RespQueue");
return RespQueue::Fifo; // Silence Warning
}
}();
if (const auto &_refreshPolicy = mcConfig.RefreshPolicy)
refreshPolicy = [=]
{
switch (*_refreshPolicy)
{
case DRAMSys::Config::RefreshPolicyType::NoRefresh:
return RefreshPolicy::NoRefresh;
case DRAMSys::Config::RefreshPolicyType::AllBank:
return RefreshPolicy::AllBank;
case DRAMSys::Config::RefreshPolicyType::PerBank:
return RefreshPolicy::PerBank;
case DRAMSys::Config::RefreshPolicyType::Per2Bank:
return RefreshPolicy::Per2Bank;
case DRAMSys::Config::RefreshPolicyType::SameBank:
return RefreshPolicy::SameBank;
default:
SC_REPORT_FATAL("Configuration", "Invalid RefreshPolicy");
return RefreshPolicy::NoRefresh; // Silence Warning
}
}();
if (const auto &_powerDownPolicy = mcConfig.PowerDownPolicy)
powerDownPolicy = [=]
{
switch (*_powerDownPolicy)
{
case DRAMSys::Config::PowerDownPolicyType::NoPowerDown:
return PowerDownPolicy::NoPowerDown;
case DRAMSys::Config::PowerDownPolicyType::Staggered:
return PowerDownPolicy::Staggered;
default:
SC_REPORT_FATAL("Configuration", "Invalid PowerDownPolicy");
return PowerDownPolicy::NoPowerDown; // Silence Warning
}
}();
if (const auto &_arbiter = mcConfig.Arbiter)
arbiter = [=]
{
switch (*_arbiter)
{
case DRAMSys::Config::ArbiterType::Simple:
return Arbiter::Simple;
case DRAMSys::Config::ArbiterType::Fifo:
return Arbiter::Fifo;
case DRAMSys::Config::ArbiterType::Reorder:
return Arbiter::Reorder;
default:
SC_REPORT_FATAL("Configuration", "Invalid Arbiter");
return Arbiter::Simple; // Silence Warning
}
}();
refreshMaxPostponed = mcConfig.RefreshMaxPostponed.value_or(refreshMaxPostponed);
refreshMaxPulledin = mcConfig.RefreshMaxPulledin.value_or(refreshMaxPulledin);
highWatermark = mcConfig.HighWatermark.value_or(highWatermark);
lowWatermark = mcConfig.LowWatermark.value_or(lowWatermark);
maxActiveTransactions = mcConfig.MaxActiveTransactions.value_or(maxActiveTransactions);
refreshManagement = mcConfig.RefreshManagement.value_or(refreshManagement);
requestBufferSize = mcConfig.RequestBufferSize.value_or(requestBufferSize);
if (requestBufferSize == 0)
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
if (const auto& _cmdMux = mcConfig.cmdMux)
cmdMux = [=] {
if (_cmdMux == DRAMSys::Config::CmdMux::Oldest)
return CmdMux::Oldest;
else
return CmdMux::Strict;
}();
if (const auto& _respQueue = mcConfig.respQueue)
respQueue = [=] {
if (_respQueue == DRAMSys::Config::RespQueue::Fifo)
return RespQueue::Fifo;
else
return RespQueue::Reorder;
}();
if (const auto& _refreshPolicy = mcConfig.refreshPolicy)
refreshPolicy = [=] {
if (_refreshPolicy == DRAMSys::Config::RefreshPolicy::NoRefresh)
return RefreshPolicy::NoRefresh;
else if (_refreshPolicy == DRAMSys::Config::RefreshPolicy::AllBank)
return RefreshPolicy::AllBank;
else if (_refreshPolicy == DRAMSys::Config::RefreshPolicy::PerBank)
return RefreshPolicy::PerBank;
else if (_refreshPolicy == DRAMSys::Config::RefreshPolicy::Per2Bank)
return RefreshPolicy::Per2Bank;
else // if (policy == DRAMSys::Config::RefreshPolicy::SameBank)
return RefreshPolicy::SameBank;
}();
if (const auto& _refreshMaxPostponed = mcConfig.refreshMaxPostponed)
refreshMaxPostponed = *_refreshMaxPostponed;
if (const auto& _refreshMaxPulledin = mcConfig.refreshMaxPulledin)
refreshMaxPulledin = *_refreshMaxPulledin;
if (const auto& _powerDownPolicy = mcConfig.powerDownPolicy)
powerDownPolicy = [=] {
if (_powerDownPolicy == DRAMSys::Config::PowerDownPolicy::NoPowerDown)
return PowerDownPolicy::NoPowerDown;
else
return PowerDownPolicy::Staggered;
}();
if (const auto& _arbiter = mcConfig.arbiter)
arbiter = [=] {
if (_arbiter == DRAMSys::Config::Arbiter::Simple)
return Arbiter::Simple;
else if (_arbiter == DRAMSys::Config::Arbiter::Fifo)
return Arbiter::Fifo;
else
return Arbiter::Reorder;
}();
if (const auto& _maxActiveTransactions = mcConfig.maxActiveTransactions)
maxActiveTransactions = *_maxActiveTransactions;
if (const auto& _refreshManagement = mcConfig.refreshManagement)
refreshManagement = *_refreshManagement;
if (const auto& _arbitrationDelayFw = mcConfig.arbitrationDelayFw)
if (const auto& _arbitrationDelayFw = mcConfig.ArbitrationDelayFw)
{
arbitrationDelayFw = std::round(sc_time(*_arbitrationDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK;
}
if (const auto& _arbitrationDelayBw = mcConfig.arbitrationDelayBw)
if (const auto& _arbitrationDelayBw = mcConfig.ArbitrationDelayBw)
{
arbitrationDelayBw = std::round(sc_time(*_arbitrationDelayBw, SC_NS) / memSpec->tCK) * memSpec->tCK;
}
if (const auto& _thinkDelayFw = mcConfig.thinkDelayFw)
if (const auto& _thinkDelayFw = mcConfig.ThinkDelayFw)
{
thinkDelayFw = std::round(sc_time(*_thinkDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK;
}
if (const auto& _thinkDelayBw = mcConfig.thinkDelayBw)
if (const auto& _thinkDelayBw = mcConfig.ThinkDelayBw)
{
thinkDelayBw = std::round(sc_time(*_thinkDelayBw, SC_NS) / memSpec->tCK) * memSpec->tCK;
}
if (const auto& _phyDelayFw = mcConfig.phyDelayFw)
if (const auto& _phyDelayFw = mcConfig.PhyDelayFw)
{
phyDelayFw = std::round(sc_time(*_phyDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK;
}
if (const auto& _phyDelayBw = mcConfig.phyDelayBw)
if (const auto& _phyDelayBw = mcConfig.PhyDelayBw)
{
phyDelayBw = std::round(sc_time(*_phyDelayBw, SC_NS) / memSpec->tCK) * memSpec->tCK;
}
{
auto _blockingReadDelay = mcConfig.blockingReadDelay.value_or(60);
auto _blockingReadDelay = mcConfig.BlockingReadDelay.value_or(60);
blockingReadDelay = std::round(sc_time(_blockingReadDelay, SC_NS) / memSpec->tCK) * memSpec->tCK;
}
{
auto _blockingWriteDelay = mcConfig.blockingWriteDelay.value_or(60);
auto _blockingWriteDelay = mcConfig.BlockingWriteDelay.value_or(60);
blockingWriteDelay = std::round(sc_time(_blockingWriteDelay, SC_NS) / memSpec->tCK) * memSpec->tCK;
}
}

View File

@@ -55,20 +55,20 @@ MemSpec::MemSpec(const DRAMSys::Config::MemSpec& memSpec,
banksPerChannel(banksPerChannel),
bankGroupsPerChannel(bankGroupsPerChannel),
devicesPerRank(devicesPerRank),
rowsPerBank(memSpec.memArchitectureSpec.entries.at("nbrOfRows")),
columnsPerRow(memSpec.memArchitectureSpec.entries.at("nbrOfColumns")),
defaultBurstLength(memSpec.memArchitectureSpec.entries.at("burstLength")),
maxBurstLength(memSpec.memArchitectureSpec.entries.find("maxBurstLength") !=
memSpec.memArchitectureSpec.entries.end()
? memSpec.memArchitectureSpec.entries.at("maxBurstLength")
rowsPerBank(memSpec.memarchitecturespec.entries.at("nbrOfRows")),
columnsPerRow(memSpec.memarchitecturespec.entries.at("nbrOfColumns")),
defaultBurstLength(memSpec.memarchitecturespec.entries.at("burstLength")),
maxBurstLength(memSpec.memarchitecturespec.entries.find("maxBurstLength") !=
memSpec.memarchitecturespec.entries.end()
? memSpec.memarchitecturespec.entries.at("maxBurstLength")
: defaultBurstLength),
dataRate(memSpec.memArchitectureSpec.entries.at("dataRate")),
bitWidth(memSpec.memArchitectureSpec.entries.at("width")),
dataRate(memSpec.memarchitecturespec.entries.at("dataRate")),
bitWidth(memSpec.memarchitecturespec.entries.at("width")),
dataBusWidth(bitWidth* devicesPerRank),
bytesPerBeat(dataBusWidth / 8),
defaultBytesPerBurst((defaultBurstLength* dataBusWidth) / 8),
maxBytesPerBurst((maxBurstLength* dataBusWidth) / 8),
fCKMHz(memSpec.memTimingSpec.entries.at("clkMhz")),
fCKMHz(memSpec.memtimingspec.entries.at("clkMhz")),
tCK(sc_time(1.0 / fCKMHz, SC_US)),
memoryId(memSpec.memoryId),
memoryType(memoryType),

View File

@@ -45,61 +45,61 @@ using namespace tlm;
MemSpecDDR3::MemSpecDDR3(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::DDR3,
memSpec.memArchitectureSpec.entries.at("nbrOfChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memArchitectureSpec.entries.at("nbrOfRanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1,
memSpec.memArchitectureSpec.entries.at("nbrOfBanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks")
* memSpec.memArchitectureSpec.entries.at("nbrOfRanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfRanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfDevices")),
tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD (tCKE),
tCKESR (tCK * memSpec.memTimingSpec.entries.at("CKESR")),
tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")),
tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")),
tRC (tCK * memSpec.memTimingSpec.entries.at("RC")),
tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")),
tRL (tCK * memSpec.memTimingSpec.entries.at("RL")),
tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")),
tWL (tCK * memSpec.memTimingSpec.entries.at("WL")),
tWR (tCK * memSpec.memTimingSpec.entries.at("WR")),
tXP (tCK * memSpec.memTimingSpec.entries.at("XP")),
tXS (tCK * memSpec.memTimingSpec.entries.at("XS")),
tCCD (tCK * memSpec.memTimingSpec.entries.at("CCD")),
tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")),
tREFI (tCK * memSpec.memTimingSpec.entries.at("REFI")),
tRFC (tCK * memSpec.memTimingSpec.entries.at("RFC")),
tRP (tCK * memSpec.memTimingSpec.entries.at("RP")),
tRRD (tCK * memSpec.memTimingSpec.entries.at("RRD")),
tWTR (tCK * memSpec.memTimingSpec.entries.at("WTR")),
tAL (tCK * memSpec.memTimingSpec.entries.at("AL")),
tXPDLL (tCK * memSpec.memTimingSpec.entries.at("XPDLL")),
tXSDLL (tCK * memSpec.memTimingSpec.entries.at("XSDLL")),
tACTPDEN (tCK * memSpec.memTimingSpec.entries.at("ACTPDEN")),
tPRPDEN (tCK * memSpec.memTimingSpec.entries.at("PRPDEN")),
tREFPDEN (tCK * memSpec.memTimingSpec.entries.at("REFPDEN")),
tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")),
iDD0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd0") : 0),
iDD2N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2n") : 0),
iDD3N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3n") : 0),
iDD4R (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4r") : 0),
iDD4W (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4w") : 0),
iDD5 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd5") : 0),
iDD6 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd6") : 0),
vDD (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd") : 0),
iDD2P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p0") : 0),
iDD2P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p1") : 0),
iDD3P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p0") : 0),
iDD3P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p1") : 0)
tCKESR (tCK * memSpec.memtimingspec.entries.at("CKESR")),
tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC (tCK * memSpec.memtimingspec.entries.at("RC")),
tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tXS (tCK * memSpec.memtimingspec.entries.at("XS")),
tCCD (tCK * memSpec.memtimingspec.entries.at("CCD")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")),
tRFC (tCK * memSpec.memtimingspec.entries.at("RFC")),
tRP (tCK * memSpec.memtimingspec.entries.at("RP")),
tRRD (tCK * memSpec.memtimingspec.entries.at("RRD")),
tWTR (tCK * memSpec.memtimingspec.entries.at("WTR")),
tAL (tCK * memSpec.memtimingspec.entries.at("AL")),
tXPDLL (tCK * memSpec.memtimingspec.entries.at("XPDLL")),
tXSDLL (tCK * memSpec.memtimingspec.entries.at("XSDLL")),
tACTPDEN (tCK * memSpec.memtimingspec.entries.at("ACTPDEN")),
tPRPDEN (tCK * memSpec.memtimingspec.entries.at("PRPDEN")),
tREFPDEN (tCK * memSpec.memtimingspec.entries.at("REFPDEN")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")),
iDD0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd0") : 0),
iDD2N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n") : 0),
iDD3N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n") : 0),
iDD4R (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r") : 0),
iDD4W (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w") : 0),
iDD5 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd5") : 0),
iDD6 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd6") : 0),
vDD (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd") : 0),
iDD2P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p0") : 0),
iDD2P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p1") : 0),
iDD3P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p0") : 0),
iDD3P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p1") : 0)
{
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
memorySizeBytes = deviceSizeBytes * devicesPerRank * ranksPerChannel * numberOfChannels;
if (!memSpec.memPowerSpec.has_value())
if (!memSpec.mempowerspec.has_value())
SC_REPORT_FATAL("MemSpec", "No power spec defined!");
std::cout << headline << std::endl;

View File

@@ -45,79 +45,79 @@ using namespace tlm;
MemSpecDDR4::MemSpecDDR4(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::DDR4,
memSpec.memArchitectureSpec.entries.at("nbrOfChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memArchitectureSpec.entries.at("nbrOfRanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks")
/ memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups"),
memSpec.memArchitectureSpec.entries.at("nbrOfBanks")
* memSpec.memArchitectureSpec.entries.at("nbrOfRanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfBankGroups")
* memSpec.memArchitectureSpec.entries.at("nbrOfRanks"),
memSpec.memArchitectureSpec.entries.at("nbrOfDevices")),
tCKE (tCK * memSpec.memTimingSpec.entries.at("CKE")),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
/ memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD (tCKE),
tCKESR (tCK * memSpec.memTimingSpec.entries.at("CKESR")),
tRAS (tCK * memSpec.memTimingSpec.entries.at("RAS")),
tRC (tCK * memSpec.memTimingSpec.entries.at("RC")),
tRCD (tCK * memSpec.memTimingSpec.entries.at("RCD")),
tRL (tCK * memSpec.memTimingSpec.entries.at("RL")),
tRPRE (tCK * memSpec.memTimingSpec.entries.at("RPRE")),
tRTP (tCK * memSpec.memTimingSpec.entries.at("RTP")),
tWL (tCK * memSpec.memTimingSpec.entries.at("WL")),
tWPRE (tCK * memSpec.memTimingSpec.entries.at("WPRE")),
tWR (tCK * memSpec.memTimingSpec.entries.at("WR")),
tXP (tCK * memSpec.memTimingSpec.entries.at("XP")),
tXS (tCK * memSpec.memTimingSpec.entries.at("XS")),
tREFI ((memSpec.memTimingSpec.entries.at("REFM") == 4) ?
(tCK * (static_cast<double>(memSpec.memTimingSpec.entries.at("REFI")) / 4)) :
((memSpec.memTimingSpec.entries.at("REFM") == 2) ?
(tCK * (static_cast<double>(memSpec.memTimingSpec.entries.at("REFI")) / 2)) :
(tCK * memSpec.memTimingSpec.entries.at("REFI")))),
tRFC ((memSpec.memTimingSpec.entries.at("REFM") == 4) ?
(tCK * memSpec.memTimingSpec.entries.at("RFC4")) :
((memSpec.memTimingSpec.entries.at("REFM") == 2) ?
(tCK * memSpec.memTimingSpec.entries.at("RFC2")) :
(tCK * memSpec.memTimingSpec.entries.at("RFC")))),
tRP (tCK * memSpec.memTimingSpec.entries.at("RP")),
tDQSCK (tCK * memSpec.memTimingSpec.entries.at("DQSCK")),
tCCD_S (tCK * memSpec.memTimingSpec.entries.at("CCD_S")),
tCCD_L (tCK * memSpec.memTimingSpec.entries.at("CCD_L")),
tFAW (tCK * memSpec.memTimingSpec.entries.at("FAW")),
tRRD_S (tCK * memSpec.memTimingSpec.entries.at("RRD_S")),
tRRD_L (tCK * memSpec.memTimingSpec.entries.at("RRD_L")),
tWTR_S (tCK * memSpec.memTimingSpec.entries.at("WTR_S")),
tWTR_L (tCK * memSpec.memTimingSpec.entries.at("WTR_L")),
tAL (tCK * memSpec.memTimingSpec.entries.at("AL")),
tXPDLL (tCK * memSpec.memTimingSpec.entries.at("XPDLL")),
tXSDLL (tCK * memSpec.memTimingSpec.entries.at("XSDLL")),
tACTPDEN (tCK * memSpec.memTimingSpec.entries.at("ACTPDEN")),
tPRPDEN (tCK * memSpec.memTimingSpec.entries.at("PRPDEN")),
tREFPDEN (tCK * memSpec.memTimingSpec.entries.at("REFPDEN")),
tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")),
iDD0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd0") : 0),
iDD2N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2n") : 0),
iDD3N (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3n") : 0),
iDD4R (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4r") : 0),
iDD4W (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd4w") : 0),
iDD5 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd5") : 0),
iDD6 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd6") : 0),
vDD (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd") : 0),
iDD02 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd02") : 0),
iDD2P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p0") : 0),
iDD2P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd2p1") : 0),
iDD3P0 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p0") : 0),
iDD3P1 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd3p1") : 0),
iDD62 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("idd62") : 0),
vDD2 (memSpec.memPowerSpec.has_value() ? memSpec.memPowerSpec.value().entries.at("vdd2") : 0)
tCKESR (tCK * memSpec.memtimingspec.entries.at("CKESR")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC (tCK * memSpec.memtimingspec.entries.at("RC")),
tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
tRPRE (tCK * memSpec.memtimingspec.entries.at("RPRE")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tWPRE (tCK * memSpec.memtimingspec.entries.at("WPRE")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tXS (tCK * memSpec.memtimingspec.entries.at("XS")),
tREFI ((memSpec.memtimingspec.entries.at("REFM") == 4) ?
(tCK * (static_cast<double>(memSpec.memtimingspec.entries.at("REFI")) / 4)) :
((memSpec.memtimingspec.entries.at("REFM") == 2) ?
(tCK * (static_cast<double>(memSpec.memtimingspec.entries.at("REFI")) / 2)) :
(tCK * memSpec.memtimingspec.entries.at("REFI")))),
tRFC ((memSpec.memtimingspec.entries.at("REFM") == 4) ?
(tCK * memSpec.memtimingspec.entries.at("RFC4")) :
((memSpec.memtimingspec.entries.at("REFM") == 2) ?
(tCK * memSpec.memtimingspec.entries.at("RFC2")) :
(tCK * memSpec.memtimingspec.entries.at("RFC")))),
tRP (tCK * memSpec.memtimingspec.entries.at("RP")),
tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tCCD_S (tCK * memSpec.memtimingspec.entries.at("CCD_S")),
tCCD_L (tCK * memSpec.memtimingspec.entries.at("CCD_L")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
tRRD_S (tCK * memSpec.memtimingspec.entries.at("RRD_S")),
tRRD_L (tCK * memSpec.memtimingspec.entries.at("RRD_L")),
tWTR_S (tCK * memSpec.memtimingspec.entries.at("WTR_S")),
tWTR_L (tCK * memSpec.memtimingspec.entries.at("WTR_L")),
tAL (tCK * memSpec.memtimingspec.entries.at("AL")),
tXPDLL (tCK * memSpec.memtimingspec.entries.at("XPDLL")),
tXSDLL (tCK * memSpec.memtimingspec.entries.at("XSDLL")),
tACTPDEN (tCK * memSpec.memtimingspec.entries.at("ACTPDEN")),
tPRPDEN (tCK * memSpec.memtimingspec.entries.at("PRPDEN")),
tREFPDEN (tCK * memSpec.memtimingspec.entries.at("REFPDEN")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")),
iDD0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd0") : 0),
iDD2N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n") : 0),
iDD3N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n") : 0),
iDD4R (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r") : 0),
iDD4W (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w") : 0),
iDD5 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd5") : 0),
iDD6 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd6") : 0),
vDD (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd") : 0),
iDD02 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd02") : 0),
iDD2P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p0") : 0),
iDD2P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p1") : 0),
iDD3P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p0") : 0),
iDD3P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p1") : 0),
iDD62 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd62") : 0),
vDD2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd2") : 0)
{
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
memorySizeBytes = deviceSizeBytes * devicesPerRank * ranksPerChannel * numberOfChannels;
if (!memSpec.memPowerSpec.has_value())
if (!memSpec.mempowerspec.has_value())
SC_REPORT_WARNING("MemSpec", "No power spec defined!");
std::cout << headline << std::endl;

Some files were not shown because too many files have changed in this diff Show More