Merge branch 'work/project_refactor' into 'develop'

Refactoring of complete repository structure, especially CMake.

See merge request ems/astdm/modeling.dram/dram.sys.5!4
This commit is contained in:
Lukas Steiner
2023-03-06 13:26:00 +00:00
748 changed files with 28816 additions and 10075 deletions

5
.gitattributes vendored Normal file
View File

@@ -0,0 +1,5 @@
*.stl filter=lfs diff=lfs merge=lfs -text
*.data.gz filter=lfs diff=lfs merge=lfs -text
*.inst.gz filter=lfs diff=lfs merge=lfs -text
*.tdb filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text

2
.gitignore vendored
View File

@@ -5,7 +5,7 @@
/dram/build
*.user
*.tdb
!/DRAMSys/tests/*/expected/*.tdb
!tests/tests_regression/*/expected/*.tdb
*.tdb-journal
*.out
/build-simulation

View File

@@ -7,10 +7,7 @@ before_script:
stages:
- build
- test_DDR3
- test_DDR4
- test_HBM2
- test_LPDDR4
- test
- coverage
build:
@@ -22,31 +19,36 @@ build:
- mkdir -p coverage
- mkdir -p build
- cd build
- cmake -DDRAMSYS_COVERAGE_CHECK=ON ../DRAMSys
- cmake -DDRAMSYS_COVERAGE_CHECK=ON -DDRAMSYS_ENABLE_EXTENSIONS=ON -DDRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE=ON -DDRAMSYS_WITH_DRAMPOWER=ON ..
- make -j 10
- find . -name "*.o" -type f -delete
artifacts:
paths:
- build/
- DRAMSys/tests/
- tests/
- coverage/
expire_in: 2 days
coverage:
stage: coverage
needs:
- test_DDR3
- test_DDR4
- test_HBM2
- test_LPDDR4
coverage: '/Total:\|(\d+\.?\d+\%)/'
script:
# delete all empty files since they produce errors
- find coverage -size 0 -type f -delete
- ls coverage/ -lah
- lcov `find coverage -type f -exec echo "-a {}" \;` -o coverage/final.out
- lcov --remove coverage/final.out '*/systemc*/include/*' '*/traceAnalyzer/*' '*/gcc*/include/*' '/usr/include/*' '*/third_party/*' -o coverage/final_dramsys.out
- lcov --remove coverage/final.out '/build/_deps/*' '/lib/*' '/usr/*' -o coverage/final_dramsys.out
- lcov --list coverage/final_dramsys.out
include:
- '/DRAMSys/tests/DDR3/ci.yml'
- '/DRAMSys/tests/DDR4/ci.yml'
- '/DRAMSys/tests/HBM2/ci.yml'
- '/DRAMSys/tests/LPDDR4/ci.yml'
- 'tests/tests_regression/DDR3/ci.yml'
- 'tests/tests_regression/DDR4/ci.yml'
- 'tests/tests_regression/HBM2/ci.yml'
- 'tests/tests_regression/LPDDR4/ci.yml'
#- '/DRAMSys/tests/dramsys-gem5/ci.yml' # Should be activated again when a new gitlab runner with right dependencies is used

16
.gitmodules vendored
View File

@@ -1,16 +0,0 @@
[submodule "DRAMSys/library/src/common/third_party/DRAMPower"]
path = DRAMSys/library/src/common/third_party/DRAMPower
url = https://github.com/tukl-msd/DRAMPower.git
branch = rgr
[submodule "DRAMSys/unitTests/googletest"]
path = DRAMSys/unitTests/googletest
url = https://github.com/google/googletest.git
[submodule "DRAMSys/library/src/common/third_party/systemc"]
path = DRAMSys/library/src/common/third_party/systemc
url = https://github.com/accellera-official/systemc.git
[submodule "DRAMSys/library/src/common/third_party/sqlite-amalgamation"]
path = DRAMSys/library/src/common/third_party/sqlite-amalgamation
url = https://github.com/azadkuh/sqlite-amalgamation.git
[submodule "DRAMSys/library/src/common/third_party/nlohmann"]
path = DRAMSys/library/src/common/third_party/nlohmann
url = https://github.com/nlohmann/json

191
CMakeLists.txt Normal file
View File

@@ -0,0 +1,191 @@
# Copyright (c) 2020, Technische Universität Kaiserslautern
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors:
# Thomas Psota
###############################################
### DRAMSys ###
###############################################
cmake_minimum_required(VERSION 3.13.0)
set(PROJECT_NAME "DRAMSys 5.0")
set(PROJECT_SHORTNAME "DRAMSys")
project(${PROJECT_NAME} VERSION "5.0")
### CMake settings ###
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
include(build_source_group)
include(diagnostics_print)
include(enable_extensions)
include(FetchContent)
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()
# Check if standalone build or being included as submodule
get_directory_property(DRAMSYS_IS_SUBMODULE PARENT_DIRECTORY)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
### Project settings ###
message(STATUS "CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
message(STATUS "CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")
message(STATUS "" )
if(NOT DRAMSYS_IS_SUBMODULE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
endif()
### DRAMSys directories ###
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_EXTENSIONS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extensions")
### Build options ###
option(DRAMSYS_BUILD_TESTS "Build DRAMSys unit tests" OFF)
option(DRAMSYS_VERBOSE_CMAKE_OUTPUT "Show detailed CMake output" OFF)
option(DRAMSYS_BUILD_CLI "Build DRAMSys Command Line Tool" ON)
option(DRAMSYS_COVERAGE_CHECK "Coverage check of DRAMSys" OFF)
option(DRAMSYS_WITH_GEM5 "Build DRAMSys with gem5 coupling" OFF)
option(DRAMSYS_WITH_DRAMPOWER "Build with DRAMPower support enabled." OFF)
option(DRAMSYS_ENABLE_EXTENSIONS "Enable proprietary DRAMSys extensions." OFF)
### Compiler settings ###
set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ Standard")
if(DRAMSYS_COVERAGE_CHECK)
message("== Coverage check enabled")
set(GCC_COVERAGE_COMPILE_FLAGS "-g -O0 -coverage -fprofile-arcs -ftest-coverage")
set(GCC_COVERAGE_LINK_FLAGS "-coverage -lgcov")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
endif()
###############################################
### Library Settings ###
###############################################
### Detect OS threading library ###
find_package(Threads)
### nlohmann_json ###
add_subdirectory(${DRAMSYS_LIBRARY_DIR}/nlohmann_json)
### sqlite3 ###
add_subdirectory(${DRAMSYS_LIBRARY_DIR}/sqlite3)
### GoogleTest ###
if(DRAMSYS_BUILD_TESTS)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest
GIT_TAG release-1.12.1)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
set_target_properties(gmock PROPERTIES FOLDER lib/gtest)
set_target_properties(gmock_main PROPERTIES FOLDER lib/gtest)
set_target_properties(gtest PROPERTIES FOLDER lib/gtest)
set_target_properties(gtest_main PROPERTIES FOLDER lib/gtest)
endif()
### sqlite-amalgamation ###
# FetchContent_Declare(
# sqlite-amalgamation
# GIT_REPOSITORY https://github.com/azadkuh/sqlite-amalgamation.git
# GIT_TAG 3.38.2)
#
# set(SQLITE_ENABLE_RTREE ON CACHE BOOL "Enable R-Tree Feature")
# FetchContent_MakeAvailable(sqlite-amalgamation)
# set_target_properties(SQLite3 PROPERTIES FOLDER lib)
# add_library(sqlite::sqlite3 ALIAS SQLite3)
### SystemC ###
FetchContent_Declare(
systemc
GIT_REPOSITORY https://github.com/accellera-official/systemc.git
GIT_TAG 2.3.4)
FetchContent_MakeAvailable(systemc)
set_target_properties(systemc PROPERTIES FOLDER lib)
### DRAMPower ###
if (DRAMSYS_WITH_DRAMPOWER)
FetchContent_Declare(
DRAMPower
GIT_REPOSITORY https://github.com/tukl-msd/DRAMPower
GIT_TAG 9e64a1b)
FetchContent_MakeAvailable(DRAMPower)
set_target_properties(DRAMPower PROPERTIES FOLDER lib)
endif ()
###############################################
### Source Directory ###
###############################################
add_subdirectory(src/util)
add_subdirectory(src/configuration)
add_subdirectory(src/libdramsys)
if(DRAMSYS_BUILD_CLI)
add_subdirectory(src/simulator)
endif()
if(DRAMSYS_ENABLE_EXTENSIONS)
dramsys_enable_extensions()
endif()
###############################################
### Test Directory ###
###############################################
if(DRAMSYS_BUILD_TESTS)
include( GoogleTest )
include( CTest )
add_subdirectory(tests)
endif()
# Add DRAMSysgem5
#if(DEFINED ENV{GEM5} AND DRAMSYS_WITH_GEM5)
# message("== gem5 coupling included")
# add_subdirectory(gem5)
#endif()

View File

@@ -1,268 +0,0 @@
# Copyright (c) 2020, Technische Universität Kaiserslautern
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors:
# Matthias Jung
# Lukas Steiner
# Derek Christ
cmake_minimum_required(VERSION 3.10)
# Project Name
project(DRAMSysLibrary)
# Configuration:
set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ Version")
set(DCMAKE_SH="CMAKE_SH-NOTFOUND")
option(DRAMSYS_WITH_DRAMPOWER "Build with DRAMPower support enabled." ON)
# Add DRAMPower:
if (DRAMSYS_WITH_DRAMPOWER)
add_subdirectory(src/common/third_party/DRAMPower)
endif()
# Add Configuration
add_subdirectory(src/common/configuration)
# Add SystemC:
if(DEFINED ENV{SYSTEMC_HOME})
find_library(SYSTEMC_LIBRARY
NAMES systemc SnpsVP
PATHS $ENV{SYSTEMC_HOME}/lib-$ENV{SYSTEMC_TARGET_ARCH}/ $ENV{SYSTEMC_HOME}/lib-linux64/ $ENV{SYSTEMC_HOME}/lib64 $ENV{SYSTEMC_HOME}/libso-$ENV{COWARE_CXX_COMPILER}/
)
message("== Building with external SystemC located in $ENV{SYSTEMC_HOME}")
else()
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build Shared Libs")
add_subdirectory(src/common/third_party/systemc)
set(SYSTEMC_LIBRARY systemc)
message("== Building with SystemC submodule")
endif()
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src/common/third_party/sqlite-amalgamation)
message("== Database recording included")
# Add sqlite3 Dependency:
set(BUILD_ENABLE_RTREE ON CACHE BOOL "Enable R-Tree Feature")
set(BUILD_ENABLE_RTREE ON)
add_subdirectory(src/common/third_party/sqlite-amalgamation)
set(RECORDING_SOURCES
src/common/TlmRecorder.cpp
src/controller/ControllerRecordable.cpp
src/simulation/DRAMSysRecordable.cpp
src/simulation/dram/DramRecordable.cpp
)
endif()
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src/controller/checker/CheckerDDR5.cpp)
message("== DDR5 included")
set(DDR5_SOURCES
src/configuration/memspec/MemSpecDDR5.cpp
src/controller/checker/CheckerDDR5.cpp
src/simulation/dram/DramDDR5.cpp
)
endif()
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src/controller/checker/CheckerLPDDR5.cpp)
message("== LPDDR5 included")
set(LPDDR5_SOURCES
src/configuration/memspec/MemSpecLPDDR5.cpp
src/controller/checker/CheckerLPDDR5.cpp
src/simulation/dram/DramLPDDR5.cpp
)
endif()
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src/controller/checker/CheckerHBM3.cpp)
message("== HBM3 included")
set(HBM3_SOURCES
src/configuration/memspec/MemSpecHBM3.cpp
src/controller/checker/CheckerHBM3.cpp
src/simulation/dram/DramHBM3.cpp
)
endif()
add_library(DRAMSysLibrary
src/common/DebugManager.cpp
src/common/dramExtensions.cpp
src/common/tlm2_base_protocol_checker.h
src/common/utils.cpp
src/configuration/Configuration.cpp
src/configuration/TemperatureSimConfig.h
src/configuration/memspec/MemSpec.cpp
src/configuration/memspec/MemSpecDDR3.cpp
src/configuration/memspec/MemSpecDDR4.cpp
src/configuration/memspec/MemSpecLPDDR4.cpp
src/configuration/memspec/MemSpecWideIO.cpp
src/configuration/memspec/MemSpecWideIO2.cpp
src/configuration/memspec/MemSpecGDDR5.cpp
src/configuration/memspec/MemSpecGDDR5X.cpp
src/configuration/memspec/MemSpecGDDR6.cpp
src/configuration/memspec/MemSpecHBM2.cpp
src/configuration/memspec/MemSpecSTTMRAM.cpp
src/controller/BankMachine.cpp
src/controller/Command.cpp
src/controller/ControllerIF.h
src/controller/Controller.cpp
src/controller/checker/CheckerIF.h
src/controller/checker/CheckerDDR3.cpp
src/controller/checker/CheckerDDR4.cpp
src/controller/checker/CheckerLPDDR4.cpp
src/controller/checker/CheckerWideIO.cpp
src/controller/checker/CheckerWideIO2.cpp
src/controller/checker/CheckerGDDR5.cpp
src/controller/checker/CheckerGDDR5X.cpp
src/controller/checker/CheckerGDDR6.cpp
src/controller/checker/CheckerHBM2.cpp
src/controller/checker/CheckerSTTMRAM.cpp
src/controller/cmdmux/CmdMuxIF.h
src/controller/cmdmux/CmdMuxOldest.cpp
src/controller/cmdmux/CmdMuxStrict.cpp
src/controller/powerdown/PowerDownManagerIF.h
src/controller/powerdown/PowerDownManagerDummy.cpp
src/controller/powerdown/PowerDownManagerStaggered.cpp
src/controller/refresh/RefreshManagerIF.h
src/controller/refresh/RefreshManagerDummy.cpp
src/controller/refresh/RefreshManagerAllBank.cpp
src/controller/refresh/RefreshManagerPerBank.cpp
src/controller/refresh/RefreshManagerPer2Bank.cpp
src/controller/refresh/RefreshManagerSameBank.cpp
src/controller/respqueue/RespQueueIF.h
src/controller/respqueue/RespQueueFifo.cpp
src/controller/respqueue/RespQueueReorder.cpp
src/controller/scheduler/SchedulerIF.h
src/controller/scheduler/SchedulerFifo.cpp
src/controller/scheduler/SchedulerFrFcfs.cpp
src/controller/scheduler/SchedulerFrFcfsGrp.cpp
src/controller/scheduler/SchedulerGrpFrFcfs.cpp
src/controller/scheduler/SchedulerGrpFrFcfsWm.cpp
src/controller/scheduler/BufferCounterIF.h
src/controller/scheduler/BufferCounterBankwise.cpp
src/controller/scheduler/BufferCounterReadWrite.cpp
src/controller/scheduler/BufferCounterShared.cpp
src/error/eccbaseclass.cpp
src/error/ecchamming.cpp
src/error/errormodel.cpp
src/error/ECC/Bit.cpp
src/error/ECC/ECC.cpp
src/error/ECC/Word.cpp
src/simulation/Arbiter.cpp
src/simulation/AddressDecoder.cpp
src/simulation/DRAMSys.cpp
src/simulation/ReorderBuffer.h
src/simulation/TemperatureController.cpp
src/simulation/dram/Dram.cpp
src/simulation/dram/DramDDR3.cpp
src/simulation/dram/DramDDR4.cpp
src/simulation/dram/DramLPDDR4.cpp
src/simulation/dram/DramWideIO.cpp
src/simulation/dram/DramWideIO2.cpp
src/simulation/dram/DramGDDR5.cpp
src/simulation/dram/DramGDDR5X.cpp
src/simulation/dram/DramGDDR6.cpp
src/simulation/dram/DramHBM2.cpp
src/simulation/dram/DramSTTMRAM.cpp
${RECORDING_SOURCES}
${DDR5_SOURCES}
${LPDDR5_SOURCES}
${HBM3_SOURCES}
)
if(DEFINED DDR5_SOURCES)
target_compile_definitions(DRAMSysLibrary PRIVATE DDR5_SIM)
endif()
if(DEFINED LPDDR5_SOURCES)
target_compile_definitions(DRAMSysLibrary PRIVATE LPDDR5_SIM)
endif()
if(DEFINED HBM3_SOURCES)
target_compile_definitions(DRAMSysLibrary PRIVATE HBM3_SIM)
endif()
if(DEFINED ENV{LIBTHREED_ICE_HOME})
message("== Thermal simulation available")
target_compile_definitions(DRAMSysLibrary PRIVATE THERMALSIM)
target_include_directories(DRAMSysLibrary
PRIVATE $ENV{LIBTHREED_ICE_HOME}/include/
)
find_library(3DICE_LIBRARY NAMES threed-ice-2.2.4 PATHS $ENV{LIBTHREED_ICE_HOME}/lib/)
target_link_libraries(DRAMSysLibrary
PRIVATE ${3DICE_LIBRARY}
)
endif()
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src/common/third_party/sqlite-amalgamation)
target_include_directories(DRAMSysLibrary
PUBLIC src/common/third_party/sqlite-amalgamation/
)
target_link_libraries(DRAMSysLibrary
PRIVATE sqlite3::sqlite3
)
endif()
# Build:
target_include_directories(DRAMSysLibrary
PRIVATE src/common/third_party/DRAMPower/src/
PUBLIC $ENV{SYSTEMC_HOME}/include/
)
if(EXISTS $ENV{SYSTEMC_HOME}/include/tlm/)
target_include_directories(DRAMSysLibrary
PUBLIC $ENV{SYSTEMC_HOME}/include/tlm/
)
endif()
target_link_libraries(DRAMSysLibrary
PUBLIC ${SYSTEMC_LIBRARY}
PUBLIC DRAMSysConfiguration
)
if (DRAMSYS_WITH_DRAMPOWER)
target_compile_definitions(DRAMSysLibrary PRIVATE DRAMPOWER)
target_link_libraries(DRAMSysLibrary
PRIVATE DRAMPower
)
endif()

View File

@@ -1 +0,0 @@
*.pyc

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,18 +0,0 @@
{
"simconfig": {
"CheckTLM2Protocol": false,
"DatabaseRecording": true,
"Debug": false,
"ECCControllerMode": "Disabled",
"EnableWindowing": true,
"ErrorCSVFile": "../../DRAMSys/library/resources/error/wideio.csv",
"ErrorChipSeed": 42,
"PowerAnalysis": true,
"SimulationName": "wideio",
"SimulationProgressBar": true,
"StoreMode": "NoStorage",
"ThermalSimulation": false,
"UseMalloc": false,
"WindowSize": 1000
}
}

View File

@@ -1,18 +0,0 @@
{
"simconfig": {
"CheckTLM2Protocol": false,
"DatabaseRecording": true,
"Debug": false,
"ECCControllerMode": "Hamming",
"EnableWindowing": true,
"ErrorCSVFile": "../../DRAMSys/library/resources/error/wideio.csv",
"ErrorChipSeed": 42,
"PowerAnalysis": true,
"SimulationName": "wideio_ecc",
"SimulationProgressBar": true,
"StoreMode": "ErrorModel",
"ThermalSimulation": false,
"UseMalloc": false,
"WindowSize": 1000
}
}

View File

@@ -1,18 +0,0 @@
{
"simconfig": {
"CheckTLM2Protocol": false,
"DatabaseRecording": true,
"Debug": false,
"ECCControllerMode": "Disabled",
"EnableWindowing": true,
"ErrorCSVFile": "../../DRAMSys/library/resources/error/wideio.csv",
"ErrorChipSeed": 42,
"PowerAnalysis": true,
"SimulationName": "wideio",
"SimulationProgressBar": true,
"StoreMode": "Store",
"ThermalSimulation": true,
"UseMalloc": false,
"WindowSize": 1000
}
}

View File

@@ -1,15 +0,0 @@
{
"thermalsimconfig": {
"TemperatureScale": "Celsius",
"StaticTemperatureDefaultValue": 89,
"ThermalSimPeriod":100,
"ThermalSimUnit":"us",
"PowerInfoFile": "powerInfo.json",
"IceServerIp": "127.0.0.1",
"IceServerPort": 11880,
"SimPeriodAdjustFactor" : 10,
"NPowStableCyclesToIncreasePeriod": 5,
"GenerateTemperatureMap": true,
"GeneratePowerMap": true
}
}

View File

@@ -1,45 +0,0 @@
CPUs :
position 0, 0 ;
dimension 2750, 4300 ;
GPU :
position 3350, 0 ;
dimension 2750, 4000 ;
BASEBAND1 :
position 4250, 4000 ;
dimension 1850, 3300 ;
BASEBAND2 :
position 3350, 7300 ;
dimension 2750, 3300 ;
LLCACHE :
position 0, 4300 ;
dimension 1900, 3000 ;
DRAMCTRL1 :
position 1900, 4300 ;
dimension 850, 3000 ;
DRAMCTRL2 :
position 3350, 4000 ;
dimension 900, 3300 ;
TSVS :
position 2750, 2300 ;
dimension 600, 6000 ;
ACELLERATORS :
position 0, 7300 ;
dimension 2750, 3300 ;

View File

@@ -1,16 +0,0 @@
channel0 :
position 150, 100 ;
dimension 2600, 5200 ;
channel1 :
position 3350, 100 ;
dimension 2600, 5200 ;
channel2 :
position 150, 5300 ;
dimension 2600, 5200 ;
channel3 :
position 3350, 5300 ;
dimension 2600, 5200 ;

View File

@@ -1,20 +0,0 @@
{
"powerInfo": {
"dram_die_channel0": {
"init_pow": 0,
"threshold": 1.0
},
"dram_die_channel1": {
"init_pow": 0,
"threshold": 1.0
},
"dram_die_channel2": {
"init_pow": 0,
"threshold": 1.0
},
"dram_die_channel3": {
"init_pow": 0,
"threshold": 1.0
}
}
}

View File

@@ -1,49 +0,0 @@
material SILICON :
thermal conductivity 1.30e-4 ;
volumetric heat capacity 1.628e-12 ;
material BEOL :
thermal conductivity 2.25e-6 ;
volumetric heat capacity 2.175e-12 ;
material COPPER :
thermal conductivity 4.01e-04 ;
volumetric heat capacity 3.37e-12 ;
top heat sink :
//sink height 1e03, area 100e06, material COPPER ;
//spreader height 0.5e03, area 70e06, material SILICON ;
heat transfer coefficient 1.3e-09 ;
temperature 318.15 ;
dimensions :
chip length 6100, width 10600 ;
cell length 100, width 100 ;
layer PCB :
height 10 ;
material BEOL ;
die DRAM :
layer 58.5 SILICON ;
source 2 SILICON ;
layer 1.5 BEOL ;
layer 58.5 SILICON ;
stack:
die DRAM_DIE DRAM floorplan "./mem.flp" ;
layer CONN_TO_PCB PCB ;
solver:
transient step 0.01, slot 0.05 ;
initial temperature 300.0 ;
output:
Tflpel(DRAM_DIE.channel0 , "temp_flp_element_ch0.txt" , average , slot );
Tflpel(DRAM_DIE.channel1 , "temp_flp_element_ch1.txt" , average , slot );
Tflpel(DRAM_DIE.channel2 , "temp_flp_element_ch2.txt" , average , slot );
Tflpel(DRAM_DIE.channel3 , "temp_flp_element_ch3.txt" , average , slot );
Tmap (DRAM_DIE, "output1.txt", slot) ;
Pmap (DRAM_DIE, "output2.txt", slot) ;

View File

@@ -1,24 +0,0 @@
75 64 0 0 0 0
80 64 0 0 0 0
85 64 0 0 0 0
89 64 0 0 0 0
75 127 0 0 0 0
80 127 0 0 0 0
85 127 0 0 0 0
89 127 2 0.03 2 0.06
75 145 0 0 0 0
80 145 0 0 0 0
85 145 0 0 1 0.03
89 145 13 0.195 3 0.09
75 164 0 0 0 0
80 164 0 0 0 0
85 164 8 0.12 2 0.06
89 164 24 0.36 4 0.12
75 182 0 0 0 0
80 182 0 0 1 0.03
85 182 16 0.24 2 0.06
89 182 41 0.615 8 0.24
75 200 0 0 0 0
80 200 5 0.075 3 0.09
85 200 24 0.36 4 0.12
89 200 67 1.005 15 0.45
1 75 64 0 0 0 0
2 80 64 0 0 0 0
3 85 64 0 0 0 0
4 89 64 0 0 0 0
5 75 127 0 0 0 0
6 80 127 0 0 0 0
7 85 127 0 0 0 0
8 89 127 2 0.03 2 0.06
9 75 145 0 0 0 0
10 80 145 0 0 0 0
11 85 145 0 0 1 0.03
12 89 145 13 0.195 3 0.09
13 75 164 0 0 0 0
14 80 164 0 0 0 0
15 85 164 8 0.12 2 0.06
16 89 164 24 0.36 4 0.12
17 75 182 0 0 0 0
18 80 182 0 0 1 0.03
19 85 182 16 0.24 2 0.06
20 89 182 41 0.615 8 0.24
21 75 200 0 0 0 0
22 80 200 5 0.075 3 0.09
23 85 200 24 0.36 4 0.12
24 89 200 67 1.005 15 0.45

View File

@@ -1,64 +0,0 @@
#!/usr/bin/perl
use warnings;
use strict;
my $filename = shift || die;
open(FH, "$filename");
while(<FH>)
{
# Get all the data adress:
$_ =~ /(\d+):\s+(\w+)\s+0x([\w\d]+)/;
my $time = $1;
my $command = $2;
my $address = $3;
my $new_address;
# Convert to binary:
$address = sprintf( "%032b", hex( $address ) );
# example:
# 31 0
# 00000000000000000000000000000001
# 00000000000000000000010000000000
# Swap adresses:
$new_address = substr($address,31 - 31,1). # R 31
substr($address,31 - 30,1). # R 30
substr($address,31 - 29,1). # R 29
substr($address,31 - 28,1). # R 28
substr($address,31 - 27,1). # R 27
substr($address,31 - 26,1). # R 26
substr($address,31 - 25,1). # R 25
substr($address,31 - 24,1). # R 24
substr($address,31 - 23,1). # R 23
substr($address,31 - 22,1). # R 22
substr($address,31 - 21,1). # R 21
substr($address,31 - 20,1). # R 20
substr($address,31 - 19,1). # R 19
substr($address,31 - 18,1). # R 18
substr($address,31 - 17,1). # R 17
substr($address,31 - 16,1). # R 16
substr($address,31 - 8,1). # R 15
substr($address,31 - 7,1). # R 14
substr($address,31 - 6,1). # R 13
substr($address,31 - 11,1). # B 12
substr($address,31 - 9,1). # B 11
substr($address,31 - 0,1). # B 10
substr($address,31 - 15,1). # C 9
substr($address,31 - 14,1). # C 8
substr($address,31 - 13,1). # C 7
substr($address,31 - 12,1). # C 6
substr($address,31 - 10,1). # C 5
substr($address,31 - 5,1). # C 4
substr($address,31 - 4,1). # C 3
substr($address,31 - 3,1). # C 2
substr($address,31 - 2,1). # C 1
substr($address,31 - 1,1); # C 0
$new_address = sprintf("%X", oct( "0b$new_address" ) );
print $time.":\t".$command."\t0x".$new_address."\n";
}

View File

@@ -1,378 +0,0 @@
#!/usr/bin/perl
use List::Util 'max';
use warnings;
use strict;
my $filename = shift || die("Please provide a input STL file");
my $numberOfRows = 16384;
my $numberOfBanks = 8;
my $numberOfColumns = 1024;
my $numberOfBytes = 8; # Byte Offset from e.g. DIMM
my $numberOfBits = 32;
my $burstLength = 8;
my $addressCorrection = 1;
my $numberOfRowBits = log($numberOfRows)/log(2);
my $numberOfBankBits = log($numberOfBanks)/log(2);
my $numberOfColumnBits = log($numberOfColumns)/log(2);
my $numberOfByteBits = log($numberOfBytes)/log(2);
my $numberOfBurstBits = log($burstLength)/log(2);
print "Number of Address Bits:\t".$numberOfBits."\n\n";
print "Number of Row Bits:\t".$numberOfRowBits."\n";
print "Number of Bank Bits:\t".$numberOfBankBits."\n";
print "Number of Col Bits:\t".$numberOfColumnBits."\n";
print ">Burst Bits in Col:\t".$numberOfBurstBits."\n";
print "Number of Byte Bits:\t".$numberOfByteBits."\n";
my $numberOfXBits = $numberOfBits - $numberOfRowBits - $numberOfBankBits - $numberOfColumnBits - $numberOfByteBits;
print "Number of Unused Bits:\t".$numberOfXBits."\n";
print "\n";
print "\n";
open(FH, "$filename");
my @activityCounter;
my @mapping;
# Initialize:
for(my $i = 0; $i < $numberOfBits; $i++)
{
$activityCounter[$i] = 0;
}
for(my $i = $numberOfXBits-1; $i >= 0; $i--)
{
$mapping[$numberOfBits-($numberOfXBits-$i)] = "X".$i;
}
my $old_address = "00000000000000000000000000000000";
while(<FH>)
{
# Get the adress:
$_ =~ /\d+:\s+\w+\s+0x([\w\d]+)\s*[\d\w]*/;
my $address = $1;
$address = sprintf( "%0".$numberOfBits."b", hex( $address ) * $addressCorrection );
# $i = 0 :: most significant bit
for(my $i = 0; $i < $numberOfBits; $i++)
{
my $new = substr($address, $i, 1);
my $old = substr($old_address, $i, 1);
if($new ne $old)
{
$activityCounter[$numberOfBits-1-$i]++;
}
}
$old_address = $address;
}
close(FH);
# Make Consistency Check:
for(my $i = 0; $i < ($numberOfByteBits+$numberOfBankBits); $i++)
{
if($activityCounter[$i] != 0)
{
print "Bits of lower C part or Y have toggled, this should not happen\n";
exit -1;
}
}
# Print bit numbers:
print "Bits\t\t";
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
print $i."\t";
}
#Print Activity
print "\nActivity\t";
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
print $activityCounter[$i]."\t";
}
#Print relative Activity
print "\nPercent\t\t";
my $sum = 0;
my @percent;
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
$sum = $sum + $activityCounter[$i];
}
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
my $string = $activityCounter[$i]/$sum*100;
$string = sprintf("%.2f", $string);
$string =~ s/\./,/g;
$percent[$i] = $string."%";
$string .= "%\t";
print $string;
}
#Fix Byte Offset:
for(my $i = 0; $i < $numberOfByteBits; $i++)
{
$activityCounter[$i] = -1;
$mapping[$i] = "Y$i";
}
#Fix Constant 0 Bits in Column due to Burstlength:
for(my $i=0; $i < $numberOfBurstBits; $i++)
{
$activityCounter[$numberOfByteBits + $i] = -1;
$mapping[$numberOfByteBits + $i] = "C$i";
}
#Search Column Locations
for(my $i = $numberOfBurstBits; $i < $numberOfColumnBits; $i++)
{
my $maximum = max(@activityCounter);
my ($index) = grep $activityCounter[$_] == $maximum , 0.. $#activityCounter;
$mapping[$index] = "C$i";
$activityCounter[$index] = -1;
}
#Search Bank Locations
for(my $i = 0; $i < $numberOfBankBits; $i++)
{
my $maximum = max(@activityCounter);
my ($index) = grep $activityCounter[$_] == $maximum , 0.. $#activityCounter;
$mapping[$index] = "B$i";
$activityCounter[$index] = -1;
}
#Search Row Locations
for(my $i = 0; $i < $numberOfRowBits; $i++)
{
my $maximum = max(@activityCounter);
my ($index) = grep $activityCounter[$_] == $maximum , 0.. $#activityCounter;
$mapping[$index] = "R$i";
$activityCounter[$index] = -1;
}
#Print final mapping
my $header = '
strict graph G
{
forcelabels=true;
rankdir=LR;
{
graph [fontname = "courier"];
node [shape=square, fontname="courier", fixedsize=true, width=0.85, height=0.85]
edge [fontname = "courier"];
';
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
$header .= " $i [pos=\"".($numberOfBits-1-$i).",0!\", xlp=\"-5,0\", label=\"$i\n".$percent[$i]."\" ]\n";
}
my $pos = 0;
for(my $i = $numberOfXBits-1; $i >= 0; $i--)
{
my $pos2 = $numberOfBits-$pos-1;
$header .= " X$i [ label=\"$pos2\nX$i\" pos=\"$pos,-5!\"]\n";
$pos++;
}
for(my $i = $numberOfBankBits-1; $i >= 0; $i--)
{
my $pos2 = $numberOfBits-$pos-1;
$header .= " B$i [ label=\"$pos2\nB$i\" pos=\"$pos,-5!\"]\n";
$pos++;
}
for(my $i = $numberOfRowBits-1; $i >= 0; $i--)
{
my $pos2 = $numberOfBits-$pos-1;
$header .= " R$i [ label=\"$pos2\nR$i\" pos=\"$pos,-5!\"]\n";
$pos++;
}
for(my $i = $numberOfColumnBits-1; $i >= 0; $i--)
{
my $pos2 = $numberOfBits-$pos-1;
$header .= " C$i [ label=\"$pos2\nC$i\" pos=\"$pos,-5!\"]\n";
$pos++;
}
for(my $i = $numberOfByteBits-1; $i >= 0; $i--)
{
my $pos2 = $numberOfBits-$pos-1;
$header .= " Y$i [ label=\"$pos2\nY$i\" pos=\"$pos,-5!\"]\n";
$pos++;
}
$header .= " }\n";
print "\nMapping\t\t";
my $maximum = max(@activityCounter);
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
if($mapping[$i] =~ /X\d/)
{
$header .= "$i -- ".$mapping[$i]." [ color=\"grey\"];\n";
}
elsif($mapping[$i] =~ /B\d/)
{
$header .= "$i -- ".$mapping[$i]." [ color=\"green\"];\n";
}
elsif($mapping[$i] =~ /R\d/)
{
$header .= "$i -- ".$mapping[$i]." [ color=\"blue\"];\n";
}
elsif($mapping[$i] =~ /C\d/)
{
$header .= "$i -- ".$mapping[$i]." [ color=\"red\"];\n";
}
elsif($mapping[$i] =~ /Y\d/)
{
$header .= "$i -- ".$mapping[$i]." [ color=\"grey\"];\n";
}
print $mapping[$i]."\t";
}
$header .= "}";
print "\n";
#Generate Scrambled Trace:
#Generate Configuration for 32x32 MUX:
# Assumption e.g. 32 bit:
# B R C
# X X B B B R R R R R R R R R R R R R R C C C C C C C C C C Y Y Y
# 31 30 29 27 26 13 12 3 2 0
# A B C D E F
#
#print "A:".($numberOfBits-1)."\n";
#print "B:".($numberOfBits-$numberOfXBits-1)."\n";
#print "C:".($numberOfBits-$numberOfXBits-$numberOfBankBits-1)."\n";
#print "D:".($numberOfBits-$numberOfXBits-$numberOfBankBits-$numberOfRowBits-1)."\n";
#print "E:".($numberOfBits-$numberOfXBits-$numberOfBankBits-$numberOfRowBits-$numberOfColumnBits-1)."\n";
#print "F:".($numberOfBits-$numberOfXBits-$numberOfBankBits-$numberOfRowBits-$numberOfColumnBits-$numberOfByteBits)."\n";
my @confVectorDecimal;
my @checkVector;
my $XCounter = 0;
my $rowCounter = 0;
my $bankCounter = 0;
my $columnCounter = 0;
my $byteCounter = 0;
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
if($mapping[$i] =~ /X(\d+)/)
{
my $idx = $numberOfBits-$numberOfXBits+$1;
#print "\$1=".$1." i=".$i." idx=".$idx." mapping=".$mapping[$i]."\n";
$confVectorDecimal[$idx] = $i;
$checkVector[$idx] = "X";
}
elsif($mapping[$i] =~ /B(\d+)/)
{
my $idx = $numberOfBits-$numberOfXBits-$numberOfBankBits+$1;
#print "\$1=".$1." i=".$i." idx=".$idx." mapping=".$mapping[$i]."\n";
$confVectorDecimal[$idx] = $i;
$checkVector[$idx] = "B";
}
elsif($mapping[$i] =~ /R(\d+)/)
{
my $idx = $numberOfBits-$numberOfXBits-$numberOfBankBits-$numberOfRowBits+$1;
#print "\$1=".$1." i=".$i." idx=".$idx." mapping=".$mapping[$i]."\n";
$confVectorDecimal[$idx] = $i;
$checkVector[$idx] = "R";
}
elsif($mapping[$i] =~ /C(\d+)/)
{
my $idx = $numberOfBits-$numberOfXBits-$numberOfBankBits-$numberOfRowBits-$numberOfColumnBits+$1;
#print "\$1=".$1." i=".$i." idx=".$idx." mapping=".$mapping[$i]."\n";
$confVectorDecimal[$idx] = $i;
$checkVector[$idx] = "C";
}
elsif($mapping[$i] =~ /Y(\d+)/)
{
my $idx = $numberOfBits-$numberOfXBits-$numberOfBankBits-$numberOfRowBits-$numberOfColumnBits-$numberOfByteBits+$1;
#print "\$1=".$1." i=".$i." idx=".$idx." mapping=".$mapping[$i]."\n";
$confVectorDecimal[$idx] = $i;
$checkVector[$idx] = "Y";
}
}
print "\n";
print "\n";
print "Configuration Vector for the mapping ";
for(my $m = $numberOfBits-1; $m >= 0; $m--)
{
print $checkVector[$m];
}
print ":\n\n";
for(my $m = $numberOfBits-1; $m >= 0; $m--)
{
#Debug:
print "mux: $m\t-->\t".$confVectorDecimal[$m]."\n";
}
print "\n";
print "\n";
for(my $m = $numberOfBits-1; $m >= 0; $m--)
{
print sprintf( "%05b", $confVectorDecimal[$m] );
}
print "\n";
print "\n";
# Generate Graph
my $dotname;
my $pdfname;
my $stlname;
if($filename =~ /(.+)\.stl/)
{
$dotname = $1.".dot";
$pdfname = $1.".pdf";
$stlname = $1."_scram.stl";
open(FH,">$dotname");
print FH $header;
close(FH);
system("neato -o $pdfname -Tpdf $dotname");
}
open(FH, "$filename");
open(SH, ">$stlname");
while(<FH>)
{
# Get all the data adress:
$_ =~ /(\d+):\s+(\w+)\s+0x([\w\d]+)/; # XXX
my $time = $1;
my $command = $2;
my $address = $3;
my $new_address;
# Convert to binary:
$address = sprintf( "%032b", hex( $address ) );
# Swap adresses:
$new_address = "";
for(my $m = $numberOfBits-1; $m >= 0; $m--)
{
#print $confVectorDecimal[$m]."\n";
$new_address .= substr($address,$numberOfBits-1-$confVectorDecimal[$m],1);
}
# Convert to Hex:
$new_address = sprintf("%X", oct( "0b$new_address" ) );
print SH $time.":\t".$command."\t0x".$new_address."\n";
}
close(FH);
close(SH);

