Merge branch 'develop' into wip/unit_test_preps
# Conflicts: # extensions/standards/DDR5/DRAMSys/controller/checker/CheckerDDR5.cpp
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
28,
|
||||
29,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
13,
|
||||
14,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
27,
|
||||
28,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
13,
|
||||
14,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
28,
|
||||
29,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
13,
|
||||
14,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
26,
|
||||
27,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
13,
|
||||
14,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANKGROUP_BIT":[
|
||||
28,
|
||||
29
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0,
|
||||
1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0,
|
||||
1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0,
|
||||
1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0,
|
||||
1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"PSEUDOCHANNEL_BIT":[
|
||||
29
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"PSEUDOCHANNEL_BIT":[
|
||||
28
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
28,
|
||||
29,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
11,
|
||||
12,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
5,
|
||||
6,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
27,
|
||||
28,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
11,
|
||||
12,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
5,
|
||||
6,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
27,
|
||||
28,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BYTE_BIT": [
|
||||
0
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"RANK_BIT":[
|
||||
30,
|
||||
31
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
13,
|
||||
14,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
25,
|
||||
26,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
12,
|
||||
13,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
25,
|
||||
26
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
11,
|
||||
12
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
23,
|
||||
24
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
11,
|
||||
12
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
26,
|
||||
27
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
11,
|
||||
12
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
27,
|
||||
28
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
12,
|
||||
13
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
24,
|
||||
25
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
11,
|
||||
12
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"CONGEN": {
|
||||
"addressmapping": {
|
||||
"BANK_BIT": [
|
||||
4,
|
||||
5
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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, ¤t_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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user