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:
5
.gitattributes
vendored
Normal file
5
.gitattributes
vendored
Normal 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
2
.gitignore
vendored
@@ -5,7 +5,7 @@
|
||||
/dram/build
|
||||
*.user
|
||||
*.tdb
|
||||
!/DRAMSys/tests/*/expected/*.tdb
|
||||
!tests/tests_regression/*/expected/*.tdb
|
||||
*.tdb-journal
|
||||
*.out
|
||||
/build-simulation
|
||||
|
||||
@@ -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
16
.gitmodules
vendored
@@ -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
191
CMakeLists.txt
Normal 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()
|
||||
|
||||
@@ -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()
|
||||
1
DRAMSys/library/resources/.gitignore
vendored
1
DRAMSys/library/resources/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
*.pyc
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) ;
|
||||
|
||||
@@ -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,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";
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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))
|
||||
@@ -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);
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
Submodule DRAMSys/library/src/common/third_party/DRAMPower deleted from 1ddc48a387
Submodule DRAMSys/library/src/common/third_party/nlohmann deleted from b7be613b6e
Submodule DRAMSys/library/src/common/third_party/sqlite-amalgamation deleted from 9be05e1340
Submodule DRAMSys/library/src/common/third_party/systemc deleted from 6041825095
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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) + " ";
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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(¤tPowerValues);
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) ;
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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}}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) ;
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) ;
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user