View File

@@ -1,23 +0,0 @@
#!/usr/bin/python
# This script generates an example trace for DDR3
#
#<addressmapping>
# <channel from="128" to="128" /> <!-- only one channel -->
# <bank from="27" to="29" />
# <row from="13" to="26" /> 26 downto 13 --> 2^14 = 16384
# <column from="3" to="12" /> Burstlength = 8 --> 8 down bits always zero --> 12 downto 3 --> 7 --> 2^7 = 128
# <bytes from="0" to="2" /> 2^3 = 8
#</addressmapping>
numberOfRows = 16384
numberOfColumns = 128
byteOffset = 64
bankOffset = numberOfRows * numberOfColumns
# Write to Bank 0
for x in range(0, bankOffset):
print "{0:d}:\tread\t0x{1:X}".format(x,(x*byteOffset))
# Write to Bank 1
for x in range(bankOffset, 2*bankOffset):
print "{0:d}:\tread\t0x{1:X}".format(x,(x*byteOffset))

View File

@@ -1,34 +0,0 @@
#!/usr/bin/perl -w
use warnings;
use strict;
open(LINEAR, "> ../traces/linear.stl");
open(RANDOM, "> ../traces/random.stl");
my $length = shift || die ("please give length of traces");
my $size = 0x40;
for(my $i=0; $i < $length; $i++)
{
my $r = int(rand($length));
#print $r." ".($size*$r)."\n";
print LINEAR "$i: read ".sprintf("0x%x",($size*$i))."\n";
print RANDOM "$i: read ".sprintf("0x%x",($size*$r))."\n";
#my $rw = int(rand(2))%2;
#if($rw == 0)
#{
# print LINEAR "$i: read ".sprintf("0x%x",($size*$i))."\n";
# print RANDOM "$i: read ".sprintf("0x%x",($size*$r))."\n";
#}
#else
#{
# print LINEAR "$i: write ".sprintf("0x%x",($size*$i))."\n";
# print RANDOM "$i: write ".sprintf("0x%x",($size*$r))."\n";
#}
}
close(LINEAR);
close(RANDOM);

View File

@@ -1,34 +0,0 @@
#!/usr/bin/perl
use List::Util 'max';
use warnings;
use strict;
my $filename = shift || die("Please provide a input STL file");
my $command = shift || die ("Pleas provide read/write");
open(FH, "$filename");
my $old_address = 0;
my %histogram;
my $command_occurance = 0;
while(<FH>)
{
# Get the adress:
$_ =~ /\d+:\s+(\w+)\s+0x([\w\d]+)\s*[\d\w]*/;
if($command eq $1)
{
my $address = hex($2);
my $distance = $address - $old_address;
$histogram{$distance} ++;
$old_address = $address;
$command_occurance++;
}
}
foreach my $key ( keys %histogram)
{
my $percent = $histogram{$key}/$command_occurance;
my $hexkey = sprintf( "%032b", abs($key) );
print "0x".$hexkey." ".abs($key)." = ".$histogram{$key}." (".$percent.")\n";
}

View File

@@ -1,31 +0,0 @@
#!/usr/bin/perl
use warnings;
use strict;
my $phaseLength = 100;
my $phaseStatus = 0;
my $max = 100000;
my $base = 0;
my $maxAddressExp = 26;
my $maxAddress = 2**$maxAddressExp;
for(my $i = 0; $i < $max; $i++)
{
if($phaseStatus == 0) # Linear
{
my $addr = (($base << 6) + (($i % $phaseLength) << 6)) % $maxAddress;
print "$i: read 0x".sprintf("%x", $addr)."\n";
}
else # Random
{
my $addr = (rand(2**($maxAddressExp-6))) << 6;
print "$i: read 0x".sprintf("%x", $addr)."\n";
}
if($i % 100 == 0 && $i != 0)
{
$phaseStatus = ($phaseStatus == 0) ? 1 : 0;
$base = rand(2**($maxAddressExp-6));
}
}

View File

@@ -1,137 +0,0 @@
#! /usr/bin/env python3
# vim: set fileencoding=utf-8
# Copyright (c) 2018, Technische Universität Kaiserslautern
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Author: Éder F. Zulian
import ctypes
# A trace file is a pre-recorded file containing memory transactions. Each
# memory transaction has a timestamp that tells the simulator when it shall
# happen, a transaction type (read or write) and a memory address given in
# hexadecimal.
#
# Here is an example syntax:
#
# ```
# # Comment lines begin with #
# # [clock-cyle]: [write|read] [hex-address]
# 31: read 0x400140
# 33: read 0x400160
# 56: write 0x7fff8000
# 81: read 0x400180
# ```
#
# The timestamp corresponds to the time the request is to be issued and it is
# given in cycles of the bus master device. Example: the device is a FPGA with
# frequency 200 MHz (clock period of 5 ns). If the timestamp is 10 it means
# that the request is to be issued when time is 50 ns.
#
# The default values given as example assume the following address mapping:
#
# DIMM Characteristics:
# Byte Offset (Y): 8 [0:2] (8-byte-wide memory module, i.e., 64-bit-wide data bus) -> 3 bit
# Cols (C): 1K [3:12] (A0 - A9) -> 10 bit
# Rows (R): 128K [13:29] (A0 - A16) -> 17 bit
# Bank (B): 8 [30:32] (BA0 - BA2) -> 3 bit
#
# 3 3 3 | 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 | 1 1 1
# 2 1 0 | 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 | 2 1 0 9 8 7 6 5 4 3 | 2 1 0
# B B B | R R R R R R R R R R R R R R R R R | C C C C C C C C C C | Y Y Y
#
# Transaction type (read or write)
transaction = 'read'
# Channel information. If your address mapping does not have channel bits keep
# it equal to 1 and set the shift to the extreme left of the address.
num_ch = 1 # Number of channels
ch_shift = 34 # Shift to reach the frist bit reserved for channels in the address
ch_mask = 0x1 # Mask for all channel bits in the address
# Bank group information. If your address mapping does not have bank groups
# keep it equal to 1 and set the shift to the extreme left of the address.
num_bank_groups = 1 # Number of bank groups
bgroup_shift = 33 # Shift to reach the frist bit reserved for bank groups in the address
bgroup_mask = 0x1 # Mask for all bits in the address related to bank groups
# Bank information
num_banks = 8 # Number of banks
bank_shift = 30 # Shift to reach the frist bit reserved for banks in the address
bank_mask = 0x7 # Mask for all bank bits in the address
# Row information
num_rows = 128 * 1024 # Number of rows
row_shift = 13 # Shift to reach the frist bit reserved for rows in the address
row_mask = 0x1ffff # Mask for all row bits in the address
# Column information
num_col = 1 * 1024 # Number of columns
col_shift = 3 # Shift to reach the frist bit reserved for columns in the address
col_mask = 0x3ff # Mask for all column bits in the address
# Burst length of 8 columns. 8 columns written/read per access (in 4 full
# clock cycles of the memory bus).
burst_len = 8
# Initial clock cycle
clock_cycle = 0
# Clock cycle increment between two accesses
clock_increment = 10
def clear_bits(mask, shift, val):
m = ctypes.c_uint64(~(mask << shift)).value
return ctypes.c_uint64(val & m).value
def set_bits(mask, shift, val, v):
val = clear_bits(mask, shift, val)
return ctypes.c_uint64(val | (v << shift)).value
address = 0
for ch in range(0, num_ch):
address = set_bits(ch_mask, ch_shift, address, ch)
for bg in range(0, num_bank_groups):
address = set_bits(bgroup_mask, bgroup_shift, address, bg)
for b in range(0, num_banks):
address = set_bits(bank_mask, bank_shift, address, b)
for row in range(0, num_rows):
address = set_bits(row_mask, row_shift, address, row)
for col in range(0, num_col, burst_len):
address = set_bits(col_mask, col_shift, address, col)
print('# clock cycle: {0:d} | {1} | address: 0x{2:010X} | channel: {3} | bank group: {4} | bank: {5} | row: {6} | column: {7}'.format(clock_cycle, transaction, address, ch, bg, b, row, col))
print('{0:d}:\t{1}\t0x{2:010X}'.format(clock_cycle, transaction, address))
clock_cycle = clock_cycle + clock_increment

View File

@@ -1,9 +0,0 @@
all:
modulecmd bash load gnuplot/latest
modulecmd bash load image-magick/latest
./temperatur.pl
movie:
ffmpeg -start_number 00000000 -i ../out/%08d.jpg -vcodec mpeg4 ../out.avi
clean:
rm *.out *.err

View File

@@ -1,135 +0,0 @@
#!/usr/bin/perl -w
use warnings;
use strict;
use File::Copy;
my $file = shift;
my $id = shift;
my $samples = shift;
my $inputPath = "/gu2/jungma/thermal/in/out-backup";
my $extractPath = "/gu2/jungma/thermal/tmp/$id";
print "Create TMP path... ";
system("mkdir $extractPath");
print " done\n";
print "Extract... ";
system("tar -xf $inputPath/$file -C $extractPath");
print " done\n";
print "Preprocessing... ";
system("sed '1d' $extractPath/out/output_core_die_full.txt > $extractPath/die0.txt");
system("sed '1d' $extractPath/out/output_mem_die_1_full.txt > $extractPath/die1.txt");
system("sed '1d' $extractPath/out/output_mem_die_2_full.txt > $extractPath/die2.txt");
system("sed '1d' $extractPath/out/output_mem_die_3_full.txt > $extractPath/die3.txt");
system("sed '1d' $extractPath/out/output_mem_die_4_full.txt > $extractPath/die4.txt");
print " done\n";
print "Gnuplot...";
open( my $GP, '|-', 'gnuplot' );
print $GP "
reset
set terminal pngcairo size 500,500 enhanced font 'Verdana,10'
set border linewidth 0
unset key
unset colorbox
unset tics
set lmargin screen 0.0
set rmargin screen 1.0
set tmargin screen 1.0
set bmargin screen 0.0
set pm3d map
set pm3d interpolate 2,2
set cbrange [318.0:388.0]
#set palette rgbformulae 22,13,-31
set palette defined ( 0 \"blue\", 3 \"green\", 4 \"yellow\", 5 \"red\", 6 \"black\" )
set output '$extractPath/die0.png'
splot '$extractPath/die0.txt' matrix every ::1
set output '$extractPath/die1.png'
splot '$extractPath/die1.txt' matrix every ::1
set output '$extractPath/die2.png'
splot '$extractPath/die2.txt' matrix every ::1
set output '$extractPath/die3.png'
splot '$extractPath/die3.txt' matrix every ::1
set output '$extractPath/die4.png'
splot '$extractPath/die4.txt' matrix every ::1";
close($GP);
print " done\n";
print "Wait for files... ";
while (1) { last if -e "$extractPath/die0.png"; print "."; sleep 1;}
while (1) { last if -e "$extractPath/die1.png"; print "."; sleep 1;}
while (1) { last if -e "$extractPath/die2.png"; print "."; sleep 1;}
while (1) { last if -e "$extractPath/die3.png"; print "."; sleep 1;}
while (1) { last if -e "$extractPath/die4.png"; print "."; sleep 1;}
print " done\n";
print "Composite ...";
system("composite -gravity center constants/thermal_model_core.png $extractPath/die0.png $extractPath/die0b.png");
system("composite -gravity center constants/thermal_model_dram_0_1.png $extractPath/die1.png $extractPath/die1b.png");
system("composite -gravity center constants/thermal_model_dram_2_3.png $extractPath/die2.png $extractPath/die2b.png");
system("composite -gravity center constants/thermal_model_dram_4_5.png $extractPath/die3.png $extractPath/die3b.png");
system("composite -gravity center constants/thermal_model_dram_6_7.png $extractPath/die4.png $extractPath/die4b.png");
print " done\n";
print "Wait for files... ";
while (1) { last if -e "$extractPath/die0b.png"; print "."; sleep 1;}
while (1) { last if -e "$extractPath/die1b.png"; print "."; sleep 1;}
while (1) { last if -e "$extractPath/die2b.png"; print "."; sleep 1;}
while (1) { last if -e "$extractPath/die3b.png"; print "."; sleep 1;}
while (1) { last if -e "$extractPath/die4b.png"; print "."; sleep 1;}
print " done\n";
print "Convert ...";
system("convert $extractPath/die0b.png -alpha set -background none -shear 0x-40 -rotate 60 +repage -crop 1048x485+0+205 $extractPath/die0c.png");
system("convert $extractPath/die1b.png -alpha set -background none -shear 0x-40 -rotate 60 +repage -crop 1048x485+0+205 $extractPath/die1c.png");
system("convert $extractPath/die2b.png -alpha set -background none -shear 0x-40 -rotate 60 +repage -crop 1048x485+0+205 $extractPath/die2c.png");
system("convert $extractPath/die3b.png -alpha set -background none -shear 0x-40 -rotate 60 +repage -crop 1048x485+0+205 $extractPath/die3c.png");
system("convert $extractPath/die4b.png -alpha set -background none -shear 0x-40 -rotate 60 +repage -crop 1048x485+0+205 $extractPath/die4c.png");
print " done\n";
print "Wait for files... ";
while (1) { last if -e "$extractPath/die0c.png"; print "."; sleep 1;}
while (1) { last if -e "$extractPath/die1c.png"; print "."; sleep 1;}
while (1) { last if -e "$extractPath/die2c.png"; print "."; sleep 1;}
while (1) { last if -e "$extractPath/die3c.png"; print "."; sleep 1;}
while (1) { last if -e "$extractPath/die4c.png"; print "."; sleep 1;}
print " done\n";
my $outFileName = sprintf("%08d", $id);
print "Produce Output ...";
system("convert -size 1048x1680 xc:black $extractPath/die0c.png -geometry +0+1200 -composite $extractPath/die1c.png -geometry +0+900 -composite $extractPath/die2c.png -geometry +0+600 -composite $extractPath/die3c.png -geometry +0+300 -composite $extractPath/die4c.png -composite $extractPath/a$outFileName.jpg");
while (1) { last if -e "$extractPath/a$outFileName.jpg"; print "."; sleep 1;}
system("convert $extractPath/a$outFileName.jpg -pointsize 80 -fill white -gravity northeast -draw \"text 20,20 '".$samples."ms'\" $extractPath/b$outFileName.jpg");
while (1) { last if -e "$extractPath/b$outFileName.jpg"; print "."; sleep 1;}
system("convert $extractPath/b$outFileName.jpg constants/legend/legend4.png +append ../out/$outFileName.jpg");
print " done\n";
print "Produce Samples ...";
for(my $i = 0; $i < $samples-1; $i++)
{
$id++;
my $outFileNameCopy = sprintf("%08d", $id);
copy("../out/$outFileName.jpg","../out/$outFileNameCopy.jpg");
}
print " done\n";
# cleanup
print "Cleanup ... ";
while (1) { last if -e "/gu2/jungma/thermal/out/$outFileName.jpg"; print "."; sleep 1;}
system("rm -rf $extractPath");
print " done\n";
##ffmpeg -start_number 00000000 -i %08d.jpg -vcodec mpeg4 test.avi

View File

@@ -1,67 +0,0 @@
#!/usr/bin/perl -w
use warnings;
use strict;
use List::Util qw( min max );
#/Volumes/Etana_tmp2/tmp_sadri/backup/sep_16/log_smartbench_traces_50_cpu_1650_mhz_100_mhz_dram_100_mhz_sampling8X_bankwise_on_test/out-backup
my $inputPath = "../in/out-backup";
my $extractPath = "../tmp";
my $samplingFile = "../in/sampling";
# Read the input file names and store it in an array
opendir (DIR, $inputPath) or die $!;
my @files;
my @sortetFiles;
while (my $file = readdir(DIR))
{
push(@files, $file);
}
@sortetFiles = sort @files;
print "Cleanup\n";
system("rm -rf *.err *.out");
system("rm -rf ../tmp/*");
print "Load modules\n";
# Estimate sampeling numbers
open(SF,$samplingFile);
my @refreshRates;
while(<SF>)
{
$_ =~ /(\d+)\.0/;
my $rate = $1;
push(@refreshRates, $rate);
}
print "Max. Rate:".max(@refreshRates)."\n";
print "Min. Rate:".min(@refreshRates)."\n";
my $counter = 0;
my $i = 0;
# For each data package start one job!
foreach(@sortetFiles)
{
my $file = $_;
if($file =~ /(\d+)-(\d+)-(\d+)-(\d+)-(\d+)-(\d+)-(\d+)\.tgz/)
{
my $samples = $refreshRates[$i];
system("bsub -W 00:05 ./temperatur.job.pl $file $counter $samples");
$counter+=$samples;
$i++;
#if($i == 100)
#{
# last;
#}
}
}
##ffmpeg -start_number 00000000 -i %08d.jpg -vcodec mpeg4 test.avi

View File

@@ -1,20 +0,0 @@
{
"simulation": {
"addressmapping": "am_ddr3_8x1Gbx8_dimm_p1KB_brc.json",
"mcconfig": "fr_fcfs.json",
"memspec": "MICRON_1Gb_DDR3-1600_8bit_G.json",
"simconfig": "ddr3.json",
"simulationid": "ddr3-example2",
"thermalconfig": "config.json",
"tracesetup": [
{
"clkMhz": 300,
"name": "ddr3_example.stl"
},
{
"clkMhz": 400,
"name": "ddr3_example.stl"
}
]
}
}

View File

@@ -1,16 +0,0 @@
{
"simulation": {
"addressmapping": "am_wideio_4x256Mb_rbc.json",
"mcconfig": "fr_fcfs.json",
"memspec": "JEDEC_256Mb_WIDEIO-200_128bit.json",
"simconfig": "wideio.json",
"simulationid": "wideio-example",
"thermalconfig": "config.json",
"tracesetup": [
{
"clkMhz": 1000,
"name": "chstone-adpcm_32.stl"
}
]
}
}

View File

@@ -1,141 +0,0 @@
#!/usr/bin/perl -w
# Copyright (c) 2015, 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:
# Matthias Jung
# Eder F. Zulian
# Lukas Steiner
use warnings;
use strict;
# Assuming this address mapping:
# {
# "CONGEN": {
# "BYTE_BIT": [
# 0,
# 1,
# 2,
# 3
# ],
# "BANK_BIT": [
# 4,
# 5
# ],
# "COLUMN_BIT": [
# 6,
# 7,
# 8,
# 9,
# 10,
# 11,
# 12
# ],
# "ROW_BIT": [
# 13,
# 14,
# 15,
# 16,
# 17,
# 18,
# 19,
# 20,
# 21,
# 22,
# 23,
# 24
# ],
# "CHANNEL_BIT": [
# 25,
# 26
# ]
# }
# }
# This is how it should look like later:
# 31: write 0x0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
my $numberOfChannels = 4;
my $numberOfRows = 4096;
my $numberOfColumns = 128;
my $bytesPerColumn = 16;
my $burstLength = 4; # burst length of 4 columns --> 4 columns written or read per access
my $dataLength = $bytesPerColumn * $burstLength;
my $channelOffset = 0x2000000;
my $rowOffset = 0x2000;
my $columnOffset = 0x40;
# Generate Data Pattern:
my $dataPatternByte = "ff";
my $dataPattern = "0x";
for(my $i = 0; $i < $dataLength; $i++)
{
$dataPattern .= $dataPatternByte;
}
my $clkCounter = 0;
my $addr = 0;
# Generate Trace file (writes):
for(my $cha = 0; $cha < ($numberOfChannels * $channelOffset); $cha = $cha + $channelOffset)
{
for(my $row = 0; $row < ($numberOfRows * $rowOffset); $row = $row + $rowOffset)
{
for(my $col = 0; $col < ($numberOfColumns * $columnOffset); $col = $col + ($columnOffset * $burstLength))
{
my $addrHex = sprintf("0x%x", $addr);
print "$clkCounter:\twrite\t$addrHex\t$dataPattern\n";
$clkCounter++;
$addr += $columnOffset * $burstLength;
}
}
}
$clkCounter = 50000000;
$addr = 0;
# Generate Trace file (reads):
for(my $cha = 0; $cha < ($numberOfChannels * $channelOffset); $cha = $cha + $channelOffset)
{
for(my $row = 0; $row < ($numberOfRows * $rowOffset); $row = $row + $rowOffset)
{
for(my $col = 0; $col < ($numberOfColumns * $columnOffset); $col = $col + ($columnOffset * $burstLength))
{
my $addrHex = sprintf("0x%x", $addr);
print "$clkCounter:\tread\t$addrHex\n";
$clkCounter++;
$addr += $columnOffset * $burstLength;
}
}
}

View File

@@ -1,122 +0,0 @@
/*
* Copyright (c) 2021, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Derek Christ
*/
#include "ThermalConfig.h"
#include "util.h"
namespace DRAMSysConfiguration
{
void to_json(json &j, const ThermalConfig &c)
{
j = json{{"TemperatureScale", c.temperatureScale},
{"StaticTemperatureDefaultValue", c.staticTemperatureDefaultValue},
{"ThermalSimPeriod", c.thermalSimPeriod},
{"ThermalSimUnit", c.thermalSimUnit},
{"PowerInfoFile", c.powerInfo},
{"IceServerIp", c.iceServerIp},
{"IceServerPort", c.iceServerPort},
{"SimPeriodAdjustFactor", c.simPeriodAdjustFactor},
{"NPowStableCyclesToIncreasePeriod", c.nPowStableCyclesToIncreasePeriod},
{"GenerateTemperatureMap", c.generateTemperatureMap},
{"GeneratePowerMap", c.generatePowerMap}};
}
void from_json(const json &j, ThermalConfig &c)
{
json j_thermalsim = get_config_json(j, thermalConfigPath, "thermalsimconfig");
j_thermalsim.at("TemperatureScale").get_to(c.temperatureScale);
j_thermalsim.at("StaticTemperatureDefaultValue").get_to(c.staticTemperatureDefaultValue);
j_thermalsim.at("ThermalSimPeriod").get_to(c.thermalSimPeriod);
j_thermalsim.at("ThermalSimUnit").get_to(c.thermalSimUnit);
j_thermalsim.at("PowerInfoFile").get_to(c.powerInfo);
j_thermalsim.at("IceServerIp").get_to(c.iceServerIp);
j_thermalsim.at("IceServerPort").get_to(c.iceServerPort);
j_thermalsim.at("SimPeriodAdjustFactor").get_to(c.simPeriodAdjustFactor);
j_thermalsim.at("NPowStableCyclesToIncreasePeriod").get_to(c.nPowStableCyclesToIncreasePeriod);
j_thermalsim.at("GenerateTemperatureMap").get_to(c.generateTemperatureMap);
j_thermalsim.at("GeneratePowerMap").get_to(c.generatePowerMap);
}
void to_json(json &j, const DramDieChannel &c)
{
j = json{{"init_pow", c.init_pow}, {"threshold", c.threshold}};
}
void from_json(const json &j, DramDieChannel &c)
{
j.at("init_pow").get_to(c.init_pow);
j.at("threshold").get_to(c.threshold);
}
void to_json(json &j, const PowerInfo &c)
{
j = json{};
for (const auto &channel : c.channels)
{
j.emplace(channel.identifier, channel);
}
}
void from_json(const json &j, PowerInfo &c)
{
json j_powerinfo = get_config_json(j, thermalConfigPath, "powerInfo");
for (const auto &entry : j_powerinfo.items())
{
DramDieChannel channel;
j_powerinfo.at(entry.key()).get_to(channel);
channel.identifier = entry.key();
c.channels.push_back(channel);
}
}
void from_dump(const std::string &dump, ThermalConfig &c)
{
json json_thermalconfig = json::parse(dump).at("thermalconfig");
json_thermalconfig.get_to(c);
}
std::string dump(const ThermalConfig &c, unsigned int indentation)
{
json json_thermalconfig;
json_thermalconfig["thermalconfig"] = c;
return json_thermalconfig.dump(indentation);
}
} // namespace DRAMSysConfiguration

View File

@@ -1,120 +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_THERMALCONFIG_H
#define DRAMSYSCONFIGURATION_THERMALCONFIG_H
#include <nlohmann/json.hpp>
namespace DRAMSysConfiguration
{
using json = nlohmann::json;
const std::string thermalConfigPath = "configs/thermalsim";
enum class TemperatureScale
{
Celsius,
Fahrenheit,
Kelvin,
Invalid = -1,
};
NLOHMANN_JSON_SERIALIZE_ENUM(TemperatureScale, {{TemperatureScale::Invalid, nullptr},
{TemperatureScale::Celsius, "Celsius"},
{TemperatureScale::Fahrenheit, "Fahrenheit"},
{TemperatureScale::Kelvin, "Kelvin"}})
enum class ThermalSimUnit
{
Seconds,
Milliseconds,
Microseconds,
Nanoseconds,
Picoseconds,
Femtoseconds,
Invalid = -1,
};
NLOHMANN_JSON_SERIALIZE_ENUM(ThermalSimUnit, {{ThermalSimUnit::Invalid, nullptr},
{ThermalSimUnit::Seconds, "s"},
{ThermalSimUnit::Milliseconds, "ms"},
{ThermalSimUnit::Microseconds, "us"},
{ThermalSimUnit::Nanoseconds, "ns"},
{ThermalSimUnit::Picoseconds, "ps"},
{ThermalSimUnit::Femtoseconds, "fs"}})
struct DramDieChannel
{
std::string identifier;
double init_pow;
double threshold;
};
void to_json(json &j, const DramDieChannel &c);
void from_json(const json &j, DramDieChannel &c);
struct PowerInfo
{
std::vector<DramDieChannel> channels;
};
void to_json(json &j, const PowerInfo &c);
void from_json(const json &j, PowerInfo &c);
struct ThermalConfig
{
TemperatureScale temperatureScale;
int staticTemperatureDefaultValue;
double thermalSimPeriod;
ThermalSimUnit thermalSimUnit;
PowerInfo powerInfo;
std::string iceServerIp;
unsigned int iceServerPort;
unsigned int simPeriodAdjustFactor;
unsigned int nPowStableCyclesToIncreasePeriod;
bool generateTemperatureMap;
bool generatePowerMap;
};
void to_json(json &j, const ThermalConfig &c);
void from_json(const json &j, ThermalConfig &c);
void from_dump(const std::string &dump, ThermalConfig &c);
std::string dump(const ThermalConfig &c, unsigned int indentation = -1);
} // namespace Configuration
#endif // DRAMSYSCONFIGURATION_THERMALCONFIG_H

View File

@@ -1,5 +0,0 @@
add_executable(simpletest simpletest.cpp)
target_link_libraries(simpletest PRIVATE DRAMSysConfiguration nlohmann_json::nlohmann_json)
add_executable(converter converter.cpp)
target_link_libraries(converter PRIVATE DRAMSysConfiguration nlohmann_json::nlohmann_json)

View File

@@ -1,226 +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 <DRAMSysConfiguration.h>
#include <fstream>
#include <iostream>
using json = nlohmann::json;
DRAMSysConfiguration::AddressMapping getAddressMapping()
{
return DRAMSysConfiguration::AddressMapping{{{0, 1}},
{{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}},
{{16}},
{{13, 14, 15}},
{{17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}},
{{33}},
{{}},
{{}}};
}
DRAMSysConfiguration::McConfig getMcConfig()
{
return DRAMSysConfiguration::McConfig{DRAMSysConfiguration::PagePolicy::Open,
DRAMSysConfiguration::Scheduler::FrFcfs,
DRAMSysConfiguration::SchedulerBuffer::Bankwise,
8,
DRAMSysConfiguration::CmdMux::Oldest,
DRAMSysConfiguration::RespQueue::Fifo,
DRAMSysConfiguration::RefreshPolicy::AllBank,
0,
0,
DRAMSysConfiguration::PowerDownPolicy::NoPowerDown,
DRAMSysConfiguration::Arbiter::Simple,
128,
{}};
}
DRAMSysConfiguration::SimConfig getSimConfig()
{
return DRAMSysConfiguration::SimConfig{
0, false, true, false, false, {"error.csv"},
42, false, {"ddr5"}, true, DRAMSysConfiguration::StoreMode::NoStorage, false, false,
1000};
}
DRAMSysConfiguration::ThermalConfig getThermalConfig()
{
std::vector<DRAMSysConfiguration::DramDieChannel> channels {{"dram_die_channel0", 0.0, 1.0}, {"dram_die_channel1", 0.0, 1.0}, {"dram_die_channel2", 0.0, 1.0}, {"dram_die_channel3", 0.0, 1.0}};
return DRAMSysConfiguration::ThermalConfig{
DRAMSysConfiguration::TemperatureScale::Celsius,
89,
100,
DRAMSysConfiguration::ThermalSimUnit::Microseconds,
DRAMSysConfiguration::PowerInfo{channels},
"127.0.0.1",
118800,
10,
5,
true,
true};
}
DRAMSysConfiguration::TracePlayer getTracePlayer()
{
DRAMSysConfiguration::TracePlayer player;
player.clkMhz = 100;
player.name = "mytrace.stl";
return player;
}
DRAMSysConfiguration::TraceGenerator getTraceGeneratorOneState()
{
DRAMSysConfiguration::TraceGenerator gen;
gen.clkMhz = 100;
gen.name = "MyTestGen";
DRAMSysConfiguration::TraceGeneratorTrafficState state0;
state0.numRequests = 1000;
state0.rwRatio = 0.5;
state0.addressDistribution = DRAMSysConfiguration::AddressDistribution::Random;
state0.addressIncrement = {};
state0.minAddress = {};
state0.maxAddress = {};
state0.clksPerRequest = {};
gen.states.emplace(0, state0);
return gen;
}
DRAMSysConfiguration::TraceGenerator getTraceGeneratorMultipleStates()
{
DRAMSysConfiguration::TraceGenerator gen;
gen.clkMhz = 100;
gen.name = "MyTestGen";
gen.maxPendingReadRequests = 8;
DRAMSysConfiguration::TraceGeneratorTrafficState state0;
state0.numRequests = 1000;
state0.rwRatio = 0.5;
state0.addressDistribution = DRAMSysConfiguration::AddressDistribution::Sequential;
state0.addressIncrement = 256;
state0.minAddress = {};
state0.maxAddress = 1024;
state0.clksPerRequest = {};
DRAMSysConfiguration::TraceGeneratorTrafficState state1;
state1.numRequests = 100;
state1.rwRatio = 0.75;
state1.addressDistribution = DRAMSysConfiguration::AddressDistribution::Sequential;
state1.addressIncrement = 512;
state1.minAddress = 1024;
state1.maxAddress = 2048;
state1.clksPerRequest = {};
gen.states.emplace(0, state0);
gen.states.emplace(1, state1);
DRAMSysConfiguration::TraceGeneratorStateTransition transistion0{1, 1.0};
gen.transitions.emplace(0, transistion0);
return gen;
}
DRAMSysConfiguration::TraceHammer getTraceHammer()
{
DRAMSysConfiguration::TraceHammer hammer;
hammer.clkMhz = 100;
hammer.name = "MyTestHammer";
hammer.numRequests = 4000;
hammer.rowIncrement = 2097152;
return hammer;
}
DRAMSysConfiguration::TraceSetup getTraceSetup()
{
using namespace DRAMSysConfiguration;
std::vector<std::variant<TracePlayer, TraceGenerator, TraceHammer>> initiators;
initiators.emplace_back(getTracePlayer());
initiators.emplace_back(getTraceGeneratorOneState());
initiators.emplace_back(getTraceGeneratorMultipleStates());
initiators.emplace_back(getTraceHammer());
return DRAMSysConfiguration::TraceSetup{initiators};
}
DRAMSysConfiguration::Configuration getConfig(const DRAMSysConfiguration::MemSpec &memSpec)
{
return DRAMSysConfiguration::Configuration{
getAddressMapping(),
getMcConfig(),
memSpec,
getSimConfig(),
"std::string_simulationId",
getThermalConfig(),
// {{}, false}, works too
getTraceSetup(),
};
}
int main()
{
DRAMSysConfiguration::Configuration conf = DRAMSysConfiguration::from_path("ddr5.json");
std::ofstream fileout("myjson.json");
json j_my;
j_my["simulation"] = getConfig(conf.memSpec); // just copy memspec over
fileout << j_my.dump(4);
std::ifstream file2("hbm2.json");
json hbm2_j = json::parse(file2, nullptr, false);
json hbm2_config = hbm2_j.at("simulation");
DRAMSysConfiguration::Configuration hbm2conf = hbm2_config.get<DRAMSysConfiguration::Configuration>();
std::ofstream filehbm2("myhbm2.json");
json j_myhbm2;
j_myhbm2["simulation"] = hbm2conf;
filehbm2 << j_myhbm2.dump(4);
std::ifstream file3("myjson.json");
json ddr5_old = json::parse(file3, nullptr, false);
json ddr5_old_conf = ddr5_old.at("simulation");
DRAMSysConfiguration::Configuration ddr5_old_config = ddr5_old_conf.get<DRAMSysConfiguration::Configuration>();
std::ofstream fileoldout("myjson2.json");
json j_oldconfconv;
j_oldconfconv["simulation"] = ddr5_old_config;
fileoldout << j_oldconfconv.dump(4);
}

View File

@@ -1,144 +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 <nlohmann/json.hpp>
#include <optional>
#include <utility>
namespace DRAMSysConfiguration
{
using json = 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 get_config_json(const json &j, const std::string &configPath, const std::string &objectName);
inline void remove_null_values(json &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 DRAMSysConfiguration
/**
* Inspired from
* https://json.nlohmann.me/features/arbitrary_types/#how-can-i-use-get-for-non-default-constructiblenon-copyable-types
*/
namespace nlohmann
{
template <typename T>
void to_json(nlohmann::json &j, const std::optional<T> &v)
{
if (v.has_value())
j = v.value();
else
j = nullptr;
}
template <typename T>
void from_json(const nlohmann::json &j, std::optional<T> &v)
{
if (j.is_null())
v = std::nullopt;
else
{
v = j.get<T>();
}
}
} // namespace nlohmann
#endif // DRAMSYSCONFIGURATION_UTIL_H

View File

@@ -1,89 +0,0 @@
/*
* Copyright (c) 2015, 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:
* Eder F. Zulian
* Matthias Jung
* Luiza Correa
* Derek Christ
*/
#ifndef TEMPERATURESIMCONFIG_H
#define TEMPERATURESIMCONFIG_H
#include <string>
#include <vector>
#include <DRAMSysConfiguration.h>
#include <systemc>
#include <utility>
#include "../common/DebugManager.h"
struct TemperatureSimConfig
{
// Temperature Scale
enum class TemperatureScale {Celsius, Fahrenheit, Kelvin} temperatureScale;
// Static Temperature Simulation parameters
int staticTemperatureDefaultValue;
// Thermal Simulation parameters
double thermalSimPeriod;
enum sc_core::sc_time_unit thermalSimUnit;
std::string iceServerIp;
unsigned int iceServerPort;
unsigned int simPeriodAdjustFactor;
unsigned int nPowStableCyclesToIncreasePeriod;
bool generateTemperatureMap;
bool generatePowerMap;
// Power related information
std::vector<float> powerInitialValues;
std::vector<float> powerThresholds;
void showTemperatureSimConfig()
{
NDEBUG_UNUSED(int i) = 0;
for (NDEBUG_UNUSED(auto e) : powerInitialValues)
{
PRINTDEBUGMESSAGE("TemperatureSimConfig", "powerInitialValues["
+ std::to_string(i++) + "]: " + std::to_string(e));
}
i = 0;
for (NDEBUG_UNUSED(auto e) : powerThresholds)
{
PRINTDEBUGMESSAGE("TemperatureSimConfig", "powerThreshold["
+ std::to_string(i++) + "]: " + std::to_string(e));
}
}
};
#endif // TEMPERATURESIMCONFIG_H

View File

@@ -1,146 +0,0 @@
/*
* Copyright (c) 2015, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Lukas Steiner
* Derek Christ
*/
#include "MemSpec.h"
using namespace sc_core;
using namespace tlm;
MemSpec::MemSpec(const DRAMSysConfiguration::MemSpec &memSpec,
MemoryType memoryType,
unsigned numberOfChannels, unsigned pseudoChannelsPerChannel,
unsigned ranksPerChannel, unsigned banksPerRank,
unsigned groupsPerRank, unsigned banksPerGroup,
unsigned banksPerChannel, unsigned bankGroupsPerChannel,
unsigned devicesPerRank)
: numberOfChannels(numberOfChannels),
pseudoChannelsPerChannel(pseudoChannelsPerChannel),
ranksPerChannel(ranksPerChannel),
banksPerRank(banksPerRank),
groupsPerRank(groupsPerRank),
banksPerGroup(banksPerGroup),
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")
: defaultBurstLength),
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")),
tCK(sc_time(1.0 / fCKMHz, SC_US)),
memoryId(memSpec.memoryId),
memoryType(memoryType),
burstDuration(tCK * (static_cast<double>(defaultBurstLength) / dataRate)),
memorySizeBytes(0)
{
commandLengthInCycles = std::vector<double>(Command::numberOfCommands(), 1);
}
sc_time MemSpec::getCommandLength(Command command) const
{
return tCK * commandLengthInCycles[command];
}
double MemSpec::getCommandLengthInCycles(Command command) const
{
return commandLengthInCycles[command];
}
uint64_t MemSpec::getSimMemSizeInBytes() const
{
return memorySizeBytes;
}
sc_time MemSpec::getRefreshIntervalAB() const
{
SC_REPORT_FATAL("MemSpec", "All-bank refresh not supported");
return SC_ZERO_TIME;
}
sc_time MemSpec::getRefreshIntervalPB() const
{
SC_REPORT_FATAL("MemSpec", "Per-bank refresh not supported");
return SC_ZERO_TIME;
}
sc_time MemSpec::getRefreshIntervalP2B() const
{
SC_REPORT_FATAL("MemSpec", "Per-2-bank refresh not supported");
return SC_ZERO_TIME;
}
sc_time MemSpec::getRefreshIntervalSB() const
{
SC_REPORT_FATAL("MemSpec", "Same-bank refresh not supported");
return SC_ZERO_TIME;
}
unsigned MemSpec::getPer2BankOffset() const
{
return 0;
}
unsigned MemSpec::getRAACDR() const
{
SC_REPORT_FATAL("MemSpec", "Refresh Management not supported");
return 0;
}
unsigned MemSpec::getRAAIMT() const
{
SC_REPORT_FATAL("MemSpec", "Refresh Management not supported");
return 0;
}
unsigned MemSpec::getRAAMMT() const
{
SC_REPORT_FATAL("MemSpec", "Refresh Management not supported");
return 0;
}
bool MemSpec::hasRasAndCasBus() const
{
return false;
}

View File

@@ -1,119 +0,0 @@
/*
* Copyright (c) 2015, 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:
* Janik Schlemminger
* Matthias Jung
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPEC_H
#define MEMSPEC_H
#include <vector>
#include <string>
#include <DRAMSysConfiguration.h>
#include <systemc>
#include <tlm>
#include "../../common/utils.h"
#include "../../controller/Command.h"
class MemSpec
{
public:
const unsigned numberOfChannels;
const unsigned pseudoChannelsPerChannel;
const unsigned ranksPerChannel;
const unsigned banksPerRank;
const unsigned groupsPerRank;
const unsigned banksPerGroup;
const unsigned banksPerChannel;
const unsigned bankGroupsPerChannel;
const unsigned devicesPerRank;
const unsigned rowsPerBank;
const unsigned columnsPerRow;
const unsigned defaultBurstLength;
const unsigned maxBurstLength;
const unsigned dataRate;
const unsigned bitWidth;
const unsigned dataBusWidth;
const unsigned bytesPerBeat;
const unsigned defaultBytesPerBurst;
const unsigned maxBytesPerBurst;
// Clock
const double fCKMHz;
const sc_core::sc_time tCK;
const std::string memoryId;
const enum class MemoryType {DDR3, DDR4, DDR5, LPDDR4, LPDDR5, WideIO,
WideIO2, GDDR5, GDDR5X, GDDR6, HBM2, HBM3, STTMRAM} memoryType;
virtual ~MemSpec() = default;
virtual sc_core::sc_time getRefreshIntervalAB() const;
virtual sc_core::sc_time getRefreshIntervalPB() const;
virtual sc_core::sc_time getRefreshIntervalP2B() const;
virtual sc_core::sc_time getRefreshIntervalSB() const;
virtual unsigned getPer2BankOffset() const;
virtual unsigned getRAAIMT() const;
virtual unsigned getRAAMMT() const;
virtual unsigned getRAACDR() const;
virtual bool hasRasAndCasBus() const;
virtual sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const = 0;
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const = 0;
sc_core::sc_time getCommandLength(Command) const;
double getCommandLengthInCycles(Command) const;
uint64_t getSimMemSizeInBytes() const;
protected:
MemSpec(const DRAMSysConfiguration::MemSpec &memSpec,
MemoryType memoryType,
unsigned numberOfChannels, unsigned pseudoChannelsPerChannel,
unsigned ranksPerChannel, unsigned banksPerRank,
unsigned groupsPerRank, unsigned banksPerGroup,
unsigned banksPerChannel, unsigned bankGroupsPerChannel,
unsigned devicesPerRank);
// Command lengths in cycles on bus, usually one clock cycle
std::vector<double> commandLengthInCycles;
sc_core::sc_time burstDuration;
uint64_t memorySizeBytes;
};
#endif // MEMSPEC_H

View File

@@ -1,105 +0,0 @@
/*
* Copyright (c) 2017, 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:
* Johannes Feldmann
* Eder F. Zulian
*/
#pragma once
class CBit
{
public:
enum VALUE {
ZERO = 0,
ONE = 1
};
protected:
VALUE m_nValue;
public:
CBit(VALUE nVal = ZERO);
virtual ~CBit();
inline void Set()
{
m_nValue = ONE;
};
inline void Clear()
{
m_nValue = ZERO;
};
inline unsigned Get()
{
if (m_nValue == ONE)
return 1;
else
return 0;
};
void Print();
CBit &operator=(unsigned d)
{
if (d == 0 ) {
m_nValue = ZERO;
} else {
m_nValue = ONE;
}
return *this;
}
friend CBit operator^(CBit l, const CBit &r)
{
if (l.m_nValue == r.m_nValue) {
return CBit(ZERO);
} else {
return CBit(ONE);
}
}
CBit &operator^=(const CBit &r)
{
if (m_nValue == r.m_nValue) {
m_nValue = ZERO;
} else {
m_nValue = ONE;
}
return *this;
}
inline bool operator==(const CBit::VALUE &r)
{
return m_nValue == r;
}
};

View File

@@ -1,161 +0,0 @@
/*
* Copyright (c) 2017, 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:
* Johannes Feldmann
* Eder F. Zulian
*/
#include "ECC.h"
// ************************************************************************************************
// Function which calculates the number of additional bits needed for a given number of data bits
// to store the hamming code and parity bit for a SECDED implementation
unsigned ECC::GetNumParityBits(unsigned nDataBits)
{
unsigned nParityBits = 0;
// Function to calculate the nube of bits: n = 2^k - k - 1
// ( Source: Hacker's Delight; p. 310; math. function 1 )
while (nDataBits > ((1 << nParityBits) - nParityBits - 1)) {
++nParityBits;
}
return nParityBits + 1; // +1 for the parity bit
}
// ************************************************************************************************
// Function which extends a given data word to the needed length for a SECDED code
void ECC::ExtendWord(CWord &v)
{
unsigned end = v.GetLength() + ECC::GetNumParityBits(v.GetLength());
// Insert x bits for the hamming code at positions where pos = 2^a; a = [0..N]
// In "Hacker's Delight" the smallest index is 1 - But in this beautiful C-Code it's 0 as it
// should be. That's why there is a '-1' in the call of v.Insert.
unsigned i = 1;
while (i < end) {
v.Insert(i - 1, CBit());
i <<= 1;
}
// Append one bit for the parity
v.Append(CBit());
}
// ************************************************************************************************
// Function which calculates the Hamming Code bits of an extended Data word.
// Function ExtendWord must be called before calling this function
// The calculated bits are stored in p, so the length of p should be at least
// 'GetNumParityBits(#data bits)-1'
void ECC::CalculateCheckbits(CWord &v, CWord &p)
{
unsigned i = 1, l = 0;
// Last bit is the parity bit - don't use this in the algorithm for hamming code
unsigned len = v.GetLength() - 1;
// Following Graph should show you the behaviour of this algorithm
// #Data bits: 11 #Hamming bits: 4 -> SECDED bits: 16 (incl. parity bit)
// Hamming Code Bit: | Bits used -> data(X)/Hamming Code(H) // Bit unused -
// 0 | H-X-X-X-X-X-X-X
// 1 | -HX--XX--XX--XX
// 2 | ---HXXX----XXXX
// 3 | -------HXXXXXXX
// For further information read "Hacker's delight" chapter 15
// ATTENTION: The order of indices is different from the one in the book,
// but it doesn't matter in which order your data or check bits are.
// But it should be the same for encoding and decoding
while (i < len) {
for (unsigned j = (i - 1); j < len; j += (i << 1)) {
for (unsigned k = 0; k < (i); k++) {
if (j + k >= len)
break;
p[l] ^= v[j + k];
}
}
l++;
i <<= 1;
}
}
// ************************************************************************************************
// Function which inserts the checkbits which were calculated with 'CalculateCheckbits' in the
// extended data word. This is needed to calculate a proper parity of ALL bits to achive a SECDED
// behaviour.
void ECC::InsertCheckbits(CWord &v, CWord p)
{
unsigned i = 1, j = 0;
while (i <= v.GetLength() - 1) {
v[i - 1] = p[j++];
i <<= 1;
}
}
// ************************************************************************************************
// Function which extracts the checkbits out of an extended data word. This is needed to check for
// bit error in the data word.
void ECC::ExtractCheckbits(CWord v, CWord &p)
{
unsigned i = 1, j = 0;
while (i <= v.GetLength() - 1) {
p[j++] = v[i - 1];
i <<= 1;
}
}
// ************************************************************************************************
// Function which calculates the overal parity
// Simply XOR all bits
void ECC::CalculateParityBit(CWord v, CBit &p)
{
// Paritybit
p = CBit::ZERO;
for (unsigned i = 0; i < v.GetLength(); i++) {
p ^= v[i];
}
}
// ************************************************************************************************
// Function to insert the parity bit into the extended data word
void ECC::InsertParityBit(CWord &v, CBit p)
{
v[v.GetLength() - 1] = p;
}
// ************************************************************************************************
// Function to extract the parity bit out of an extended data word.
void ECC::ExtractParityBit(CWord v, CBit &p)
{
p = v[v.GetLength() - 1];
}

View File

@@ -1,74 +0,0 @@
/*
* Copyright (c) 2017, 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:
* Johannes Feldmann
* Eder F. Zulian
*/
#pragma once
#include "Word.h"
#include "Bit.h"
// ************************************************************************************************
//
// | __/ __/ __| | __| _ _ _ __| |_(_)___ _ _ ___
// | _| (_| (__ | _| || | ' \/ _| _| / _ \ ' \(_-<
// |___\___\___| |_| \_,_|_||_\__|\__|_\___/_||_/__/
//
// ------------------------------------------------------------------------------------------------
// ECC Implementation as described in "Hacker's Delight - second Edition" by Henry S. Warren, Jr.
// ------------------------------------------------------------------------------------------------
// This namespace gives you some handy functions to get a SEC-DED implementation.
//
// SEC-DED: Single Error Correction - Double Error Detection
// This is the most common error correction code (ECC).
// It consists of two different correction codes: Haming code + parity code.
//
// For further details read chapter 15 of "Hacker's Delight - second Edition"
// ************************************************************************************************
namespace ECC {
unsigned GetNumParityBits(unsigned nDataBits);
// Extends the data word that it can be used with hamming code
// Several bits will be included at specific places
void ExtendWord(CWord &v);
void CalculateCheckbits(CWord &v, CWord &p);
void InsertCheckbits(CWord &v, CWord p);
void ExtractCheckbits(CWord v, CWord &p);
void CalculateParityBit(CWord v, CBit &p);
void InsertParityBit(CWord &v, CBit p);
void ExtractParityBit(CWord v, CBit &p);
}

View File

@@ -1,152 +0,0 @@
/*
* Copyright (c) 2017, 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:
* Johannes Feldmann
* Eder F. Zulian
*/
// ECC_Test.cpp : Entry point for the console application.
//
#include "stdafx.h"
#include <time.h>
#include "ECC.h"
int main()
{
// Random number init
srand(time(NULL));
// Erstellen
unsigned size = 4;
CWord p(ECC::GetNumParityBits(size)), v(size);
// Daten eingeben
for (unsigned a = 0; a < 16; a++) {
v = a;
v.Rotate();
ECC::ExtendWord(v);
printf("%d:\t", a);
p = 0;
ECC::CalculateCheckbits(v, p);
ECC::InsertCheckbits(v, p);
ECC::CalculateParityBit(v, p[3]);
ECC::InsertParityBit(v, p[3]);
v.Print();
v.Resize(size);
}
printf("\r\n");
for (unsigned x = 0; x < 100; x++) {
//Get random number
unsigned a = rand() % 16;
v.Resize(size);
v = a;
v.Rotate();
ECC::ExtendWord(v);
p = 0;
ECC::CalculateCheckbits(v, p);
ECC::InsertCheckbits(v, p);
ECC::CalculateParityBit(v, p[3]);
ECC::InsertParityBit(v, p[3]);
v.Print();
// Insert error
unsigned pos = rand() % 8;
v[pos] ^= CBit(CBit::ONE);
printf("Data: %d, Error at pos %d: ", a, pos + 1);
v[pos].Print();
printf("\r\n");
v.Print();
p = 0;
ECC::CalculateCheckbits(v, p);
ECC::CalculateParityBit(v, p[3]);
printf("%d:\t", a);
p.Print();
// Interpreting Data
unsigned syndrome = 0;
for (unsigned i = 0; i < p.GetLength() - 1; i++) {
if (p[i] == CBit::ONE)
syndrome += (1 << i);
}
if (p[3] == CBit::ZERO) {
// Parity even
if (syndrome) {
// Double error
printf("Double error detected.\r\n");
break;
} else {
// No Error
printf("No error detected.\r\n");
break;
}
} else {
// Parity odd
if (syndrome) {
// Bit error
printf("Error detected in Bit %d.\r\n", syndrome);
if (syndrome == pos + 1)
continue;
else
break;
} else {
// Overall parity Error
printf("Overall parity error detected.\r\n");
if (pos == 7 || pos == 3 || pos == 1 || pos == 0)
continue;
else
break;
}
}
}
system("pause");
return 0;
}

View File

@@ -1,180 +0,0 @@
/*
* Copyright (c) 2017, 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:
* Johannes Feldmann
* Eder F. Zulian
*/
#include "Word.h"
#include <math.h>
#include <iostream>
#include <string.h>
using std::cout;
using std::deque;
CWord::CWord(unsigned nBitLength)
: m_nBitLength(nBitLength)
{
m_word.resize(nBitLength);
}
CWord::~CWord()
{
}
CBit *CWord::GetAt(unsigned nBitPos)
{
if (nBitPos < m_nBitLength) {
return &m_word.at(nBitPos);
}
return nullptr;
}
void CWord::Set(unsigned data)
{
deque<CBit>::iterator it;
if (m_nBitLength < sizeof(data)) {
it = m_word.begin();
for (unsigned i = 0; i < m_nBitLength; i++) {
(*it++) = data & 1;
data >>= 1;
}
} else {
for (it = m_word.begin(); it != m_word.end(); it++) {
(*it) = data & 1;
data >>= 1;
}
}
}
void CWord::Set(const unsigned char *data, unsigned lengthInBits)
{
deque<CBit>::iterator it;
if (m_nBitLength < lengthInBits) {
it = m_word.begin();
for (unsigned pos = 0; pos < m_nBitLength; pos++) {
(*it) = data[pos >> 3] & (1 << (7 - (pos & 7)));
it++;
}
} else {
unsigned pos = 0;
for (it = m_word.begin(); it != m_word.end(); it++) {
(*it) = data[pos >> 3] & (1 << (7 - (pos & 7)));
++pos;
}
}
}
void CWord::Rotate()
{
deque<CBit> buffer = m_word;
for (unsigned i = 0; i < m_nBitLength; i++) {
m_word.at(m_nBitLength - i - 1) = buffer.at(i);
}
}
bool CWord::Insert(unsigned npos, CBit b)
{
if (npos >= m_nBitLength)
return false;
deque<CBit>::iterator it = m_word.begin() + npos;
m_word.insert(it, b);
m_nBitLength++;
return true;
}
bool CWord::Delete(unsigned npos)
{
if (npos >= m_nBitLength)
return false;
deque<CBit>::iterator it = m_word.begin() + npos;
m_word.erase(it);
m_nBitLength++;
return true;
}
void CWord::Append(CBit b)
{
m_word.push_back(b);
m_nBitLength++;
}
void CWord::Resize(unsigned nsize)
{
m_word.resize(nsize);
m_nBitLength = nsize;
}
bool CWord::PartShiftRight(unsigned nPos, unsigned /*nShift*/)
{
if (nPos >= m_nBitLength)
return false;
/*for (unsigned i = 0; i < nShift; i++)
{
m_word.insert()
}*/
return true;
}
void CWord::Print()
{
deque<CBit>::iterator it;
for (it = m_word.begin(); it != m_word.end(); it++) {
(*it).Print();
}
cout << "\r\n";
}
void CWord::Copy(unsigned char *ptr)
{
unsigned len = ceil(m_word.size() / 8);
memset(ptr, 0, len);
unsigned pos = 0;
for (auto it = m_word.begin(); it != m_word.end(); it++) {
ptr[pos >> 3] |= (*it).Get() << (7 - (pos & 7));
++pos;
}
}

View File

@@ -1,98 +0,0 @@
/*
* Copyright (c) 2017, 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:
* Johannes Feldmann
* Eder F. Zulian
*/
#pragma once
#include <deque>
#include "Bit.h"
class CWord
{
protected:
unsigned m_nBitLength;
std::deque<CBit> m_word;
public:
CWord(unsigned nBitLength);
virtual ~CWord();
CBit *GetAt(unsigned nBitPos);
void Set(unsigned data);
void Set(const unsigned char *data, unsigned lengthInBits);
void Rotate();
bool Insert(unsigned npos, CBit b);
bool Delete(unsigned npos);
void Copy(unsigned char *ptr);
void Append(CBit b);
void Resize(unsigned nsize);
bool PartShiftRight(unsigned nPos, unsigned nShift);
inline unsigned GetLength() const
{
return m_nBitLength;
};
void Print();
CWord &operator=(unsigned d)
{
Set(d);
return *this;
}
CBit &operator[](unsigned nPos)
{
return m_word.at(nPos);
}
friend CWord operator >> (CWord l, const unsigned &r)
{
for (unsigned i = 0; i < r; i++) {
l.m_word.pop_front();
l.m_word.push_back(CBit(CBit::VALUE::ZERO));
}
return l;
}
};

View File

@@ -1,120 +0,0 @@
/*
* Copyright (c) 2017, 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:
* Johannes Feldmann
* Eder F. Zulian
*/
#include "eccbaseclass.h"
using namespace sc_core;
using namespace tlm;
tlm::tlm_sync_enum ECCBaseClass::nb_transport_fw( int id,
tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, sc_time &delay )
{
if (trans.get_command() == TLM_WRITE_COMMAND && phase == BEGIN_REQ) {
// Allocate memory for encoded data using the size provided by AllocationEncode
unsigned nEncodedDataSize = AllocationSize(trans.get_data_length());
assert(nEncodedDataSize != 0);
unsigned char *pEncodedData = new unsigned char[nEncodedDataSize];
// Save memory pointer and size
m_mDataPointer[pEncodedData].pData = trans.get_data_ptr();
m_mDataPointer[pEncodedData].nDataSize = trans.get_data_length();
// Data Encoding
Encode(trans.get_data_ptr(), trans.get_data_length(), pEncodedData,
nEncodedDataSize);
// Change transport data length and pointer
trans.set_data_length(nEncodedDataSize);
trans.set_data_ptr(pEncodedData);
} else if (trans.get_command() == TLM_READ_COMMAND && phase == BEGIN_REQ) {
// Allocate memory for reading data using the size provided by AllocationEncode
unsigned nReadDataSize = AllocationSize(trans.get_data_length());
assert(nReadDataSize != 0);
unsigned char *pReadData = new unsigned char[nReadDataSize];
// Save memory pointer and size
m_mDataPointer[pReadData].pData = trans.get_data_ptr();
m_mDataPointer[pReadData].nDataSize = trans.get_data_length();
// Change transport data length and pointer
trans.set_data_length(nReadDataSize);
trans.set_data_ptr(pReadData);
}
return i_socket[id]->nb_transport_fw( trans, phase, delay );
}
// Backward interface
tlm::tlm_sync_enum ECCBaseClass::nb_transport_bw( int id,
tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, sc_time &delay )
{
if (trans.get_command() == TLM_READ_COMMAND && phase == BEGIN_RESP) {
//Look for the corresponding data pointer for decoding
auto it = m_mDataPointer.find(trans.get_data_ptr());
assert(it != m_mDataPointer.end());
// Data Decoding
Decode(trans.get_data_ptr(), trans.get_data_length(), it->second.pData,
it->second.nDataSize);
// delete data pointer from map
m_mDataPointer.erase(it);
// Delete data pointer used for encoded data
delete[] trans.get_data_ptr();
// Set data pointer and size for decoded data
trans.set_data_ptr(it->second.pData);
trans.set_data_length(it->second.nDataSize);
} else if (trans.get_command() == TLM_WRITE_COMMAND && phase == BEGIN_RESP) {
//Look for the corresponding data pointer for decoding
auto it = m_mDataPointer.find(trans.get_data_ptr());
assert(it != m_mDataPointer.end());
// delete data pointer from map
m_mDataPointer.erase(it);
// Delete data pointer used for encoded data
delete[] trans.get_data_ptr();
// Set data pointer and size for decoded data
trans.set_data_ptr(it->second.pData);
trans.set_data_length(it->second.nDataSize);
}
return t_socket[id]->nb_transport_bw( trans, phase, delay );
}

View File

@@ -1,102 +0,0 @@
/*
* Copyright (c) 2017, 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:
* Johannes Feldmann
* Eder F. Zulian
*/
#ifndef ECCBASECLASS_H
#define ECCBASECLASS_H
#include <systemc>
#include <tlm>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include <tlm_utils/multi_passthrough_target_socket.h>
#include "ECC/ECC.h"
#include "../common/DebugManager.h"
class ECCBaseClass : sc_core::sc_module
{
public:
struct DataStruct {
unsigned char *pData;
unsigned int nDataSize;
};
private:
std::map<unsigned char *, DataStruct> m_mDataPointer;
public:
// Function prototype for calculated the size of memory needed for saving the encoded data
// Input nBytes: Number of bytes which have to be encoded
// Return value: Number of bytes which have to be allocated for storing the encoded data
virtual unsigned AllocationSize(unsigned nBytes) = 0;
protected:
// Function prototype for encoding data.
// Data pointer is provided in pDataIn, length in Bytes provided in nDataIn
// Result should be written in pDataOut, which has a size of nDataOut.
// pDataOut is already allocated with a size given by function AllocationEncode
virtual void Encode(const unsigned char *pDataIn, unsigned nDataIn,
unsigned char *pDataOut, unsigned nDataOut) = 0;
// Function prototype for decoding data.
// Data pointer is provided in pDataIn, length in Bytes provided in nDataIn
// Result should be written in pDataOut, which has a size of nDataOut.
// pDataOut is already allocated with a size given by function AllocationDecode
virtual void Decode(const unsigned char *pDataIn, unsigned nDataIn,
unsigned char *pDataOut, unsigned nDataOut) = 0;
public:
tlm_utils::multi_passthrough_target_socket<ECCBaseClass> t_socket;
tlm_utils::multi_passthrough_initiator_socket<ECCBaseClass> i_socket;
SC_CTOR(ECCBaseClass)
: t_socket("t_socket")
, i_socket("i_socket")
{
t_socket.register_nb_transport_fw(this, &ECCBaseClass::nb_transport_fw);
i_socket.register_nb_transport_bw(this, &ECCBaseClass::nb_transport_bw);
}
// Forward interface
tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload &trans,
tlm::tlm_phase &phase, sc_core::sc_time &delay );
// Backward interface
tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload &trans,
tlm::tlm_phase &phase, sc_core::sc_time &delay );
};
#endif // ECCBASECLASS_H

View File

@@ -1,166 +0,0 @@
/*
* Copyright (c) 2017, 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:
* Johannes Feldmann
* Eder F. Zulian
*/
#include "ecchamming.h"
#include "ECC/ECC.h"
unsigned ECCHamming::AllocationSize(unsigned nBytes)
{
// For this hamming for 8 bytes one extra byte is needed:l
return nBytes + ceil(nBytes / m_nDatawordSize) * m_nCodewordSize;
}
void ECCHamming::Encode(const unsigned char *pDataIn, const unsigned nDataIn,
unsigned char *pDataOut, const unsigned nDataOut)
{
// Calculate how many 8 byte blocks are there
unsigned nBlocks = nDataIn / m_nDatawordSize;
// No partly filled blocks are supported
assert(nDataIn % m_nDatawordSize == 0);
// Create ECC data for every block
for (unsigned i = 0; i < nBlocks; i++) {
// Create all variables needed for calulation
CWord dataword(InBits(m_nDatawordSize)); // Size in bits
CWord codeword(InBits(m_nCodewordSize)); // Size in bits
// Fill in current data block
dataword.Set(&pDataIn[i * m_nDatawordSize], InBits(m_nDatawordSize));
// Extend data word. It grows from m_nDatawordSize to m_nDatawordSize + m_nCodewordSize
ECC::ExtendWord(dataword);
// Initialize the codeword with zeros
codeword = 0;
// Calculate Checkbits
ECC::CalculateCheckbits(dataword, codeword);
ECC::InsertCheckbits(dataword, codeword);
// Calculate Parity
ECC::CalculateParityBit(dataword, codeword[7]);
// Check if there is enough space in the output array (should always be)
assert((i + 1) * (m_nDatawordSize + m_nCodewordSize) <= nDataOut);
// Copy old data
memcpy(&pDataOut[i * (m_nDatawordSize + m_nCodewordSize)],
&pDataIn[i * m_nDatawordSize], m_nDatawordSize);
// Save hamming code + parity bit in the last byte
codeword.Copy(&pDataOut[i * (m_nDatawordSize + m_nCodewordSize) +
m_nDatawordSize]);
}
}
void ECCHamming::Decode(const unsigned char *pDataIn, const unsigned nDataIn,
unsigned char *pDataOut, const unsigned nDataOut)
{
// Calculate how many 9 byte blocks are there
unsigned nBlocks = nDataIn / (m_nDatawordSize + m_nCodewordSize);
// No partly filled blocks are supported
assert(nDataIn % (m_nDatawordSize + m_nCodewordSize) == 0);
// Verify ECC data for every block
for (unsigned i = 0; i < nBlocks; i++) {
// Create all variables needed for calulation
CWord dataword(InBits(m_nDatawordSize)); // Size in bits
CWord codeword(InBits(m_nCodewordSize)); // Size in bits
// Fill in current data block
dataword.Set(&pDataIn[i * (m_nDatawordSize + m_nCodewordSize)],
InBits(m_nDatawordSize));
codeword.Set(&pDataIn[i * (m_nDatawordSize + m_nCodewordSize) +
m_nDatawordSize], InBits(m_nCodewordSize));
// Extend data word. It grows from m_nDatawordSize to m_nDatawordSize + m_nCodewordSize
ECC::ExtendWord(dataword);
// Insert old codeword
ECC::InsertCheckbits(dataword, codeword);
ECC::InsertParityBit(dataword, codeword[7]);
// Reset codeword
codeword = 0;
// Calculate Checkbits again
ECC::CalculateCheckbits(dataword, codeword);
// Calculate Parity again
ECC::CalculateParityBit(dataword, codeword[7]);
// Translate codeword
bool bParity = codeword[7] == CBit::ONE;
// calculate syndrome
unsigned char c = 0;
codeword.Rotate();
codeword.Copy(&c);
c &= 0x7F;
// Parity Error?
if (bParity) {
// Parity Error
if (c == 0) {
// Only Parity Bit broken - continue
std::cout << "Parity Bit error" << std::endl;
} else {
// Data or Hamming Code Bit broken
std::cout << "Single Error Detected" << std::endl;
}
} else {
// No Parity Error
if (c == 0) {
// No error at all - continue
} else {
// Double error detected
std::cout << "Double Error Detected (Block " << i << ")." << std::endl;
}
}
// Check if there is enough space in the output array (should always be)
assert((i + 1) * (m_nDatawordSize) <= nDataOut);
// Copy data
memcpy(&pDataOut[i * m_nDatawordSize],
&pDataIn[i * (m_nDatawordSize + m_nCodewordSize)], m_nDatawordSize);
}
}

View File

@@ -1,82 +0,0 @@
/*
* Copyright (c) 2017, 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:
* Johannes Feldmann
* Eder F. Zulian
*/
#ifndef ECCHAMMIMG_H
#define ECCHAMMIMG_H
#include "eccbaseclass.h"
class ECCHamming : public ECCBaseClass
{
private:
// Hamming constants for this special implementation
const unsigned m_nDatawordSize = 8; // bytes
const unsigned m_nCodewordSize = 1; // bytes
inline unsigned InBits(unsigned n)
{
return n << 3;
}; // use this if constants are needed in bits
public:
// Function prototype for calculated the size of memory needed for saving the encoded data
// Input nBytes: Number of bytes which have to be encoded
// Return value: Number of bytes which have to be allocated for storing the encoded data
virtual unsigned AllocationSize(unsigned nBytes);
protected:
// Function prototype for encoding data.
// Data pointer is provided in pDataIn, length in Bytes provided in nDataIn
// Result should be written in pDataOut, which has a size of nDataOut.
// pDataOut is already allocated with a size given by function AllocationEncode
virtual void Encode(const unsigned char *pDataIn, unsigned nDataIn,
unsigned char *pDataOut, unsigned nDataOut);
// Function prototype for decoding data.
// Data pointer is provided in pDataIn, length in Bytes provided in nDataIn
// Result should be written in pDataOut, which has a size of nDataOut.
// pDataOut is already allocated with a size given by function AllocationDecode
virtual void Decode(const unsigned char *pDataIn, unsigned nDataIn,
unsigned char *pDataOut, unsigned nDataOut);
public:
ECCHamming(::sc_core::sc_module_name name) : ECCBaseClass(name)
{};
};
#endif // ECCHAMMIMG_H

View File

@@ -1,753 +0,0 @@
/*
* Copyright (c) 2015, 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:
* Matthias Jung
*/
#include "errormodel.h"
#include "../common/DebugManager.h"
#include "../simulation/TemperatureController.h"
#include "../simulation/AddressDecoder.h"
#include "../common/dramExtensions.h"
#ifdef DRAMPOWER
#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h"
#endif
#include <random>
#include <chrono>
#include <bitset>
#include <cmath>
#include <sstream>
#include <fstream>
using namespace sc_core;
errorModel::errorModel(const sc_module_name& name, const Configuration& config,
TemperatureController& temperatureController, libDRAMPower *dramPower)
: sc_module(name), memSpec(*config.memSpec), temperatureController(temperatureController)
{
this->DRAMPower = dramPower;
init(config);
}
void errorModel::init(const Configuration& config)
{
powerAnalysis = config.powerAnalysis;
thermalSim = config.thermalSimulation;
// Get Configuration parameters:
burstLenght = config.memSpec->defaultBurstLength;
numberOfColumns = config.memSpec->columnsPerRow;
bytesPerColumn = std::log2(config.memSpec->dataBusWidth);
// Adjust number of bytes per column dynamically to the selected ecc controller
//TODO: bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC(bytesPerColumn);
numberOfRows = config.memSpec->rowsPerBank;
numberOfBitErrorEvents = 0;
// Initialize the lastRow Access array:
lastRowAccess = new sc_time[numberOfRows];
for (unsigned int i = 0; i < numberOfRows; i++)
lastRowAccess[i] = SC_ZERO_TIME;
// The name is set when the context is clear.
contextStr = "";
// Parse data input:
parseInputData(config);
prepareWeakCells();
// Initialize context variables:
myChannel = -1;
myRank = -1;
myBankgroup = -1;
myBank = -1;
// Test 1:
// If you want to test the function that get the number
// of bit errors for a given temperature and time
// uncomment the following lines:
//
//std::cout << "MAXTemp:" << maxTemperature << std::endl;
//std::cout << "MAXTime:" << maxTime << std::endl;
//getNumberOfFlips(45.0,sc_time(200.0,SC_MS));
//getNumberOfFlips(45.0,sc_time(190.0,SC_MS));
//getNumberOfFlips(45.0,sc_time(180.0,SC_MS));
//getNumberOfFlips(75.0,sc_time(200.0,SC_MS));
//getNumberOfFlips(75.0,sc_time(190.0,SC_MS));
//getNumberOfFlips(75.0,sc_time(180.0,SC_MS));
//getNumberOfFlips(85.0,sc_time(200.0,SC_MS));
//getNumberOfFlips(85.0,sc_time(190.0,SC_MS));
//getNumberOfFlips(85.0,sc_time(180.0,SC_MS));
//getNumberOfFlips(88.0,sc_time(200.0,SC_MS));
//getNumberOfFlips(88.0,sc_time(190.0,SC_MS));
//getNumberOfFlips(88.0,sc_time(180.0,SC_MS));
//getNumberOfFlips(89.0,sc_time(64.0,SC_MS));
//getNumberOfFlips(89.0,sc_time(64.0,SC_MS));
//getNumberOfFlips(89.0,sc_time(64.0,SC_MS));
// Test 2:
// X X X
// X 1 1
// X 1 1
//weakCells[0].bit = 0;
//weakCells[0].col = 0;
//weakCells[0].row = 0;
//weakCells[0].dependent = true;
markBitFlips();
}
errorModel::~errorModel()
{
// Remove all data from the dataMap:
for (std::map<DecodedAddress, unsigned char *>::iterator it = dataMap.begin();
it != dataMap.end(); ++it ) {
delete it->second;
}
// Delete all elements from the dataMap:
dataMap.clear();
// Remove all data from the lastRowAccess
delete [] lastRowAccess;
// Clean errorMap
errorMap.clear();
// Clean list of weak cells:
delete [] weakCells;
// If an access happened to a bank the numner of error events should be shown:
if (myChannel != -1 && myBank != -1 && myBankgroup != -1 && myRank != -1 ) {
std::cout << contextStr
<< ": Number of Retention Error Events = " << numberOfBitErrorEvents
<< std::endl;
}
}
void errorModel::store(tlm::tlm_generic_payload &trans)
{
// Check wich bits have flipped during the last access and mark them as flipped:
markBitFlips();
// Get the key for the dataMap from the transaction's dram extension:
// FIXME
// ControllerExtension &ext = ControllerExtension::getExtension(trans);
// DecodedAddress key = DecodedAddress(ext.getChannel().ID(), ext.getRank().ID(),
// ext.getBankGroup().ID(), ext.getBank().ID(),
// ext.getRow().ID(), ext.getColumn().ID(), 0);
DecodedAddress key;
// Set context:
setContext(key);
std::stringstream msg;
msg << "bank: " << key.bank << " group: " << key.bankgroup << " bytes: " <<
key.byte << " channel: " << key.channel << " column: " << key.column <<
" rank: " << key.rank << " row: " << key.row;
PRINTDEBUGMESSAGE(name(), msg.str());
// Check if the provided data length is correct:
assert((bytesPerColumn * burstLenght) == trans.get_data_length());
PRINTDEBUGMESSAGE(name(), ("Data length: " + std::to_string(trans.get_data_length()) +
" bytesPerColumn: " + std::to_string(bytesPerColumn)).c_str());
// Handle the DRAM burst,
for (unsigned int i = 0; i < trans.get_data_length(); i += bytesPerColumn) {
unsigned char *data;
// Check if address is not already stored:
if (dataMap.count(key) == 0) {
// Generate a new data entry
data = new unsigned char[bytesPerColumn];
} else { // In case the address was stored before:
data = dataMap[key];
}
// Copy the data from the transaction to the data pointer
memcpy(data, trans.get_data_ptr() + i, bytesPerColumn);
// Save part of the burst in the dataMap
// TODO: Check if we can have double entries, is key unique?
dataMap.insert(std::pair<DecodedAddress, unsigned char *>(key, data));
// Reset flipped weak cells in this area, since they are rewritten now
for (unsigned int j = 0; j < maxNumberOfWeakCells; j++) {
// If the current written column in a row has a week cell:
if (weakCells[j].row == key.row && weakCells[j].col == key.column) {
// If the bit was marked as flipped due to a retention error
// mark it as unflipped:
if (weakCells[j].flipped == true) {
weakCells[j].flipped = false;
}
}
}
// The next burst element is handled, therfore the column address must be increased
key.column++;
// Check that there is no column overfow:
std::stringstream msg;
msg << "key.column is " << key.column << " columnsPerRow is " <<
numberOfColumns;
PRINTDEBUGMESSAGE(name(), msg.str());
assert(key.column <= numberOfColumns);
}
}
void errorModel::load(tlm::tlm_generic_payload &trans)
{
// Check wich bits have flipped during the last access and mark them as flipped:
markBitFlips();
// Get the key for the dataMap from the transaction's dram extension:
// FIXME
// DramExtension &ext = DramExtension::getExtension(trans);
// DecodedAddress key = DecodedAddress(ext.getChannel().ID(), ext.getRank().ID(),
// ext.getBankGroup().ID(), ext.getBank().ID(),
// ext.getRow().ID(), ext.getColumn().ID(), 0);
DecodedAddress key;
// Set context:
setContext(key);
// Check if the provided data length is correct:
assert((bytesPerColumn * burstLenght) == trans.get_data_length());
// Handle the DRAM burst:
for (unsigned int i = 0; i < trans.get_data_length(); i += bytesPerColumn) {
// Check if address is not stored:
if (dataMap.count(key) == 0) {
SC_REPORT_FATAL("errormodel", "Reading from an empty memory location");
}
// Copy the dataMap to the transaction data pointer
memcpy(trans.get_data_ptr() + i, dataMap[key], bytesPerColumn);
// The next burst element is handled, therfore the column address must be increased
key.column++;
// Check that there is no column overfow:
assert(key.column <= numberOfColumns);
}
}
void errorModel::markBitFlips()
{
double temp = getTemperature();
for (unsigned int row = 0;
row < memSpec.rowsPerBank; row++) {
// If the row has never been accessed ignore it and go to the next one
if (lastRowAccess[row] != SC_ZERO_TIME) {
// Get the time interval between now and the last acivate/refresh
sc_time interval = sc_time_stamp() - lastRowAccess[row];
// Obtain the number of bit flips for the current temperature and the time interval:
unsigned int n = getNumberOfFlips(temp, interval);
// Check if the current row is in the range of bit flips for this interval
// and temperature, if yes mark it as flipped:
for (unsigned int i = 0; i < n; i++) {
// Check if Bit has marked as flipped yet, if yes mark it as flipped
if (!weakCells[i].flipped && weakCells[i].row == row) {
std::stringstream msg;
msg << "Maked weakCell[" << i << "] as flipped" << std::endl;
PRINTDEBUGMESSAGE(name(), msg.str());
weakCells[i].flipped = true;
}
}
}
}
}
void errorModel::refresh(unsigned int row)
{
// A refresh is internally composed of ACT and PRE that are executed
// on all banks, therefore we call the activate method:
activate(row);
}
void errorModel::activate(unsigned int row)
{
// Check wich bits have flipped during the last access and mark them as flipped:
markBitFlips();
// The Activate command is responsible that an retention error is manifested.
// Therefore, Flip the bit in the data structure if it is marked as flipped
// and if it is a one. Transisitons from 0 to 1 are only happening
// in DRAM with anticells. This behavior is not implemented yet.
for (unsigned int i = 0; i < maxNumberOfWeakCells; i++) {
if (weakCells[i].flipped == true && weakCells[i].row == row) {
// Estimate key to access column data
DecodedAddress key;
key.bank = myBank;
key.bankgroup = myBankgroup;
key.channel = myChannel;
key.column = weakCells[i].col;
key.rank = myRank;
key.row = row;
// Byte position in column:
unsigned int byte = weakCells[i].bit / 8;
// Bit position in byte:
unsigned int bitInByte = weakCells[i].bit % 8;
// Check if the bit is 1 (only 1->0 transitions are supported)
// DRAMs based on anti cells are not supported yet by this model
if (getBit(key, byte, bitInByte) == 1) {
// Prepare bit mask: invert mask and AND it later
unsigned char mask = pow(2, bitInByte);
mask = ~mask;
// Temporal storage for modification:
unsigned char tempByte;
if (weakCells[i].dependent == false) {
// Load the affected byte to tempByte
memcpy(&tempByte, dataMap[key] + byte, 1);
// Flip the bit:
tempByte = (tempByte & mask);
// Output on the Console:
std::stringstream msg;
msg << "Bit Flipped!"
<< " row: " << key.row
<< " col: " << key.column
<< " bit: " << weakCells[i].bit;
PRINTDEBUGMESSAGE(name(), msg.str());
numberOfBitErrorEvents++;
// Copy the modified byte back to the dataMap:
memcpy(dataMap[key] + byte, &tempByte, 1);
} else { // if(weakCells[i].dependent == true)
// Get the neighbourhood of the bit and store it in the
// grid variable:
// | 0 1 2 |
// grid = | 3 4 5 |
// | 6 7 8 |
unsigned int grid[9];
grid[0] = getBit(key.row - 1, key.column, byte, bitInByte - 1);
grid[1] = getBit(key.row - 1, key.column, byte, bitInByte );
grid[2] = getBit(key.row - 1, key.column, byte, bitInByte + 1);
grid[3] = getBit(key.row , key.column, byte, bitInByte - 1);
grid[4] = getBit(key.row , key.column, byte, bitInByte );
grid[5] = getBit(key.row , key.column, byte, bitInByte + 1);
grid[6] = getBit(key.row + 1, key.column, byte, bitInByte - 1);
grid[7] = getBit(key.row + 1, key.column, byte, bitInByte );
grid[8] = getBit(key.row + 1, key.column, byte, bitInByte + 1);
unsigned int sum = 0;
for (int s = 0; s < 9; s++) {
sum += grid[s];
}
if (sum <= 4) {
// Load the affected byte to tempByte
memcpy(&tempByte, dataMap[key] + byte, 1);
// Flip the bit:
tempByte = (tempByte & mask);
numberOfBitErrorEvents++;
// Copy the modified byte back to the dataMap:
memcpy(dataMap[key] + byte, &tempByte, 1);
// Output on the Console:
std::stringstream msg;
msg << "Dependent Bit Flipped!"
<< " row: " << key.row
<< " col: " << key.column
<< " bit: " << weakCells[i].bit
<< " sum: " << sum << std::endl
<< grid[0] << grid[1] << grid[2] << std::endl
<< grid[3] << grid[4] << grid[5] << std::endl
<< grid[6] << grid[7] << grid[8];
PRINTDEBUGMESSAGE(name(), msg.str());
} else {
// Output on the Console:
std::stringstream msg;
msg << "Dependent Bit NOT Flipped!"
<< " row: " << key.row
<< " col: " << key.column
<< " bit: " << weakCells[i].bit
<< " sum: " << sum << std::endl
<< grid[0] << grid[1] << grid[2] << std::endl
<< grid[3] << grid[4] << grid[5] << std::endl
<< grid[6] << grid[7] << grid[8];
PRINTDEBUGMESSAGE(name(), msg.str());
}
}
}
}
}
lastRowAccess[row] = sc_time_stamp();
}
// This method is used to get a bit with a key, usually for independent case:
unsigned int errorModel::getBit(DecodedAddress key, unsigned int byteInColumn,
unsigned int bitInByte)
{
// If the data was not writte by the produce yet it is zero:
if (dataMap.count(key) == 0) {
return 0;
} else { // Return the value of the bit
unsigned char tempByte;
// Copy affected byte to a temporal variable:
memcpy(&tempByte, dataMap[key] + byteInColumn, 1);
unsigned char mask = pow(2, bitInByte);
unsigned int result = (tempByte & mask) >> bitInByte;
std::bitset<8> x(mask);
std::stringstream msg;
msg << "mask = " << x
<< " bitInByte = " << bitInByte
<< " tempByte = " << (unsigned int)tempByte
<< " result = " << result;
PRINTDEBUGMESSAGE(name(), msg.str());
return result;
}
}
// This method is used to get neighbourhoods, for the dependent case:
unsigned int errorModel::getBit(int row, int column, int byteInColumn,
int bitInByte)
{
// Border-Exception handling:
// Switch the byte if bit under/overflow:
if (bitInByte < 0) {
byteInColumn--;
bitInByte = 7;
} else if (bitInByte >= 8) {
byteInColumn++;
bitInByte = 0;
}
// Switch the column if byte under/overflow
if (byteInColumn < 0) {
column--;
byteInColumn = bytesPerColumn;
} else if (byteInColumn >= int(byteInColumn)) {
column++;
byteInColumn = 0;
}
// If we switch the row we return 0 (culumn under/overflow)
if (column < 0) {
return 0;
} else if (column >= int(numberOfColumns)) {
return 0;
}
// Row over/underflow return 0
if (row < 0) {
return 0;
} else if (row >= int(numberOfRows)) {
return 0;
}
DecodedAddress key;
key.bank = myBank;
key.bankgroup = myBankgroup;
key.channel = myChannel;
key.rank = myRank;
key.column = column;
key.row = row;
return getBit(key, byteInColumn, bitInByte);
}
double errorModel::getTemperature()
{
// FIXME
// make sure the context is set (myChannel has the proper value) before
// requesting the temperature.
double temperature = 89;
if (this->myChannel != -1)
{
#ifdef DRAMPOWER
if (thermalSim && powerAnalysis)
{
// TODO
// check if this is best way to request information to DRAMPower.
unsigned long long clk_cycles = sc_time_stamp() / memSpec.tCK;
DRAMPower->calcWindowEnergy(clk_cycles);
float average_power = (float)DRAMPower->getPower().average_power;
temperature = temperatureController.getTemperature(this->myChannel, average_power);
} else {
temperature = temperatureController.getTemperature(this->myChannel, 0);
}
#else
temperature = temperatureController.getTemperature(this->myChannel, 0);
#endif
}
return temperature;
}
void errorModel::parseInputData(const Configuration& config)
{
std::string fileName = config.errorCSVFile;
std::ifstream inputFile(fileName);
if (inputFile.is_open()) {
std::string line;
while (std::getline(inputFile, line)) {
std::istringstream iss(line);
std::string str_temperature;
std::string str_retentionTime;
std::string str_mu_independent;
std::string str_sigma_independent;
std::string str_mu_dependent;
std::string str_sigma_dependent;
// Parse file:
iss >> str_temperature
>> str_retentionTime
>> str_mu_independent
>> str_sigma_independent
>> str_mu_dependent
>> str_sigma_dependent;
double temp = std::stod(str_temperature.c_str(), 0);
sc_time retentionTime = sc_time(std::stod(str_retentionTime.c_str(), 0),
SC_MS);
unsigned int mu_independent = std::stod(str_mu_independent.c_str(), 0);
unsigned int sigma_independent = std::stod(str_sigma_independent.c_str(), 0);
unsigned int mu_dependent = std::stod(str_mu_dependent.c_str(), 0);
unsigned int sigma_dependent = std::stod(str_sigma_dependent.c_str(), 0);
errors e;
//calculate normal distribution of # of independent errors
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
std::normal_distribution<double> distribution(mu_independent,
sigma_independent);
e.independent = ceil(distribution(generator));
// calculate normal distribution of # of dependent errors
unsigned seed2 = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator2(seed2);
std::normal_distribution<double> distribution2(mu_dependent, sigma_dependent);
e.dependent = ceil(distribution2(generator2));
// Store parsed data to the errorMap:
errorMap[temp][retentionTime] = e;
std::stringstream msg;
msg << "Temperature = " << temp
<< " Time = " << retentionTime
<< " independent = " << errorMap[temp][retentionTime].independent
<< " dependent = " << errorMap[temp][retentionTime].dependent;
PRINTDEBUGMESSAGE(name(), msg.str());
}
inputFile.close();
} else {
SC_REPORT_FATAL("errormodel", "Cannot open ErrorCSVFile");
}
}
void errorModel::prepareWeakCells()
{
// Get the Maxium number of weak cells by iterating over the errorMap:
maxNumberOfWeakCells = 0;
maxNumberOfDepWeakCells = 0;
for ( const auto &i : errorMap ) {
for ( const auto &j : i.second ) {
// Get number of dependent weak cells:
if ( j.second.dependent > maxNumberOfDepWeakCells) {
maxNumberOfDepWeakCells = j.second.dependent;
}
// Get the total number of weak cells (independet + dependent):
if ( j.second.independent + j.second.dependent > maxNumberOfWeakCells) {
maxNumberOfWeakCells = j.second.independent + j.second.dependent;
}
}
}
// Get the highest temperature in the error map:
maxTemperature = 0;
for ( const auto &i : errorMap ) {
if (i.first > maxTemperature) {
maxTemperature = i.first;
}
}
// Get the highest time in the error map:
maxTime = SC_ZERO_TIME;
for ( const auto &i : errorMap ) {
for ( const auto &j : i.second ) {
if (j.first > maxTime) {
maxTime = j.first;
}
}
}
// Generate weak cells:
weakCells = new weakCell[maxNumberOfWeakCells];
for (unsigned int i = 0; i < maxNumberOfWeakCells; i++) {
unsigned int row, col, bit;
// Select positions of weak cells randomly, uniformly distributed:
row = (unsigned int) (rand() % numberOfRows);
col = (unsigned int) (rand() % numberOfColumns);
bit = (unsigned int) (rand() % (bytesPerColumn * 8));
// Test if weak cell has been chosen already before:
bool found = false;
for (unsigned int k = 0; k < i; k++) {
if ((weakCells[k].row == row) && (weakCells[k].col == col)
&& (weakCells[k].bit == bit)) {
found = true;
break;
}
}
// If a cell was already choosen as weak we have to roll the dice again:
if (found) {
i--;
} else {
weakCells[i].row = row; // Row in the bank
weakCells[i].col = col; // Column in the row
weakCells[i].bit = bit; // Bit position in column
weakCells[i].flipped =
false; // Flag whether this position has already flipped
weakCells[i].dependent =
false; // init dependency flag with false, dependent cells will be estimated in the next step
}
}
// Generate dependent weak cells:
for (unsigned int i = 1; i <= maxNumberOfDepWeakCells; i++) {
unsigned int r = (rand() % maxNumberOfWeakCells);
// If the dependent weak cell was choosen before roll the dice again:
if (weakCells[r].dependent) {
i--;
} else {
weakCells[r].dependent = true;
}
}
// Debug output where the weak cells are located:
for (unsigned int i = 0; i < maxNumberOfWeakCells; i++) {
std::stringstream msg;
msg << "row=" << weakCells[i].row
<< " col=" << weakCells[i].col
<< " bit=" << weakCells[i].bit
<< " flip=" << weakCells[i].flipped
<< " dep=" << weakCells[i].dependent;
PRINTDEBUGMESSAGE(name(), msg.str());
}
}
// Retrieve number of flipping bits which fits best to temperature input and time since last refresh
unsigned int errorModel::getNumberOfFlips(double temp, sc_time time)
{
// Check if the provided temperature and retention time are in a valid
// range that is covered by the input data stored in the errorMap. In case
// of values out of the valid range the simulation will be aborted.
if (temp > maxTemperature) {
SC_REPORT_FATAL("errormodel", "temperature out of range");
}
if (time > maxTime) {
SC_REPORT_FATAL("errormodel", "time out of range");
}
// Find nearest temperature:
double nearestTemperature = 0;
for ( const auto &i : errorMap ) {
if (i.first >= temp) { // for worst case reasons we go to the next bin
nearestTemperature = i.first;
break;
}
}
// Find nearest time:
sc_time nearestTime;
for ( const auto &i : errorMap[nearestTemperature]) {
if (i.first >= time) { // for worst case reasons we go to the next bin
nearestTime = i.first;
break;
}
}
errors e = errorMap[nearestTemperature][nearestTime];
//std::stringstream msg;
//msg << "ACT/REF temp:" << temp
// << " time:" << time
// << " nearestTemp:" << nearestTemperature
// << " nearestTime:" << nearestTime
// << " ind:" << e.independent
// << " dep:" << e.dependent;
//printDebugMessage(msg.str());
return e.independent + e.dependent;
}
void errorModel::setContext(DecodedAddress addr)
{
// This function is called the first store ore load to get the context in
// which channel, rank or bank the error model is used.
if (myChannel == -1 && myBank == -1 && myBankgroup == -1 && myRank == -1 ) {
myChannel = addr.channel;
myBank = addr.bank;
myBankgroup = addr.bankgroup;
myRank = addr.rank;
contextStr = "Channel_" + std::to_string(myChannel) + "_Bank_" + std::to_string(
myBank) + " ";
}
}

View File

@@ -1,147 +0,0 @@
/*
* Copyright (c) 2015, 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:
* Matthias Jung
*/
#ifndef ERRORMODEL_H
#define ERRORMODEL_H
#include <map>
#include <systemc>
#include "../configuration/Configuration.h"
#include "../simulation/AddressDecoder.h"
#include "../simulation/TemperatureController.h"
class libDRAMPower;
class errorModel : public sc_core::sc_module
{
public:
errorModel(const sc_core::sc_module_name& name, const Configuration& config,
TemperatureController& temperatureController, libDRAMPower* dramPower = nullptr);
~errorModel() override;
// Access Methods:
void store(tlm::tlm_generic_payload &trans);
void load(tlm::tlm_generic_payload &trans);
void refresh(unsigned int row);
void activate(unsigned int row);
void setTemperature(double t);
double getTemperature();
private:
void init(const Configuration& config);
bool powerAnalysis;
libDRAMPower *DRAMPower;
bool thermalSim;
TemperatureController& temperatureController;
const MemSpec& memSpec;
// Configuration Parameters:
unsigned int burstLenght;
unsigned int numberOfColumns;
unsigned int bytesPerColumn;
unsigned int numberOfRows;
// context:
std::string contextStr;
// Online Parameters:
unsigned int numberOfBitErrorEvents;
// Private Methods:
void parseInputData(const Configuration& config);
void prepareWeakCells();
void markBitFlips();
unsigned int getNumberOfFlips(double temp, sc_core::sc_time time);
void setContext(DecodedAddress addr);
unsigned int getBit(DecodedAddress key, unsigned int byte,
unsigned int bitInByte);
unsigned int getBit(int row, int column, int byteInColumn, int bitInByte);
// Input related data structures:
struct errors {
double independent;
double dependent;
};
// temperature time number of errors
// | | |
std::map<double, std::map<sc_core::sc_time, errors> > errorMap;
unsigned int maxNumberOfWeakCells;
unsigned int maxNumberOfDepWeakCells;
double maxTemperature;
sc_core::sc_time maxTime;
// Storage of weak cells:
struct weakCell {
unsigned int row;
unsigned int col;
unsigned int bit;
bool flipped;
bool dependent;
};
weakCell *weakCells;
// To use a map for storing the data a comparing function must be defined
struct DecodedAddressComparer
{
bool operator() (const DecodedAddress &first ,
const DecodedAddress &second) const
{
if (first.row == second.row)
return first.column < second.column;
else
return first.row < second.row;
}
};
// The data structure stores complete column accesses
// A DRAM burst will be splitted up in several column accesses
// e.g. BL=4 means that 4 elements will be added to the dataMap!
std::map<DecodedAddress, unsigned char *, DecodedAddressComparer> dataMap;
// An array to save when the last ACT/REF to a row happened:
sc_core::sc_time *lastRowAccess;
// Context Variables (will be written by the first dram access)
int myChannel;
int myRank;
int myBankgroup;
int myBank;
};
#endif // ERRORMODEL_H

View File

@@ -1,185 +0,0 @@
/*
* Copyright (c) 2015, 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:
* Eder F. Zulian
* Matthias Jung
* Derek Christ
*/
#include <cmath>
#include "TemperatureController.h"
#include "../configuration/Configuration.h"
using namespace sc_core;
double TemperatureController::temperatureConvert(double tKelvin)
{
if (temperatureScale == TemperatureSimConfig::TemperatureScale::Celsius) {
return tKelvin - 273.15;
} else if (temperatureScale == TemperatureSimConfig::TemperatureScale::Fahrenheit) {
return (tKelvin - 273.15) * 1.8 + 32;
}
return tKelvin;
}
double TemperatureController::getTemperature(int deviceId, float currentPower)
{
PRINTDEBUGMESSAGE(name(), "Temperature requested by device " + std::to_string(
deviceId) + " current power is " + std::to_string(currentPower));
if (dynamicTempSimEnabled)
{
currentPowerValues.at(deviceId) = currentPower;
checkPowerThreshold(deviceId);
// FIXME: using the static temperature value until the vector of temperatures is filled
if (temperatureValues.empty())
return temperatureConvert(staticTemperature + 273.15);
return temperatureConvert(temperatureValues.at(deviceId));
}
else
{
PRINTDEBUGMESSAGE(name(), "Temperature is " + std::to_string(staticTemperature));
return staticTemperature;
}
}
void TemperatureController::updateTemperatures()
{
#ifdef THERMALSIM
thermalSimulation->sendPowerValues(&currentPowerValues);
thermalSimulation->simulate();
thermalSimulation->getTemperature(temperaturesBuffer, TDICE_OUTPUT_INSTANT_SLOT,
TDICE_OUTPUT_TYPE_TFLPEL, TDICE_OUTPUT_QUANTITY_AVERAGE);
std::string mapfile;
sc_time ts = sc_time_stamp();
if (genTempMap == true) {
mapfile = temperatureMapFile + "_" + std::to_string(ts.to_default_time_units())
+ ".txt";
thermalSimulation->getTemperatureMap(mapfile);
}
if (genPowerMap == true) {
mapfile = powerMapFile + "_" + std::to_string(ts.to_default_time_units()) +
".txt";
thermalSimulation->getPowerMap(mapfile);
}
#endif
// Save values just obtained for posterior use
temperatureValues = temperaturesBuffer;
// Clear the buffer, otherwise it will grow every request
temperaturesBuffer.clear();
}
void TemperatureController::checkPowerThreshold(int deviceId)
{
if (std::abs(lastPowerValues.at(deviceId) - currentPowerValues.at(
deviceId)) > powerThresholds.at(deviceId)) {
decreaseSimPeriod = true;
}
lastPowerValues.at(deviceId) = currentPowerValues.at(deviceId);
}
double TemperatureController::adjustThermalSimPeriod()
{
// Temperature Simulation Period Dynamic Adjustment
//
// 1. Adjustment is requierd when:
//
// 1.1. The power dissipation of one or more devices change considerably
// (exceeds the configured threshold for that device in any direction,
// i.e. increases or decreases substantially) during the current
// simulaiton period.
//
// 1.1.1. The simulation period will be reduced by a factor of 'n' so the
// simulation occurs 'n' times more often.
//
// 1.1.2. The step 1.1.1 will be repeated until the point that there are
// no sustantial changes in power dissipation between two consecutive
// executions of the thermal simulation, i.e. all changes for all devices
// are less than the configured threshold.
//
// 1.2. The current simulation period differs from the target period
// defined in the configuration by the user.
//
// 1.2.1 Provided a scenario in which power dissipation changes do not
// exceed the thresholds, the situation period will be kept for a number
// of simulation cycles 'nc' and after 'nc' the period will be increased
// again in steps of 'n/2' until it achieves the desired value given by
// configuration or the described in 1.1 occurs.
if (decreaseSimPeriod)
{
period = period / periodAdjustFactor;
cyclesSinceLastPeriodAdjust = 0;
decreaseSimPeriod = false;
PRINTDEBUGMESSAGE(name(), "Thermal Simulation period reduced to " + std::to_string(
period) + ". Target is " + std::to_string(targetPeriod));
}
else
{
if (period != targetPeriod) {
cyclesSinceLastPeriodAdjust++;
if (cyclesSinceLastPeriodAdjust >= nPowStableCyclesToIncreasePeriod) {
cyclesSinceLastPeriodAdjust = 0;
period = period * ((double)periodAdjustFactor / 2);
if (period > targetPeriod)
period = targetPeriod;
PRINTDEBUGMESSAGE(name(), "Thermal Simulation period increased to "
+ std::to_string(period) + ". Target is " + std::to_string(targetPeriod));
}
}
}
return period;
}
void TemperatureController::temperatureThread()
{
while (true)
{
updateTemperatures();
double p = adjustThermalSimPeriod();
NDEBUG_UNUSED(int i) = 0;
for (NDEBUG_UNUSED(auto t) : temperatureValues) {
PRINTDEBUGMESSAGE(name(), "Temperature[" + std::to_string(i++)
+ "] is " + std::to_string(t));
}
PRINTDEBUGMESSAGE(name(), "Thermal simulation period is " + std::to_string(p));
wait(sc_time(p, t_unit));
}
}

View File

@@ -1,151 +0,0 @@
/*
* Copyright (c) 2015, 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:
* Eder F. Zulian
* Matthias Jung
* Derek Christ
*/
#ifndef TEMPERATURECONTROLLER_H
#define TEMPERATURECONTROLLER_H
#include <string>
#include <systemc>
#include "../common/DebugManager.h"
#include "../common/utils.h"
#include "../configuration/Configuration.h"
#ifdef THERMALSIM
#include "IceWrapper.h"
#endif
class TemperatureController : sc_core::sc_module
{
public:
TemperatureController(const TemperatureController&) = delete;
TemperatureController& operator=(const TemperatureController&) = delete;
SC_HAS_PROCESS(TemperatureController);
TemperatureController() = default;
TemperatureController(const sc_core::sc_module_name& name, const Configuration& config) : sc_core::sc_module(name)
{
temperatureScale = config.temperatureSim.temperatureScale;
dynamicTempSimEnabled = config.thermalSimulation;
staticTemperature = config.temperatureSim.staticTemperatureDefaultValue;
if (dynamicTempSimEnabled)
{
#ifdef THERMALSIM
// Connect to the server
std::string ip = config.temperatureSim.iceServerIp;
unsigned int port = config.temperatureSim.iceServerPort;
thermalSimulation = new IceWrapper(ip, port);
PRINTDEBUGMESSAGE(name(), "Dynamic temperature simulation. Server @ "
+ ip + ":" + std::to_string(port));
#else
SC_REPORT_FATAL(sc_module::name(),
"DRAMSys was build without support to dynamic temperature simulation. Check the README file for further details.");
#endif
// Initial power dissipation values (got from config)
currentPowerValues = config.temperatureSim.powerInitialValues;
lastPowerValues = currentPowerValues;
// Substantial changes in power will trigger adjustments in the simulaiton period. Get the thresholds from config.
powerThresholds = config.temperatureSim.powerThresholds;
decreaseSimPeriod = false;
periodAdjustFactor = config.temperatureSim.simPeriodAdjustFactor;
nPowStableCyclesToIncreasePeriod = config.temperatureSim.nPowStableCyclesToIncreasePeriod;
cyclesSinceLastPeriodAdjust = 0;
// Get the target period for the thermal simulation from config.
targetPeriod = config.temperatureSim.thermalSimPeriod;
period = targetPeriod;
t_unit = config.temperatureSim.thermalSimUnit;
genTempMap = config.temperatureSim.generateTemperatureMap;
temperatureMapFile = "temperature_map";
std::system("rm -f temperature_map*");
genPowerMap = config.temperatureSim.generatePowerMap;
powerMapFile = "power_map";
std::system("rm -f power_map*");
SC_THREAD(temperatureThread);
}
else
{
PRINTDEBUGMESSAGE(sc_module::name(), "Static temperature simulation. Temperature set to " +
std::to_string(staticTemperature));
}
}
double getTemperature(int deviceId, float currentPower);
private:
TemperatureSimConfig::TemperatureScale temperatureScale;
double temperatureConvert(double tKelvin);
double staticTemperature;
bool dynamicTempSimEnabled;
#ifdef THERMALSIM
IceWrapper *thermalSimulation;
#endif
std::vector<float> temperaturesBuffer;
std::vector<float> temperatureValues;
std::vector<float> currentPowerValues;
std::vector<float> lastPowerValues;
std::vector<float> powerThresholds;
double targetPeriod;
double period;
enum sc_core::sc_time_unit t_unit;
void temperatureThread();
void updateTemperatures();
double adjustThermalSimPeriod();
void checkPowerThreshold(int deviceId);
bool decreaseSimPeriod;
unsigned int periodAdjustFactor;
unsigned int cyclesSinceLastPeriodAdjust;
unsigned int nPowStableCyclesToIncreasePeriod;
bool genTempMap;
std::string temperatureMapFile;
bool genPowerMap;
std::string powerMapFile;
};
#endif // TEMPERATURECONTROLLER_H

View File

@@ -1,238 +0,0 @@
/*
* Copyright (c) 2016, 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:
* Eder F. Zulian
*/
#ifndef EXAMPLEINITIATOR_H
#define EXAMPLEINITIATOR_H
#include <cstdlib>
#include <iostream>
#include <systemc>
#include "MemoryManager.h"
#include "common/dramExtensions.h"
#include "TracePlayer.h"
struct ExampleInitiator : sc_core::sc_module
{
// TLM-2 socket, defaults to 32-bits wide, base protocol
tlm_utils::simple_initiator_socket<ExampleInitiator> socket;
SC_CTOR(ExampleInitiator)
: socket("socket"),
request_in_progress(nullptr),
m_peq(this, &ExampleInitiator::peq_cb)
{
socket.register_nb_transport_bw(this, &ExampleInitiator::nb_transport_bw);
SC_THREAD(thread_process);
}
void thread_process()
{
tlm::tlm_generic_payload *trans;
tlm::tlm_phase phase;
sc_core::sc_time delay;
dump_mem();
init_mem();
dump_mem();
for (unsigned char &i : data)
i = 0x55;
// Generate 2 write transactions
for (int i = 0; i < 2; i++) {
int adr = i * 64;
tlm::tlm_command cmd = tlm::TLM_WRITE_COMMAND;
// Grab a new transaction from the memory manager
trans = m_mm.allocate();
trans->acquire();
trans->set_command(cmd);
trans->set_address(adr);
trans->set_data_ptr(reinterpret_cast<unsigned char *>(&data[0]));
trans->set_data_length(64);
trans->set_streaming_width(4);
trans->set_byte_enable_ptr(nullptr);
trans->set_dmi_allowed(false);
trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
// ExampleInitiator must honor BEGIN_REQ/END_REQ exclusion rule
if (request_in_progress)
wait(end_request_event);
request_in_progress = trans;
phase = tlm::BEGIN_REQ;
// Timing annotation models processing time of initiator prior to call
delay = sc_core::sc_time(100000, sc_core::SC_PS);
std::cout << "Address " << std::hex << adr << " new, cmd=" << (cmd ? "write" : "read")
<< ", data=" << std::hex << data[0] << " at time " << sc_core::sc_time_stamp()
<< " in " << name() << std::endl;
GenerationExtension *genExtension = new GenerationExtension(sc_core::sc_time_stamp());
trans->set_auto_extension(genExtension);
// Non-blocking transport call on the forward path
tlm::tlm_sync_enum status;
status = socket->nb_transport_fw( *trans, phase, delay );
// Check value returned from nb_transport_fw
if (status == tlm::TLM_UPDATED) {
// The timing annotation must be honored
m_peq.notify( *trans, phase, delay );
} else if (status == tlm::TLM_COMPLETED) {
// The completion of the transaction necessarily ends the BEGIN_REQ phase
request_in_progress = nullptr;
// The target has terminated the transaction
check_transaction( *trans );
// Allow the memory manager to free the transaction object
trans->release();
}
sc_core::wait(sc_core::sc_time(500, sc_core::SC_NS));
dump_mem();
}
sc_core::wait(sc_core::sc_time(500, sc_core::SC_NS));
sc_core::sc_stop();
}
static void init_mem()
{
unsigned char buffer[64];
for (unsigned char &i : buffer)
i = 0xff;
for (int addr = 0; addr < 128; addr += 64) {
tlm::tlm_generic_payload trans;
trans.set_command( tlm::TLM_WRITE_COMMAND );
trans.set_address( addr );
trans.set_data_ptr( buffer );
trans.set_data_length( 64 );
socket->transport_dbg( trans );
}
}
static void dump_mem()
{
for (int addr = 0; addr < 128; addr += 64) {
unsigned char buffer[64];
tlm::tlm_generic_payload trans;
trans.set_command( tlm::TLM_READ_COMMAND );
trans.set_address( addr );
trans.set_data_ptr( buffer );
trans.set_data_length( 64 );
socket->transport_dbg( trans );
std::cout << "\nMemory dump\n";
for (int i = 0; i < 64; i++)
std::cout << "mem[" << addr + i << "] = " << std::hex << (int)buffer[i] << std::endl;
}
}
// TLM-2 backward non-blocking transport method
virtual tlm::tlm_sync_enum nb_transport_bw( tlm::tlm_generic_payload &trans,
tlm::tlm_phase &phase, sc_core::sc_time &delay )
{
m_peq.notify( trans, phase, delay );
return tlm::TLM_ACCEPTED;
}
// Payload event queue callback to handle transactions from target
// Transaction could have arrived through return path or backward path
void peq_cb(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase)
{
if (phase == tlm::END_REQ || (&trans == request_in_progress
&& phase == tlm::BEGIN_RESP)) {
// The end of the BEGIN_REQ phase
request_in_progress = nullptr;
end_request_event.notify();
} else if (phase == tlm::BEGIN_REQ || phase == tlm::END_RESP)
SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by initiator");
if (phase == tlm::BEGIN_RESP) {
check_transaction( trans );
// Send final phase transition to target
tlm::tlm_phase fw_phase = tlm::END_RESP;
sc_core::sc_time delay = sc_core::sc_time(60000, sc_core::SC_PS);
socket->nb_transport_fw( trans, fw_phase, delay );
// Ignore return value
// Allow the memory manager to free the transaction object
trans.release();
}
}
// Called on receiving BEGIN_RESP or TLM_COMPLETED
void check_transaction(tlm::tlm_generic_payload &trans)
{
if ( trans.is_response_error() ) {
char txt[100];
sprintf(txt, "Transaction returned with error, response status = %s",
trans.get_response_string().c_str());
SC_REPORT_ERROR("TLM-2", txt);
}
tlm::tlm_command cmd = trans.get_command();
uint64_t adr = trans.get_address();
int *ptr = reinterpret_cast<int *>( trans.get_data_ptr() );
std::cout << std::hex << adr << " check, cmd=" << (cmd ? "write" : "read")
<< ", data=" << std::hex << *ptr << " at time " << sc_core::sc_time_stamp()
<< " in " << sc_core::name() << std::endl;
if (cmd == tlm::TLM_READ_COMMAND)
assert( *ptr == -int(adr) );
}
MemoryManager m_mm;
unsigned char data[64];
tlm::tlm_generic_payload *request_in_progress;
sc_core::sc_event end_request_event;
tlm_utils::peq_with_cb_and_phase<ExampleInitiator> m_peq;
};
#endif // EXAMPLEINITIATOR_H

View File

@@ -1,238 +0,0 @@
/*
* Copyright (c) 2022, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Lukas Steiner
*/
#include "LengthConverter.h"
using namespace sc_core;
using namespace tlm;
// TODO: return status, TLM_INCOMPLETE_RESPONSE, acquire + release
LengthConverter::LengthConverter(const sc_module_name &name, unsigned maxOutputLength, bool storageEnabled) :
sc_module(name), payloadEventQueue(this, &LengthConverter::peqCallback), storageEnabled(storageEnabled),
memoryManager(storageEnabled, maxOutputLength), maxOutputLength(maxOutputLength)
{
iSocket.register_nb_transport_bw(this, &LengthConverter::nb_transport_bw);
tSocket.register_nb_transport_fw(this, &LengthConverter::nb_transport_fw);
tSocket.register_transport_dbg(this, &LengthConverter::transport_dbg);
}
tlm_sync_enum LengthConverter::nb_transport_fw(tlm_generic_payload& trans,
tlm_phase& phase, sc_time& fwDelay)
{
if (phase == BEGIN_REQ)
trans.acquire();
payloadEventQueue.notify(trans, phase, fwDelay);
return TLM_ACCEPTED;
}
tlm_sync_enum LengthConverter::nb_transport_bw(tlm_generic_payload &payload,
tlm_phase &phase, sc_time &bwDelay)
{
payloadEventQueue.notify(payload, phase, bwDelay);
return TLM_ACCEPTED;
}
unsigned int LengthConverter::transport_dbg(tlm_generic_payload &trans)
{
return iSocket->transport_dbg(trans);
}
void LengthConverter::peqCallback(tlm_generic_payload &cbTrans, const tlm_phase &cbPhase)
{
if (cbPhase == BEGIN_REQ) // from initiator
{
if (cbTrans.get_data_length() <= maxOutputLength)
{
// pipe transaction through
tlm_phase fwPhase = BEGIN_REQ;
sc_time fwDelay = SC_ZERO_TIME;
tlm_sync_enum returnStatus = iSocket->nb_transport_fw(cbTrans, fwPhase, fwDelay);
// TODO: END_REQ/BEGIN_RESP shortcut
}
else
{
// split transaction up into multiple sub-transactions
createChildTranses(&cbTrans);
tlm_generic_payload* firstChildTrans = cbTrans.get_extension<ParentExtension>()->getNextChildTrans();
tlm_phase fwPhase = BEGIN_REQ;
sc_time fwDelay = SC_ZERO_TIME;
tlm_sync_enum returnStatus = iSocket->nb_transport_fw(*firstChildTrans, fwPhase, fwDelay);
}
}
else if (cbPhase == END_REQ)
{
if (ChildExtension::isChildTrans(&cbTrans))
{
tlm_generic_payload* nextChildTrans = cbTrans.get_extension<ChildExtension>()->getNextChildTrans();
if (nextChildTrans != nullptr)
{
tlm_phase fwPhase = BEGIN_REQ;
//sc_time fwDelay = SC_ZERO_TIME;
sc_time fwDelay = sc_time(1, SC_NS);
tlm_sync_enum returnStatus = iSocket->nb_transport_fw(*nextChildTrans, fwPhase, fwDelay);
}
else
{
tlm_generic_payload* parentTrans = cbTrans.get_extension<ChildExtension>()->getParentTrans();
tlm_phase bwPhase = END_REQ;
sc_time bwDelay = SC_ZERO_TIME;
tlm_sync_enum returnStatus = tSocket->nb_transport_bw(*parentTrans, bwPhase, bwDelay);
}
}
else
{
tlm_phase bwPhase = END_REQ;
sc_time bwDelay = SC_ZERO_TIME;
tlm_sync_enum returnStatus = tSocket->nb_transport_bw(cbTrans, bwPhase, bwDelay);
}
}
else if (cbPhase == BEGIN_RESP)
{
if (ChildExtension::isChildTrans(&cbTrans))
{
{
tlm_phase fwPhase = END_RESP;
sc_time fwDelay = SC_ZERO_TIME;
tlm_sync_enum returnStatus = iSocket->nb_transport_fw(cbTrans, fwPhase, fwDelay);
}
if (storageEnabled && cbTrans.is_read())
{
tlm_generic_payload* parentTrans = cbTrans.get_extension<ChildExtension>()->getParentTrans();
std::copy(cbTrans.get_data_ptr(), cbTrans.get_data_ptr() + maxOutputLength,
parentTrans->get_data_ptr() + (cbTrans.get_address() - parentTrans->get_address()));
}
if (cbTrans.get_extension<ChildExtension>()->notifyChildTransCompletion()) // all children finished
{
// BEGIN_RESP über tSocket
tlm_generic_payload* parentTrans = cbTrans.get_extension<ChildExtension>()->getParentTrans();
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay = SC_ZERO_TIME;
parentTrans->set_response_status(tlm::TLM_OK_RESPONSE);
tlm_sync_enum returnStatus = tSocket->nb_transport_bw(*parentTrans, bwPhase, bwDelay);
}
}
else
{
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay = SC_ZERO_TIME;
cbTrans.set_response_status(tlm::TLM_OK_RESPONSE);
tlm_sync_enum returnStatus = tSocket->nb_transport_bw(cbTrans, bwPhase, bwDelay);
}
}
else if (cbPhase == END_RESP)
{
if (ParentExtension::isParentTrans(&cbTrans))
{
cbTrans.get_extension<ParentExtension>()->releaseChildTranses();
}
else
{
tlm_phase fwPhase = END_RESP;
sc_time fwDelay = SC_ZERO_TIME;
tlm_sync_enum returnStatus = iSocket->nb_transport_fw(cbTrans, fwPhase, fwDelay);
}
cbTrans.release();
}
else
SC_REPORT_FATAL(0, "Payload event queue in LengthConverter was triggered with unknown phase");
}
void LengthConverter::createChildTranses(tlm_generic_payload* parentTrans)
{
unsigned numChildTranses = parentTrans->get_data_length() / maxOutputLength;
std::vector<tlm_generic_payload*> childTranses;
for (unsigned childId = 0; childId < numChildTranses; childId++)
{
tlm_generic_payload* childTrans = memoryManager.allocate();
childTrans->acquire();
childTrans->set_command(parentTrans->get_command());
childTrans->set_address(parentTrans->get_address() + childId * maxOutputLength);
childTrans->set_data_length(maxOutputLength);
if (storageEnabled && parentTrans->is_write())
std::copy(parentTrans->get_data_ptr() + childId * maxOutputLength, parentTrans->get_data_ptr() +
(childId + 1) * maxOutputLength, childTrans->get_data_ptr());
ChildExtension::setExtension(childTrans, parentTrans);
childTranses.push_back(childTrans);
}
ParentExtension::setExtension(parentTrans, std::move(childTranses));
}
LengthConverter::MemoryManager::MemoryManager(bool storageEnabled, unsigned maxDataLength)
: storageEnabled(storageEnabled), maxDataLength(maxDataLength)
{}
LengthConverter::MemoryManager::~MemoryManager()
{
while (!freePayloads.empty())
{
tlm_generic_payload* payload = freePayloads.top();
if (storageEnabled)
delete[] payload->get_data_ptr();
payload->reset();
delete payload;
freePayloads.pop();
}
}
tlm_generic_payload* LengthConverter::MemoryManager::allocate()
{
if (freePayloads.empty())
{
auto* payload = new tlm_generic_payload(this);
if (storageEnabled)
{
auto* data = new unsigned char[maxDataLength];
payload->set_data_ptr(data);
}
return payload;
}
else
{
tlm_generic_payload* result = freePayloads.top();
freePayloads.pop();
return result;
}
}
void LengthConverter::MemoryManager::free(tlm_generic_payload* payload)
{
freePayloads.push(payload);
}

View File

@@ -1,233 +0,0 @@
/*
* Copyright (c) 2022, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Lukas Steiner
*/
#ifndef LENGTHCONVERTER_H
#define LENGTHCONVERTER_H
#include <iostream>
#include <utility>
#include <vector>
#include <queue>
#include <set>
#include <unordered_map>
#include <stack>
#include <tlm>
#include <systemc>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
#include <tlm_utils/peq_with_cb_and_phase.h>
//TLM_DECLARE_EXTENDED_PHASE(REQ_ARBITRATION);
//TLM_DECLARE_EXTENDED_PHASE(RESP_ARBITRATION);
class LengthConverter : public sc_core::sc_module
{
public:
tlm_utils::simple_initiator_socket<LengthConverter> iSocket;
tlm_utils::simple_target_socket<LengthConverter> tSocket;
LengthConverter(const sc_core::sc_module_name& name, unsigned maxOutputLength, bool storageEnabled);
SC_HAS_PROCESS(LengthConverter);
private:
tlm_utils::peq_with_cb_and_phase<LengthConverter> payloadEventQueue;
void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase);
//std::vector<bool> tSocketIsBusy;
//std::vector<bool> iSocketIsBusy;
const unsigned maxOutputLength;
const bool storageEnabled;
void createChildTranses(tlm::tlm_generic_payload* parentTrans);
//std::uint64_t getTargetAddress(std::uint64_t address) const;
//int getISocketId(std::uint64_t address) const;
//std::vector<std::queue<tlm::tlm_generic_payload *>> pendingRequests;
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase,
sc_core::sc_time &fwDelay);
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase,
sc_core::sc_time &bwDelay);
unsigned int transport_dbg(tlm::tlm_generic_payload &trans);
class MemoryManager : public tlm::tlm_mm_interface
{
public:
MemoryManager(bool storageEnabled, unsigned maxDataLength);
~MemoryManager() override;
tlm::tlm_generic_payload* allocate();
void free(tlm::tlm_generic_payload* payload) override;
private:
std::stack<tlm::tlm_generic_payload*> freePayloads;
bool storageEnabled = false;
unsigned maxDataLength;
} memoryManager;
class ChildExtension : public tlm::tlm_extension<ChildExtension>
{
private:
tlm::tlm_generic_payload* parentTrans;
explicit ChildExtension(tlm::tlm_generic_payload* parentTrans) : parentTrans(parentTrans) {}
public:
//ChildExtension() = delete;
tlm_extension_base* clone() const override
{
return new ChildExtension(parentTrans);
}
void copy_from(tlm_extension_base const &ext) override
{
const auto& cpyFrom = dynamic_cast<const ChildExtension&>(ext);
parentTrans = cpyFrom.parentTrans;
}
tlm::tlm_generic_payload* getParentTrans()
{
return parentTrans;
}
static void setExtension(tlm::tlm_generic_payload* childTrans, tlm::tlm_generic_payload* parentTrans)
{
auto *extension = childTrans->get_extension<ChildExtension>();
if (extension != nullptr)
{
extension->parentTrans = parentTrans;
}
else
{
extension = new ChildExtension(parentTrans);
childTrans->set_auto_extension(extension);
}
}
static bool isChildTrans(const tlm::tlm_generic_payload* trans)
{
if (trans->get_extension<ChildExtension>() != nullptr)
return true;
else
return false;
}
tlm::tlm_generic_payload* getNextChildTrans()
{
return parentTrans->get_extension<ParentExtension>()->getNextChildTrans();
}
bool notifyChildTransCompletion()
{
return parentTrans->get_extension<ParentExtension>()->notifyChildTransCompletion();
}
};
class ParentExtension : public tlm::tlm_extension<ParentExtension>
{
private:
std::vector<tlm::tlm_generic_payload*> childTranses;
unsigned nextEndReqChildId = 0;
unsigned completedChildTranses = 0;
explicit ParentExtension(std::vector<tlm::tlm_generic_payload*> _childTranses)
: childTranses(std::move(_childTranses)) {}
public:
ParentExtension() = delete;
tlm_extension_base* clone() const override
{
return new ParentExtension(childTranses);
}
void copy_from(tlm_extension_base const &ext) override
{
const auto& cpyFrom = dynamic_cast<const ParentExtension&>(ext);
childTranses = cpyFrom.childTranses;
}
static bool isParentTrans(const tlm::tlm_generic_payload* trans)
{
auto* extension = trans->get_extension<ParentExtension>();
if (extension != nullptr)
return !extension->childTranses.empty();
else
return false;
}
static void setExtension(tlm::tlm_generic_payload* parentTrans, std::vector<tlm::tlm_generic_payload*> childTranses)
{
auto* extension = parentTrans->get_extension<ParentExtension>();
if (extension != nullptr)
{
extension->childTranses = std::move(childTranses);
extension->nextEndReqChildId = 0;
extension->completedChildTranses = 0;
}
else
{
extension = new ParentExtension(std::move(childTranses));
parentTrans->set_auto_extension(extension);
}
}
tlm::tlm_generic_payload* getNextChildTrans()
{
if (nextEndReqChildId < childTranses.size())
return childTranses[nextEndReqChildId++];
else
return nullptr;
}
bool notifyChildTransCompletion()
{
completedChildTranses++;
return completedChildTranses == childTranses.size();
}
void releaseChildTranses()
{
std::for_each(childTranses.begin(), childTranses.end(),
[](tlm::tlm_generic_payload* childTrans){childTrans->release();});
childTranses.clear();
}
};
};
#endif // LENGTHCONVERTER_H

View File

@@ -1,29 +0,0 @@
# DDR3 Dual Rank Test with Staggered Power Down Policy and Scheduler FrFcfsGrp
example_DDR3:
stage: test_DDR3
script:
- export GCOV_PREFIX=$(pwd)
- export GCOV_PREFIX_STRIP=$(pwd | awk -F"/" '{print NF-1}')
- cd build/simulator
- ./DRAMSys ../../DRAMSys/tests/DDR3/simulations/ddr3-example.json ../../DRAMSys/tests/DDR3/
- mv DRAMSys_ddr3-dual-rank_ddr3_ch0.tdb ddr3-dual-rank_ddr3_ch0.tdb
- ls -lah
- ls -lah ../../DRAMSys/tests/DDR3/expected/
- sqldiff ../../DRAMSys/tests/DDR3/expected/ddr3-dual-rank_ddr3_ch0.tdb ddr3-dual-rank_ddr3_ch0.tdb
- perl -e 'if(`sqldiff --table Phases ../../DRAMSys/tests/DDR3/expected/ddr3-dual-rank_ddr3_ch0.tdb ddr3-dual-rank_ddr3_ch0.tdb` eq "") {exit(0)} else {exit(-1)}'
- perl -e 'if(`sqldiff --table Transactions ../../DRAMSys/tests/DDR3/expected/ddr3-dual-rank_ddr3_ch0.tdb ddr3-dual-rank_ddr3_ch0.tdb` eq "") {exit(0)} else {exit(-1)}'
- perl -e 'if(`sqldiff --table Power ../../DRAMSys/tests/DDR3/expected/ddr3-dual-rank_ddr3_ch0.tdb ddr3-dual-rank_ddr3_ch0.tdb` eq "") {exit(0)} else {exit(-1)}'
# Run Code Coverage
- lcov -q -c --rc geninfo_adjust_src_path=$GCOV_PREFIX -d ${CI_PROJECT_DIR}/build/ -o ${CI_PROJECT_DIR}/coverage/${CI_JOB_NAME}.out
cache:
key: build
paths:
- build/
policy: pull
artifacts:
paths:
- build/simulator/ddr3-dual-rank_ddr3_ch0.tdb
- coverage/${CI_JOB_NAME}.out
expire_in: 2 days

View File

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

View File

@@ -1,14 +0,0 @@
{
"mcconfig": {
"PagePolicy": "Open",
"Scheduler": "FrFcfsGrp",
"RequestBufferSize": 8,
"CmdMux": "Oldest",
"RespQueue": "Fifo",
"RefreshPolicy": "Rankwise",
"RefreshMaxPostponed": 0,
"RefreshMaxPulledin": 0,
"PowerDownPolicy": "Staggered",
"PowerDownTimeout": 100
}
}

View File

@@ -1,61 +0,0 @@
{
"memspec": {
"memarchitecturespec": {
"burstLength": 8,
"dataRate": 2,
"nbrOfBanks": 8,
"nbrOfColumns": 1024,
"nbrOfRanks": 2,
"nbrOfChannels": 1,
"nbrOfRows": 16384,
"width": 64,
"nbrOfDevices": 1
},
"memoryId": "MICRON_2GB_DDR3-1066_64bit_D_SODIMM",
"memoryType": "DDR3",
"mempowerspec": {
"idd0": 720.0,
"idd2n": 400.0,
"idd2p0": 80.0,
"idd2p1": 200.0,
"idd3n": 440.0,
"idd3p0": 240.0,
"idd3p1": 240.0,
"idd4r": 1200.0,
"idd4w": 1200.0,
"idd5": 1760.0,
"idd6": 48.0,
"vdd": 1.5
},
"memtimingspec": {
"AL": 0,
"CCD": 4,
"CKE": 3,
"CKESR": 4,
"CL": 7,
"DQSCK": 0,
"FAW": 20,
"RAS": 20,
"RC": 27,
"RCD": 7,
"REFI": 4160,
"RFC": 59,
"RL": 7,
"RP": 7,
"RRD": 4,
"RTP": 4,
"WL": 6,
"WR": 8,
"WTR": 4,
"XP": 4,
"XPDLL": 13,
"XS": 64,
"XSDLL": 512,
"ACTPDEN": 1,
"PRPDEN": 1,
"REFPDEN": 1,
"RTRS": 1,
"clkMhz": 533
}
}
}

View File

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

View File

@@ -1,15 +0,0 @@
{
"thermalsimconfig": {
"TemperatureScale": "Celsius",
"StaticTemperatureDefaultValue": 89,
"ThermalSimPeriod":100,
"ThermalSimUnit":"us",
"PowerInfoFile": "powerInfo.json",
"IceServerIp": "127.0.0.1",
"IceServerPort": 11880,
"SimPeriodAdjustFactor" : 10,
"NPowStableCyclesToIncreasePeriod": 5,
"GenerateTemperatureMap": true,
"GeneratePowerMap": true
}
}

View File

@@ -1,45 +0,0 @@
CPUs :
position 0, 0 ;
dimension 2750, 4300 ;
GPU :
position 3350, 0 ;
dimension 2750, 4000 ;
BASEBAND1 :
position 4250, 4000 ;
dimension 1850, 3300 ;
BASEBAND2 :
position 3350, 7300 ;
dimension 2750, 3300 ;
LLCACHE :
position 0, 4300 ;
dimension 1900, 3000 ;
DRAMCTRL1 :
position 1900, 4300 ;
dimension 850, 3000 ;
DRAMCTRL2 :
position 3350, 4000 ;
dimension 900, 3300 ;
TSVS :
position 2750, 2300 ;
dimension 600, 6000 ;
ACELLERATORS :
position 0, 7300 ;
dimension 2750, 3300 ;

View File

@@ -1,16 +0,0 @@
channel0 :
position 150, 100 ;
dimension 2600, 5200 ;
channel1 :
position 3350, 100 ;
dimension 2600, 5200 ;
channel2 :
position 150, 5300 ;
dimension 2600, 5200 ;
channel3 :
position 3350, 5300 ;
dimension 2600, 5200 ;

View File

@@ -1,20 +0,0 @@
{
"powerInfo": {
"dram_die_channel0": {
"init_pow": 0,
"threshold": 1.0
},
"dram_die_channel1": {
"init_pow": 0,
"threshold": 1.0
},
"dram_die_channel2": {
"init_pow": 0,
"threshold": 1.0
},
"dram_die_channel3": {
"init_pow": 0,
"threshold": 1.0
}
}
}

View File

@@ -1,49 +0,0 @@
material SILICON :
thermal conductivity 1.30e-4 ;
volumetric heat capacity 1.628e-12 ;
material BEOL :
thermal conductivity 2.25e-6 ;
volumetric heat capacity 2.175e-12 ;
material COPPER :
thermal conductivity 4.01e-04 ;
volumetric heat capacity 3.37e-12 ;
top heat sink :
//sink height 1e03, area 100e06, material COPPER ;
//spreader height 0.5e03, area 70e06, material SILICON ;
heat transfer coefficient 1.3e-09 ;
temperature 318.15 ;
dimensions :
chip length 6100, width 10600 ;
cell length 100, width 100 ;
layer PCB :
height 10 ;
material BEOL ;
die DRAM :
layer 58.5 SILICON ;
source 2 SILICON ;
layer 1.5 BEOL ;
layer 58.5 SILICON ;
stack:
die DRAM_DIE DRAM floorplan "./mem.flp" ;
layer CONN_TO_PCB PCB ;
solver:
transient step 0.01, slot 0.05 ;
initial temperature 300.0 ;
output:
Tflpel(DRAM_DIE.channel0 , "temp_flp_element_ch0.txt" , average , slot );
Tflpel(DRAM_DIE.channel1 , "temp_flp_element_ch1.txt" , average , slot );
Tflpel(DRAM_DIE.channel2 , "temp_flp_element_ch2.txt" , average , slot );
Tflpel(DRAM_DIE.channel3 , "temp_flp_element_ch3.txt" , average , slot );
Tmap (DRAM_DIE, "output1.txt", slot) ;
Pmap (DRAM_DIE, "output2.txt", slot) ;

View File

@@ -1,16 +0,0 @@
{
"simulation": {
"addressmapping": "am_ddr3_8x2Gbx8_dimm_p1KB_dual_rank_rbc.json",
"mcconfig": "fr_fcfs_grp.json",
"memspec": "MICRON_2GB_DDR3-1066_64bit_D_SODIMM.json",
"simconfig": "ddr3.json",
"simulationid": "ddr3-dual-rank",
"thermalconfig": "config.json",
"tracesetup": [
{
"clkMhz": 533,
"name": "trace_test2.stl"
}
]
}
}

View File

@@ -1,29 +0,0 @@
# DDR4 with 4 bank groups, flexible rankwise refresh and FrFcfs scheduler:
example_DDR4:
stage: test_DDR4
script:
- export GCOV_PREFIX=$(pwd)
- export GCOV_PREFIX_STRIP=$(pwd | awk -F"/" '{print NF-1}')
- cd build/simulator
- ./DRAMSys ../../DRAMSys/tests/DDR4/simulations/ddr4-example.json ../../DRAMSys/tests/DDR4/
- mv DRAMSys_ddr4-bankgrp_ddr4_ch0.tdb ddr4-bankgrp_ddr4_ch0.tdb
- ls -lah
- ls -lah ../../DRAMSys/tests/DDR4/expected/
- sqldiff ../../DRAMSys/tests/DDR4/expected/ddr4-bankgrp_ddr4_ch0.tdb ddr4-bankgrp_ddr4_ch0.tdb
- perl -e 'if(`sqldiff --table Phases ../../DRAMSys/tests/DDR4/expected/ddr4-bankgrp_ddr4_ch0.tdb ddr4-bankgrp_ddr4_ch0.tdb` eq "") {exit(0)} else {exit(-1)}'
- perl -e 'if(`sqldiff --table Transactions ../../DRAMSys/tests/DDR4/expected/ddr4-bankgrp_ddr4_ch0.tdb ddr4-bankgrp_ddr4_ch0.tdb` eq "") {exit(0)} else {exit(-1)}'
- perl -e 'if(`sqldiff --table Power ../../DRAMSys/tests/DDR4/expected/ddr4-bankgrp_ddr4_ch0.tdb ddr4-bankgrp_ddr4_ch0.tdb` eq "") {exit(0)} else {exit(-1)}'
# Run Code Coverage
- lcov -q -c --rc geninfo_adjust_src_path=$GCOV_PREFIX -d ${CI_PROJECT_DIR}/build/ -o ${CI_PROJECT_DIR}/coverage/${CI_JOB_NAME}.out
cache:
key: build
paths:
- build/
policy: pull
artifacts:
paths:
- build/simulator/ddr4-bankgrp_ddr4_ch0.tdb
- coverage/${CI_JOB_NAME}.out
expire_in: 2 days

View File

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

View File

@@ -1,11 +0,0 @@
{"mcconfig": {
"PagePolicy": "ClosedAdaptive",
"Scheduler": "FrFcfs",
"RequestBufferSize": 8,
"CmdMux": "Oldest",
"RespQueue": "Fifo",
"RefreshPolicy": "Rankwise",
"RefreshMaxPostponed": 8,
"RefreshMaxPulledin": 8,
"PowerDownPolicy": "NoPowerDown",
"PowerDownTimeout": 100}}

View File

@@ -1,71 +0,0 @@
{
"memspec": {
"memarchitecturespec": {
"burstLength": 8,
"dataRate": 2,
"nbrOfBankGroups": 4,
"nbrOfBanks": 16,
"nbrOfColumns": 1024,
"nbrOfRanks": 1,
"nbrOfChannels": 1,
"nbrOfRows": 32768,
"width": 8,
"nbrOfDevices": 8
},
"memoryId": "MICRON_4Gb_DDR4-1866_8bit_A",
"memoryType": "DDR4",
"mempowerspec": {
"idd0": 56.25,
"idd02": 4.05,
"idd2n": 33.75,
"idd2p0": 17.0,
"idd2p1": 17.0,
"idd3n": 39.5,
"idd3p0": 22.5,
"idd3p1": 22.5,
"idd4r": 157.5,
"idd4w": 135.0,
"idd5": 118.0,
"idd6": 20.25,
"idd62": 2.6,
"vdd": 1.2,
"vdd2": 2.5
},
"memtimingspec": {
"AL": 0,
"CCD_L": 5,
"CCD_S": 4,
"CKE": 6,
"CKESR": 7,
"CL": 13,
"DQSCK": 2,
"FAW": 22,
"RAS": 32,
"RC": 45,
"RCD": 13,
"REFM": 1,
"REFI": 3644,
"RFC": 243,
"RL": 13,
"RPRE": 1,
"RP": 13,
"RRD_L": 5,
"RRD_S": 4,
"RTP": 8,
"WL": 12,
"WPRE": 1,
"WR": 14,
"WTR_L": 7,
"WTR_S": 3,
"XP": 8,
"XPDLL": 255,
"XS": 252,
"XSDLL": 512,
"ACTPDEN": 1,
"PRPDEN": 1,
"REFPDEN": 1,
"RTRS": 1,
"clkMhz": 933
}
}
}

View File

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

View File

@@ -1,15 +0,0 @@
{
"thermalsimconfig": {
"TemperatureScale": "Celsius",
"StaticTemperatureDefaultValue": 89,
"ThermalSimPeriod":100,
"ThermalSimUnit":"us",
"PowerInfoFile": "powerInfo.json",
"IceServerIp": "127.0.0.1",
"IceServerPort": 11880,
"SimPeriodAdjustFactor" : 10,
"NPowStableCyclesToIncreasePeriod": 5,
"GenerateTemperatureMap": true,
"GeneratePowerMap": true
}
}

View File

@@ -1,45 +0,0 @@
CPUs :
position 0, 0 ;
dimension 2750, 4300 ;
GPU :
position 3350, 0 ;
dimension 2750, 4000 ;
BASEBAND1 :
position 4250, 4000 ;
dimension 1850, 3300 ;
BASEBAND2 :
position 3350, 7300 ;
dimension 2750, 3300 ;
LLCACHE :
position 0, 4300 ;
dimension 1900, 3000 ;
DRAMCTRL1 :
position 1900, 4300 ;
dimension 850, 3000 ;
DRAMCTRL2 :
position 3350, 4000 ;
dimension 900, 3300 ;
TSVS :
position 2750, 2300 ;
dimension 600, 6000 ;
ACELLERATORS :
position 0, 7300 ;
dimension 2750, 3300 ;

View File

@@ -1,16 +0,0 @@
channel0 :
position 150, 100 ;
dimension 2600, 5200 ;
channel1 :
position 3350, 100 ;
dimension 2600, 5200 ;
channel2 :
position 150, 5300 ;
dimension 2600, 5200 ;
channel3 :
position 3350, 5300 ;
dimension 2600, 5200 ;

View File

@@ -1,20 +0,0 @@
{
"powerInfo": {
"dram_die_channel0": {
"init_pow": 0,
"threshold": 1.0
},
"dram_die_channel1": {
"init_pow": 0,
"threshold": 1.0
},
"dram_die_channel2": {
"init_pow": 0,
"threshold": 1.0
},
"dram_die_channel3": {
"init_pow": 0,
"threshold": 1.0
}
}
}

View File

@@ -1,49 +0,0 @@
material SILICON :
thermal conductivity 1.30e-4 ;
volumetric heat capacity 1.628e-12 ;
material BEOL :
thermal conductivity 2.25e-6 ;
volumetric heat capacity 2.175e-12 ;
material COPPER :
thermal conductivity 4.01e-04 ;
volumetric heat capacity 3.37e-12 ;
top heat sink :
//sink height 1e03, area 100e06, material COPPER ;
//spreader height 0.5e03, area 70e06, material SILICON ;
heat transfer coefficient 1.3e-09 ;
temperature 318.15 ;
dimensions :
chip length 6100, width 10600 ;
cell length 100, width 100 ;
layer PCB :
height 10 ;
material BEOL ;
die DRAM :
layer 58.5 SILICON ;
source 2 SILICON ;
layer 1.5 BEOL ;
layer 58.5 SILICON ;
stack:
die DRAM_DIE DRAM floorplan "./mem.flp" ;
layer CONN_TO_PCB PCB ;
solver:
transient step 0.01, slot 0.05 ;
initial temperature 300.0 ;
output:
Tflpel(DRAM_DIE.channel0 , "temp_flp_element_ch0.txt" , average , slot );
Tflpel(DRAM_DIE.channel1 , "temp_flp_element_ch1.txt" , average , slot );
Tflpel(DRAM_DIE.channel2 , "temp_flp_element_ch2.txt" , average , slot );
Tflpel(DRAM_DIE.channel3 , "temp_flp_element_ch3.txt" , average , slot );
Tmap (DRAM_DIE, "output1.txt", slot) ;
Pmap (DRAM_DIE, "output2.txt", slot) ;

View File

@@ -1,16 +0,0 @@
{
"simulation": {
"addressmapping": "am_ddr4_8x4Gbx8_dimm_p1KB_brc.json",
"mcconfig": "fr_fcfs.json",
"memspec": "MICRON_4Gb_DDR4-1866_8bit_A.json",
"simconfig": "ddr4.json",
"simulationid": "ddr4-bankgrp",
"thermalconfig": "config.json",
"tracesetup": [
{
"clkMhz": 933,
"name": "trace_test3.stl"
}
]
}
}

View File

@@ -1,31 +0,0 @@
example_HBM2:
stage: test_HBM2
script:
- export GCOV_PREFIX=$(pwd)
- export GCOV_PREFIX_STRIP=$(pwd | awk -F"/" '{print NF-1}')
- cd build/simulator
- ./DRAMSys ../../DRAMSys/tests/HBM2/simulations/hbm2-example.json ../../DRAMSys/tests/HBM2/
- mv DRAMSys_hbm2-example_hbm2_ch0.tdb hbm2-example_hbm2_ch0.tdb
- mv DRAMSys_hbm2-example_hbm2_ch1.tdb hbm2-example_hbm2_ch1.tdb
- ls -lah
- ls -lah ../../DRAMSys/tests/HBM2/expected/
- sqldiff ../../DRAMSys/tests/HBM2/expected/hbm2-example_hbm2_ch0.tdb hbm2-example_hbm2_ch0.tdb
- perl -e 'if(`sqldiff --table Phases ../../DRAMSys/tests/HBM2/expected/hbm2-example_hbm2_ch0.tdb hbm2-example_hbm2_ch0.tdb` eq "") {exit(0)} else {exit(-1)}'
- perl -e 'if(`sqldiff --table Transactions ../../DRAMSys/tests/HBM2/expected/hbm2-example_hbm2_ch0.tdb hbm2-example_hbm2_ch0.tdb` eq "") {exit(0)} else {exit(-1)}'
- perl -e 'if(`sqldiff --table Power ../../DRAMSys/tests/HBM2/expected/hbm2-example_hbm2_ch0.tdb hbm2-example_hbm2_ch0.tdb` eq "") {exit(0)} else {exit(-1)}'
- sqldiff ../../DRAMSys/tests/HBM2/expected/hbm2-example_hbm2_ch1.tdb hbm2-example_hbm2_ch1.tdb
- perl -e 'if(`sqldiff --table Phases ../../DRAMSys/tests/HBM2/expected/hbm2-example_hbm2_ch1.tdb hbm2-example_hbm2_ch1.tdb` eq "") {exit(0)} else {exit(-1)}'
- perl -e 'if(`sqldiff --table Transactions ../../DRAMSys/tests/HBM2/expected/hbm2-example_hbm2_ch1.tdb hbm2-example_hbm2_ch1.tdb` eq "") {exit(0)} else {exit(-1)}'
- perl -e 'if(`sqldiff --table Power ../../DRAMSys/tests/HBM2/expected/hbm2-example_hbm2_ch1.tdb hbm2-example_hbm2_ch1.tdb` eq "") {exit(0)} else {exit(-1)}'
- lcov -q -c --rc geninfo_adjust_src_path=$GCOV_PREFIX -d ${CI_PROJECT_DIR}/build/ -o ${CI_PROJECT_DIR}/coverage/${CI_JOB_NAME}.out
cache:
key: build
paths:
- build/
policy: pull
artifacts:
paths:
- build/simulator/hbm2-example_hbm2_ch0.tdb
- coverage/${CI_JOB_NAME}.out
expire_in: 2 days

View File

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

View File

@@ -1,14 +0,0 @@
{
"mcconfig": {
"PagePolicy": "Closed",
"Scheduler": "Fifo",
"RequestBufferSize": 8,
"CmdMux": "Strict",
"RespQueue": "Fifo",
"RefreshPolicy": "NoRefresh",
"RefreshMaxPostponed": 0,
"RefreshMaxPulledin": 0,
"PowerDownPolicy": "NoPowerDown",
"PowerDownTimeout": 100
}
}

View File

@@ -1,48 +0,0 @@
{
"memspec": {
"memarchitecturespec": {
"burstLength": 4,
"dataRate": 2,
"nbrOfBankGroups": 4,
"nbrOfBanks": 16,
"nbrOfColumns": 128,
"nbrOfPseudoChannels": 1,
"nbrOfChannels": 2,
"nbrOfDevices": 1,
"nbrOfRows": 32768,
"width": 128
},
"memoryId": "https://www.computerbase.de/2019-05/amd-memory-tweak-vram-oc/#bilder",
"memoryType": "HBM2",
"memtimingspec": {
"CCDL": 3,
"CCDS": 2,
"CKE": 8,
"DQSCK": 1,
"FAW": 16,
"PL": 0,
"RAS": 28,
"RC": 42,
"RCDRD": 12,
"RCDWR": 6,
"REFI": 3900,
"REFISB": 244,
"RFC": 220,
"RFCSB": 96,
"RL": 17,
"RP": 14,
"RRDL": 6,
"RRDS": 4,
"RREFD": 8,
"RTP": 5,
"RTW": 18,
"WL": 7,
"WR": 14,
"WTRL": 9,
"WTRS": 4,
"XP": 8,
"XS": 216,
"clkMhz": 1000
}
}
}

View File

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

View File

@@ -1,15 +0,0 @@
{
"thermalsimconfig": {
"TemperatureScale": "Celsius",
"StaticTemperatureDefaultValue": 89,
"ThermalSimPeriod":100,
"ThermalSimUnit":"us",
"PowerInfoFile": "powerInfo.json",
"IceServerIp": "127.0.0.1",
"IceServerPort": 11880,
"SimPeriodAdjustFactor" : 10,
"NPowStableCyclesToIncreasePeriod": 5,
"GenerateTemperatureMap": true,
"GeneratePowerMap": true
}
}

View File

@@ -1,45 +0,0 @@
CPUs :
position 0, 0 ;
dimension 2750, 4300 ;
GPU :
position 3350, 0 ;
dimension 2750, 4000 ;
BASEBAND1 :
position 4250, 4000 ;
dimension 1850, 3300 ;
BASEBAND2 :
position 3350, 7300 ;
dimension 2750, 3300 ;
LLCACHE :
position 0, 4300 ;
dimension 1900, 3000 ;
DRAMCTRL1 :
position 1900, 4300 ;
dimension 850, 3000 ;
DRAMCTRL2 :
position 3350, 4000 ;
dimension 900, 3300 ;
TSVS :
position 2750, 2300 ;
dimension 600, 6000 ;
ACELLERATORS :
position 0, 7300 ;
dimension 2750, 3300 ;

View File

@@ -1,16 +0,0 @@
channel0 :
position 150, 100 ;
dimension 2600, 5200 ;
channel1 :
position 3350, 100 ;
dimension 2600, 5200 ;
channel2 :
position 150, 5300 ;
dimension 2600, 5200 ;
channel3 :
position 3350, 5300 ;
dimension 2600, 5200 ;

View File

@@ -1,20 +0,0 @@
{
"powerInfo": {
"dram_die_channel0": {
"init_pow": 0,
"threshold": 1.0
},
"dram_die_channel1": {
"init_pow": 0,
"threshold": 1.0
},
"dram_die_channel2": {
"init_pow": 0,
"threshold": 1.0
},
"dram_die_channel3": {
"init_pow": 0,
"threshold": 1.0
}
}
}

View File

@@ -1,49 +0,0 @@
material SILICON :
thermal conductivity 1.30e-4 ;
volumetric heat capacity 1.628e-12 ;
material BEOL :
thermal conductivity 2.25e-6 ;
volumetric heat capacity 2.175e-12 ;
material COPPER :
thermal conductivity 4.01e-04 ;
volumetric heat capacity 3.37e-12 ;
top heat sink :
//sink height 1e03, area 100e06, material COPPER ;
//spreader height 0.5e03, area 70e06, material SILICON ;
heat transfer coefficient 1.3e-09 ;
temperature 318.15 ;
dimensions :
chip length 6100, width 10600 ;
cell length 100, width 100 ;
layer PCB :
height 10 ;
material BEOL ;
die DRAM :
layer 58.5 SILICON ;
source 2 SILICON ;
layer 1.5 BEOL ;
layer 58.5 SILICON ;
stack:
die DRAM_DIE DRAM floorplan "./mem.flp" ;
layer CONN_TO_PCB PCB ;
solver:
transient step 0.01, slot 0.05 ;
initial temperature 300.0 ;
output:
Tflpel(DRAM_DIE.channel0 , "temp_flp_element_ch0.txt" , average , slot );
Tflpel(DRAM_DIE.channel1 , "temp_flp_element_ch1.txt" , average , slot );
Tflpel(DRAM_DIE.channel2 , "temp_flp_element_ch2.txt" , average , slot );
Tflpel(DRAM_DIE.channel3 , "temp_flp_element_ch3.txt" , average , slot );
Tmap (DRAM_DIE, "output1.txt", slot) ;
Pmap (DRAM_DIE, "output2.txt", slot) ;

View File

@@ -1,20 +0,0 @@
{
"simulation": {
"addressmapping": "am_hbm2_8Gb_pc_brc.json",
"mcconfig": "fifoStrict.json",
"memspec": "HBM2.json",
"simconfig": "hbm2.json",
"simulationid": "hbm2-example",
"thermalconfig": "config.json",
"tracesetup": [
{
"clkMhz": 1000,
"name": "trace1_test4.stl"
},
{
"clkMhz": 1000,
"name": "trace2_test4.stl"
}
]
}
}

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