From 84d706788d6b07afd3f6e64e565e9463f2e64997 Mon Sep 17 00:00:00 2001 From: Retrocamara42 Date: Tue, 1 Oct 2024 04:57:16 -0500 Subject: [PATCH] feat: project init-tlm and ratatoskr --- .gitignore | 3 + CMakeLists.txt | 54 + README.md | 9 + build.sh | 9 + config/XYZ_4_4_1_8B_8VC.xml | 508 +++ config/config.xml | 83 + config/data1.xml | 808 ++++ config/data_original.xml | 134 + config/map1.xml | 147 + config/map_original.xml | 42 + config/network.xml | 3248 +++++++++++++++++ config/simple_2_point_test/2pt_data.xml | 76 + config/simple_2_point_test/2pt_map.xml | 15 + config/simple_2_point_test/config.xml | 55 + config/simple_2_point_test/net.xml | 879 +++++ config/simple_test/config.xml | 55 + config/simple_test/net.xml | 879 +++++ config/simple_test/simple_data.xml | 50 + config/simple_test/simple_map.xml | 11 + config/structure.xml | 360 ++ report.txt | 1537 ++++++++ src/main.cpp | 59 + src/networkInterface/NetworkInterfaceTlm.cpp | 413 +++ src/networkInterface/NetworkInterfaceTlm.h | 218 ++ src/networkManager/NetworkManager.cpp | 134 + src/networkManager/NetworkManager.h | 82 + src/noc/noc.cpp | 185 + src/noc/noc.h | 125 + .../container/ClassicContainer.h | 104 + src/ratatoskrUtils/container/Container.h | 42 + src/ratatoskrUtils/container/FlitContainer.h | 109 + .../container/PacketContainer.h | 90 + src/ratatoskrUtils/link/Link.cpp | 114 + src/ratatoskrUtils/link/Link.h | 62 + src/ratatoskrUtils/model/NetworkParticipant.h | 45 + .../networkInterface/NetworkInterface.cpp | 36 + .../networkInterface/NetworkInterface.h | 52 + .../processingElement/ProcessingElement.cpp | 36 + .../processingElement/ProcessingElement.h | 48 + .../processingElement/ProcessingElementVC.cpp | 391 ++ .../processingElement/ProcessingElementVC.h | 80 + src/ratatoskrUtils/traffic/Flit.cpp | 89 + src/ratatoskrUtils/traffic/Flit.h | 62 + src/ratatoskrUtils/traffic/Packet.cpp | 56 + src/ratatoskrUtils/traffic/Packet.h | 56 + src/ratatoskrUtils/traffic/TrafficPool.cpp | 35 + src/ratatoskrUtils/traffic/TrafficPool.h | 44 + src/ratatoskrUtils/traffic/netrace/.gitignore | 1 + src/ratatoskrUtils/traffic/netrace/NETRACE | 3 + .../traffic/netrace/NetracePool.cpp | 153 + .../traffic/netrace/NetracePool.h | 65 + .../traffic/netrace/ntNetrace.cpp | 755 ++++ .../traffic/netrace/ntNetrace.h | 195 + .../traffic/netrace/ntQueue.cpp | 187 + src/ratatoskrUtils/traffic/netrace/ntQueue.h | 66 + .../traffic/synthetic/SyntheticPacket.h | 38 + .../traffic/synthetic/SyntheticPool.cpp | 309 ++ .../traffic/synthetic/SyntheticPool.h | 57 + src/ratatoskrUtils/traffic/task/TaskPacket.h | 36 + src/ratatoskrUtils/traffic/task/TaskPool.cpp | 45 + src/ratatoskrUtils/traffic/task/TaskPool.h | 44 + src/ratatoskrUtils/utils/GlobalReport.cpp | 610 ++++ src/ratatoskrUtils/utils/GlobalReport.h | 220 ++ src/ratatoskrUtils/utils/GlobalResources.cpp | 720 ++++ src/ratatoskrUtils/utils/GlobalResources.h | 153 + src/ratatoskrUtils/utils/PacketFactory.cpp | 47 + src/ratatoskrUtils/utils/PacketFactory.h | 39 + src/ratatoskrUtils/utils/Report.cpp | 132 + src/ratatoskrUtils/utils/Report.h | 87 + src/ratatoskrUtils/utils/Statistics.cpp | 73 + src/ratatoskrUtils/utils/Statistics.h | 54 + src/ratatoskrUtils/utils/Structures.cpp | 338 ++ src/ratatoskrUtils/utils/Structures.h | 422 +++ src/ratatoskrUtils/utils/TrafficTracer.cpp | 44 + src/ratatoskrUtils/utils/TrafficTracer.h | 46 + src/ratatoskrUtils/utils/portsOpenConst.h | 42 + src/router/router.cpp | 393 ++ src/router/router.h | 254 ++ src/utils/configuration.h | 43 + src/utils/memory_manager.cpp | 40 + src/utils/memory_manager.h | 32 + src/utils/noc_logger.cpp | 91 + src/utils/noc_logger.h | 63 + src/utils/utils.cpp | 39 + src/utils/utils.h | 64 + 85 files changed, 17729 insertions(+) create mode 100644 .gitignore create mode 100755 CMakeLists.txt create mode 100755 README.md create mode 100755 build.sh create mode 100644 config/XYZ_4_4_1_8B_8VC.xml create mode 100755 config/config.xml create mode 100755 config/data1.xml create mode 100755 config/data_original.xml create mode 100755 config/map1.xml create mode 100755 config/map_original.xml create mode 100755 config/network.xml create mode 100644 config/simple_2_point_test/2pt_data.xml create mode 100644 config/simple_2_point_test/2pt_map.xml create mode 100755 config/simple_2_point_test/config.xml create mode 100644 config/simple_2_point_test/net.xml create mode 100755 config/simple_test/config.xml create mode 100644 config/simple_test/net.xml create mode 100644 config/simple_test/simple_data.xml create mode 100644 config/simple_test/simple_map.xml create mode 100755 config/structure.xml create mode 100755 report.txt create mode 100755 src/main.cpp create mode 100755 src/networkInterface/NetworkInterfaceTlm.cpp create mode 100755 src/networkInterface/NetworkInterfaceTlm.h create mode 100755 src/networkManager/NetworkManager.cpp create mode 100755 src/networkManager/NetworkManager.h create mode 100755 src/noc/noc.cpp create mode 100755 src/noc/noc.h create mode 100755 src/ratatoskrUtils/container/ClassicContainer.h create mode 100755 src/ratatoskrUtils/container/Container.h create mode 100644 src/ratatoskrUtils/container/FlitContainer.h create mode 100755 src/ratatoskrUtils/container/PacketContainer.h create mode 100755 src/ratatoskrUtils/link/Link.cpp create mode 100755 src/ratatoskrUtils/link/Link.h create mode 100755 src/ratatoskrUtils/model/NetworkParticipant.h create mode 100755 src/ratatoskrUtils/networkInterface/NetworkInterface.cpp create mode 100755 src/ratatoskrUtils/networkInterface/NetworkInterface.h create mode 100755 src/ratatoskrUtils/processingElement/ProcessingElement.cpp create mode 100755 src/ratatoskrUtils/processingElement/ProcessingElement.h create mode 100755 src/ratatoskrUtils/processingElement/ProcessingElementVC.cpp create mode 100755 src/ratatoskrUtils/processingElement/ProcessingElementVC.h create mode 100755 src/ratatoskrUtils/traffic/Flit.cpp create mode 100755 src/ratatoskrUtils/traffic/Flit.h create mode 100755 src/ratatoskrUtils/traffic/Packet.cpp create mode 100755 src/ratatoskrUtils/traffic/Packet.h create mode 100755 src/ratatoskrUtils/traffic/TrafficPool.cpp create mode 100755 src/ratatoskrUtils/traffic/TrafficPool.h create mode 100755 src/ratatoskrUtils/traffic/netrace/.gitignore create mode 100755 src/ratatoskrUtils/traffic/netrace/NETRACE create mode 100755 src/ratatoskrUtils/traffic/netrace/NetracePool.cpp create mode 100755 src/ratatoskrUtils/traffic/netrace/NetracePool.h create mode 100755 src/ratatoskrUtils/traffic/netrace/ntNetrace.cpp create mode 100755 src/ratatoskrUtils/traffic/netrace/ntNetrace.h create mode 100755 src/ratatoskrUtils/traffic/netrace/ntQueue.cpp create mode 100755 src/ratatoskrUtils/traffic/netrace/ntQueue.h create mode 100755 src/ratatoskrUtils/traffic/synthetic/SyntheticPacket.h create mode 100755 src/ratatoskrUtils/traffic/synthetic/SyntheticPool.cpp create mode 100755 src/ratatoskrUtils/traffic/synthetic/SyntheticPool.h create mode 100755 src/ratatoskrUtils/traffic/task/TaskPacket.h create mode 100755 src/ratatoskrUtils/traffic/task/TaskPool.cpp create mode 100755 src/ratatoskrUtils/traffic/task/TaskPool.h create mode 100644 src/ratatoskrUtils/utils/GlobalReport.cpp create mode 100644 src/ratatoskrUtils/utils/GlobalReport.h create mode 100755 src/ratatoskrUtils/utils/GlobalResources.cpp create mode 100755 src/ratatoskrUtils/utils/GlobalResources.h create mode 100755 src/ratatoskrUtils/utils/PacketFactory.cpp create mode 100755 src/ratatoskrUtils/utils/PacketFactory.h create mode 100644 src/ratatoskrUtils/utils/Report.cpp create mode 100644 src/ratatoskrUtils/utils/Report.h create mode 100755 src/ratatoskrUtils/utils/Statistics.cpp create mode 100755 src/ratatoskrUtils/utils/Statistics.h create mode 100755 src/ratatoskrUtils/utils/Structures.cpp create mode 100755 src/ratatoskrUtils/utils/Structures.h create mode 100755 src/ratatoskrUtils/utils/TrafficTracer.cpp create mode 100755 src/ratatoskrUtils/utils/TrafficTracer.h create mode 100755 src/ratatoskrUtils/utils/portsOpenConst.h create mode 100755 src/router/router.cpp create mode 100755 src/router/router.h create mode 100755 src/utils/configuration.h create mode 100755 src/utils/memory_manager.cpp create mode 100755 src/utils/memory_manager.h create mode 100644 src/utils/noc_logger.cpp create mode 100644 src/utils/noc_logger.h create mode 100755 src/utils/utils.cpp create mode 100755 src/utils/utils.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2250e41 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build +out +sim diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..ea30a27 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,54 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +PROJECT(sim) + +SET(CMAKE_PREFIX_PATH /usr/local/systemc-2.3.3/) + +set(CMAKE_CXX_STANDARD 17) + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -pthread") + +set(CMAKE_BUILD_TYPE Release) + +INCLUDE_DIRECTORIES(${CMAKE_PREFIX_PATH}/include) +INCLUDE_DIRECTORIES(./src) + +FIND_LIBRARY(systemc systemc ${CMAKE_PREFIX_PATH}/lib-linux64) +LINK_DIRECTORIES(${CMAKE_PREFIX_PATH}/lib-linux64) + +ADD_DEFINITIONS(-D SC_INCLUDE_DYNAMIC_PROCESSES -D SYSTEMC_DISABLE_COPYRIGHT_MESSAGE -D ENABLE_BUFFER_VC_STATS -D SC_DISABLE_API_VERSION_CHECK) + +ADD_EXECUTABLE(${PROJECT_NAME} + src/main.cpp + src/networkInterface/NetworkInterfaceTlm.cpp + src/networkManager/NetworkManager.cpp + src/noc/noc.cpp + src/router/router.cpp + src/utils/memory_manager.cpp + src/utils/utils.cpp + src/utils/noc_logger.cpp + src/ratatoskrUtils/utils/Report.cpp + src/ratatoskrUtils/utils/GlobalReport.cpp + src/ratatoskrUtils/utils/Structures.cpp + src/ratatoskrUtils/utils/PacketFactory.cpp + src/ratatoskrUtils/utils/GlobalResources.cpp + src/ratatoskrUtils/utils/Statistics.cpp + src/ratatoskrUtils/processingElement/ProcessingElement.cpp + src/ratatoskrUtils/processingElement/ProcessingElementVC.cpp + src/ratatoskrUtils/networkInterface/NetworkInterface.cpp + src/ratatoskrUtils/traffic/Packet.cpp + src/ratatoskrUtils/traffic/Flit.cpp + src/ratatoskrUtils/traffic/synthetic/SyntheticPool.cpp + src/ratatoskrUtils/traffic/task/TaskPool.cpp + src/ratatoskrUtils/traffic/TrafficPool.cpp + src/ratatoskrUtils/link/Link.cpp + src/ratatoskrUtils/traffic/netrace/NetracePool.cpp + src/ratatoskrUtils/traffic/netrace/NetracePool.h + src/ratatoskrUtils/traffic/netrace/ntNetrace.h + src/ratatoskrUtils/traffic/netrace/ntNetrace.cpp + src/ratatoskrUtils/traffic/netrace/ntQueue.h + src/ratatoskrUtils/traffic/netrace/ntQueue.cpp + src/ratatoskrUtils/utils/TrafficTracer.cpp +) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} systemc pugixml boost_system zmq boost_program_options) + diff --git a/README.md b/README.md new file mode 100755 index 0000000..970cfd6 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# Defines + +`cmake -DDEFINE_ENABLE_NETRACE=ON` + +enables netrace mode + +`cmake -DDEFINE_ENABLE_GUI=ON` + +enables GUI mode diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..97d2219 --- /dev/null +++ b/build.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +mkdir build +cd build +cmake .. +make -j +cp sim .. +cd .. +rm -rf build diff --git a/config/XYZ_4_4_1_8B_8VC.xml b/config/XYZ_4_4_1_8B_8VC.xml new file mode 100644 index 0000000..54540b2 --- /dev/null +++ b/config/XYZ_4_4_1_8B_8VC.xml @@ -0,0 +1,508 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/config.xml b/config/config.xml new file mode 100755 index 0000000..871c7e0 --- /dev/null +++ b/config/config.xml @@ -0,0 +1,83 @@ + + + + + report + + + config/network.xml + + + + + + synthetic + + + + + + + + + + + + + + + + + + + + + + + src/model/config/data.xml + src/model/config/map.xml + traffic/pipelinePerformance_2D/PipelineResetTB.xml + traffic/pipelinePerformance_2D/PipelineResetTBMapping.xml + src/model/traffic/netrace/testraces/example.tra.bz2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 6 9 10 21 22 25 26 37 38 41 42 + + diff --git a/config/data1.xml b/config/data1.xml new file mode 100755 index 0000000..b0faec3 --- /dev/null +++ b/config/data1.xml @@ -0,0 +1,808 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/data_original.xml b/config/data_original.xml new file mode 100755 index 0000000..76e1b2b --- /dev/null +++ b/config/data_original.xml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/map1.xml b/config/map1.xml new file mode 100755 index 0000000..e31574e --- /dev/null +++ b/config/map1.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/map_original.xml b/config/map_original.xml new file mode 100755 index 0000000..20a9bb3 --- /dev/null +++ b/config/map_original.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/network.xml b/config/network.xml new file mode 100755 index 0000000..c21e274 --- /dev/null +++ b/config/network.xml @@ -0,0 +1,3248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/simple_2_point_test/2pt_data.xml b/config/simple_2_point_test/2pt_data.xml new file mode 100644 index 0000000..c694991 --- /dev/null +++ b/config/simple_2_point_test/2pt_data.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/simple_2_point_test/2pt_map.xml b/config/simple_2_point_test/2pt_map.xml new file mode 100644 index 0000000..b097f1a --- /dev/null +++ b/config/simple_2_point_test/2pt_map.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/config/simple_2_point_test/config.xml b/config/simple_2_point_test/config.xml new file mode 100755 index 0000000..4de57e7 --- /dev/null +++ b/config/simple_2_point_test/config.xml @@ -0,0 +1,55 @@ + + + + + report + + + config/simple_test/net.xml + + + + + + task + config/simple_2_point_test/2pt_data.xml + config/simple_2_point_test/2pt_map.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 6 9 10 + + diff --git a/config/simple_2_point_test/net.xml b/config/simple_2_point_test/net.xml new file mode 100644 index 0000000..843b14b --- /dev/null +++ b/config/simple_2_point_test/net.xml @@ -0,0 +1,879 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/simple_test/config.xml b/config/simple_test/config.xml new file mode 100755 index 0000000..d53d3a0 --- /dev/null +++ b/config/simple_test/config.xml @@ -0,0 +1,55 @@ + + + + + report + + + config/simple_test/net.xml + + + + + + task + config/simple_test/simple_data.xml + config/simple_test/simple_map.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 6 9 10 + + diff --git a/config/simple_test/net.xml b/config/simple_test/net.xml new file mode 100644 index 0000000..843b14b --- /dev/null +++ b/config/simple_test/net.xml @@ -0,0 +1,879 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/simple_test/simple_data.xml b/config/simple_test/simple_data.xml new file mode 100644 index 0000000..27d0643 --- /dev/null +++ b/config/simple_test/simple_data.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/simple_test/simple_map.xml b/config/simple_test/simple_map.xml new file mode 100644 index 0000000..bee1db8 --- /dev/null +++ b/config/simple_test/simple_map.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/config/structure.xml b/config/structure.xml new file mode 100755 index 0000000..1c81b61 --- /dev/null +++ b/config/structure.xml @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/report.txt b/report.txt new file mode 100755 index 0000000..fa66334 --- /dev/null +++ b/report.txt @@ -0,0 +1,1537 @@ +Report file of this simulation run. + +---------------------------------------------------- +General Information: +---------------------------------------------------- +Lost Packets: 0 +Average flit latency: -nan ns. +Average packet latency: -nan ns. +Average network latency: -nan ns. +Clock Counts: [0, 0, 0] +---------------------------------------------------- +Router Matrixes: +---------------------------------------------------- +Routing calculations: +---------------------------------------------------- +Link Matrixes: +---------------------------------------------------- +Transmission matrix of links 0: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 1: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 2: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 3: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 4: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 5: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 6: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 7: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 8: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 9: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 10: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 11: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 12: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 13: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 14: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 15: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 16: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 17: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 18: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 19: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 20: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 21: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 22: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 23: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 24: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 25: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 26: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 27: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 28: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 29: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 30: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 31: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 32: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 33: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 34: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 35: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 36: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 37: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 38: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 39: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 40: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 41: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 42: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 43: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 44: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 45: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 46: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 47: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 48: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 49: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 50: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 51: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 52: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 53: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 54: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 55: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 56: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 57: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 58: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 59: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 60: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 61: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 62: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 63: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 64: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 65: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 66: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 67: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 68: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 69: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 70: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 71: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 72: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 73: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 74: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 75: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 76: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 77: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 78: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 79: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 80: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 81: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 82: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 83: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 84: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 85: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 86: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 87: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 88: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 89: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 90: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 91: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 92: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 93: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 94: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 95: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 96: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 97: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 98: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 99: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 100: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 101: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 102: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 103: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 104: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 105: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 106: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 107: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 108: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 109: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 110: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 111: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 112: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 113: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 114: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 115: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 116: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 117: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 118: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 119: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 120: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 121: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 122: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 123: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 124: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 125: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 126: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 127: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 128: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 129: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 130: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 131: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 132: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 133: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 134: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 135: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 136: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 137: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 138: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 139: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 140: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 141: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 142: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 143: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 144: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 145: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 146: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 147: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 148: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 149: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 150: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 151: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 152: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 153: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 154: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 155: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 156: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 157: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 158: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 159: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 160: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 161: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 162: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 163: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 164: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 165: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 166: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 167: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 168: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 169: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 170: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 171: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 172: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 173: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 174: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 175: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 176: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 177: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 178: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 179: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 180: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 181: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 182: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 183: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 184: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 185: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 186: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 187: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 188: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 189: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 190: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 191: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 192: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 193: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 194: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 195: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 196: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 197: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 198: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 199: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 200: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 201: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 202: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 203: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 204: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 205: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 206: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 207: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 208: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 209: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 210: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 211: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 212: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 213: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 214: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 215: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 216: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 217: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 218: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 219: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 220: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 221: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 222: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 223: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 224: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 225: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 226: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 227: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 228: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 229: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 230: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 231: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 232: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 233: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 234: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 235: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 236: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 237: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 238: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 239: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 240: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 241: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 242: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 243: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 244: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 245: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 246: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 247: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 248: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 249: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 250: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 251: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 252: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 253: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 254: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 255: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 256: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 257: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 258: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 259: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 260: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 261: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 262: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 263: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 264: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 265: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 266: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 267: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 268: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 269: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 270: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 271: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 272: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 273: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 274: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 275: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 276: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 277: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 278: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 279: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 280: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 281: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 282: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 283: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 284: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 285: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 286: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 287: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 288: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 289: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 290: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 291: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 292: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 293: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 294: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 295: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 296: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 297: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 298: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 299: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 300: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 301: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 302: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] +Transmission matrix of links 303: +from\to IDLE HEAD HID +IDLE [ -nan, -nan, -nan ] +HEAD [ -nan, -nan, -nan ] +HID [ -nan, -nan, -nan ] diff --git a/src/main.cpp b/src/main.cpp new file mode 100755 index 0000000..2080a2c --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (C) 2024 Juan Neyra + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "systemc.h" +#include +#include +#include +#include "boost/program_options.hpp" + +#include "ratatoskrUtils/utils/GlobalResources.h" +#include "networkManager/NetworkManager.h" + +namespace po = boost::program_options; + +int sc_main(int arg_num, char *arg_vec[]) +{ + po::variables_map vm; + po::options_description desc("Allowed Options"); + desc.add_options()("configFolder", po::value()->default_value(""), "Input path for config.xml and net.xml"); + try { + po::store(po::parse_command_line(arg_num, arg_vec, desc), vm); + po::notify(vm); + } + catch (po::error &e) { + cerr << "ERROR: " << e.what() << endl << endl << desc << endl; + return 1; + } + std::string configFolder = vm["configFolder"].as(); + + // start simulation + std::unique_ptr networkManager = + std::make_unique("Layer", configFolder); + GlobalResources& globalResources = GlobalResources::getInstance(); + cout << "Random seed " << globalResources.rd_seed << endl; + cout << endl + << "Starting Simulation!" << endl; + sc_start(globalResources.simulation_time, SC_NS); + cout << endl + << "Simulation completed! Time: "<< sc_time_stamp() << endl; + return 0; +} diff --git a/src/networkInterface/NetworkInterfaceTlm.cpp b/src/networkInterface/NetworkInterfaceTlm.cpp new file mode 100755 index 0000000..c024b4b --- /dev/null +++ b/src/networkInterface/NetworkInterfaceTlm.cpp @@ -0,0 +1,413 @@ +/******************************************************************************* + * Copyright (C) 2024 Juan Neyra + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "NetworkInterfaceTlm.h" +#include + +#include "ratatoskrUtils/traffic/Flit.h" +#include "utils/configuration.h" +#include "utils/utils.h" + +DECLARE_EXTENDED_PHASE(INTERNAL_PROC_PHASE); + +using namespace std; + +NetworkInterfaceTlm::NetworkInterfaceTlm(sc_module_name nm, Node& node, + uint8_t max_pos[3]) : NetworkInterface(nm, node), + credit_counter(NUM_CREDITS), ni_name(nm), + initiator((string(nm)+"_initiator").c_str()), + target((string(nm)+"_target").c_str()), + init_peq(this, &NetworkInterfaceTlm::init_peq_cb), + target_peq(this, &NetworkInterfaceTlm::target_peq_cb), + curr_req(0), resp_in_progress(false), + nxt_resp_pend(0), end_req_pend(0) { + sc_report_handler::set_actions(NI_LOG, SC_INFO, SC_LOG|SC_DISPLAY); + try { + this->id = node.id%(globalResources.nodes.size()/2); + this->dbid = rep.registerElement("ProcessingElement", this->id); + this->node = node; + this->packetPortContainer = new PacketPortContainer( + ("NI_PACKET_CONTAINER"+to_string(this->id)).c_str()); + copy(max_pos, max_pos + 3, this->max_pos); + } + catch (exception& e) { + log_error(e.what()); + } + SC_THREAD(thread); + sensitive << clk.pos() << clk.neg(); + + SC_METHOD(receivePacketFromPE); + sensitive << packetPortContainer->portValidIn.pos(); + + initiator.register_nb_transport_bw(this, + &NetworkInterfaceTlm::nb_transport_bw_cb, 0); + target.register_nb_transport_fw(this, + &NetworkInterfaceTlm::nb_transport_fw_cb, 0); +} + +NetworkInterfaceTlm::~NetworkInterfaceTlm() { + delete packetPortContainer; +} + +void NetworkInterfaceTlm::initialize(){ + /* NOT IMPLEMENTED */ +} + + +void NetworkInterfaceTlm::bind(Connection* con, SignalContainer* sigContIn, SignalContainer* sigContOut) { + if (con==nullptr) + packetPortContainer->bind(sigContIn, sigContOut); +} + +void NetworkInterfaceTlm::receiveFlitFromRouter(){ + /* NOT IMPLEMENTED */ +} + +void NetworkInterfaceTlm::receivePacketFromPE() { + if (packetPortContainer->portValidIn.posedge()) { + //log_info("receive()"); + Packet* p = packetPortContainer->portDataIn.read(); + generateFlitsForPacket(p); + packet_send_queue.push(p); + } +} + +void NetworkInterfaceTlm::get_start_end_pos_string(Packet* p, + string pos[2]){ + pos[0] = to_string(node.pos.x) + "," + + to_string(node.pos.y) + "," + to_string(node.pos.z); + pos[1] = to_string(p->dst.pos.x) + "," + + to_string(p->dst.pos.y) + "," + + to_string(p->dst.pos.z); +} + +void NetworkInterfaceTlm::generateFlitsForPacket(Packet* p) { + int flitsPerPacket = p->size; + for (int i = 0; idataType, sc_time_stamp().to_double()); + p->toTransmit.push_back(current_flit->id); + p->flits.push_back(current_flit); + + string start_end_pos[2]; + get_start_end_pos_string(p, start_end_pos); + log_info("Flits generated for packet of id "+to_string(p->id)+ + " to be sent to "+start_end_pos[1]+" from "+start_end_pos[0]); + } +} + +void NetworkInterfaceTlm::send_data_to_noc(){ + // if no flits to transmit, generate them + Packet* p = packet_send_queue.front(); + if (p->toTransmit.empty()){ + generateFlitsForPacket(p); + } + // get current flit to send + flitID_t f_id = p->toTransmit.front(); + auto iter = find_if(p->flits.begin(), p->flits.end(), + [&f_id](Flit* f) { return f->id==f_id; }); + Flit* current_flit = *iter; + current_flit->injectionTime = sc_time_stamp().to_double(); + + auto toDelete_pos = find(p->toTransmit.begin(), p->toTransmit.end(), current_flit->id); + p->toTransmit.erase(toDelete_pos); + p->inTransmit.push_back(current_flit->id); + + if (p->toTransmit.empty()) { + packet_send_queue.pop(); + } + + // allocate tlm object + tlm::tlm_generic_payload* trans = m_mm.allocate(); + trans->acquire(); + // add id to transaction + link_extension* ext = new link_extension(); + ext->link = Direction::local; + trans->set_extension(ext); + // send flit + trans->set_command(tlm::TLM_WRITE_COMMAND); + + float dst_pos[3] = {p->dst.pos.x, p->dst.pos.y, p->dst.pos.z}; + uint8_t int_dest_pos[3]; + convert_pos_to_int(dst_pos, int_dest_pos); + trans->set_address(int_dest_pos[0] + int_dest_pos[1]*max_pos[0] + + int_dest_pos[2]*max_pos[0]*max_pos[1]); + trans->set_data_ptr(reinterpret_cast + (current_flit)); + trans->set_data_length(p->size); + trans->set_streaming_width(4); + trans->set_byte_enable_ptr(0); + trans->set_dmi_allowed(false); + trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + + credit_counter--; + + sc_time delay = sc_time(REQ_INIT_DELAY, UNITS_DELAY); + tlm::tlm_phase send_phase = tlm::BEGIN_REQ; + initiator->nb_transport_fw(*trans, send_phase, delay); + + string start_end_pos[2]; + get_start_end_pos_string(p, start_end_pos); + log_info("Flit send to "+start_end_pos[1]+" from "+start_end_pos[0]); + globalReport.issueNoCInputDataAmount(sc_time_stamp(),globalResources.bitWidth); + +} + + +void NetworkInterfaceTlm::thread() { + while(true){ + //log_info("send_data_process()"); + if (clk.posedge()) { + if (!packet_send_queue.empty()) { + if (credit_counter != 0){ + send_data_to_noc(); + } + else { + log_info("Waiting for Router!"); + } + } + if (!packet_recv_queue.empty()) { + if (packetPortContainer->portFlowControlIn.read()) { + Packet* p = packet_recv_queue.front(); + packet_recv_queue.pop(); + packetPortContainer->portValidOut.write(true); + packetPortContainer->portDataOut.write(p); + // log arrival of packet + string start_end_pos[2]; + get_start_end_pos_string(p, start_end_pos); + log_info("Packet with id " + to_string(p->id) + + " arrived at PE "+start_end_pos[1]); + } + } + } + else if (clk.negedge()) { + packetPortContainer->portValidOut.write(false); + } + wait(); + } +} + +tlm::tlm_sync_enum NetworkInterfaceTlm::nb_transport_bw_cb(int id, + tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, sc_time& delay) { + init_peq.notify(trans, phase, delay); + return tlm::TLM_ACCEPTED; +} + + +void NetworkInterfaceTlm::init_peq_cb(tlm_gp& trans, const tlm::tlm_phase& phase){ + if (phase == tlm::END_REQ) { + credit_counter++; + } + else if (phase == tlm::BEGIN_REQ || phase == tlm::END_RESP) + log_fatal("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_time delay = sc_time(RESP_END_DELAY, UNITS_DELAY); + initiator->nb_transport_fw(trans, fw_phase, delay); + } +} + + +// Called on receiving BEGIN_RESP or TLM_COMPLETED +void NetworkInterfaceTlm::check_transaction(tlm_gp& trans) { + if(trans.is_response_error()) { + char txt[100]; + sprintf(txt, "Transaction returned with error, response status = %s", + trans.get_response_string().c_str()); + log_error(txt); + } + + // Log completed routing + tlm_command cmd = trans.get_command(); + sc_dt::uint64 adr = trans.get_address(); + int* ptr = reinterpret_cast(trans.get_data_ptr()); + std::stringstream stream; + stream << hex << adr << " check, cmd=" << (cmd ? 'W' : 'R') + << ", data=" << hex << *ptr; + log_info(stream.str()); + // Allow the memory manager to free the transaction object + trans.release(); +} + +tlm::tlm_sync_enum NetworkInterfaceTlm::nb_transport_fw_cb(int id, + tlm_gp& trans, tlm::tlm_phase& phase, sc_time& delay){ + unsigned int len = trans.get_data_length(); + unsigned char* byt = trans.get_byte_enable_ptr(); + unsigned int wid = trans.get_streaming_width(); + if (byt != 0) { + trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE ); + return tlm::TLM_COMPLETED; + } + if (len > 4 || wid < len) { + trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE ); + return tlm::TLM_COMPLETED; + } + + target_peq.notify(trans, phase, delay); + return tlm::TLM_ACCEPTED; +} + + +void NetworkInterfaceTlm::receive_and_process_flit(tlm_gp& trans){ + trans.set_response_status(tlm::TLM_OK_RESPONSE); + unsigned char* data_ptr = trans.get_data_ptr(); + Flit* received_flit = reinterpret_cast(data_ptr); + Packet* p = received_flit->packet; + double time = sc_time_stamp().to_double(); + + auto position = find(p->inTransmit.begin(), p->inTransmit.end(), received_flit->id); + if (position!=p->inTransmit.end()) + p->inTransmit.erase(position); + p->transmitted.push_back(received_flit->id); + + if (received_flit->type==TAIL || received_flit->type==SINGLE){ + stringstream ss; + string flit_type = received_flit->type==SINGLE ? "Single":"Tail"; + ss << "Receive Flit " << flit_type << *received_flit; + log_info(ss.str()); + } + if (!p->toTransmit.empty() || !p->inTransmit.empty()) { + stringstream ss; + ss << "Received Tail Flit, but still missing flits! " + << *received_flit; + log_info(ss.str()); + } + globalReport.issueNoCOutputDataAmount(sc_time_stamp(),globalResources.bitWidth); + if (p->toTransmit.empty() && p->inTransmit.empty()) + packet_recv_queue.push(p); + credit_counter++; + + if(resp_in_progress) { + if(nxt_resp_pend){ + log_fatal("Attempt to have two pending responses in target"); + nxt_resp_pend = &trans; + } + } + else{ send_response(trans); } +} + + +void NetworkInterfaceTlm::target_peq_cb(tlm_gp& trans, const tlm::tlm_phase& phase){ + switch (phase) { + case tlm::BEGIN_REQ: + trans.acquire(); + send_end_req(trans); + break; + + case tlm::END_RESP: + if (!resp_in_progress){ + log_fatal( + "Illegal transaction phase END_RESP received by target"); + } + trans.release(); + credit_counter++; + // Target itself is now clear to issue the next BEGIN_RESP + resp_in_progress = false; + if (nxt_resp_pend){ + send_response(*nxt_resp_pend); + nxt_resp_pend = 0; + } + break; + + case tlm::END_REQ: + case tlm::BEGIN_RESP: + log_fatal("Illegal transaction phase received by target"); + break; + + default: + if(phase == INTERNAL_PROC_PHASE){ + receive_and_process_flit(trans); + } + break; + } +} + +tlm::tlm_sync_enum NetworkInterfaceTlm::send_end_req(tlm_gp& trans){ + // Queue the acceptance and the response with the appropriate latency + tlm::tlm_phase bw_phase = tlm::END_REQ; + sc_time delay = sc_time(REQ_END_DELAY, UNITS_DELAY); // Accept delay + + tlm::tlm_sync_enum status = target->nb_transport_bw(trans, + bw_phase, delay); + if (status == tlm::TLM_COMPLETED) { + trans.release(); + return status; + } + + // Queue internal event to mark beginning of response + delay = delay + sc_time(INTERN_PROC_DELAY, UNITS_DELAY); // Latency + target_peq.notify(trans, INTERNAL_PROC_PHASE, delay); + + return status; +} + + +void NetworkInterfaceTlm::send_response(tlm_gp& trans){ + resp_in_progress = true; + sc_time delay = SC_ZERO_TIME; + tlm::tlm_phase bw_phase = tlm::BEGIN_RESP; + + tlm::tlm_sync_enum status = target->nb_transport_bw( + trans, bw_phase, delay); + credit_counter--; + + if (status == tlm::TLM_UPDATED){ + target_peq.notify(trans, bw_phase, delay); + } + else if (status == tlm::TLM_COMPLETED) { + // The initiator has terminated the transaction + trans.release(); + resp_in_progress = false; + credit_counter++; + } +} + + +void NetworkInterfaceTlm::log_info(string msg){ + string log_msg = ni_name + ": (Node" + + to_string(node.id)+"): "+msg; + SC_REPORT_INFO(NI_LOG, (log_msg).c_str()); +} + +void NetworkInterfaceTlm::log_error(string msg){ + string log_msg = ni_name + ": (Node" + + to_string(node.id)+"): "+msg; + SC_REPORT_ERROR(NI_LOG, (log_msg).c_str()); +} + +void NetworkInterfaceTlm::log_fatal(string msg){ + string log_msg = ni_name + ": (Node" + + to_string(node.id)+"): "+msg; + SC_REPORT_FATAL(NI_LOG, (log_msg).c_str()); +} diff --git a/src/networkInterface/NetworkInterfaceTlm.h b/src/networkInterface/NetworkInterfaceTlm.h new file mode 100755 index 0000000..2f3924c --- /dev/null +++ b/src/networkInterface/NetworkInterfaceTlm.h @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (C) 2024 Juan Neyra + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#ifndef SC_INCLUDE_DYNAMIC_PROCESSES +#define SC_INCLUDE_DYNAMIC_PROCESSES +#endif + +#include "systemc.h" +#include "tlm.h" +#include +#include +#include + +#include "ratatoskrUtils/utils/Structures.h" +#include "ratatoskrUtils/utils/TrafficTracer.h" +#include "ratatoskrUtils/container/PacketContainer.h" +#include "ratatoskrUtils/networkInterface/NetworkInterface.h" + +#include "noc/noc.h" +#include "utils/memory_manager.h" +#include "utils/noc_logger.h" + + +using namespace tlm_utils; + +class NetworkInterfaceTlm : public NetworkInterface { +public: + typedef simple_initiator_socket_tagged ni_init_socket; + typedef simple_target_socket_tagged ni_targ_socket; + + std::queue packet_send_queue; + std::queue packet_recv_queue; + + string ni_name; + // To PE + sc_in clk; + PacketPortContainer* packetPortContainer; + // To Router + ni_init_socket initiator; + ni_targ_socket target; + tlm_utils::peq_with_cb_and_phase init_peq; + tlm_utils::peq_with_cb_and_phase target_peq; + tlm_gp* curr_req; + tlm_gp* end_req_pend; + tlm_gp* nxt_resp_pend; + tlm_gp* nxt_send_data_pend; + bool resp_in_progress; + bool send_data_in_progress; + int credit_counter; + Dir send_data_in_prog_dest; + MemoryManager m_mm; + uint8_t max_pos[3]; + + sc_event_or_list ev_msg_arrv; + + SC_HAS_PROCESS(NetworkInterfaceTlm); + + NetworkInterfaceTlm(sc_module_name nm, Node& node, uint8_t max_pos[3]); + + ~NetworkInterfaceTlm() override; + + /** + * Not implemented, nothing to initialize, come from parent class + */ + void initialize() override; + + /** + * Binds packet port container to Processing Element + * + * @param con connection struct + * @param sigContIn input signals for port + * @param sigContOut output signal for port + */ + void bind(Connection* conn, SignalContainer* sigContIn, + SignalContainer* sigContOut) override; + + /** + * Main SC THREAD. Has logic to send and receive flits + */ + void thread() override; + + /** + * Gets current flit to transmit and send it to the router in noc + */ + void send_data_to_noc(); + + /** + * Generates flits when a packet arrives + */ + void receivePacketFromPE() override; + + /** + * Not implemented. TLM's target nb_transport_fw_cb callback + * used instead + */ + void receiveFlitFromRouter(); + + /** + * Used inside receivePacketFromPE to generate flits + * + * @param p packet from which to generate flits + */ + void generateFlitsForPacket(Packet *p); + + /** + * Gets the node position and the destination of packet + * as strings + * + * @param p packet from which to extract destination + * @param pos stores the start (0) and end position (1) + */ + void get_start_end_pos_string(Packet* p, string pos[2]); + + /** + * Checks transaction for errors, if no error found, log + * transaction and release transaction object. Called when + * transaction is completed + * + * @param trans TLM transaction object + */ + void check_transaction(tlm_gp& trans); + + /** + * Logs the arrival of a flit + * + * @param trans TLM transaction object + */ + void receive_and_process_flit(tlm_gp& trans); + + /** + * Callback function for non blocking transport forward + * + * @param id active link + * @param trans TLM generic payload object + * @param phase TLM current phase + * @param delay TLM expected delay + */ + tlm::tlm_sync_enum nb_transport_fw_cb(int id, tlm_gp& trans, + tlm::tlm_phase& phase, sc_time& delay); + + /** + * Callback function for non blocking transport backward + * + * @param id active link + * @param trans TLM generic payload object + * @param phase TLM current phase + * @param delay TLM expected delay + */ + tlm::tlm_sync_enum nb_transport_bw_cb(int id, tlm_gp& trans, + tlm::tlm_phase& phase, sc_time& delay); + + /** + * Callback initiator Payload Event Queue (PEQ) + * + * @param trans TLM generic payload object + * @param phase TLM current phase + */ + void init_peq_cb(tlm_gp& trans, const tlm::tlm_phase& phase); + + /** + * Callback target Payload Event Queue (PEQ) + * + * @param trans TLM generic payload object + * @param phase TLM current phase + */ + void target_peq_cb(tlm_gp& trans, const tlm::tlm_phase& phase); + + /** + * Send end request + * + * @param trans TLM generic payload object + */ + tlm::tlm_sync_enum send_end_req(tlm_gp& trans); + + /** + * Send begin response + * + * @param link active link + * @param trans TLM generic payload object + */ + void send_response(tlm_gp& trans); + + + /** Log info + * @param msg log message + */ + void log_info(string msg); + + /** Log error + * @param msg log message + */ + void log_error(string msg); + + /** Log fatal + * @param msg log message + */ + void log_fatal(string msg); +}; diff --git a/src/networkManager/NetworkManager.cpp b/src/networkManager/NetworkManager.cpp new file mode 100755 index 0000000..83e0d5d --- /dev/null +++ b/src/networkManager/NetworkManager.cpp @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (C) 2024 Juan Neyra + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "NetworkManager.h" +#include "ratatoskrUtils/traffic/synthetic/SyntheticPool.h" +#include "ratatoskrUtils/traffic/task/TaskPool.h" +#include "ratatoskrUtils/traffic/netrace/NetracePool.h" + + +NetworkManager::NetworkManager(sc_module_name nm, std::string configFolder){ + dbid = rep.registerElement("NetworkManager", 0); + tlmNoc = new TlmNoc("TlmNoc", configFolder); + + networkParticipants.resize(globalResources.nodes.size()); + createTrafficPool(); + createClocks(); + createNetworkParticipants(); + createLinks(); + runNoC(); +} + +void NetworkManager::createClocks() { + clocks.resize(globalResources.nodeTypes.size()); + for (const auto &nodeType : globalResources.nodeTypes) { + clocks.at(nodeType->id) = std::make_unique( + ("NodeType" + std::to_string(nodeType->id) + "Clock").c_str(), + nodeType->clockDelay, SC_NS); + } +} + + +void NetworkManager::createTrafficPool() { + unsigned long numOfPEs = globalResources.nodes.size() / 2; +#ifndef ENABLE_NETRACE + if (globalResources.benchmark == "task") { + tp = std::make_unique(); + } else if (globalResources.benchmark == "synthetic") { + tp = std::make_unique(); + } else { + FATAL("Please specify correct benchmark type"); + } +#endif +#ifdef ENABLE_NETRACE + tp = std::make_unique("NetracePool"); +#endif + tp->processingElements.resize(numOfPEs); +} + +void NetworkManager::createNetworkParticipants() { + int numOfPEs = tp->processingElements.size(); + for (Node &n : globalResources.nodes) { + if (n.type->model == "ProcessingElement") { + // Creating an network interface + std::string ni_name = "ni_" + std::to_string(n.id % numOfPEs); + uint8_t max_pos[3]; + get_max_pos(max_pos); + NetworkInterfaceTlm *ni = new NetworkInterfaceTlm( + ni_name.c_str(), n, max_pos); + ni->clk(*clocks.at(n.type->id)); + networkParticipants.at(n.id) = dynamic_cast(ni); + + std::string pe_name = "pe_" + std::to_string(n.id % numOfPEs); + ProcessingElementVC *pe = new ProcessingElementVC(pe_name.c_str(), n, tp.get()); + std::unique_ptr sig1 = + std::make_unique( + ("packetSigCon1_" + std::to_string(n.id)).c_str()); + std::unique_ptr sig2 = + std::make_unique( + ("packetSigCon2_" + std::to_string(n.id)).c_str()); + ni->bind(nullptr, sig1.get(), sig2.get()); + pe->bind(nullptr, sig2.get(), sig1.get()); + networkParticipants.push_back(dynamic_cast(pe)); + packetSignalContainers.push_back(move(sig1)); + packetSignalContainers.push_back(move(sig2)); + tp->processingElements.at(n.id % numOfPEs) = pe; + } + } +} + + + +void NetworkManager::createLinks() { + int link_id = 0; + for (auto &c : globalResources.connections) { + int connNodesSize = c.nodes.size(); + if (connNodesSize == 2) { //might extend to bus architecture + // gets nodes for connections + Node &node1 = globalResources.nodes.at(c.nodes.at(0)); + Node &node2 = globalResources.nodes.at(c.nodes.at(1)); + bool is_node1_pe = node1.type->model == "ProcessingElement"; + bool is_node2_pe = node2.type->model == "ProcessingElement"; + if (is_node1_pe || is_node2_pe){ + int ni_id = is_node1_pe ? node1.id : node2.id; + int rout_id = is_node1_pe ? node2.id : node1.id; + NetworkInterfaceTlm* ni = + dynamic_cast( + networkParticipants.at(ni_id)); + MyRouter* router = tlmNoc->getRouterNodeId(rout_id); + ni->initiator.bind(*router->target_socket[DIR::Local]); + router->init_socket[DIR::Local]->bind(ni->target); + } + link_id += 2; + } else { + LOG(true,"Unsupported number of endpoints in connection "+to_string(c.id)); + } + } +} + +void NetworkManager::runNoC() { + for (auto &r : networkParticipants) { + if (r) { + r->initialize(); + } + } + tp->start(); +} \ No newline at end of file diff --git a/src/networkManager/NetworkManager.h b/src/networkManager/NetworkManager.h new file mode 100755 index 0000000..12f6ebc --- /dev/null +++ b/src/networkManager/NetworkManager.h @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (C) 2024 Juan Neyra + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#ifndef SC_INCLUDE_DYNAMIC_PROCESSES +#define SC_INCLUDE_DYNAMIC_PROCESSES +#endif + +#include "systemc.h" +#include "tlm.h" + +#include "ratatoskrUtils/utils/GlobalResources.h" +#include "ratatoskrUtils/utils/Report.h" +#include "ratatoskrUtils/utils/Structures.h" +#include "ratatoskrUtils/traffic/TrafficPool.h" + +#include "networkInterface/NetworkInterfaceTlm.h" +#include "noc/noc.h" + +using namespace tlm; + +class NetworkManager : public sc_module{ +public: + SC_HAS_PROCESS(NetworkManager); + + explicit NetworkManager(sc_module_name, std::string); + +private: + GlobalResources& globalResources = GlobalResources::getInstance(); + Report& rep = Report::getInstance(); + int dbid; + std::vector> clocks; + std::unique_ptr tp; + TlmNoc* tlmNoc; + std::vector networkParticipants; + std::vector> packetSignalContainers; + + /** + * Create clocks for Ratatoskr PEs + */ + void createClocks(); + + /** + * Create the traffic pool with the tasks for PEs + */ + void createTrafficPool(); + + /** + * Create Network Participants (creates PE and NI, and + * connects them) + */ + void createNetworkParticipants(); + + /** + * Connects Network Interface to Routers in NoC + */ + void createLinks(); + + /** + * Initialize routers and starts traffic pool + */ + void runNoC(); +}; \ No newline at end of file diff --git a/src/noc/noc.cpp b/src/noc/noc.cpp new file mode 100755 index 0000000..0737b83 --- /dev/null +++ b/src/noc/noc.cpp @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (C) 2024 Juan Neyra + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "noc.h" +#include "utils/noc_logger.h" +#include "utils/utils.h" + +using namespace std; + +TlmNoc::TlmNoc(sc_module_name nm, string config_folder): sc_module(nm){ + setup_logger(); + sc_report_handler::set_actions(N_LOG, SC_INFO, SC_LOG|SC_DISPLAY); + initializeGlobalResources(config_folder); + initNoc(); + connectNoc(); +} + +TlmNoc::~TlmNoc() { +} + +void TlmNoc::initializeGlobalResources(string config_folder) { + // initialize global resources and rep + globalResources = GlobalResources::getInstance(); + GlobalReport &globalReport = GlobalReport::getInstance(); + Report &rep = Report::getInstance(); + sleep(1); + + string config_path = "config/"+config_folder+"/config.xml";//"config/config.xml"; + globalResources.readConfigFile(config_path); + globalReport.readConfigFile(config_path); + + string network_path = "config/"+config_folder+"/net.xml"; + //globalResources.noc_file; + globalResources.readNoCLayout(network_path); + globalResources.readTaskAndMapFiles(globalResources.data_file, globalResources.map_file); + globalReport.resizeMatrices(); + + globalResources.activateFlitTracing = false; + globalResources.outputDirectory = "out"; +} + +void TlmNoc::initNoc() { + uint8_t max_pos[3]; + get_max_pos(max_pos); + + for (Node &n : globalResources.nodes) { + if (n.type->model == "RouterVC") { + string name = "router_" + to_string(n.id); + float float_rout_pos[3] = {n.pos.x, n.pos.y, n.pos.z}; + uint8_t rout_pos[3]; + convert_pos_to_int(float_rout_pos, rout_pos); + + string msg = name + " initialized in position " + + to_string(rout_pos[0]) + "," + to_string(rout_pos[1]) + + "," + to_string(rout_pos[2]); + log_info(msg); + MyRouter *r = new MyRouter(name.c_str(), rout_pos, max_pos); + routers.push_back(r); + int id = routers.size()-1; + mapNodeRouter.insert( + pair(n.id, int(routers.size())-1)); + } + } +} + + +void TlmNoc::connectRouters(Node node1, Node node2, int link){ + int n1_id = mapNodeRouter[node1.id]; + int n2_id = mapNodeRouter[node2.id]; + if(node1.type->model == "RouterVC" && + node2.type->model == "RouterVC"){ + int connDir = node1.getDirOfCon(link); + int opposDir = DIR::getOppositeDir(connDir); + + routers[n1_id]->init_socket[connDir]->bind( + *routers[n2_id]->target_socket[opposDir]); + routers[n2_id]->init_socket[opposDir]->bind( + *routers[n1_id]->target_socket[connDir]); + routers[n1_id]->valid_links[connDir] = true; + routers[n2_id]->valid_links[opposDir] = true; + log_conn(routers[n1_id]->router_name,routers[n2_id]->router_name, + DIR::toString(connDir), DIR::toString(opposDir)); + } + else{ + int r_id = node1.type->model == "RouterVC" ? n1_id:n2_id; + api_initiators.push_back(routers[r_id]->init_socket[DIR::Local]); + api_targets.push_back(routers[r_id]->target_socket[DIR::Local]); + routers[r_id]->valid_links[DIR::Local] = true; + log_conn(routers[r_id]->router_name, "noc interface", + DIR::toString(DIR::Local), "external"); + } + +} + + +void TlmNoc::connectUnbounded(){ + // connecting unbounded routers + for (uint8_t id=0; id < routers.size(); id++){ + for (uint8_t dir=0; dir < Direction::num_dirs; dir++){ + if (!routers[id]->valid_links[dir]){ + tlm_init_socket* unbound_init = new tlm_init_socket( + ("unb_init_"+to_string(id)+"_"+to_string(dir)).c_str()); + unbound_init->bind(*routers[id]->target_socket[dir]); + unbounded_initiators.push_back(unbound_init); + + tlm_targ_socket* unbound_targ = new tlm_targ_socket( + ("unb_targ_"+to_string(id)+"_"+to_string(dir)).c_str()); + routers[id]->init_socket[dir]->bind(*unbound_targ); + unbounded_targets.push_back(unbound_targ); + + log_conn(routers[id]->router_name, "unbounded_" + + to_string(id)+"_"+to_string(dir), + DIR::toString(dir), "unbounded"); + } + } + } + +} + + +void TlmNoc::connectNoc(){ + int link_id = 0; + for (auto &c : globalResources.connections) { + if(c.nodes.size() == 2){ + Node &node1 = globalResources.nodes.at(c.nodes.at(0)); + Node &node2 = globalResources.nodes.at(c.nodes.at(1)); + connectRouters(node1, node2, c.id); + link_id += 2; + } else { + log_error("Unsupported number of endpoints in connection " + + to_string(c.id)); + } + } + + connectUnbounded(); +} + +MyRouter* TlmNoc::getRouter(int id){ + return routers.at(id); +} + +MyRouter* TlmNoc::getRouterNodeId(int node_id){ + int rout_id = mapNodeRouter.find(node_id)->first; + return routers.at(rout_id); +} + + +/******************* LOG FUNCTIONS ********************/ +void TlmNoc::log_info(string msg){ + SC_REPORT_INFO(N_LOG, (msg).c_str()); +} + +void TlmNoc::log_warn(string msg){ + SC_REPORT_WARNING(N_LOG, (msg).c_str()); +} + +void TlmNoc::log_error(string msg){ + SC_REPORT_ERROR(N_LOG, (msg).c_str()); +} + +void TlmNoc::log_conn(string router1, string router2, + string link1, string link2){ + string msg = router1 + " on link " + link1 + " connected to " + + router2 + " on link " + link2; + log_info(msg); +} + diff --git a/src/noc/noc.h b/src/noc/noc.h new file mode 100755 index 0000000..94e652e --- /dev/null +++ b/src/noc/noc.h @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (C) 2024 Juan Neyra + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#ifndef SC_INCLUDE_DYNAMIC_PROCESSES +#define SC_INCLUDE_DYNAMIC_PROCESSES +#endif + +#include +#include +#include +#include + +#include "systemc.h" +#include "tlm.h" + +#include "ratatoskrUtils/utils/Structures.h" +#include "ratatoskrUtils/utils/GlobalResources.h" + +#include "router/router.h" + +using namespace tlm; + +class TlmNoc : public sc_module { +public: + typedef tlm_utils::simple_initiator_socket_tagged tlm_init_socket; + typedef tlm_utils::simple_target_socket_tagged tlm_targ_socket; + + SC_HAS_PROCESS(TlmNoc); + + explicit TlmNoc(sc_module_name, string); + + ~TlmNoc() override; + + std::vector api_initiators; + std::vector api_targets; + uint8_t max_pos[3]; + std::map mapNodeRouter; + MyRouter* getRouter(int id); + MyRouter* getRouterNodeId(int node_id); + +private: + std::vector routers; + uint8_t num_rout_x; + uint8_t num_rout_y; + uint8_t num_rout_z; + std::vector unbounded_initiators; + std::vector unbounded_targets; + + GlobalResources& globalResources = GlobalResources::getInstance(); + + /** + * Initialize global resources + */ + void initializeGlobalResources(string config_folder); + + /** + * Initialize variable in noc + */ + void initNoc(); + + + /** + * Connects two routers or a router and a core (network interface) + * + * @param node1 first node to connect + * @param node2 second node to connect + * @param link link of first node that will be connected + */ + void connectRouters(Node node1, Node node2, int link); + + /** + * Connects unbounded links to dummy initiators and targets + */ + void connectUnbounded(); + + /** + * Connects all routers using GlobalResources object + */ + void connectNoc(); + + + /** Log info + * @param msg log message + */ + void log_info(string msg); + + /** Log warning + * @param msg log message + */ + void log_warn(string msg); + + /** Log error + * @param msg log message + */ + void log_error(string msg); + + /** Log a connection between two routers + * @param router1 name of router 1 + * @param router2 name of router 2 + * @param link1 name of connected link in router 1 + * @param link2 name of connected link in router 2 + */ + void log_conn(string router1, string router2, + string link1, string link2); +}; diff --git a/src/ratatoskrUtils/container/ClassicContainer.h b/src/ratatoskrUtils/container/ClassicContainer.h new file mode 100755 index 0000000..1d4941c --- /dev/null +++ b/src/ratatoskrUtils/container/ClassicContainer.h @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "Container.h" + +class ClassicSignalContainer : public SignalContainer { +public: + sc_signal sigValid; + sc_signal*> sigFlowControl; + sc_signal sigData; + sc_signal sigVc; + + ClassicSignalContainer(sc_module_name nm) + : + SignalContainer(nm) + { + }; + + ~ClassicSignalContainer() + { + }; + +}; + +class ClassicPortContainer : public PortContainer { +public: + sc_in portValidIn; + sc_in*> portFlowControlIn; + sc_in portDataIn; + sc_in portVcIn; + + sc_out portValidOut; + sc_out*> portFlowControlOut; + sc_out portDataOut; + sc_out portVcOut; + + ClassicPortContainer(sc_module_name nm) + : + PortContainer(nm) + { + }; + + ~ClassicPortContainer() + { + }; + + void bind(SignalContainer* sIn, SignalContainer* sOut) + { + auto cscin = dynamic_cast(sIn); + auto cscout = dynamic_cast(sOut); + + assert(cscin); + assert(cscout); + + portValidIn(cscin->sigValid); + portFlowControlIn(cscin->sigFlowControl); + portDataIn(cscin->sigData); + portVcIn(cscin->sigVc); + + portValidOut(cscout->sigValid); + portFlowControlOut(cscout->sigFlowControl); + portDataOut(cscout->sigData); + portVcOut(cscout->sigVc); + + }; + + void bindOpen(SignalContainer* sIn) + { + auto cscin = dynamic_cast(sIn); + + assert(cscin); + + portValidIn(cscin->sigValid); + portFlowControlIn(cscin->sigFlowControl); + portDataIn(cscin->sigData); + portVcIn(cscin->sigVc); + + portValidOut(portOpen); + portFlowControlOut(portOpen); + portDataOut(portOpen); + portVcOut(portOpen); + } +}; + diff --git a/src/ratatoskrUtils/container/Container.h b/src/ratatoskrUtils/container/Container.h new file mode 100755 index 0000000..5b4f7bc --- /dev/null +++ b/src/ratatoskrUtils/container/Container.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "systemc.h" + +#include "ratatoskrUtils/utils/portsOpenConst.h" + +class SignalContainer : public sc_module { +public: + explicit SignalContainer(const sc_module_name& nm) { }; + + ~SignalContainer() override = default; +}; + +class PortContainer : public sc_module { +public: + explicit PortContainer(const sc_module_name& nm) { }; + + ~PortContainer() override = default; + + virtual void bind(SignalContainer*, SignalContainer*) = 0; +}; diff --git a/src/ratatoskrUtils/container/FlitContainer.h b/src/ratatoskrUtils/container/FlitContainer.h new file mode 100644 index 0000000..eb7312a --- /dev/null +++ b/src/ratatoskrUtils/container/FlitContainer.h @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "Container.h" + +#include "ratatoskrUtils/traffic/Flit.h" +#include "ratatoskrUtils/utils/Structures.h" + +class FlitSignalContainer : public SignalContainer { +public: + sc_signal sigValid; + sc_signal sigFlowControlValid; + sc_signal sigFlowControl; + sc_signal sigData; + sc_signal sigVc; + + explicit FlitSignalContainer(const sc_module_name& nm) + : + SignalContainer(nm) + { + } + + ~FlitSignalContainer() override = default; + +}; + +class FlitPortContainer : public PortContainer { +public: + sc_in portValidIn; + sc_in portFlowControlValidIn; + sc_in portFlowControlIn; + sc_in portDataIn; + sc_in portVcIn; + + sc_out portValidOut; + sc_out portFlowControlValidOut; + sc_out portFlowControlOut; + sc_out portDataOut; + sc_out portVcOut; + + explicit FlitPortContainer(const sc_module_name& nm) + : + PortContainer(nm) + { + } + + ~FlitPortContainer() override = default; + + void bind(SignalContainer* sIn, SignalContainer* sOut) override + { + auto cscin = dynamic_cast(sIn); + auto cscout = dynamic_cast(sOut); + + assert(cscin); + assert(cscout); + + portValidIn(cscin->sigValid); + portFlowControlValidIn(cscin->sigFlowControlValid); + portFlowControlIn(cscin->sigFlowControl); + portDataIn(cscin->sigData); + portVcIn(cscin->sigVc); + + portValidOut(cscout->sigValid); + portFlowControlValidOut(cscout->sigFlowControlValid); + portFlowControlOut(cscout->sigFlowControl); + portDataOut(cscout->sigData); + portVcOut(cscout->sigVc); + + } + + void bindOpen(SignalContainer* sIn) + { + auto cscin = dynamic_cast(sIn); + + assert(cscin); + + portValidIn(cscin->sigValid); + portFlowControlValidIn(cscin->sigFlowControlValid); + portFlowControlIn(cscin->sigFlowControl); + portDataIn(cscin->sigData); + portVcIn(cscin->sigVc); + + portValidOut(portOpen); + portFlowControlValidOut(portOpen); + portFlowControlOut(portOpen); + portDataOut(portOpen); + portVcOut(portOpen); + } +}; diff --git a/src/ratatoskrUtils/container/PacketContainer.h b/src/ratatoskrUtils/container/PacketContainer.h new file mode 100755 index 0000000..911f112 --- /dev/null +++ b/src/ratatoskrUtils/container/PacketContainer.h @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "Container.h" +#include "ratatoskrUtils/traffic/Packet.h" + +class PacketSignalContainer : public SignalContainer { +public: + sc_signal sigValid; + sc_signal sigFlowControl; + sc_signal sigData; + + explicit PacketSignalContainer(const sc_module_name& nm) + : + SignalContainer(nm) + { + }; + + ~PacketSignalContainer() override = default; + +}; + +class PacketPortContainer : public PortContainer { +public: + sc_in portValidIn; + sc_in portFlowControlIn; + sc_in portDataIn; + + sc_out portValidOut; + sc_out portFlowControlOut; + sc_out portDataOut; + + explicit PacketPortContainer(const sc_module_name& nm) + : + PortContainer(nm) + { + } + + ~PacketPortContainer() override = default; + + void bind(SignalContainer* sIn, SignalContainer* sOut) override + { + auto cscin = dynamic_cast(sIn); + auto cscout = dynamic_cast(sOut); + + assert(cscin); + assert(cscout); + + portValidIn(cscin->sigValid); + portFlowControlIn(cscin->sigFlowControl); + portDataIn(cscin->sigData); + portValidOut(cscout->sigValid); + portFlowControlOut(cscout->sigFlowControl); + portDataOut(cscout->sigData); + }; + + void bindOpen(SignalContainer* sIn) + { + auto cscin = dynamic_cast(sIn); + + assert(cscin); + + portValidIn(cscin->sigValid); + portFlowControlIn(cscin->sigFlowControl); + portDataIn(cscin->sigData); + portValidOut(portOpen); + portFlowControlOut(portOpen); + portDataOut(portOpen); + } +}; diff --git a/src/ratatoskrUtils/link/Link.cpp b/src/ratatoskrUtils/link/Link.cpp new file mode 100755 index 0000000..b96e5af --- /dev/null +++ b/src/ratatoskrUtils/link/Link.cpp @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "Link.h" + +Link::Link(sc_module_name nm, const Connection& c, int globalID) + : + id(c.id), + globalID(globalID), + previousTransmissionState(0), + currentTransmissionState(0) +{ + classicPortContainer = new FlitPortContainer( + ("link_portCont_"+std::to_string(this->id)).c_str()); + + // this->rawDataOutput = new ofstream((std::string) nm + ".txt"); + SC_THREAD(passthrough_thread); + sensitive << clk.pos(); +} + +Link::~Link() +{ + delete classicPortContainer; + // rawDataOutput->close(); + // delete rawDataOutput; +} + +void Link::passthrough_thread() +{ + while (true) { + wait(); + wait(0, SC_NS); + std::string outputToFile; + + int IDLESTATE = 0; + int HEADSTATE = 1; + int HEADIDLESTATE = 2; + int offset = 3; // three fields: idle, head, headidle + + if (!classicPortContainer->portValidIn.read()) { + // this cycle idle + if (previousTransmissionState==IDLESTATE) { + // initially, no flits traverse links + outputToFile = "__;"; + currentTransmissionState = IDLESTATE; + } + else if (flitType==HEAD) { + // a head flit traversed previously + outputToFile = std::to_string(flitDataType) + "_;"; + currentTransmissionState = HEADIDLESTATE; + } + else { + // a flit already traversed the links + outputToFile = std::to_string(flitDataType) + "_;"; + if (flitType!=HEAD && flitType!=BODY && flitType!=TAIL) + continue; + currentTransmissionState = (2*flitDataType) + offset + 1; + } + } + else { + // this cycle active + Flit* currentFlit = classicPortContainer->portDataIn.read(); + flitType = currentFlit->type; + flitDataType = currentFlit->dataType; + flitID = currentFlit->id; + if (flitType==HEAD) { + //received head flit + outputToFile = "HD;"; + currentTransmissionState = HEADSTATE; + } + else { + // received data flit + outputToFile = std::to_string(flitDataType) + "D;"; + if (flitType!=HEAD && flitType!=BODY && flitType!=TAIL) + continue; + currentTransmissionState = (2*flitDataType) + offset; + } + } + + //rawDataOutput->write(outputToFile.c_str(), 3); + //rawDataOutput->flush(); + report.issueLinkMatrixUpdate(globalID, currentTransmissionState, previousTransmissionState); + + previousTransmissionState = currentTransmissionState; + } +} + +void Link::bind(SignalContainer* sigContIn, SignalContainer* sigContOut) +{ + classicPortContainer->bind(sigContIn, sigContOut); +} + +void Link::bindOpen(SignalContainer* sigContIn) +{ + classicPortContainer->bindOpen(sigContIn); +} diff --git a/src/ratatoskrUtils/link/Link.h b/src/ratatoskrUtils/link/Link.h new file mode 100755 index 0000000..d94a04e --- /dev/null +++ b/src/ratatoskrUtils/link/Link.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "systemc.h" +#include +#include + +#include "ratatoskrUtils/traffic/Flit.h" +#include "ratatoskrUtils/traffic/Packet.h" +#include "ratatoskrUtils/container/FlitContainer.h" +#include "ratatoskrUtils/utils/GlobalResources.h" +#include "ratatoskrUtils/utils/GlobalReport.h" + +class Link : public sc_module { +public: + GlobalResources& globalResources = GlobalResources::getInstance(); + GlobalReport& report = GlobalReport::getInstance(); + int id, globalID; + dataTypeID_t flitDataType; + flitID_t flitID; + FlitType flitType; + + int previousTransmissionState; + int currentTransmissionState; + // UNCOMMENT FOR RAW DATA ON LINK (@Lennart) + // ofstream *rawDataOutput; + sc_in clk; + FlitPortContainer* classicPortContainer; + + SC_HAS_PROCESS(Link); + + Link(sc_module_name nm, const Connection& c, int globalID); + + ~Link() override; + + void bind(SignalContainer* sigContIn, SignalContainer* sigContOut); + + void bindOpen(SignalContainer* sigContIn); + + void passthrough_thread(); +}; + diff --git a/src/ratatoskrUtils/model/NetworkParticipant.h b/src/ratatoskrUtils/model/NetworkParticipant.h new file mode 100755 index 0000000..529b762 --- /dev/null +++ b/src/ratatoskrUtils/model/NetworkParticipant.h @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (C) 2018 joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "systemc.h" +#include +#include + +#include "ratatoskrUtils/utils/GlobalResources.h" +#include "ratatoskrUtils/utils/GlobalReport.h" +#include "ratatoskrUtils/utils/Report.h" +#include "ratatoskrUtils/container/Container.h" + +class NetworkParticipant { +public: + GlobalResources& globalResources = GlobalResources::getInstance(); + GlobalReport& globalReport = GlobalReport::getInstance(); + Report& rep = Report::getInstance(); + PacketFactory& packetFactory = PacketFactory::getInstance(); + + virtual void initialize() = 0; + + virtual void bind(Connection*, SignalContainer*, SignalContainer*) = 0; + + ~NetworkParticipant() = default; +}; diff --git a/src/ratatoskrUtils/networkInterface/NetworkInterface.cpp b/src/ratatoskrUtils/networkInterface/NetworkInterface.cpp new file mode 100755 index 0000000..1cffaae --- /dev/null +++ b/src/ratatoskrUtils/networkInterface/NetworkInterface.cpp @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (C) 2018 joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "NetworkInterface.h" + +NetworkInterface::NetworkInterface(sc_module_name nm, Node& node) + : + id(node.id), + node(node) +{ + this->dbid = rep.registerElement("NetworkInterface", this->id); + + rep.reportAttribute(dbid, "pos_x", std::to_string(node.pos.x)); + rep.reportAttribute(dbid, "pos_y", std::to_string(node.pos.y)); + rep.reportAttribute(dbid, "pos_z", std::to_string(node.pos.z)); + rep.reportAttribute(dbid, "clock", std::to_string(node.type->clockDelay)); + rep.reportAttribute(dbid, "type", node.type->model); +} diff --git a/src/ratatoskrUtils/networkInterface/NetworkInterface.h b/src/ratatoskrUtils/networkInterface/NetworkInterface.h new file mode 100755 index 0000000..643d029 --- /dev/null +++ b/src/ratatoskrUtils/networkInterface/NetworkInterface.h @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (C) 2018 joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "systemc.h" +#include +#include + +#include "ratatoskrUtils/model/NetworkParticipant.h" +#include "ratatoskrUtils/utils/Structures.h" +#include "ratatoskrUtils/utils/GlobalReport.h" +#include "ratatoskrUtils/traffic/Packet.h" + +class NetworkInterface : public NetworkParticipant, public sc_module { +public: + int id; + int dbid; + Node node; + Report& rep = Report::getInstance(); + + SC_HAS_PROCESS(NetworkInterface); + + NetworkInterface(sc_module_name nm, Node& node); + + virtual void thread() = 0; + + virtual void receivePacketFromPE() = 0; + + virtual void receiveFlitFromRouter() = 0; + + virtual void generateFlitsForPacket(Packet *p) = 0; +}; + diff --git a/src/ratatoskrUtils/processingElement/ProcessingElement.cpp b/src/ratatoskrUtils/processingElement/ProcessingElement.cpp new file mode 100755 index 0000000..c5831fc --- /dev/null +++ b/src/ratatoskrUtils/processingElement/ProcessingElement.cpp @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (C) 2018 joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "ProcessingElement.h" + +ProcessingElement::ProcessingElement(sc_module_name mn, Node& node, TrafficPool* tp) + : + node(node), + trafficPool(tp) +{ + this->id = node.id%(globalResources.nodes.size()/2); + this->dbid = rep.registerElement("NetworkInterface", this->id); + rep.reportAttribute(dbid, "pos_x", std::to_string(node.pos.x)); + rep.reportAttribute(dbid, "pos_y", std::to_string(node.pos.y)); + rep.reportAttribute(dbid, "pos_z", std::to_string(node.pos.z)); + rep.reportAttribute(dbid, "clock", std::to_string(node.type->clockDelay)); + rep.reportAttribute(dbid, "type", node.type->model); +} diff --git a/src/ratatoskrUtils/processingElement/ProcessingElement.h b/src/ratatoskrUtils/processingElement/ProcessingElement.h new file mode 100755 index 0000000..b68657c --- /dev/null +++ b/src/ratatoskrUtils/processingElement/ProcessingElement.h @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (C) 2018 joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "systemc.h" +#include +#include +#include "ratatoskrUtils/model/NetworkParticipant.h" + +class TrafficPool; + +class ProcessingElement : public NetworkParticipant, public sc_module { +public: + int id; + int dbid; + Node& node; + TrafficPool* trafficPool; + + SC_HAS_PROCESS(ProcessingElement); + + ProcessingElement(sc_module_name mn, Node& node, TrafficPool* tp); + + virtual void receive() = 0; + + virtual void execute(Task&) = 0; + + virtual void thread() = 0; +}; + diff --git a/src/ratatoskrUtils/processingElement/ProcessingElementVC.cpp b/src/ratatoskrUtils/processingElement/ProcessingElementVC.cpp new file mode 100755 index 0000000..8beb49d --- /dev/null +++ b/src/ratatoskrUtils/processingElement/ProcessingElementVC.cpp @@ -0,0 +1,391 @@ +/******************************************************************************* + * Copyright (C) 2018 joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include + +ProcessingElementVC::ProcessingElementVC(sc_module_name mn, Node& node, TrafficPool* tp) + : + ProcessingElement(mn, node, tp) +{ + this->packetPortContainer = new PacketPortContainer(("NI_PACKET_CONTAINER"+std::to_string(this->id)).c_str()); + + SC_THREAD(thread); + SC_METHOD(receive); + sensitive << packetPortContainer->portValidIn.pos(); +} + +void ProcessingElementVC::initialize() +{ + packetPortContainer->portValidOut.write(false); + packetPortContainer->portFlowControlOut.write(true); + // sc_spawn(sc_bind(&SyntheticPool::sendThread, this, con.first, + // con.second,initDelay,sp.waveCount,sp.waveDelay,sp.pkgPerWave, sp.name)); +} + +void ProcessingElementVC::thread() +{ +#ifndef ENABLE_NETRACE + while(true) { + int timeStamp = static_cast(sc_time_stamp().value()/1000); + + std::vector removeList; + + // EXPLAIN: check if time of the task has already been passed. If it has passed remove it. + for (auto const& tw : destWait) { + DataDestination dest = tw.first; + Task task = destToTask.at(dest); + if (taskTerminationTime.count(task) && taskTerminationTime.at(task)node, dstNode, globalResources.flitsPerPacket, sc_time_stamp().to_double(), + dest.dataType); + double time = sc_time_stamp().to_double(); + + // EXPLAIN: create packet and send it + if ((float) globalResources.synthetic_start_measurement_time<=(time/1000)) + globalReport.undeliveredPackages++; + + packetPortContainer->portValidOut = true; + packetPortContainer->portDataOut = p; + + // EXPLAIN: decrement number of packets left to be sent + countLeft.at(dest)--; + + // EXPLAIN: if there are no more packet to this destination remove destination from list of destinations + if (!countLeft.at(dest)) { + countLeft.erase(dest); + destWait.erase(dest); + + Task task = destToTask.at(dest); + destToTask.erase(dest); + taskToDest.at(task).erase(dest); + + // EXPLAIN: There are no more destinations to the task, all packets of the task has been send + if (taskToDest.at(task).empty()) { + taskToDest.erase(task); + execute(task); + } + } + // EXPLAIN: is there are more packets to the destination schedule the next packet + else { + destWait.at(dest) = + globalResources.getRandomIntBetween(dest.minInterval, dest.maxInterval)+timeStamp; + } + break; + } + } + + wait(SC_ZERO_TIME); + packetPortContainer->portValidOut = false; + + int nextCall = -1; + for (auto const& dw : destWait) { + if (nextCall>dw.second || nextCall==-1) { + /* In synthetic mode, we want to apply uniform_batch_mode experiment, + * that means all tasks need to send data once in one interval + * with some random offset in each interval. + */ + + /* TODO: + * Attention: we are always taking the minStart and minInterval to calculate the nextCall. + * In the future, we may add randomness to the process, + * by selecting a number between minStart and maxStart, + * and the same thing for minInterval and maxInterval. + */ + if (globalResources.benchmark=="synthetic") { + Task task = this->destToTask.at(dw.first); + int minInterval = dw.first.minInterval; + + if (timeStampnode.id) == globalResources.netraceNodeToTask.end()){ + auto clockDelay = this->node.type->clockDelay; + event.notify(clockDelay, SC_NS); + wait(event); + continue; + } + + if(ntInject.empty()){ + auto clockDelay = this->node.type->clockDelay; + event.notify(clockDelay, SC_NS); + wait(event); + continue; + } + + trace_packet = *ntInject.front().first.packet; + ntInject.pop(); + + float packetSizeInByte = (float) ntnetrace.nt_packet_sizes[trace_packet.type]; + int bytesLastPacket = (int)packetSizeInByte % (int)bytesPerPacket; + int packetsLeft = ((int)packetSizeInByte/ (int)bytesPerPacket) + (int)(bool)(bytesLastPacket); + + if (0 == bytesLastPacket) + bytesLastPacket = (int)bytesPerPacket; + + flitsLastPacket = (int) ceil(bytesLastPacket / bytesPerFlit) + 1; //header flit + + dstNode = globalResources.nodes.at(trace_packet.dst); + Packet* p; + + do{ + if (packetsLeft > 1) + p = packetFactory.createPacket(this->node, dstNode, globalResources.flitsPerPacket, sc_time_stamp().to_double(),1); + else + p = packetFactory.createPacket(this->node, dstNode, flitsLastPacket , sc_time_stamp().to_double(),1); + + packetPortContainer->portValidOut = true; + packetPortContainer->portDataOut = p; + wait(SC_ZERO_TIME); + packetPortContainer->portValidOut = false; + + auto clockDelay = this->node.type->clockDelay; + event.notify(clockDelay, SC_NS); + wait(event); + + }while(--packetsLeft > 0); + + } + +#endif + +} + +void ProcessingElementVC::execute(Task& task) +{ + // EXPLAIN: if there are no repetitions of the task left, create a new number of repetitions (probably used only in the first call for init) + if (!taskRepeatLeft.count(task)) { + taskRepeatLeft[task] = globalResources.getRandomIntBetween(task.minRepeat, task.maxRepeat); + } + else { + // EXPLAIN: decrement the number of repetitions left by 1 and if they reach 0 after that remove the task from list (task is done). + if (taskRepeatLeft.at(task)>0) { + taskRepeatLeft.at(task)--; + } + + if (!taskRepeatLeft.at(task)) { + taskRepeatLeft.erase(task); + return; + } + } + + // EXPLAIN: if there is no start time init one + if (!taskStartTime.count(task)) { + taskStartTime[task] = globalResources.getRandomIntBetween(task.minStart, task.maxStart); + } + + // EXPLAIN: if there is no termination time init one + if (!taskTerminationTime.count(task) && task.minDuration!=-1) { + taskTerminationTime[task] = + taskStartTime[task]+globalResources.getRandomIntBetween(task.minDuration, task.maxDuration); + } + + // EXPLAIN: if there are no requirements left start sending + if (task.requirements.empty()) { + startSending(task); + } + else { + // EXPLAIN: go through all requirements and add them to lists + for (DataRequirement& r : task.requirements) { + neededFor[r.dataType].insert(task); + neededAmount[std::make_pair(task, r.dataType)] = globalResources.getRandomIntBetween(r.minCount, + r.maxCount); + needs[task].insert(r.dataType); + } + } +} + +void ProcessingElementVC::bind(Connection* con, SignalContainer* sigContIn, SignalContainer* sigContOut) +{ + packetPortContainer->bind(sigContIn, sigContOut); +} + +void ProcessingElementVC::receive() +{ + LOG(globalReport.verbose_pe_function_calls, + "PE" << this->id << "(Node" << node.id << ")\t- receive_data_process()"); + + // EXPLAIN: checks for positive edge of the validIn signal. This is the trigger + if (packetPortContainer->portValidIn.posedge()) { + + // EXPLAIN: read packet from port + Packet* received_packet = packetPortContainer->portDataIn.read(); + + if (received_packet) { + dataTypeID_t type = received_packet->dataType; + + // EXPLAIN: check if receivedData already has a counter for the packet type of the received packet. If yes increment if, if no create one + if (receivedData.count(type)) { + ++receivedData.at(type); + } + else { + receivedData[type] = 1; + } + + // EXPLAIN: check if now all required data has arrived and if yes start sending data + checkNeed(); + + // EXPLAIN: delete packet + packetFactory.deletePacket(received_packet); + } + } +} + +// EXPLAIN: select possible destinations and set all timings and packet numbers for these destinations they are saved in destWait +void ProcessingElementVC::startSending(Task& task) +{ + // EXPLAIN: There are multiple possibilities where to send the data. Select one based on probability + float rn = globalResources.getRandomFloatBetween(0, 1); + int numOfPoss = task.possibilities.size(); + for (unsigned int i = 0; irn) { + + // EXPLAIN: A possibility is chosen. Set the destinations of this possibility as the dest of the task + std::vector destVec = task.possibilities.at(i).dataDestinations; + for (DataDestination& dest : destVec) { + destToTask[dest] = task; + taskToDest[task].insert(dest); + + // EXPLAIN: get random packet count per dest + countLeft[dest] = globalResources.getRandomIntBetween(dest.minCount, dest.maxCount); + + // EXPLAIN: random delay time to start sending data to dest + int delayTime = + static_cast((sc_time_stamp().value()/1000) + +globalResources.getRandomIntBetween(dest.minDelay, dest.maxDelay)); + + if (taskStartTime.count(task) && taskStartTime.at(task)>delayTime) { + destWait[dest] = taskStartTime.at(task); + } + else { + destWait[dest] = delayTime; + } + // EXPLAIN: schedule event in systemC + event.notify(SC_ZERO_TIME); + } + break; + } + else { + rn -= task.possibilities.at(i).probability; + } + } +} + +void ProcessingElementVC::checkNeed() +{ + // EXPLAIN: iterate through received data + for (auto const& data : receivedData) { + dataTypeID_t type = data.first; + std::vector> removeList; + + // EXPLAIN: check if there are task that need this data + if (neededFor.count(type)) { + + // EXPLAIN: iterate over tasks needing the data + for (const Task& t : neededFor.at(type)) { + std::pair pair = std::make_pair(t, type); + neededAmount.at(pair) -= receivedData.at(type); + /* This line was commented out because if a task requires several packets from several data types, + it says that the task is finished receiving the required packets while in fact, it still needs some packets. + receivedData.at(type) = 0; + */ + + // EXPLAIN: check if the needed amount (datatype for specific task) is reached. If yes remove the pair + if (neededAmount.at(pair)<=0) { + removeList.push_back(pair); + // This line is also commented out for the same reason mentioned above. + // receivedData.at(type) = -neededAmount.at(pair); + } + } + } + // EXPLAIN: remove data from lists + for (auto& p : removeList) { + neededFor.erase(p.second); + neededAmount.erase(p); + needs.at(p.first).erase(p.second); + + // EXPLAIN: check if all data requirements of the task are satisfied. If yes start sending + if (needs.at(p.first).empty()) { + startSending(p.first); + } + } + } +} + +ProcessingElementVC::~ProcessingElementVC() +{ + delete packetPortContainer; +} diff --git a/src/ratatoskrUtils/processingElement/ProcessingElementVC.h b/src/ratatoskrUtils/processingElement/ProcessingElementVC.h new file mode 100755 index 0000000..4e8638d --- /dev/null +++ b/src/ratatoskrUtils/processingElement/ProcessingElementVC.h @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (C) 2018 joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "systemc.h" +#include +#include +#include + +#include "ratatoskrUtils/traffic/Flit.h" +#include "ratatoskrUtils/traffic/TrafficPool.h" +#include "ratatoskrUtils/utils/GlobalResources.h" +#include "ratatoskrUtils/utils/Report.h" +#include "ratatoskrUtils/utils/Structures.h" +#include +#ifdef ENABLE_NETRACE +#include +#endif +#include "ProcessingElement.h" + +class ProcessingElementVC : public ProcessingElement { +public: + sc_event event; + PacketPortContainer* packetPortContainer; + std::map> neededFor; + std::map, int> neededAmount; + std::map> needs; + std::map receivedData; + std::map destToTask; + std::map> taskToDest; + std::map taskRepeatLeft; + std::map taskStartTime; + std::map taskTerminationTime; + std::map countLeft; + std::map destWait; + +#ifdef ENABLE_NETRACE + std::queue> ntInject; + std::queue> ntWaiting; +#endif + + SC_HAS_PROCESS(ProcessingElementVC); + + ProcessingElementVC(sc_module_name mn, Node& node, TrafficPool* tp); + + ~ProcessingElementVC(); + + void initialize() override; + + void bind(Connection*, SignalContainer*, SignalContainer*) override; + + void execute(Task&) override; + + void receive() override; + + void thread() override; + + void startSending(Task&); + + void checkNeed(); +}; diff --git a/src/ratatoskrUtils/traffic/Flit.cpp b/src/ratatoskrUtils/traffic/Flit.cpp new file mode 100755 index 0000000..2e57e90 --- /dev/null +++ b/src/ratatoskrUtils/traffic/Flit.cpp @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (C) 2018 joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "Flit.h" +#include "Packet.h" +#include "TrafficPool.h" + +long long Flit::idcnt = 0; + +Flit::Flit(FlitType type, long long seq_nb, Packet* p) + : + type(type), + seq_nb(seq_nb), + packet(p), + id(++idcnt), + dataType(-1), + injectionTime(0), + headFlit(nullptr) +{ + this->dbid = rep.registerElement("Flit", this->id); + rep.reportAttribute(dbid, "flit_packet", std::to_string(p->id)); + rep.reportAttribute(dbid, "flit_type", std::to_string(type)); + rep.reportAttribute(dbid, "flit_seq", std::to_string(seq_nb)); + if (type==FlitType::HEAD || type==FlitType::SINGLE) + this->headFlit = this; + else + this->headFlit = p->flits.at(0); +} + +Flit::Flit(FlitType type, long long seq_nb, Packet* p, dataTypeID_t dataType, double generationTime) + : + Flit(type, seq_nb, p) +{ + this->generationTime = generationTime; + this->dataType = dataType; +} + +ostream& operator<<(ostream& os, const Flit& flit) +{ + int processingElementsSize = GlobalResources::getInstance().nodes.size()/2; + os << "["; + switch (flit.type) { + case HEAD: + os << "H"; + break; + case BODY: + os << "B"; + break; + case TAIL: + os << "T"; + break; + case SINGLE: + os << "S"; + break; + } + os << "_" << flit.id << ": " << flit.packet->src.id%processingElementsSize << "-->" + << flit.packet->dst.id%processingElementsSize << "]"; + return os; +} + +void sc_trace(sc_trace_file*& tf, const Flit& flit, std::string nm) +{ + sc_trace(tf, flit.type, nm+".type"); + sc_trace(tf, flit.seq_nb, nm+".seq_nb"); + sc_trace(tf, flit.id, nm+".id"); +} + +Flit::~Flit() +{ + +} diff --git a/src/ratatoskrUtils/traffic/Flit.h b/src/ratatoskrUtils/traffic/Flit.h new file mode 100755 index 0000000..8dd8c63 --- /dev/null +++ b/src/ratatoskrUtils/traffic/Flit.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "systemc.h" +#include +#include "ratatoskrUtils/utils/Report.h" + +#include "ratatoskrUtils/utils/Structures.h" + +using flitID_t = long long; + +class Packet; + +enum FlitType { + HEAD = 10, BODY = 11, TAIL = 12, SINGLE = 13, +}; + +class Flit { +public: + Report& rep = Report::getInstance(); + static flitID_t idcnt; + flitID_t id; + flitID_t dbid; + long long seq_nb; + FlitType type; + Packet* packet; + Flit* headFlit; + dataTypeID_t dataType; + double injectionTime; + double generationTime; + + Flit(FlitType type, long long seq_nb, Packet* p); + + Flit(FlitType type, long long seq_nb, Packet* p, dataTypeID_t dataType, double generationTime); + + friend ostream& operator<<(ostream& os, const Flit& flit); + + friend void sc_trace(sc_trace_file*& tf, const Flit& flit, std::string nm); + + ~Flit(); +}; + diff --git a/src/ratatoskrUtils/traffic/Packet.cpp b/src/ratatoskrUtils/traffic/Packet.cpp new file mode 100755 index 0000000..af114c3 --- /dev/null +++ b/src/ratatoskrUtils/traffic/Packet.cpp @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "Packet.h" + +long long Packet::idcnt = 0; + +Packet::Packet(Node& src, Node& dst, int size, double generationTime, dataTypeID_t dataType) + : + src(src), + dst(dst), + size(size), + generationTime(generationTime), + dataType(dataType) +{ + this->id = idcnt; + ++idcnt; + this->pkgclass = -1; + this->numhops = 0; + this->dbid = rep.registerElement("Packet", this->id); + rep.reportAttribute(dbid, "packet_src", std::to_string(src.id)); + rep.reportAttribute(dbid, "packet_dst", std::to_string(dst.id)); +} + +std::ostream& operator<<(std::ostream& os, const Packet& p) +{ + os << "ID: " << p.id << ", SRC: " << p.src.id << ", DST: " << p.dst.id << ", Size: " << p.size << ", Generated at: " + << p.generationTime << std::endl; + return os; +} + +Packet::~Packet() +{ + for(auto& f:flits){ + delete f; + } + flits.clear(); +} diff --git a/src/ratatoskrUtils/traffic/Packet.h b/src/ratatoskrUtils/traffic/Packet.h new file mode 100755 index 0000000..7bb2d73 --- /dev/null +++ b/src/ratatoskrUtils/traffic/Packet.h @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +# pragma once + +#include +#include +#include +#include +#include +#include +#include "Flit.h" +#include "ratatoskrUtils/utils/Report.h" + +struct Packet { + static long long idcnt; + long long id; + long long dbid; + Node src; + Node dst; + int size; // set number of flits per packet + double generationTime; + dataTypeID_t dataType; // type identifier for link matrices + int pkgclass; // tag for adaptive routing + int numhops; + std::vector traversedRouters; + std::vector toTransmit; + std::vector inTransmit; + std::vector transmitted; + std::vector flits; + Report& rep = Report::getInstance(); + + Packet(Node& src, Node& dst, int size, double generationTime, dataTypeID_t dataType); + + friend ostream & operator <<(ostream & os, const Packet& p); + + ~Packet(); +}; diff --git a/src/ratatoskrUtils/traffic/TrafficPool.cpp b/src/ratatoskrUtils/traffic/TrafficPool.cpp new file mode 100755 index 0000000..a344afc --- /dev/null +++ b/src/ratatoskrUtils/traffic/TrafficPool.cpp @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "TrafficPool.h" +#include "ratatoskrUtils/networkInterface/NetworkInterface.h" +TrafficPool::TrafficPool() +{ + this->dbid = rep.registerElement("TrafficPool", 0); +} + +TrafficPool::~TrafficPool() +{ + processingElements.clear(); // The actual objects were deleted in the destructor of NoC class. +} + + + diff --git a/src/ratatoskrUtils/traffic/TrafficPool.h b/src/ratatoskrUtils/traffic/TrafficPool.h new file mode 100755 index 0000000..3f9cbc4 --- /dev/null +++ b/src/ratatoskrUtils/traffic/TrafficPool.h @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "ratatoskrUtils/utils/Structures.h" +#include "ratatoskrUtils/utils/GlobalResources.h" +#include "ratatoskrUtils/utils/Report.h" +#include "Packet.h" +#include "ratatoskrUtils/processingElement/ProcessingElement.h" + +class TrafficPool { +public: + GlobalResources& globalResources = GlobalResources::getInstance(); + Report& rep = Report::getInstance(); + int dbid; + std::vector processingElements; + + TrafficPool(); + + ~TrafficPool(); + + virtual void start() = 0; + + virtual void clear(Task*) = 0; +}; diff --git a/src/ratatoskrUtils/traffic/netrace/.gitignore b/src/ratatoskrUtils/traffic/netrace/.gitignore new file mode 100755 index 0000000..1abe7a1 --- /dev/null +++ b/src/ratatoskrUtils/traffic/netrace/.gitignore @@ -0,0 +1 @@ +testraces/* diff --git a/src/ratatoskrUtils/traffic/netrace/NETRACE b/src/ratatoskrUtils/traffic/netrace/NETRACE new file mode 100755 index 0000000..3629a40 --- /dev/null +++ b/src/ratatoskrUtils/traffic/netrace/NETRACE @@ -0,0 +1,3 @@ +add netrace source code here + +http://www.cs.utexas.edu/~netrace/ diff --git a/src/ratatoskrUtils/traffic/netrace/NetracePool.cpp b/src/ratatoskrUtils/traffic/netrace/NetracePool.cpp new file mode 100755 index 0000000..d63561e --- /dev/null +++ b/src/ratatoskrUtils/traffic/netrace/NetracePool.cpp @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (C) 2020 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +#include +#include "NetracePool.h" + +NetracePool::NetracePool(sc_module_name nm) +{ + cout << endl; + cout << "Running in Netrace Benchmark mode." << endl; + cout << " The minimum total node count of the NoC must be the number of netrace simulated nodes." << endl; + SC_THREAD(thread); +} + +NetracePool::~NetracePool() +{ +} + +void NetracePool::thread() { + ntNetrace ntnetrace; +#ifdef ENABLE_NETRACE + int i; + int ignore_dependencies = 1; + int start_region = globalResources.netraceStartRegion; + int reader_throttling = 0; + const char* tracefile = globalResources.netraceFile.c_str(); + + int packets_left = 0; + cycle = 0; + nt_packet_t* trace_packet = NULL; + nt_packet_t* packet = NULL; + ntnetrace.nt_open_trfile( tracefile ); + if( ignore_dependencies ) { + ntnetrace.nt_disable_dependencies(); + } + if (globalResources.netraceVerbosity >= 1) + ntnetrace.nt_print_trheader(); + header = ntnetrace.nt_get_trheader(); + ntnetrace.nt_seek_region( &header->regions[start_region] ); + for( i = 0; i < start_region; i++ ) { + cycle += header->regions[i].num_cycles; + } + + x_nodes = sqrt( header->num_nodes ); + y_nodes = header->num_nodes / x_nodes; + + ntQueue* waiting[header->num_nodes]; + ntQueue* inject[header->num_nodes]; + ntQueue* traverse[header->num_nodes]; + + if( !reader_throttling ) { + trace_packet = ntnetrace.nt_read_packet(); + } else if( !ignore_dependencies ) { + ntnetrace.nt_init_self_throttling(); + } + + //initial delay after which the simulation starts + event.notify(10, SC_NS); + wait(event); + + for(;;){ + + // Reset packets remaining check + packets_left = 0; + + // Get packets for this cycle + if( reader_throttling ) { + nt_packet_list_t* list; + for( list = ntnetrace.nt_get_cleared_packets_list(); list != NULL; list = list->next ) { + if( list->node_packet != NULL ) { + trace_packet = list->node_packet; + queue_node_t* new_node = (queue_node_t*) malloc( sizeof(queue_node_t) ); + new_node->packet = trace_packet; + new_node->cycle = (trace_packet->cycle > cycle) ? trace_packet->cycle : cycle; + inject[trace_packet->src]->queue_push( inject[trace_packet->src], new_node, new_node->cycle ); + } else { + printf( "Malformed packet list" ); + exit(-1); + } + } + ntnetrace.nt_empty_cleared_packets_list(); + } else { + //std::cout << "here 8 @ " << sc_time_stamp() << std::endl; + //ntnetrace.nt_print_packet(trace_packet); + //std::cout << "trace_packet->cycle " << trace_packet->cycle << std::endl; + while( (trace_packet != NULL) && (trace_packet->cycle == cycle) ) { + // Place in appropriate queue + queue_node_t* new_node = (queue_node_t*) malloc( sizeof(queue_node_t) ); + new_node->packet = trace_packet; + new_node->cycle = (trace_packet->cycle > cycle) ? trace_packet->cycle : cycle; + if( ignore_dependencies || ntnetrace.nt_dependencies_cleared( trace_packet ) ) { + // Add to inject queue + if (globalResources.netraceVerbosity >= 2) { + cout << "@ " << sc_time_stamp(); + ntnetrace.nt_print_packet(new_node->packet); + } + int src = static_cast(trace_packet->src); + ProcessingElementVC* pe = (ProcessingElementVC*) processingElements.at(src); + pe->ntInject.push(std::make_pair(*new_node, new_node->cycle)); + } else { + // Add to waiting queue + ProcessingElementVC* pe = (ProcessingElementVC*) processingElements.at(trace_packet->src); + pe->ntWaiting.push(std::make_pair(*new_node, new_node->cycle)); + } + // Get another packet from trace + trace_packet = ntnetrace.nt_read_packet(); + } + if( (trace_packet != NULL) && (trace_packet->cycle < cycle) ) { + // Error check: Crash and burn + printf( "Invalid trace_packet cycle time: %llu, current cycle: %llu\n", trace_packet->cycle, cycle ); + exit(-1); + } + } + + cycle++; + + int clockDelay = 500; // Netrace runs at 2GHz + event.notify(clockDelay, SC_PS); + wait(event); + } +#endif +} + +void NetracePool::clear(Task*) +{ +} + +void NetracePool::start() +{ + int numOfPEs = processingElements.size(); + for (auto& task: globalResources.tasks) { + processingElements.at(task.nodeID%numOfPEs)->execute(task); + } +} \ No newline at end of file diff --git a/src/ratatoskrUtils/traffic/netrace/NetracePool.h b/src/ratatoskrUtils/traffic/netrace/NetracePool.h new file mode 100755 index 0000000..0be79c6 --- /dev/null +++ b/src/ratatoskrUtils/traffic/netrace/NetracePool.h @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (C) 2020 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +#pragma once + +#include "systemc.h" +#include "ratatoskrUtils/utils/GlobalResources.h" +#include "ratatoskrUtils/utils/Report.h" +#include "ratatoskrUtils/utils/Structures.h" +#include "ratatoskrUtils/traffic/TrafficPool.h" +#include "ratatoskrUtils/traffic/netrace/ntNetrace.h" +#include "ratatoskrUtils/traffic/netrace/ntQueue.h" +#include "ratatoskrUtils/processingElement/ProcessingElementVC.h" + +#define L2_LATENCY 8 + +typedef struct queue_node queue_node_t; +struct queue_node { + nt_packet_t* packet; + unsigned long long int cycle; +}; + +class NetracePool : public TrafficPool, sc_module { +public: + unsigned long long int calc_packet_timing( nt_packet_t* ); + + nt_header_t* header; + int x_nodes, y_nodes; + unsigned long long int cycle; + + + SC_HAS_PROCESS(NetracePool); + + sc_event event; + + NetracePool(sc_module_name);//sc_module_name nm); + + ~NetracePool(); + + void clear(Task*) override; + + void start() override; + + void thread(); +}; + diff --git a/src/ratatoskrUtils/traffic/netrace/ntNetrace.cpp b/src/ratatoskrUtils/traffic/netrace/ntNetrace.cpp new file mode 100755 index 0000000..4fae35e --- /dev/null +++ b/src/ratatoskrUtils/traffic/netrace/ntNetrace.cpp @@ -0,0 +1,755 @@ +/* + * Copyright (c) 2010-2011 The University of Texas at Austin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * 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; + * neither the name of the copyright holders 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 + * OWNER 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. + */ + +/* + * Modified by Jan Moritz Joseph (c) 2020 + */ + + +#include +#include "ntNetrace.h" + +ntNetrace::ntNetrace(){ + +} + + +void ntNetrace::nt_open_trfile( const char* trfilename ) { + nt_close_trfile(); + int i; + int length = 20; + for( i = 0; trfilename[i] != 0; i++, length++ ); + nt_input_popencmd = (char*) malloc( length * sizeof(char) ); + sprintf( nt_input_popencmd, "bzip2 -dc %s", trfilename ); + nt_input_tracefile = popen( nt_input_popencmd, "r" ); + if( nt_input_tracefile == NULL ) { + std::cout << "failed to open pipe to trace file" << std::endl; + } + nt_input_trheader = nt_read_trheader(); + if( nt_dependency_array == NULL ) { + nt_dependency_array = (nt_dep_ref_node_t**) malloc(sizeof(nt_dep_ref_node_t*) * NT_DEPENDENCY_ARRAY_SIZE); + memset( nt_dependency_array, 0, sizeof(nt_dep_ref_node_t*) * NT_DEPENDENCY_ARRAY_SIZE ); + nt_num_active_packets = 0; + } else { + std::cout << "dependency array not NULL on file open"<nt_magic = in_header->nt_magic; + to_return->version = in_header->version; + strcpy( to_return->benchmark_name, in_header->benchmark_name ); + to_return->num_nodes = in_header->num_nodes; + to_return->num_cycles = in_header->num_cycles; + to_return->num_packets = in_header->num_packets; + to_return->notes_length = in_header->notes_length; + to_return->num_regions = in_header->num_regions; + free( in_header ); + + // Error Checking + if( to_return->nt_magic != NT_MAGIC ) { + if( nt_little_endian() != 1 ) { + std::cout << "only little endian architectures are currently supported" << std::endl; + } else { + std::cout << "invalid trace file: bad magic" << std::endl; + } + } + if( to_return->version != 1.0f ) { + sprintf( strerr, "trace file is unsupported version: %f", to_return->version ); + std::cout << strerr <notes_length > 0 && to_return->notes_length < 8192 ) { + to_return->notes = (char*) malloc( to_return->notes_length * sizeof(char) ); + if( (err = fread( to_return->notes, sizeof(char), to_return->notes_length, nt_input_tracefile )) < 0 ) { + sprintf( strerr, "failed to read trace file header notes: err = %d\n", err ); + std::cout <notes = NULL; + } + if( to_return->num_regions > 0 ) { + if( to_return->num_regions <= 100 ) { + to_return->regions = (nt_regionhead_t*) malloc( to_return->num_regions * sizeof(nt_regionhead_t) ); + if( (err = fread( to_return->regions, sizeof(nt_regionhead_t), to_return->num_regions, nt_input_tracefile )) < 0 ) { + sprintf( strerr, "failed to read trace file header regions: error = %d\n", err ); + std::cout << strerr << std::endl; + } + } else { + std::cout << "lots of regions... is this correct?" << std::endl; + } + } else { + to_return->regions = NULL; + } + return to_return; +} + +void ntNetrace::nt_disable_dependencies() { + if( nt_track_cleared_packets_list ) { + std::cout << "Cannot turn off dependencies when tracking cleared packets list" << std::endl; + } + nt_dependencies_off = 1; +} + +void ntNetrace::nt_seek_region( nt_regionhead_t* region ) { + int err = 0; + char strerr[180]; + if( nt_input_tracefile != NULL ) { + if( region != NULL ) { + // Clear all existing dependencies + nt_delete_all_dependencies(); + // Reopen file to fast-forward to region + // fseek doesn't work on compressed file + pclose( nt_input_tracefile ); + nt_input_tracefile = popen( nt_input_popencmd, "r" ); + unsigned long long int seek_offset = nt_get_headersize() + region->seek_offset; + unsigned long long int read_length = 4096; + char* buffer = (char*) malloc( read_length ); + while( seek_offset > read_length ) { + if( (err = fread( buffer, 1, read_length, nt_input_tracefile )) < 0 ) { + sprintf( strerr, "failed to seek region: error = %d\n", err ); + std::cout << strerr << std::endl; + } + seek_offset -= read_length; + } + if( (err = fread( buffer, 1, seek_offset, nt_input_tracefile )) < 0 ) { + sprintf( strerr, "failed to seek region: error = %d\n", err ); + std::cout << strerr << std::endl; + } + free( buffer ); + if( nt_self_throttling ) { + // Prime the pump to read in self throttled packets + nt_prime_self_throttle(); + } + } else { + std::cout << "invalid region passed: NULL" < 0 && err < sizeof(struct nt_packet_pack) ) { + // Bad packet - end of file + std::cout << "unexpectedly reached end of trace file - perhaps corrupt" << std::endl; + } else if( err == 0 ) { + // End of file + free( to_return ); + to_return = NULL; + return to_return; + } + if( !nt_dependencies_off ) { + // Track dependencies: add to_return to dependencies array + nt_dep_ref_node_t* node_ptr = nt_get_dependency_node( to_return->id ); + if( node_ptr == NULL ) { + node_ptr = nt_add_dependency_node( to_return->id ); + } + node_ptr->node_packet = to_return; + } + nt_num_active_packets++; + nt_latest_active_packet_cycle = to_return->cycle; + if( to_return->num_deps == 0 ) { + to_return->deps = NULL; + } else { + to_return->deps = nt_dependency_malloc( to_return->num_deps ); + if( (err = fread( to_return->deps, sizeof(nt_dependency_t), to_return->num_deps, nt_input_tracefile )) < 0 ) { + sprintf( strerr, "failed to read dependencies: err = %d", err ); + std::cout << strerr << std::endl; + } + if( !nt_dependencies_off ) { + // Track dependencies: add to_return downward dependencies to array + for( i = 0; i < to_return->num_deps; i++ ) { + unsigned int dep_id = to_return->deps[i]; + nt_dep_ref_node_t* node_ptr = nt_get_dependency_node( dep_id ); + if( node_ptr == NULL ) { + node_ptr = nt_add_dependency_node( dep_id ); + } + node_ptr->ref_count++; + } + } + } + } else { + std::cout << "must open trace file with nt_open_trfile before reading" << std::endl; + } + return to_return; +} + +nt_dep_ref_node_t* ntNetrace::nt_add_dependency_node( unsigned int packet_id ) { + if( nt_dependency_array != NULL ) { + unsigned int index = packet_id % NT_DEPENDENCY_ARRAY_SIZE; + nt_dep_ref_node_t* dep_ptr = nt_dependency_array[index]; + if( dep_ptr == NULL ) { + nt_dependency_array[index] = (nt_dep_ref_node_t*) malloc( sizeof(nt_dep_ref_node_t) ); + dep_ptr = nt_dependency_array[index]; + } else { + for( ; dep_ptr->next_node != NULL; dep_ptr = dep_ptr->next_node ); + dep_ptr->next_node = (nt_dep_ref_node_t*) malloc( sizeof(nt_dep_ref_node_t) ); + dep_ptr = dep_ptr->next_node; + } + dep_ptr->node_packet = NULL; + dep_ptr->packet_id = packet_id; + dep_ptr->ref_count = 0; + dep_ptr->next_node = NULL; + return dep_ptr; + } else { + std::cout << "dependency array NULL on ntNode addition" < nt_latest_active_packet_cycle ) { + nt_packet_t* packet; + while( nt_latest_active_packet_cycle <= read_to_cycle && !nt_done_reading ) { + packet = nt_read_packet(); + if( packet == NULL ) { + // This is the exit condition... how do we signal it to the + // network simulator? We shouldn't need to... It is tracking + // whether there are packets in flight. + // Just in case, we'll provide this global indicator + nt_done_reading = 1; + } else if( nt_dependencies_cleared( packet ) ) { + nt_add_cleared_packet_to_list( packet ); + //} else { + // Ignore this packet, since the reader is already tracking it + } + } + } +} + +nt_packet_t* ntNetrace::nt_remove_dependency_node( unsigned int packet_id ) { + if( nt_dependency_array != NULL ) { + unsigned int index = packet_id % NT_DEPENDENCY_ARRAY_SIZE; + nt_dep_ref_node_t* dep_ptr = nt_dependency_array[index]; + if( dep_ptr == NULL ) { + return NULL; + } else { + nt_dep_ref_node_t* prev_ptr = NULL; + for( ; dep_ptr != NULL; prev_ptr = dep_ptr, dep_ptr = dep_ptr->next_node ) { + if( dep_ptr->packet_id == packet_id ) break; + } + if( dep_ptr == NULL ) { + return NULL; + } + if( prev_ptr == NULL ) { + nt_dependency_array[index] = dep_ptr->next_node; + } else { + prev_ptr->next_node = dep_ptr->next_node; + } + nt_packet_t* packet = dep_ptr->node_packet; + free( dep_ptr ); + return packet; + } + } else { + std::cout << "dependency array NULL on ntNode remove" <next_node ) { + if( dep_ptr->packet_id == packet_id ) break; + } + return dep_ptr; + } else { + std::cout << "dependency array not NULL on ntNode search" << std::endl; + } + return NULL; +} + +int ntNetrace::nt_dependencies_cleared( nt_packet_t* packet ) { + if( nt_input_tracefile != NULL ) { + nt_dep_ref_node_t* node_ptr = nt_get_dependency_node( packet->id ); + if( node_ptr == NULL || nt_dependencies_off ) { + return 1; + } else { + return (node_ptr->ref_count == 0); + } + } else { + std::cout << "must open trace file with nt_open_trfile before injecting" << std::endl; + } + return 1; +} + +void ntNetrace::nt_clear_dependencies_free_packet( nt_packet_t* packet ) { + unsigned int i; + if( nt_input_tracefile != NULL ) { + if( packet != NULL ) { + // If self-throttling, read ahead in the trace file + // to ensure that there are new packets ready to go + if( nt_self_throttling ) { + nt_read_ahead( packet->cycle ); + } + for( i = 0; i < packet->num_deps; i++ ) { + unsigned int dep_id = packet->deps[i]; + nt_dep_ref_node_t* node_ptr = nt_get_dependency_node( dep_id ); + if( node_ptr == NULL ) { + if( !nt_dependencies_off ) { + // TODO: check if this is a problem with short seeks + nt_print_packet( packet ); + std::cout << "failed to find dependency ntNode" << std::endl; + } + } else { + if( node_ptr->ref_count == 0 ) { + std::cout << "invalid reference count on ntNode while decrementing" << std::endl; + } + node_ptr->ref_count--; + if( nt_track_cleared_packets_list ) { + if( node_ptr->ref_count == 0 ) { + // This test alleviates the possibility of a packet + // having ref_count zero before it has been read + // from the trace (node_packet = NULL) + if( node_ptr->node_packet ) { + nt_add_cleared_packet_to_list( node_ptr->node_packet ); + } + } + } + } + } + nt_remove_dependency_node( packet->id ); + nt_packet_free( packet ); + nt_num_active_packets--; + } + } else { + std::cout << "must open trace file with nt_open_trfile before ejecting" << std::endl; + } +} + +void ntNetrace::nt_init_cleared_packets_list() { + if( nt_dependencies_off ) { + std::cout << "Cannot return cleared packets list when dependencies are turned off" << std::endl; + } + nt_track_cleared_packets_list = 1; + nt_cleared_packets_list = NULL; + nt_cleared_packets_list_tail = NULL; +} + +void ntNetrace::nt_init_self_throttling() { + if( nt_dependencies_off ) { + std::cout << "Cannot self throttle packets when dependencies are turned off" << std::endl; + } + nt_self_throttling = 1; + nt_primed_self_throttle = 0; + nt_init_cleared_packets_list(); +} + +nt_packet_list_t* ntNetrace::nt_get_cleared_packets_list() { + if( !nt_primed_self_throttle ) { + nt_prime_self_throttle(); + } + return nt_cleared_packets_list; +} + +void ntNetrace::nt_prime_self_throttle() { + nt_packet_t* packet = nt_read_packet(); + if( nt_dependencies_cleared( packet ) ) { + nt_add_cleared_packet_to_list( packet ); + } + nt_primed_self_throttle = 1; + nt_read_ahead( packet->cycle ); +} + +void ntNetrace::nt_add_cleared_packet_to_list( nt_packet_t* packet ) { + nt_packet_list_t* new_node = (nt_packet_list_t*) malloc( sizeof(nt_packet_list_t) ); + new_node->node_packet = packet; + new_node->next = NULL; + if( nt_cleared_packets_list == NULL ) { + nt_cleared_packets_list = nt_cleared_packets_list_tail = new_node; + } else { + nt_cleared_packets_list_tail->next = new_node; + nt_cleared_packets_list_tail = new_node; + } +} + +void ntNetrace::nt_empty_cleared_packets_list() { + while( nt_cleared_packets_list != NULL ) { + nt_packet_list_t* temp = nt_cleared_packets_list; + nt_cleared_packets_list = nt_cleared_packets_list->next; + free( temp ); + } + nt_cleared_packets_list = nt_cleared_packets_list_tail = NULL; +} + +void ntNetrace::nt_close_trfile() { + if( nt_input_tracefile != NULL ) { + pclose( nt_input_tracefile ); + nt_input_tracefile = NULL; + nt_free_trheader( nt_input_trheader ); + if( nt_input_popencmd != NULL ) { + free( nt_input_popencmd ); + } + nt_input_popencmd = NULL; + nt_delete_all_dependencies(); + free(nt_dependency_array); + nt_dependency_array = NULL; + } +} + +void ntNetrace::nt_delete_all_dependencies() { + int i; + for( i = 0; i < NT_DEPENDENCY_ARRAY_SIZE; i++ ) { + while( nt_dependency_array[i] != NULL ) { + nt_remove_dependency_node( nt_dependency_array[i]->packet_id ); + } + } +} + +void ntNetrace::nt_print_header( nt_header_t* header ) { + unsigned int i; + if( header != NULL ) { + printf( "NT_TRACEFILE---------------------\n" ); + + printf( " Benchmark: %s\n", header->benchmark_name ); + printf( " Magic Correct? %s\n", (header->nt_magic == NT_MAGIC) ? "TRUE" : "FALSE" ); + printf( " Tracefile Version: v%1.1f\n", header->version ); + printf( " Number of Program Regions: %d\n", header->num_regions ); + printf( " Number of Simulated Nodes: %d\n", header->num_nodes ); + printf( " Simulated Cycles: %lld\n", header->num_cycles ); + printf( " Simulated Packets: %lld\n", header->num_packets ); + printf( " Average injection rate: %f\n", (double)header->num_packets / (double)header->num_cycles ); + if( header->notes_length > 0 ) { + printf( " Notes: %s\n", header->notes ); + } + + for( i = 0; i < header->num_regions; i++ ) { + printf( " Region %d:\n", i ); + printf( " Seek Offset: %lld\n", header->regions[i].seek_offset ); + printf( " Simulated Cycles: %lld\n", header->regions[i].num_cycles ); + printf( " Simulated Packets: %lld\n", header->regions[i].num_packets ); + printf( " Average injection rate: %f\n", (double)header->regions[i].num_packets / (double)header->regions[i].num_cycles ); + printf( " Average injection rate per ntNode: %f\n", (double)header->regions[i].num_packets / (double)header->regions[i].num_cycles / (double)header->num_nodes ); + } + printf( " Size of header (B): %u\n", nt_get_headersize() ); + printf( "NT_TRACEFILE---------------------\n" ); + } else { + printf( "NULL header passed to nt_print_header\n" ); + } +} + +void ntNetrace::nt_print_trheader() { + nt_print_header( nt_input_trheader ); +} + +nt_header_t* ntNetrace::nt_get_trheader() { + if( nt_input_tracefile != NULL ) { + return nt_input_trheader; + } else { + std::cout << "must open trace file with nt_open_trfile before header is available" <version; + } else { + std::cout << "must open trace file with nt_open_trfile before version is available" <node_types >> 4 ); +} + +int ntNetrace::nt_get_dst_type( nt_packet_t* packet ) { + return (int) ( 0xF & packet->node_types ); +} + +const std::string ntNetrace::nt_node_type_to_string( int type ) { + if( type < NT_NUM_NODE_TYPES ) { + return nt_node_types[type]; + } else { + return nt_node_types[NT_NUM_NODE_TYPES]; + } +} + +int ntNetrace::nt_get_packet_size( nt_packet_t* packet ) { + if( packet->type < NT_NUM_PACKET_TYPES ) { + return nt_packet_sizes[packet->type]; + } else { + return nt_packet_sizes[0]; + } +} + +const char* ntNetrace::nt_packet_type_to_string( nt_packet_t* packet ) { + if( packet->type < NT_NUM_PACKET_TYPES ) { + return nt_packet_types[packet->type].c_str(); + } else { + return nt_packet_types[0].c_str(); + } +} + +nt_packet_t* ntNetrace::nt_packet_copy( nt_packet_t* packet ) { + if( packet != NULL ) { + nt_packet_t* to_return = nt_packet_malloc(); + memcpy( to_return, packet, sizeof(nt_packet_t) ); + if( packet->num_deps > 0 ) { + to_return->deps = nt_dependency_malloc( to_return->num_deps ); + memcpy( to_return->deps, packet->deps, sizeof(nt_dependency_t) * to_return->num_deps ); + } + return to_return; + } + return NULL; +} + +void ntNetrace::nt_packet_free( nt_packet_t* packet ) { + if( packet != NULL ) { + if( packet->num_deps > 0 ) { + free( packet->deps ); + } + free( packet ); + } +} + +void ntNetrace::nt_print_packet( nt_packet_t* packet ) { + int i; + if( packet != NULL ) { + printf( " ID:%u CYC:%llu SRC:%u DST:%u ADR:0x%08x TYP:%s NDEP:%u", + packet->id, packet->cycle, packet->src, + packet->dst, packet->addr, nt_packet_type_to_string( packet ), + packet->num_deps ); + for( i = 0; i < packet->num_deps; i++ ) { + printf( " %d", packet->deps[i] ); + } + printf( "\n" ); + } else { + printf( "WARNING: %s:%d: NULL packet printed!\n", __FILE__, __LINE__ ); + } +} + +void ntNetrace::nt_free_trheader( nt_header_t* header ) { + if( header != NULL ) { + if( header->regions != NULL ) { + free( header->regions ); + } + if( header->notes != NULL ) { + free( header->notes ); + } + free( header ); + } +} + +int ntNetrace::nt_get_headersize() { + +#pragma pack(push,1) + struct nt_header_pack { + unsigned int nt_magic; + float version; + char benchmark_name[NT_BMARK_NAME_LENGTH]; + unsigned char num_nodes; + unsigned long long int num_cycles; + unsigned long long int num_packets; + unsigned int notes_length; // Includes null-terminating char + unsigned int num_regions; + char padding[9]; + }; +#pragma pack(pop) + + if( nt_input_tracefile != NULL ) { + int to_return = 0; + to_return += sizeof(struct nt_header_pack); + to_return += nt_input_trheader->notes_length; + to_return += nt_input_trheader->num_regions * sizeof(nt_regionhead_t); + return to_return; + } else { + std::cout << "must open trace file with nt_open_trfile before header is available" <nt_magic = header->nt_magic; + out_header->version = header->version; + strcpy( out_header->benchmark_name, header->benchmark_name ); + out_header->num_nodes = header->num_nodes; + out_header->num_cycles = header->num_cycles; + out_header->num_packets = header->num_packets; + out_header->notes_length = header->notes_length; + out_header->num_regions = header->num_regions; + fwrite( out_header, sizeof(struct nt_header_pack), 1, fp ); + fwrite( header->notes, sizeof(char), header->notes_length, fp ); + fwrite( header->regions, sizeof(nt_regionhead_t), header->num_regions, fp ); + free( out_header ); + } else { + std::cout<< "dumping NULL header" <deps, sizeof(nt_dependency_t), packet->num_deps, fp ); + } else { + std::cout << "dumping NULL packet" < +#include +#include +#include +#include "string" + +// Macro Definitions +//#define DEBUG_ON +#define NT_MAGIC 0x484A5455 +#define NT_BMARK_NAME_LENGTH 30 +#define NT_DEPENDENCY_ARRAY_SIZE 200 +#define NT_NUM_PACKET_TYPES 31 +#define NT_NUM_NODE_TYPES 4 +#define NT_NODE_TYPE_L1D 0 +#define NT_NODE_TYPE_L1I 1 +#define NT_NODE_TYPE_L2 2 +#define NT_NODE_TYPE_MC 3 +#define NT_READ_AHEAD 1000000 + +// Type Declaration +typedef unsigned int nt_dependency_t; +typedef struct nt_header nt_header_t; +typedef struct nt_regionhead nt_regionhead_t; +typedef struct nt_packet nt_packet_t; +typedef struct nt_dep_ref_node nt_dep_ref_node_t; +typedef struct nt_packet_list nt_packet_list_t; + +struct nt_header { + unsigned int nt_magic; + float version; + char benchmark_name[NT_BMARK_NAME_LENGTH]; + unsigned char num_nodes; + unsigned long long int num_cycles; + unsigned long long int num_packets; + unsigned int notes_length; // Includes null-terminating char + unsigned int num_regions; + char* notes; + nt_regionhead_t* regions; +}; + +struct nt_regionhead { + unsigned long long int seek_offset; + unsigned long long int num_cycles; + unsigned long long int num_packets; +}; + +struct nt_packet { + unsigned long long int cycle; + unsigned int id; + unsigned int addr; + unsigned char type; + unsigned char src; + unsigned char dst; + unsigned char node_types; + unsigned char num_deps; + nt_dependency_t* deps; +}; + +struct nt_dep_ref_node { + nt_packet_t* node_packet; + unsigned int packet_id; + unsigned int ref_count; + nt_dep_ref_node_t* next_node; +}; + +struct nt_packet_list { + nt_packet_t* node_packet; + nt_packet_list_t* next; +}; + +class ntNetrace{ +public: + + ntNetrace(); + +// Data Members + char* nt_input_popencmd; + FILE* nt_input_tracefile; + char* nt_input_buffer; + nt_header_t* nt_input_trheader; + int nt_dependencies_off; + int nt_self_throttling; + int nt_primed_self_throttle; + int nt_done_reading; + unsigned long long int nt_latest_active_packet_cycle; + nt_dep_ref_node_t** nt_dependency_array; + unsigned long long int nt_num_active_packets; + nt_packet_list_t* nt_cleared_packets_list; + nt_packet_list_t* nt_cleared_packets_list_tail; + int nt_track_cleared_packets_list; + const std::vector nt_packet_types = {{ "InvalidCmd", "ReadReq", "ReadResp", + "ReadRespWithInvalidate", "WriteReq", "WriteResp", + "Writeback", "InvalidCmd", "InvalidCmd", "InvalidCmd", + "InvalidCmd", "InvalidCmd", "InvalidCmd", "UpgradeReq", + "UpgradeResp", "ReadExReq", "ReadExResp", "InvalidCmd", + "InvalidCmd", "InvalidCmd", "InvalidCmd", "InvalidCmd", + "InvalidCmd", "InvalidCmd", "InvalidCmd", "BadAddressError", + "InvalidCmd", "InvalidateReq", "InvalidateResp", + "DowngradeReq", "DowngradeResp" }}; + std::vector nt_packet_sizes = { /*InvalidCmd*/ -1, /*ReadReq*/ 8, /*ReadResp*/ 72, + /*ReadRespWithInvalidate*/ 72, /*WriteReq*/ 72, /*WriteResp*/ 8, + /*Writeback*/ 72, /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, + /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*UpgradeReq*/ 8, + /*UpgradeResp*/ 8, /*ReadExReq*/ 8, /*ReadExResp*/ 72, /*InvalidCmd*/ -1, + /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, + /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*InvalidCmd*/ -1, /*BadAddressError*/ 8, + /*InvalidCmd*/ -1, /*InvalidateReq*/ 8, /*InvalidateResp*/ 8, + /*DowngradeReq*/ 8, /*DowngradeResp*/ 72 }; + const std::vector nt_node_types = { "L1 Data Cache", "L1 Instruction Cache", + "L2 Cache", "Memory Controller", "Invalid Node Type" }; + +// Interface Functions + void nt_open_trfile( const char* ); + void nt_disable_dependencies( void ); + void nt_seek_region( nt_regionhead_t* ); + nt_packet_t* nt_read_packet( void ); + int nt_dependencies_cleared( nt_packet_t* ); + void nt_clear_dependencies_free_packet( nt_packet_t* ); + void nt_close_trfile( void ); + void nt_init_cleared_packets_list(); + void nt_init_self_throttling(); + nt_packet_list_t* nt_get_cleared_packets_list(); + void nt_empty_cleared_packets_list(); + +// Utility Functions + void nt_print_trheader( void ); + void nt_print_packet( nt_packet_t* ); + nt_header_t* nt_get_trheader( void ); + float nt_get_trversion( void ); + int nt_get_src_type( nt_packet_t* ); + int nt_get_dst_type( nt_packet_t* ); + const std::string nt_node_type_to_string( int ); + const char* nt_packet_type_to_string( nt_packet_t* ); + int nt_get_packet_size( nt_packet_t* ); + +// Netrace Internal Helper Functions + int nt_little_endian( void ); + nt_header_t* nt_read_trheader( void ); + void nt_print_header( nt_header_t* ); + void nt_free_trheader( nt_header_t* ); + int nt_get_headersize( void ); + nt_packet_t* nt_packet_malloc( void ); + nt_dependency_t* nt_dependency_malloc( unsigned char ); + nt_dep_ref_node_t* nt_get_dependency_node( unsigned int ); + nt_dep_ref_node_t* nt_add_dependency_node( unsigned int ); + nt_packet_t* nt_remove_dependency_node( unsigned int ); + void nt_delete_all_dependencies( void ); + nt_packet_t* nt_packet_copy( nt_packet_t* ); + void nt_packet_free( nt_packet_t* ); + void nt_read_ahead( unsigned long long int ); + void nt_prime_self_throttle( void ); + void nt_add_cleared_packet_to_list( nt_packet_t* ); + void* _nt_checked_malloc( size_t, char*, int ); // Use the macro defined above instead of this function + void _nt_error( const char*, char*, int ); // Use the macro defined above instead of this functio + +// Backend functions for creating trace files + void nt_dump_header( nt_header_t*, FILE* ); + void nt_dump_packet( nt_packet_t*, FILE* ); + +}; + diff --git a/src/ratatoskrUtils/traffic/netrace/ntQueue.cpp b/src/ratatoskrUtils/traffic/netrace/ntQueue.cpp new file mode 100755 index 0000000..13664ed --- /dev/null +++ b/src/ratatoskrUtils/traffic/netrace/ntQueue.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2010-2011 The University of Texas at Austin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * 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; + * neither the name of the copyright holders 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 + * OWNER 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. + */ + +/* + * Modified by Jan Moritz Joseph (c) 2020 + */ + +#include +#include "ntQueue.h" + + +queue_t* ntQueue::queue_new() { + queue_t* to_return = (queue_t*) malloc( sizeof(queue_t) ); + if( to_return == NULL ) { + printf( "Failed malloc in queue_new\n" ); + exit(0); + } + to_return->head = NULL; + to_return->tail = NULL; + return to_return; +} + +void ntQueue::queue_delete( queue_t* q ) { + void* elem; + while( ! queue_empty( q ) ) { + elem = queue_pop_front( q ); + free( elem ); + } + free( q ); +} + +int ntQueue::queue_empty( queue_t* q ) { + return (q == NULL) || (q->head == NULL); +} + +void ntQueue::queue_push_back( queue_t* q, void* e ) { + if( q != NULL ) { + if( q->head == NULL ) { + q->head = (node_t*) malloc( sizeof(node_t) ); + if( q->head == NULL ) { + printf( "Failed malloc in queue_push_back\n" ); + exit(0); + } + q->tail = q->head; + q->head->prev = NULL; + q->head->next = NULL; + q->head->elem = e; + q->head->prio = 0; + } else { + q->tail->next = (node_t*) malloc( sizeof(node_t) ); + if( q->head == NULL ) { + printf( "Failed malloc in queue_push_back\n" ); + exit(0); + } + q->tail->next->prev = q->tail; + q->tail = q->tail->next; + q->tail->next = NULL; + q->tail->elem = e; + q->tail->prio = q->tail->prev->prio; + } + } else { + printf( "Must initialize queue with queue_new()\n" ); + exit(0); + } +} + +void ntQueue::queue_push( queue_t* q, void* e, unsigned long long int prio ) { + if( q != NULL ) { + if( q->head == NULL ) { + q->head = (node_t*) malloc( sizeof(node_t) ); + if( q->head == NULL ) { + printf( "Failed malloc in queue_push\n" ); + exit(0); + } + q->tail = q->head; + q->head->prev = NULL; + q->head->next = NULL; + q->head->elem = e; + q->head->prio = prio; + } else { + node_t* to_add = (node_t*) malloc( sizeof(node_t) ); + if( to_add == NULL ) { + printf( "Failed malloc in queue_push\n" ); + exit(0); + } + to_add->prio = prio; + to_add->elem = e; + node_t* behind; + for( behind = q->head; (behind != NULL) && (behind->prio < prio); behind = behind->next ); + to_add->next = behind; + if( behind == NULL ) { + to_add->prev = q->tail; + q->tail->next = to_add; + q->tail = to_add; + } else if( behind == q->head ) { + to_add->prev = behind->prev; + behind->prev = to_add; + q->head = to_add; + } else { + to_add->prev = behind->prev; + to_add->prev->next = to_add; + behind->prev = to_add; + } + } + } else { + printf( "Must initialize queue with queue_new()\n" ); + exit(0); + } +} + +void* ntQueue::queue_peek_front( queue_t* q ) { + if( (q != NULL) && (q->head != NULL) ) { + return q->head->elem; + } else { + return NULL; + } +} + +void* ntQueue::queue_pop_front( queue_t* q ) { + void* to_return = NULL; + if( (q != NULL) && (q->head != NULL) ) { + to_return = q->head->elem; + node_t* temp = q->head; + q->head = q->head->next; + if( q->head == NULL ) { + q->tail = NULL; + } + free( temp ); + } + return to_return; +} + +void ntQueue::queue_remove( queue_t* q, void* e ) { + if( q != NULL ) { + node_t* temp = q->head; + while( temp != NULL ) { + if( temp->elem == e ) { + if( temp->prev == NULL ) { + if( temp->next == NULL ) { + q->head = NULL; + q->tail = NULL; + } else { + q->head = temp->next; + temp->next->prev = NULL; + } + } else { + temp->prev->next = temp->next; + if( temp->next != NULL ) { + temp->next->prev = temp->prev; + } else { + q->tail = temp->prev; + } + } + free( temp ); + temp = NULL; + } else { + temp = temp->next; + } + } + } +} + diff --git a/src/ratatoskrUtils/traffic/netrace/ntQueue.h b/src/ratatoskrUtils/traffic/netrace/ntQueue.h new file mode 100755 index 0000000..a702cc1 --- /dev/null +++ b/src/ratatoskrUtils/traffic/netrace/ntQueue.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2010-2011 The University of Texas at Austin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * 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; + * neither the name of the copyright holders 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 + * OWNER 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. + */ + +/* + * Modified by Jan Moritz Joseph (c) 2020 + */ + +// basically this is a std queue with std::pair(elem, prio) + + +#pragma once + + +#include "stdio.h" +#include "stdlib.h" + +typedef struct ntNode node_t; +typedef struct ntQueue queue_t; + +struct ntNode { + node_t* prev; + node_t* next; + unsigned long long int prio; + void* elem; +}; + +class ntQueue { +public: + node_t* head; + node_t* tail; + + queue_t* queue_new( void ); + void queue_delete( queue_t* ); + int queue_empty( queue_t* ); + void queue_push_back( queue_t*, void* ); + void queue_push( queue_t*, void*, unsigned long long int ); + void* queue_peek_front( queue_t* ); + void* queue_pop_front( queue_t* ); + void queue_remove( queue_t*, void* ); +}; + diff --git a/src/ratatoskrUtils/traffic/synthetic/SyntheticPacket.h b/src/ratatoskrUtils/traffic/synthetic/SyntheticPacket.h new file mode 100755 index 0000000..7e0e50d --- /dev/null +++ b/src/ratatoskrUtils/traffic/synthetic/SyntheticPacket.h @@ -0,0 +1,38 @@ +#include + +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include + +#include "ratatoskrUtils/traffic/Packet.h" + +struct SyntheticPacket : Packet { + std::string phase; + + SyntheticPacket(Node& src, Node& dst, int size, int generationTime, std::string phase) + :Packet(src, dst, size, generationTime, 3) + { + this->phase = std::move(phase); + } +}; diff --git a/src/ratatoskrUtils/traffic/synthetic/SyntheticPool.cpp b/src/ratatoskrUtils/traffic/synthetic/SyntheticPool.cpp new file mode 100755 index 0000000..0c104ac --- /dev/null +++ b/src/ratatoskrUtils/traffic/synthetic/SyntheticPool.cpp @@ -0,0 +1,309 @@ +#include + +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "SyntheticPool.h" + +SyntheticPool::SyntheticPool() +{ + cout << endl; + cout << "Synthetic Testrun" << endl; +} + +void SyntheticPool::start() +{ + taskID_t taskId = 0; + int phaseId = 0; + //dataTypeID_t dataTypeId = 0; + dataDestID_t dataDestId = 0; + int maxClockDelay = 1; + for (auto const& nodeType: globalResources.nodeTypes) { + if (nodeType->clockDelay>maxClockDelay) + maxClockDelay = nodeType->clockDelay; + } + + for (const SyntheticPhase& sp : globalResources.syntheticPhases) { + LOG(true, "SyntheticPool\t Initialize phase \"" << sp.name << "\" with \"" << sp.distribution + << "\" distribution"); + + std::map srcToDst; + if (sp.distribution=="uniform") { + srcToDst = uniform(taskId, phaseId, dataDestId, maxClockDelay, sp); + } + else if (sp.distribution=="bitComplement") { + srcToDst = bitComplement(); + } + else if (sp.distribution=="tornado") { + srcToDst = tornado(); + } + else if (sp.distribution=="transpose") { + srcToDst = transpose(); + } + else if (sp.distribution=="hotspot") { + srcToDst = hotSpot(taskId, phaseId, dataDestId, maxClockDelay, sp); + } + else { + FATAL("Distribution is not implemented"); + } + } + +/* for (std::pair con : srcToDst) { + DataType* dataType = new DataType(dataTypeId, std::to_string(dataTypeId)); + ++dataTypeId; + + std::vector dests; + DataDestination* dest = new DataDestination(dataDestId, dataType, processingElements.at(con.second)->node, sp->minInterval, sp->maxInterval); + dest->minCount = sp->minCount; + dest->maxCount = sp->maxCount; + dest->minDelay = sp->minDelay; + dest->maxDelay = sp->maxDelay; + dests.push_back(dest); + ++dataDestId; + + std::vector>> possibilities; + possibilities.push_back(std::make_pair(1, dests)); + + Task* task = new Task(taskId, processingElements.at(con.first)->node); + task->minStart = sp->minStart; + task->maxStart = sp->maxStart; + task->minDuration = sp->minDuration; + task->maxDuration = sp->maxDuration; + task->minRepeat = sp->minRepeat; + task->maxRepeat = sp->maxRepeat; + task->possibilities = possibilities; + + processingElements.at(con.first)->execute(task); + ++taskId; + }*/ +} + +std::map +SyntheticPool::uniform(taskID_t& taskId, int& phaseId, + dataDestID_t& dataDestId, int maxClockDelay, const SyntheticPhase& sp) +{ + int numOfPEs = processingElements.size(); + for (unsigned int i = 0; inode.id); + task.minStart = sp.minStart; + task.maxStart = sp.maxStart; + task.minDuration = sp.minDuration; + task.maxDuration = sp.maxDuration; + task.syntheticPhase = sp.id; + + int minInterval = static_cast(std::floor((float) maxClockDelay/sp.injectionRate)); + int maxInterval = static_cast(std::floor((float) maxClockDelay/sp.injectionRate)); + if (sp.minRepeat==-1 && sp.maxRepeat==-1) { + task.minRepeat = static_cast(std::floor( + (float) (task.minDuration-task.minStart)/(float) minInterval)); + task.maxRepeat = static_cast(std::floor( + (float) (task.maxDuration-task.minStart)/(float) maxInterval)); + } + else { + task.minRepeat = sp.minRepeat; + task.maxRepeat = sp.maxRepeat; + } + + std::vector possibilities{}; + possID_t poss_id = 0; + int dataTypeId = globalResources.getRandomIntBetween(0, globalResources.numberOfTrafficTypes-1); + DataType dataType = DataType(dataTypeId, std::to_string(dataTypeId)); + for (unsigned int j = 0; jnode; + int minInterval = std::floor((float) maxClockDelay/sp.injectionRate); + int maxInterval = std::floor((float) maxClockDelay/sp.injectionRate); + + std::vector dests{}; + DataDestination dest = DataDestination(dataDestId, dataType.id, n.id, minInterval, maxInterval); + dest.minCount = sp.minCount; + dest.maxCount = sp.maxCount; + dest.minDelay = sp.minDelay; + dest.maxDelay = sp.maxDelay; + dests.push_back(dest); + possibilities.emplace_back(poss_id, 1.f/(numOfPEs-1), dests); + ++poss_id; + ++dataDestId; + } + } + task.possibilities = possibilities; + globalResources.tasks.push_back(task); + ++taskId; + } + shuffle_execute_tasks(phaseId); + ++phaseId; + + return std::map(); +} + +std::map SyntheticPool::bitComplement() +{ + std::map srcToDst{}; + + int numOfPEs = processingElements.size(); + + for (int i = 0; i SyntheticPool::transpose() +{ + std::map srcToDst{}; + int numOfPEs = processingElements.size(); + + for (int i = 0; i SyntheticPool::tornado() +{ + std::map srcToDst{}; + + std::vector* xPos = &globalResources.xPositions; + std::vector* yPos = &globalResources.yPositions; + std::vector* zPos = &globalResources.zPositions; + + int numOfPEs = processingElements.size(); + for (int i = 0; i srcPos = processingElements.at(i)->node.pos; + Vec3D dstPos; + dstPos.x = xPos->at(((std::find(xPos->begin(), xPos->end(), srcPos.x)-xPos->begin())+(xPos->size() >> 1))% + xPos->size()); + dstPos.y = yPos->at(((std::find(yPos->begin(), yPos->end(), srcPos.y)-yPos->begin())+(yPos->size() >> 1))% + yPos->size()); + dstPos.z = zPos->at(((std::find(zPos->begin(), zPos->end(), srcPos.z)-zPos->begin())+(zPos->size() >> 1))% + zPos->size()); + + Node* dstNode = nullptr; + std::vector matching_nodes = globalResources.getNodesByPos(dstPos); + for (auto& node : matching_nodes) { + if (node->type->model=="ProcessingElement") { + dstNode = node; + break; + } + } + if (dstNode) { + srcToDst[i] = dstNode->id; // TODO: node's id or processing element id? + } + + } + + return srcToDst; +} + +std::map SyntheticPool::hotSpot(taskID_t& taskId, int& phaseId, dataDestID_t& dataDestId, int maxClockDelay, + const SyntheticPhase& sp) +{ + /*int numOfPEs = processingElements.size(); + + if (hotSpot==-1) { + hotSpot = globalResources.getRandomIntBetween(0, numOfPEs-1); + } + + LOG(true, "\t\t Hotspot: " << hotSpot); + + std::map srcToDst{}; + for (int i = 0; inode.id); + task.minStart = sp.minStart; + task.maxStart = sp.maxStart; + task.minDuration = sp.minDuration; + task.maxDuration = sp.maxDuration; + task.syntheticPhase = sp.id; + + int minInterval = static_cast(std::floor((float) maxClockDelay/sp.injectionRate)); + int maxInterval = static_cast(std::floor((float) maxClockDelay/sp.injectionRate)); + if (sp.minRepeat==-1 && sp.maxRepeat==-1) { + task.minRepeat = static_cast(std::floor( + (float) (task.minDuration-task.minStart)/(float) minInterval)); + task.maxRepeat = static_cast(std::floor( + (float) (task.maxDuration-task.minStart)/(float) maxInterval)); + } + else { + task.minRepeat = sp.minRepeat; + task.maxRepeat = sp.maxRepeat; + } + + std::vector possibilities{}; + possID_t poss_id = 1; + int dataTypeId = 1; + DataType dataType = DataType(dataTypeId, std::to_string(dataTypeId)); + if (i!=hotspot) { // a PE should not send data to itself. + Node n = processingElements.at(hotspot)->node; + int minInterval = std::floor((float) maxClockDelay/sp.injectionRate); + int maxInterval = std::floor((float) maxClockDelay/sp.injectionRate); + + std::vector dests{}; + DataDestination dest = DataDestination(dataDestId, dataType.id, n.id, minInterval, maxInterval); + dest.minCount = sp.minCount; + dest.maxCount = sp.maxCount; + dest.minDelay = sp.minDelay; + dest.maxDelay = sp.maxDelay; + dests.push_back(dest); + possibilities.emplace_back(poss_id, 1, dests); + ++dataDestId; + } + task.possibilities = possibilities; + globalResources.tasks.push_back(task); + ++taskId; + } + shuffle_execute_tasks(phaseId); + ++phaseId; + + return std::map(); +} + +void SyntheticPool::clear(Task*) +{ +} + +void SyntheticPool::shuffle_execute_tasks(int phaseId) +{ + // Execute the tasks in random order + int numOfPEs = processingElements.size(); + int offset = phaseId*numOfPEs; + auto start = globalResources.tasks.begin()+offset; + auto end = globalResources.tasks.end(); + std::vector phaseTasks(start, end); + + std::shuffle(phaseTasks.begin(), phaseTasks.end(), *globalResources.rand); + for (Task& task : phaseTasks) { + processingElements.at(task.nodeID%numOfPEs)->execute(task); + } +} + +SyntheticPool::~SyntheticPool() +{ +} diff --git a/src/ratatoskrUtils/traffic/synthetic/SyntheticPool.h b/src/ratatoskrUtils/traffic/synthetic/SyntheticPool.h new file mode 100755 index 0000000..0ddfa14 --- /dev/null +++ b/src/ratatoskrUtils/traffic/synthetic/SyntheticPool.h @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "systemc.h" +#include "ratatoskrUtils/utils/GlobalResources.h" +#include "ratatoskrUtils/utils/Report.h" +#include "ratatoskrUtils/utils/Structures.h" +#include "SyntheticPacket.h" +#include "ratatoskrUtils/traffic/TrafficPool.h" + +class SyntheticPool : public TrafficPool { +public: + SyntheticPool(); + + ~SyntheticPool(); + + void clear(Task*) override; + + void start() override; + + void shuffle_execute_tasks(int phaseId); + +private: + + std::map + uniform(taskID_t& taskId, int& phaseId, dataDestID_t& dataDestId, int maxClockDelay, + const SyntheticPhase& sp); + + std::map transpose(); + + std::map tornado(); + + std::map hotSpot(taskID_t& taskId, int& phaseId, dataDestID_t& dataDestId, int maxClockDelay, + const SyntheticPhase& sp); + + std::map bitComplement(); +}; diff --git a/src/ratatoskrUtils/traffic/task/TaskPacket.h b/src/ratatoskrUtils/traffic/task/TaskPacket.h new file mode 100755 index 0000000..c919fbf --- /dev/null +++ b/src/ratatoskrUtils/traffic/task/TaskPacket.h @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (C) 2018 joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include + +#include "ratatoskrUtils/traffic/Packet.h" + +struct TaskPacket : Packet { + + TaskPacket(Node& src, Node& dst, int size, int generationTime, dataTypeID_t dataType) + :Packet(src, dst, size, generationTime, 0) + { + + } +}; + diff --git a/src/ratatoskrUtils/traffic/task/TaskPool.cpp b/src/ratatoskrUtils/traffic/task/TaskPool.cpp new file mode 100755 index 0000000..69e686a --- /dev/null +++ b/src/ratatoskrUtils/traffic/task/TaskPool.cpp @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include +#include "TaskPool.h" + +TaskPool::TaskPool() +{ + cout << endl; + cout << "Task Testrun" << endl; +} + +TaskPool::TaskPool(int numOfElements) +{ +} + +void TaskPool::start() +{ + int numOfPEs = processingElements.size(); + for (auto& task: globalResources.tasks) { + processingElements.at(task.nodeID%numOfPEs)->execute(task); + } +} + +void TaskPool::clear(Task*) +{ +} diff --git a/src/ratatoskrUtils/traffic/task/TaskPool.h b/src/ratatoskrUtils/traffic/task/TaskPool.h new file mode 100755 index 0000000..65fde4a --- /dev/null +++ b/src/ratatoskrUtils/traffic/task/TaskPool.h @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (C) 2018 joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "systemc.h" + +#include +#include "ratatoskrUtils/utils/GlobalResources.h" +#include "ratatoskrUtils/utils/Report.h" +#include "ratatoskrUtils/utils/Structures.h" +#include "ratatoskrUtils/traffic/TrafficPool.h" + +class TaskPool : public TrafficPool { + +public: + TaskPool(); + + TaskPool(int numOfElements); + + ~TaskPool() = default; + + void clear(Task*) override; + + void start() override; +}; diff --git a/src/ratatoskrUtils/utils/GlobalReport.cpp b/src/ratatoskrUtils/utils/GlobalReport.cpp new file mode 100644 index 0000000..85fad74 --- /dev/null +++ b/src/ratatoskrUtils/utils/GlobalReport.cpp @@ -0,0 +1,610 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "GlobalReport.h" +#include "Structures.h" +#include + +GlobalReport::GlobalReport() + : + total_power_s(0.0), + latencyNetwork("network latency"), + latencyFlit("flit latency"), + latencyPacket("packet latency ") +{ +} + +void GlobalReport::reportComplete(const std::string& filename) +{ + ofstream myfile; + myfile.open(filename+".txt"); + // Writing general simulation data: + myfile << boost::format("Report file of this simulation run. \n\n"); + myfile << "----------------------------------------------------" << endl; + myfile << "General Information:" << endl; + myfile << "----------------------------------------------------" << endl; + reportPerformance(myfile); + reportClockCount(myfile); + + // Writing router routing calculations + myfile << "----------------------------------------------------" << endl; + myfile << "Router Matrixes:" << endl; + myfile << "----------------------------------------------------" << endl; + myfile << "Routing calculations:\n"; + reportRoutingCalculations(myfile); + + // Writing links matrixes + myfile << "----------------------------------------------------" << endl; + myfile << "Link Matrixes:" << endl; + myfile << "----------------------------------------------------" << endl; + reportLinkMatrices(myfile); + myfile.close(); + + // Generate csv for links matrices + std::string csvFilename = filename+"_Links.csv"; + ofstream csvfile; + csvfile.open(csvFilename); + reportLinkMatricesCSV(csvfile); + csvfile.close(); + + // Generate csv for performance statistics + csvFilename = filename+"_Performance.csv"; + csvfile.open(csvFilename); + reportPerformanceCSV(csvfile); + csvfile.close(); + + // Generate csv for routers power statistics + csvFilename = filename+"_Routers_Power.csv"; + csvfile.open(csvFilename); + reportRoutersPowerCSV(csvfile); + csvfile.close(); + + //Writing Bandwidth csvs + csvFilename = filename+"_Bandwidth_Input.csv"; + csvfile.open(csvFilename); + reportNoCBandwidthInput(csvfile); + csvfile.close(); + + csvFilename = filename+"_Bandwidth_Output.csv"; + csvfile.open(csvFilename); + reportNoCBandwidthOutput(csvfile); + csvfile.close(); + +#ifdef ENABLE_BUFFER_VC_STATS + reportAllRoutersUsageHist(); +#endif +} + +void GlobalReport::reportPerformance(ostream& stream) +{ + float avgFlitLat = latencyFlit.average()/(float) 1000; + float avgPacketLat = latencyPacket.average()/(float) 1000; + float avgNetworkLat = latencyNetwork.average()/(float) 1000; + if (undeliveredPackages < globalResources.nodes.size()||undeliveredPackages<0) + undeliveredPackages = 0; + float undeliveredPacketsLatency = undeliveredPackages * globalResources.simulation_time; + float actualNetworkLat = avgNetworkLat + undeliveredPacketsLatency; + stream << boost::format("Lost Packets: %3.2f\n")%undeliveredPackages; + stream << boost::format("Average flit latency: %3.2f ns.\n")%avgFlitLat; + stream << boost::format("Average packet latency: %3.2f ns.\n")%avgPacketLat; + stream << boost::format("Average network latency: %3.2f ns.\n")%actualNetworkLat; +} + +void GlobalReport::reportPerformanceCSV(ostream& stream) +{ + float avgFlitLat = latencyFlit.average()/(float) 1000; + float avgPacketLat = latencyPacket.average()/(float) 1000; + float avgNetworkLat = latencyNetwork.average()/(float) 1000; + if (undeliveredPackages < globalResources.nodes.size() || undeliveredPackages < 0) + undeliveredPackages = 0; + float undeliveredPacketsLatency = undeliveredPackages * globalResources.simulation_time; + float actualNetworkLat = avgNetworkLat + undeliveredPacketsLatency; + stream << boost::format("avgFlitLat, %2.3f\n")%avgFlitLat; + stream << boost::format("avgPacketLat, %2.3f\n")%avgPacketLat; + stream << boost::format("avgNetworkLat, %2.3f\n")%actualNetworkLat; +} + +void GlobalReport::issueRoutingCalculation(int id) +{ + auto it = routingCalculations.find(id); + if (it!=routingCalculations.end()) + ++it->second; + else + routingCalculations.insert(std::make_pair(id, 1)); +} + +void GlobalReport::reportRoutingCalculations(ostream& stream) +{ + for (auto it : routingCalculations) { + stream << boost::format("\tRouter id: %i had %i calculations \n")%it.first%it.second; + } +} + +void GlobalReport::issueLinkMatrixUpdate(int id, int currentTransmissionState, int lastTransmissionState) +{ + ++linkTransmissionMatrices.at(id).at( + currentTransmissionState+linkTransmissionsMatrixNumberOfStates*lastTransmissionState); +} + +void GlobalReport::reportLinkMatrix(int id, ostream& stream) +{ + auto transmissionMatrix = linkTransmissionMatrices.at(id); + int clockCyclesOfLink = std::accumulate(transmissionMatrix.begin(), transmissionMatrix.end(), 0); + stream << boost::format("Transmission matrix of links %i:\n")%id; + int colit = 0, rowit = 0; + stream << boost::format("from\\to IDLE HEAD HID"); + for (int var = 0; var(pow(linkTransmissionsMatrixNumberOfStates, 2)); + stream << boost::format("link_id"); + for (int var = 0; var(matrix.second.at(it-matrix.second.begin())); + if (std::next(it)==matrix.second.end()) { + stream << boost::format("%i\n")%value; + } + else { + stream << boost::format("%i, ")%value; + } + } + } +} + +void GlobalReport::updateAverageNetworkLatencySystemLevel(double newLatency) +{ + if (averageNetworkLatencySystemLevel==-1) { + averageNetworkLatencySystemLevel = newLatency; + } + else { + double scalingLarge = ((double) averageNetworkLatencySystemLevelInstances/ + ((double) averageNetworkLatencySystemLevelInstances+(double) 1)); + double first = scalingLarge*averageNetworkLatencySystemLevel; + double scalingSmall = ((double) 1/((double) averageNetworkLatencySystemLevelInstances+(double) 1)); + double second = scalingSmall*newLatency; + averageNetworkLatencySystemLevel = first+second; + } + ++averageNetworkLatencySystemLevelInstances; +} + +void GlobalReport::reportAverageNetworkLatencySystemLevel() +{ + cout << "The average network latency was: " << averageNetworkLatencySystemLevel << endl; +} + +void GlobalReport::updateMaxNetworkLatencySystemLevel(double newLatency) +{ + if (maxNetworkLatency routers_ids{}; + if (!bufferReportRouters.empty()) { + routers_ids = bufferReportRouters; + } + else { + int num_nodes = globalResources.nodes.size(); + for (unsigned int i = 0; imodel=="RouterVC") { + routers_ids.push_back(i); + } + } + } + int numSimulatedRouters = static_cast(globalResources.nodes.size()/2); + int num_routers = routers_ids.size(); + for (unsigned int i = 0; i" << endl; + } + } +} + +void GlobalReport::readConfigFile(const std::string& config_path) +{ + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(config_path.c_str()); + assert(result && "Failed to read simulator config file!"); + + // PE Verbosity + pugi::xml_node verbose_node = doc.child("configuration").child("verbose").child("processingElements"); + this->verbose_pe_function_calls = verbose_node.child("function_calls").attribute("value").as_bool(); + this->verbose_pe_send_flit = verbose_node.child("send_flit").attribute("value").as_bool(); + this->verbose_pe_send_head_flit = verbose_node.child("send_head_flit").attribute("value").as_bool(); + this->verbose_pe_receive_flit = verbose_node.child("receive_flit").attribute("value").as_bool(); + this->verbose_pe_receive_tail_flit = verbose_node.child("receive_tail_flit").attribute( + "value").as_bool(); + this->verbose_pe_throttle = verbose_node.child("throttle").attribute("value").as_bool(); + this->verbose_pe_reset = verbose_node.child("reset").attribute("value").as_bool(); + + // Router Verbosity + verbose_node = doc.child("configuration").child("verbose").child("router"); + this->verbose_router_function_calls = verbose_node.child("function_calls").attribute( + "value").as_bool(); + this->verbose_router_send_flit = verbose_node.child("send_flit").attribute("value").as_bool(); + this->verbose_router_send_head_flit = verbose_node.child("send_head_flit").attribute( + "value").as_bool(); + this->verbose_router_receive_flit = verbose_node.child("receive_flit").attribute("value").as_bool(); + this->verbose_router_receive_head_flit = verbose_node.child("receive_head_flit").attribute( + "value").as_bool(); + this->verbose_router_assign_channel = verbose_node.child("assign_channel").attribute( + "value").as_bool(); + this->verbose_router_throttle = verbose_node.child("throttle").attribute("value").as_bool(); + this->verbose_router_buffer_overflow = verbose_node.child("buffer_overflow").attribute( + "value").as_bool(); + this->verbose_router_reset = verbose_node.child("reset").attribute("value").as_bool(); + + // Netrace Verbosity + verbose_node = doc.child("configuration").child("verbose").child("netrace"); + this->verbose_netrace_inject = verbose_node.child("inject").attribute("value").as_bool(); + this->verbose_netrace_eject = verbose_node.child("eject").attribute("value").as_bool(); + this->verbose_netrace_router_receive = verbose_node.child("router_receive").attribute( + "value").as_bool(); + + // Task Verbosity + verbose_node = doc.child("configuration").child("verbose").child("tasks"); + this->verbose_task_xml_parse = verbose_node.child("xml_parse").attribute("value").as_bool(); + this->verbose_task_data_receive = verbose_node.child("data_receive").attribute("value").as_bool(); + this->verbose_task_data_send = verbose_node.child("data_send").attribute("value").as_bool(); + this->verbose_task_source_execute = verbose_node.child("source_execute").attribute( + "value").as_bool(); + this->verbose_task_function_calls = verbose_node.child("function_calls").attribute( + "value").as_bool(); + + std::string s = doc.child("configuration").child("report").child_value("bufferReportRouters"); + std::string delimiter = " "; + std::size_t current, previous = 0; + current = s.find(delimiter); + while (current!=std::string::npos) { + try { + bufferReportRouters.push_back(std::stoi(s.substr(previous, current-previous))); + } + catch (char* error) { + cout << "Error: " << error << endl; + } + previous = current+1; + current = s.find(delimiter, previous); + } + bufferReportRouters.push_back(std::stoi(s.substr(previous, current-previous))); +} + +void GlobalReport::resizeMatrices() +{ + numRouters = static_cast(globalResources.nodes.size()/2); + VCsUsageHist.resize(numRouters); + bufferUsagePerVCHist.resize(numRouters); + linkTransmissionsMatrixNumberOfStates = (2*globalResources.numberOfTrafficTypes)+3; + + int numOfLinks = globalResources.connections.size()*2; + for (int link_id = 0; link_id(pow(linkTransmissionsMatrixNumberOfStates, 2)); + std::vector matrix(numberElements, 0); + linkTransmissionMatrices.insert(std::make_pair(link_id, matrix)); + } + + clockCounts.resize(globalResources.nodeTypes.size()/2, 0.0); + buffer_router_push_pwr_d.resize(numRouters, 0.0); + buffer_router_pop_pwr_d.resize(numRouters, 0.0); + buffer_router_front_pwr_d.resize(numRouters, 0.0); + buffer_router_pwr_s.resize(numRouters, 0.0); + routing_pwr_d.resize(numRouters, 0.0); + routing_pwr_s.resize(numRouters, 0.0); + crossbar_pwr_d.resize(numRouters, 0.0); + crossbar_pwr_s.resize(numRouters, 0.0); + ni_pwr_d.resize(numRouters, 0.0); + ni_pwr_s.resize(numRouters, 0.0); + + //Connection con = globalResources.connections.at(0); + //int vcCount = con.vcsCount.at(0); + int vcCount = -1; + for (auto con : globalResources.connections){ + for (auto vc : con.vcsCount){ + vcCount = vcCount > vc ? vcCount : vc; + } + } + + VCsUsageHist.resize(numRouters); + for (auto& vec_2d:VCsUsageHist) { + vec_2d.resize(DIR::size); + for (auto& vec:vec_2d) { + vec.resize(vcCount+1); + } + } + bufferUsagePerVCHist.resize(numRouters); + for (auto& vec_3d:bufferUsagePerVCHist) { + vec_3d.resize(DIR::size); + for (auto& vec_2d:vec_3d) { + vec_2d.resize(vcCount); + for (auto& vec:vec_2d) { + vec.resize(MAX_BUFFER_DEPTH+1); + } + } + } +} + +void GlobalReport::reportClockCount(ostream& stream) +{ + stream << "Clock Counts: ["; + int numOfClocks = clockCounts.size(); + for (int i = 0; iclockCounts.at(layer) += 1; +} + +void GlobalReport::increaseBufferPush(int router_id) +{ + buffer_router_push_pwr_d.at(router_id) += 1; +} + +void GlobalReport::increaseBufferPop(int router_id) +{ + buffer_router_pop_pwr_d.at(router_id) += 1; +} + +void GlobalReport::increaseBufferFront(int router_id) +{ + buffer_router_front_pwr_d.at(router_id) += 1; +} + +void GlobalReport::increaseRouting(int router_id) +{ + routing_pwr_d.at(router_id) += 1; +} + +void GlobalReport::increaseCrossbar(int router_id) +{ + crossbar_pwr_d.at(router_id) += 1; +} + +void GlobalReport::reportRoutersPowerCSV(ostream& csvfile) +{ + csvfile << "router_id," << "buffer_push," << "buffer_pop," << "buffer_read_front," << "routing," << "crossbar" + << "\n"; + for (int id = 0; id +#include +#include + +#include "GlobalResources.h" +#include "Statistics.h" + +class GlobalReport { +public: + int droppedCounter = 0; // number of dropped flits. + + Statistics latencyNetwork; + Statistics latencyFlit; + Statistics latencyPacket; + + //Link state transmission matrixes + std::map > linkTransmissionMatrices; + int linkTransmissionsMatrixNumberOfStates; + + //Router state vectors and matrices + std::map routingCalculations; + + double averageNetworkLatencySystemLevel = -1; + int averageNetworkLatencySystemLevelInstances = 0; + double maxNetworkLatency = 0; + long long undeliveredPackages = 0; + + int numRouters; + /* 1st dimension is all routers. + * 2nd dimension is all ports (directions) of a router. + * 3rd dimension is all possible number of active VCs. + */ + std::vector>> VCsUsageHist; + /* 1st dimension is all routers. + * 2nd dimension is all ports (directions) of a router. + * 3rd dimension is all possible number of VCs. + * 4th dimension is all buffer positions of a VC. + */ + std::vector>>> bufferUsagePerVCHist; + + void readConfigFile(const std::string& config_path); + + /// VERBOSE /// + //processing elements + bool verbose_pe_function_calls = false; + bool verbose_pe_send_flit = false; + bool verbose_pe_send_head_flit = false; + bool verbose_pe_receive_flit = false; + bool verbose_pe_receive_tail_flit = false; + bool verbose_pe_throttle = false; + bool verbose_pe_reset = false; + + //router + bool verbose_router_function_calls = false; + bool verbose_router_send_flit = false; + bool verbose_router_send_head_flit = false; + bool verbose_router_receive_flit = false; + bool verbose_router_receive_head_flit = false; + bool verbose_router_assign_channel = false; + bool verbose_router_throttle = false; + bool verbose_router_buffer_overflow = false; + bool verbose_router_reset = false; + + //netrace + bool verbose_netrace_inject = false; + bool verbose_netrace_eject = false; + bool verbose_netrace_router_receive = false; + + //tasks + bool verbose_task_function_calls = false; + bool verbose_task_xml_parse = false; + bool verbose_task_data_receive = true; + bool verbose_task_data_send = true; + bool verbose_task_source_execute = true; + + static GlobalReport& getInstance() + { + static GlobalReport instance; + return instance; + } + + void reportComplete(const std::string& filename); + + void reportPerformance(ostream& stream); + + void reportPerformanceCSV(ostream& stream); + + // Link state transmission matrixes + void issueLinkMatrixUpdate(int id, int currentTransmissionState, int lastTransmissionState); + + void reportLinkMatrix(int id, ostream& stream); + + void reportLinkMatrices(ostream& stream); + + void reportLinkMatricesCSV(ostream& stream); + + // Router status vectors and matrices + void issueRoutingCalculation(int id); + + void reportRoutingCalculations(ostream& stream); + + void updateAverageNetworkLatencySystemLevel(double newLatency); + + void reportAverageNetworkLatencySystemLevel(); + + void updateMaxNetworkLatencySystemLevel(double newLatency); + + void reportMaxNetworkLatencySystemLevel(); + + void updateVCUsageHist(int routerId, int dir, int numOfActiveVCs); + + void reportVCUsageHist(std::string& csvFileName, int routerId); + + void updateBuffUsagePerVCHist(int routerId, int dir, int vc, int bufferOccupation); + + void reportBuffPerVCUsageHist(std::string& csvFileName, int routerId, int dir); + + void reportAllRoutersUsageHist(); + + void resizeMatrices(); + + void increaseClockCount(int layer); + + void reportClockCount(ostream& stream); + + void increaseBufferPush(int router_id); + + void increaseBufferPop(int router_id); + + void increaseBufferFront(int router_id); + + void increaseRouting(int router_id); + + void increaseCrossbar(int router_id); + + void reportRoutersPowerCSV(ostream& csvfile); + + std::vector bufferReportRouters; + + void increase_power_stats(int router_id, int dir); + + void report_power_stats(std::string& csvFileName, int router_id); + + //Bandwidth + void issueNoCInputDataAmount(sc_time time, int dataAmount); + + void issueNoCOutputDataAmount(sc_time time, int dataAmount); + + void reportNoCBandwidthInput(ostream& csvfile); + + void reportNoCBandwidthOutput(ostream& csvfile); + +private: + GlobalResources& globalResources = GlobalResources::getInstance(); + + double total_power_s; //unused + + //Buffer consumption (power per event is determined by a LUT of buffer depth and flit size) + std::vector buffer_router_push_pwr_d; // per flit pushed on buffer + std::vector buffer_router_pop_pwr_d; // per flit popped of buffer (not for lookup) + std::vector buffer_router_front_pwr_d; // per flit data received from buffer (only count if flit exists) + std::vector buffer_router_pwr_s; // leakage per router cycle per buffer + + //Power consumption of routing Algorithm (determined by routing algorithm) + std::vector routing_pwr_d; //per routing function called + std::vector routing_pwr_s; //Leakage per Router Cycle + + //Routing function gives vector of possible directions/VCs + //Selection function selects direction/VC + //Power Consumption of selection Function (determined by selection function) + //double selection_pwr_d; //per selection function called + //double selection_pwr_s; //Leakage per Router Cycle + // not implemented! + + //Power consumption of Crossbar (determined by IOs (5) and Flit size) + std::vector crossbar_pwr_d; // per sent flit + std::vector crossbar_pwr_s; // Leakage per Router Cycle + + //Power consumption of Network Interface (determined by flit size) + std::vector ni_pwr_d; // per local flit sent or received + std::vector ni_pwr_s; // Leakage per Router Cycle + + // Used to create the buffer axes in the histogram of buffer usage + const int MAX_BUFFER_DEPTH = 50; + // Generate VC and buffer histograms for only these routers + + std::vector clockCounts; + + //Bandwidth measurement + std::map noCInputDataAmount; + std::map noCOutputDataAmount; + + + GlobalReport(); +}; + diff --git a/src/ratatoskrUtils/utils/GlobalResources.cpp b/src/ratatoskrUtils/utils/GlobalResources.cpp new file mode 100755 index 0000000..b1620d2 --- /dev/null +++ b/src/ratatoskrUtils/utils/GlobalResources.cpp @@ -0,0 +1,720 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +#include "GlobalResources.h" +#include +#include + +GlobalResources::GlobalResources() + : simulation_time(0), + outputToFile(false), + activateFlitTracing(false), + routingVerticalThreshold(1.0), + Vdd(1.0), + isUniform(false), + numberOfTrafficTypes(0), + synthetic_start_measurement_time(-1) +{ + rand = new std::mt19937_64(); + auto seed = std::random_device{}(); + rand->seed(seed); + rd_seed = seed; +} + +GlobalResources &GlobalResources::getInstance() +{ + static GlobalResources instance; + return instance; +} + +int GlobalResources::getRandomIntBetween(int min, int max) +{ + std::uniform_int_distribution dis(min, max); + return dis(*rand); +} + +float GlobalResources::getRandomFloatBetween(float min, float max) +{ + std::uniform_real_distribution dis(min, max); + return dis(*rand); +} + +void GlobalResources::readAttributeIfExists(pugi::xml_node node, const char *child, const char *attribute, int &var) +{ + readAttributeIfExists(node.child(child), attribute, var); +} + +void GlobalResources::readAttributeIfExists(pugi::xml_node node, const char *attribute, int &var) +{ + if (!node.attribute(attribute).empty()) + { + var = node.attribute(attribute).as_int(); + } +} + +int GlobalResources::readRequiredIntAttribute(pugi::xml_node node, const char *child, const char *attribute) +{ + return readRequiredIntAttribute(node.child(child), attribute); +} + +int GlobalResources::readRequiredIntAttribute(pugi::xml_node node, const char *attribute) +{ + if (node.attribute(attribute).empty()) + { + FATAL("Can not read node:" << node.path() << " " << attribute); + } + return node.attribute(attribute).as_int(); +} + +float GlobalResources::readRequiredFloatAttribute(pugi::xml_node node, const char *child, const char *attribute) +{ + return readRequiredFloatAttribute(node.child(child), attribute); +} + +float GlobalResources::readRequiredFloatAttribute(pugi::xml_node node, const char *attribute) +{ + if (node.attribute(attribute).empty()) + { + FATAL("Can not read node:" << node.path() << " " << attribute); + } + return node.attribute(attribute).as_float(); +} + +std::string +GlobalResources::readRequiredStringAttribute(pugi::xml_node node, const char *child, const char *attribute) +{ + return readRequiredStringAttribute(node.child(child), attribute); +} + +std::string GlobalResources::readRequiredStringAttribute(pugi::xml_node node, const char *attribute) +{ + if (node.attribute(attribute).empty()) + { + FATAL("Can not read node:" << node.path() << " " << attribute); + } + return node.attribute(attribute).as_string(); +} + +std::vector GlobalResources::string_split(const std::string &str, const std::string &delim) +{ + std::vector strings; + auto start = 0U; + auto end = str.find(delim); + while (end != std::string::npos) + { + strings.push_back(str.substr(start, end - start)); + start = static_cast(end + 1); + end = str.find(delim, start); + } + strings.push_back(str.substr(start, end)); + return strings; +} + +std::vector GlobalResources::strs_to_ints(const std::vector &strings) +{ + std::vector ints{}; + for (auto &str : strings) + { + ints.push_back(std::stoi(str)); + } + return ints; +} + +void GlobalResources::createRoutingTable() +{ + std::string filename; + filename = RoutingTable_file; + + std::ifstream infile(filename); + std::string line; + + int cpt_line = 0; + + while (std::getline(infile, line)) + { + std::istringstream iss(line); + std::string word; + int DIR; + std::vector v; + while (iss >> word) + { + DIR = std::stoi(word); + v.push_back(DIR); + } + + RoutingTable.push_back(v); + cpt_line += 1; + } + std::cout << "Routing Table :" << std::endl; + + for (auto vec : RoutingTable) + { + for (auto x : vec) + std::cout << x << " , "; + std::cout << std::endl; + } +} + +void GlobalResources::readConfigFile(const std::string &configPath) +{ + pugi::xml_document doc; + + std::cout << "Reading simulator config: " << configPath << endl; + struct stat buffer; + if (!stat(configPath.c_str(), &buffer) == 0) + cout << endl + << "ERROR: Config file not found, program will exit with exception" << endl + << endl; + pugi::xml_parse_result result = doc.load_file(configPath.c_str()); + assert(result && "Failed to read simulator config file!"); + + //GENERAL + pugi::xml_node gen_node = doc.child("configuration").child("general"); + simulation_time = gen_node.child("simulationTime").attribute("value").as_int(); + outputToFile = gen_node.child("outputToFile").attribute("value").as_bool(); + outputFileName = gen_node.child("outputToFile").child_value(); + activateFlitTracing = gen_node.child("flitTracing").attribute("value").as_bool(); + + //ROUTING TABLE + pugi::xml_node Routing_node = doc.child("configuration").child("noc").child("routingTable"); + if (Routing_node.child("routingTable_mode") != NULL) + { + RoutingTable_mode = Routing_node.child("routingTable_mode").attribute("value").as_bool(); + } + else + { + RoutingTable_mode = 0; + } + std::cout << "Routing table mode: " << RoutingTable_mode << std::endl; + + if (RoutingTable_mode == 1) + { + pugi::xml_node RTFile_node = Routing_node.child("routingTable_path"); + RoutingTable_file = readRequiredStringAttribute(RTFile_node, "value"); + createRoutingTable(); + + // DIRECTION MATRIX + pugi::xml_node DMFile_node = Routing_node.child("directionMatrix_path"); + DirectionMat_file = readRequiredStringAttribute(DMFile_node, "value"); + } + + //NOC + pugi::xml_node noc_node = doc.child("configuration").child("noc"); + noc_file = noc_node.child_value("nocFile"); + flitsPerPacket = noc_node.child("flitsPerPacket").attribute("value").as_int(); + bitWidth = noc_node.child("bitWidth").attribute("value").as_int(); + routingVerticalThreshold = noc_node.child("routingVerticalThreshold").attribute("value").as_float(); + Vdd = noc_node.child("Vdd").attribute("value").as_float(); + + //APPLICATION + pugi::xml_node app_node = doc.child("configuration").child("application"); + benchmark = app_node.child_value("benchmark"); + data_file = app_node.child_value("dataFile"); + map_file = app_node.child_value("mapFile"); + simulation_file = app_node.child_value("simulationFile"); + mapping_file = app_node.child_value("mappingFile"); + netraceFile = app_node.child_value("netraceFile"); + netraceStartRegion = app_node.child("netraceStartRegion").attribute("value").as_int(); + isUniform = app_node.child("isUniform").attribute("value").as_bool(); + numberOfTrafficTypes = app_node.child("numberOfTrafficTypes").attribute("value").as_int(); + + synthID_t syntheticPhaseID = 0; + for (pugi::xml_node phase_node : app_node.child("synthetic").children("phase")) + { + std::string name = readRequiredStringAttribute(phase_node, "name"); + std::string distribution = readRequiredStringAttribute(phase_node, "distribution", "value"); + float injectionRate = readRequiredFloatAttribute(phase_node, "injectionRate", "value"); + SyntheticPhase sp = SyntheticPhase(syntheticPhaseID, name, distribution, injectionRate); + ++syntheticPhaseID; + + readAttributeIfExists(phase_node, "start", "min", sp.minStart); + readAttributeIfExists(phase_node, "start", "max", sp.maxStart); + readAttributeIfExists(phase_node, "duration", "min", sp.minDuration); + readAttributeIfExists(phase_node, "duration", "max", sp.maxDuration); + readAttributeIfExists(phase_node, "repeat", "min", sp.minRepeat); + readAttributeIfExists(phase_node, "repeat", "max", sp.maxRepeat); + readAttributeIfExists(phase_node, "count", "min", sp.minCount); + readAttributeIfExists(phase_node, "count", "max", sp.maxCount); + readAttributeIfExists(phase_node, "delay", "min", sp.minDelay); + readAttributeIfExists(phase_node, "delay", "max", sp.maxDelay); + readAttributeIfExists(phase_node, "hotspot", "value", sp.hotspot); + + //set first start time after warmup to start of measurement + if (benchmark == "synthetic" && name != "warmup" && + synthetic_start_measurement_time == -1) + { + synthetic_start_measurement_time = sp.minStart; + } + syntheticPhases.push_back(sp); + } +} + +void GlobalResources::readNoCLayout(const std::string &nocPath) +{ + std::cout << "Reading NoC layout: " << nocPath << endl; + assert(access(nocPath.c_str(), F_OK) != -1); + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(nocPath.c_str()); + assert(result && "Failed to read NoC file!"); + + pugi::xml_node noc_node = doc.child("network-on-chip"); + bufferDepthType = noc_node.child("bufferDepthType").attribute("value").as_string(); + if (!bufferDepthType.empty() && (bufferDepthType != "single" && bufferDepthType != "perVC")) + { + FATAL("The value of bufferDepthType in your network file should be either 'single' or 'perVC'!"); + } + + // topology + topology = noc_node.child_value("topology"); + routingCircular = std::set({std::string("torus"), std::string("ring")}).count(topology); + + readNodeTypes(noc_node); + readNodes(noc_node); + readConnections(noc_node); + if (!RoutingTable_mode) + { + fillDirInfoOfNodeConn(); + } + else + { + fillDirInfoOfNodeConn_DM(); + } + +#ifdef ENABLE_NETRACE + int temp_z = noc_node.child("abstract").child("z").attribute("value").as_int(); + std::vector temp_xs; + std::vector temp_ys; + int temp; + std::stringstream iss; + iss = std::stringstream(noc_node.child("abstract").child("y").attribute("value").as_string()); + while (iss >> temp) + temp_xs.push_back(temp); + iss = std::stringstream(noc_node.child("abstract").child("x").attribute("value").as_string()); + while (iss >> temp) + temp_ys.push_back(temp); + int node_count = 0; + for(int i = 0; i < temp_z; i++) + node_count += (temp_xs[i] * temp_ys[i]); + + // make sure node_count always larger equal than 64, because netrace simulates 64 nodes + // this line is to make it compatible for old simulation (old network.xml do not have xs, ys & z values.) + node_count = (node_count > 64)? node_count : 64; + + for (int i = 0; i < node_count; ++i) + { + netraceNodeToTask.insert(std::pair(i + node_count, i)); + netraceTaskToNode.insert(std::pair(i, i + node_count)); + } +#endif +} + +void GlobalResources::readNodeTypes(const pugi::xml_node &noc_node) +{ + for (pugi::xml_node node : noc_node.child("nodeTypes").children("nodeType")) + { + dataTypeID_t typeID = node.attribute("id").as_int(); + std::string model = node.child("model").attribute("value").as_string(); + if (model.empty()) + cout << "Model not set properly for nodeType with id " << typeID << endl; + std::string routing = node.child("routing").attribute("value").as_string(); + std::string selection = node.child("selection").attribute("value").as_string(); + int clkDelay = node.child("clockDelay").attribute("value").as_int(); + std::string arbiterType = node.child("arbiterType").attribute("value").as_string(); + auto nodeType = std::make_shared(typeID, model, routing, selection, clkDelay, arbiterType); + nodeTypes.emplace_back(nodeType); + } +} + +void GlobalResources::readNodes(const pugi::xml_node &noc_node) +{ + for (pugi::xml_node xmlnode : noc_node.child("nodes").children("node")) + { + nodeID_t nodeID = xmlnode.attribute("id").as_int(); + std::string name = "node_" + std::to_string(nodeID); + float x = xmlnode.child("xPos").attribute("value").as_float(); + float y = xmlnode.child("yPos").attribute("value").as_float(); + float z = xmlnode.child("zPos").attribute("value").as_float(); + xPositions.push_back(x); + yPositions.push_back(y); + zPositions.push_back(z); + nodeTypeID_t nodeTypeID = xmlnode.child("nodeType").attribute("value").as_int(); + std::shared_ptr nodeType = nodeTypes.at(nodeTypeID); + int layer = xmlnode.child("layer").attribute("value").as_int(); + nodes.emplace_back(nodeID, Vec3D(x, y, z), nodeType, layer); + } + sortNodesPositions(); +} + +void GlobalResources::sortNodesPositions() +{ + sort(xPositions.begin(), xPositions.end()); + xPositions.erase(unique(xPositions.begin(), xPositions.end()), xPositions.end()); + + sort(yPositions.begin(), yPositions.end()); + yPositions.erase(unique(yPositions.begin(), yPositions.end()), yPositions.end()); + + sort(zPositions.begin(), zPositions.end()); + zPositions.erase(unique(zPositions.begin(), zPositions.end()), zPositions.end()); +} + +void GlobalResources::fillDirInfoOfNodeConn() +{ + for (Node &node : nodes) + { + //check for common directions + Vec3D distance{}; + for (int connectedNodeID : node.connectedNodes) + { + Node connectedNode = nodes.at(connectedNodeID); + distance = node.pos - connectedNode.pos; + connID_t matching_conn = node.getConnWithNode(connectedNode); + DIR::TYPE dir{}; + if (distance.isZero()) + { //no axis differs + dir = DIR::Local; + } + else + { //one axis differs + if (routingCircular && xPositions.size() > 2 && (node.pos.x == 0. && connectedNode.pos.x == 1. && node.pos.y == connectedNode.pos.y)) + { + dir = DIR::West; + } + else if (routingCircular && xPositions.size() > 2 && (node.pos.x == 1. && connectedNode.pos.x == 0. && node.pos.y == connectedNode.pos.y)) + { + dir = DIR::East; + } + else if (routingCircular && yPositions.size() > 2 && (node.pos.y == 0. && connectedNode.pos.y == 1. && node.pos.x == connectedNode.pos.x)) + { + dir = DIR::South; + } + else if (routingCircular && yPositions.size() > 2 && (node.pos.y == 1. && connectedNode.pos.y == 0. && node.pos.x == connectedNode.pos.x)) + { + dir = DIR::North; + } + else if (distance.x > 0) + { + dir = DIR::West; + } + else if (distance.x < 0) + { + dir = DIR::East; + } + else if (distance.y < 0) + { + dir = DIR::North; + } + else if (distance.y > 0) + { + dir = DIR::South; + } + else if (distance.z < 0) + { + dir = DIR::Up; + } + else if (distance.z > 0) + { + dir = DIR::Down; + } + } + node.setConPosOfDir(dir, matching_conn); + node.setDirOfConn(matching_conn, dir); + } + } +} + +// My fillDirInfoOfNodeConn() function. Rely on Direction_Mat.txt file + +void GlobalResources::fillDirInfoOfNodeConn_DM() +{ + std::cout << "Start filling direction of nodes \n"; + + std::vector> directions_mat; + std::ifstream infile(DirectionMat_file); + std::string line; + + int cpt_line = 0; + + while (std::getline(infile, line)) + { + std::istringstream iss(line); + std::string word; + int DIR; + std::vector v; + while (iss >> word) + { + DIR = std::stoi(word); + v.push_back(DIR); + } + + directions_mat.push_back(v); + cpt_line += 1; + } + std::cout << "Direction Matrix :" << std::endl; + + for (auto vec : directions_mat) + { + for (auto x : vec) + std::cout << x << " , "; + std::cout << std::endl; + } + + for (Node &node : nodes) + { + for (int connectedNodeID : node.connectedNodes) + { + Node connectedNode = nodes.at(connectedNodeID); + Vec3D distance{}; + distance = node.pos - connectedNode.pos; + connID_t matching_conn = node.getConnWithNode(connectedNode); + DIR::TYPE dir{}; + int d; + if (distance.isZero()) + { //no axis differs + dir = DIR::Local; + } + else + { + d = directions_mat[node.id][connectedNode.id]; + if (d == -1) + { + std::cout << "error, no direction found \n"; + } + else + { + if (d == 1) + { + dir = DIR::East; + } + else + { + if (d == 2) + { + dir = DIR::West; + } + else + { + if (d == 3) + { + dir = DIR::North; + } + else + { + if (d == 4) + { + dir = DIR::South; + } + else + { + if (d == 5) + { + dir = DIR::Up; + } + else + { + if (d == 6) + { + dir = DIR::Down; + } + } + } + } + } + } + } + } + node.setConPosOfDir(dir, matching_conn); + node.setDirOfConn(matching_conn, dir); + } + } +} + +void GlobalResources::readConnections(const pugi::xml_node &noc_node) +{ + for (pugi::xml_node xml_con : noc_node.child("connections").children("con")) + { + connID_t connID = xml_con.attribute("id").as_int(); + std::vector nodesOfConnection{}; + std::vector vcsCount{}; + std::vector buffersDepth{}; + std::vector> buffersDepths{}; + + for (pugi::xml_node xml_port : xml_con.child("ports").children("port")) + { + nodeID_t connectedNodeID = xml_port.child("node").attribute("value").as_int(); + nodesOfConnection.push_back(connectedNodeID); + int vcCount = xml_port.child("vcCount").attribute("value").as_int(); + vcsCount.push_back(vcCount); + buffersDepth.push_back(xml_port.child("bufferDepth").attribute("value").as_int()); + + if (bufferDepthType == "perVC") + { + std::string str_vec = xml_port.child("buffersDepths").attribute("value").as_string(); + std::vector strings = string_split(str_vec, ","); + if (strings.size() != vcCount) + { + FATAL("The buffersDepths size is not equal to vcCount!"); + } + std::vector bd = strs_to_ints(strings); + buffersDepths.push_back(bd); + } + } + + assert(nodesOfConnection.size() == 2); // make sure each connection only consists 2 nodes + + float length = xml_con.child("length").attribute("value").as_float(); + int depth = xml_con.child("depth").attribute("value").as_int(); + int width = xml_con.child("width").attribute("value").as_int(); + + Connection con = Connection(connID, nodesOfConnection, vcsCount, buffersDepth, buffersDepths, length, width, + depth); + + int nodesSize = nodesOfConnection.size(); + con.bufferUtilization.resize(nodesSize); + for (nodeID_t nID : con.nodes) + { + // Now that we know the nodes of each connection, we should reflect this info to the nodes themselves. + for (nodeID_t dstNodeID : con.nodes) + { + if (nID != dstNodeID) + nodes.at(nID).connectedNodes.push_back(dstNodeID); + } + nodes.at(nID).connections.push_back(con.id); + } + + connections.push_back(con); + } +} + +void GlobalResources::readTaskAndMapFiles(const std::string &taskFilePath, const std::string &mappingFilePath) +{ + std::map bindings = readMappingFile(mappingFilePath); + readTaskFile(taskFilePath, bindings); +} + +std::map GlobalResources::readMappingFile(const std::string &mappingFilePath) +{ + std::cout << "Reading Mapping config: " << mappingFilePath << endl; + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(mappingFilePath.c_str()); + assert(result && "Failed to read Mapping file!"); + + pugi::xml_node map_node = doc.child("map"); + std::map bindings; + for (pugi::xml_node bind_node : map_node.children("bind")) + { + int taskID = readRequiredIntAttribute(bind_node, "task", "value"); + int nodeID = readRequiredIntAttribute(bind_node, "node", "value"); + bindings.emplace(taskID, nodeID); + } + return bindings; +} + +void GlobalResources::readTaskFile(const std::string &taskFilePath, const std::map &bindings) +{ + //TODO the bindings vector was used to get the destination node and not task, of a current task.. keep it? + std::cout << "Reading Data config: " << taskFilePath << endl; + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(taskFilePath.c_str()); + assert(result && "Failed to read Data file!"); + pugi::xml_node data_node = doc.child("data"); + + // Read Data Types + numberOfTrafficTypes = static_cast(data_node.child("dataTypes").select_nodes("dataType").size()); + for (pugi::xml_node type_node : data_node.child("dataTypes").children("dataType")) + { + dataTypeID_t dataTypeID = readRequiredIntAttribute(type_node, "id"); + std::string name = readRequiredStringAttribute(type_node, "name", "value"); + dataTypes.emplace_back(dataTypeID, name); + } + // Read Tasks + for (pugi::xml_node task_node : data_node.child("tasks").children("task")) + { + taskID_t taskID = task_node.attribute("id").as_int(); + std::cout< requirements{}; + for (pugi::xml_node requirement_node : task_node.child("requires").children("requirement")) + { + dataReqID_t reqID = readRequiredIntAttribute(requirement_node, "id"); + dataTypeID_t typeID = readRequiredIntAttribute(requirement_node, "type", "value"); + DataRequirement req = DataRequirement{reqID, typeID}; + readAttributeIfExists(requirement_node, "count", "min", req.minCount); + readAttributeIfExists(requirement_node, "count", "max", req.maxCount); + requirements.push_back(req); + } + task.requirements = requirements; + + // Read Destinations + std::vector possibilities{}; + for (pugi::xml_node generate_node : task_node.child("generates").children("possibility")) + { + possID_t possID = readRequiredIntAttribute(generate_node, "id"); + float probability = readRequiredFloatAttribute(generate_node, "probability", "value"); + std::vector destinations{}; + for (pugi::xml_node destination_node : generate_node.child("destinations").children("destination")) + { + dataDestID_t dataDestID = readRequiredIntAttribute(destination_node, "id"); + dataTypeID_t typeID = readRequiredIntAttribute(destination_node, "type", "value"); + taskID_t destTaskID = readRequiredIntAttribute(destination_node, "task", "value"); + int minInterval = readRequiredIntAttribute(destination_node, "interval", "min"); + int maxInterval = readRequiredIntAttribute(destination_node, "interval", "max"); + DataDestination dataDestination = DataDestination{dataDestID, typeID, destTaskID, minInterval, + maxInterval}; + + readAttributeIfExists(destination_node, "count", "min", dataDestination.minCount); + readAttributeIfExists(destination_node, "count", "max", dataDestination.maxCount); + readAttributeIfExists(destination_node, "delay", "min", dataDestination.minDelay); + readAttributeIfExists(destination_node, "delay", "max", dataDestination.maxDelay); + + destinations.push_back(dataDestination); + } + possibilities.emplace_back(possID, probability, destinations); + } + task.possibilities = possibilities; + + tasks.push_back(task); + } +} + +std::vector GlobalResources::getNodesByPos(const Vec3D &pos) +{ + std::vector matching_nodes{}; + for (auto &node : nodes) + if (node.getNodeByPos(pos)) + { + matching_nodes.push_back(&node); + } + return matching_nodes; +} + +GlobalResources::~GlobalResources() +{ + delete rand; +} diff --git a/src/ratatoskrUtils/utils/GlobalResources.h b/src/ratatoskrUtils/utils/GlobalResources.h new file mode 100755 index 0000000..071788b --- /dev/null +++ b/src/ratatoskrUtils/utils/GlobalResources.h @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "Structures.h" +#include "pugixml.hpp" + +// my includes +#include +#include +#include +#include +#include + +class GlobalResources +{ + +public: + std::vector xPositions; + std::vector yPositions; + std::vector zPositions; + //General + int simulation_time; + bool outputToFile; + bool activateFlitTracing; + std::string outputFileName; + std::string outputDirectory; + std::string noc_file; + int flitsPerPacket = 0; + int bitWidth = 32; + float routingVerticalThreshold = 1.0f; + float Vdd = 1.0f; + std::string bufferDepthType; + std::string RoutingTable_file; + bool RoutingTable_mode; + std::vector> RoutingTable; + std::string DirectionMat_file; + //Application + std::string benchmark; + std::string data_file; + std::string map_file; + std::string simulation_file; + std::string mapping_file; + std::string netraceFile; + int netraceStartRegion; +#ifdef ENABLE_NETRACE + std::map netraceNodeToTask; + std::map netraceTaskToNode; + int netraceVerbosity = 2; // 2==all, 1 == base, 0 == none +#endif + bool isUniform; + int numberOfTrafficTypes; + int synthetic_start_measurement_time; + // General NoC data + std::vector> nodeTypes; + std::vector nodes; + std::vector connections; + std::vector tasks; + std::vector dataTypes; + std::vector syntheticPhases; + std::string topology; // store the topology of the network (mesh, torus, ring) + bool routingCircular = false; // decide whether the routing algorithm is routed in a circular way (for torus and ring) + + long long rd_seed; + std::mt19937_64 *rand; + + //debug + bool routingDebugMode = false; + + static GlobalResources &getInstance(); + + int getRandomIntBetween(int, int); + + float getRandomFloatBetween(float, float); + + void readConfigFile(const std::string &configPath); + + void readNoCLayout(const std::string &nocPath); + + void readTaskAndMapFiles(const std::string &taskFilePath, const std::string &mappingFilePath); + + std::vector getNodesByPos(const Vec3D &pos); + +private: + GlobalResources(); + + ~GlobalResources(); + + std::vector string_split(const std::string &str, const std::string &delim); + + std::vector strs_to_ints(const std::vector &strings); + + void readNodeTypes(const pugi::xml_node &noc_node); + + void readNodes(const pugi::xml_node &noc_node); + + void sortNodesPositions(); + + void fillDirInfoOfNodeConn(); + + void fillDirInfoOfNodeConn_DM(); + + void readConnections(const pugi::xml_node &noc_node); + + void readAttributeIfExists(pugi::xml_node, const char *, const char *, int &); + + void readAttributeIfExists(pugi::xml_node, const char *, int &); + + void readTaskFile(const std::string &taskFilePath, const std::map &bindings); + + std::map readMappingFile(const std::string &mappingFilePath); + + std::string readRequiredStringAttribute(pugi::xml_node, const char *, const char *); + + std::string readRequiredStringAttribute(pugi::xml_node, const char *); + + int readRequiredIntAttribute(pugi::xml_node, const char *, const char *); + + int readRequiredIntAttribute(pugi::xml_node, const char *); + + float readRequiredFloatAttribute(pugi::xml_node, const char *, const char *); + + float readRequiredFloatAttribute(pugi::xml_node, const char *); + + void createRoutingTable(); +}; diff --git a/src/ratatoskrUtils/utils/PacketFactory.cpp b/src/ratatoskrUtils/utils/PacketFactory.cpp new file mode 100755 index 0000000..ac40c4c --- /dev/null +++ b/src/ratatoskrUtils/utils/PacketFactory.cpp @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (C) 2018 joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +#include "PacketFactory.h" + +PacketFactory& PacketFactory::getInstance() +{ + static PacketFactory instance; + return instance; +} + +Packet* PacketFactory::createPacket(Node& src, Node& dst, int size, double generationTime, dataTypeID_t dataType) +{ + auto p = new Packet(src, dst, size, sc_time_stamp().to_double(), dataType); + packets.push_back(p); + return p; +} + +void PacketFactory::deletePacket(Packet* p) +{ + auto it = std::find(packets.begin(), packets.end(), p); + if (it != packets.end()) { + delete (*it); + packets.erase(it); + } else { + cerr << "payload not in packet vector" << endl; + } +} diff --git a/src/ratatoskrUtils/utils/PacketFactory.h b/src/ratatoskrUtils/utils/PacketFactory.h new file mode 100755 index 0000000..314288c --- /dev/null +++ b/src/ratatoskrUtils/utils/PacketFactory.h @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (C) 2018 joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +#pragma once + +#include +#include + +class PacketFactory { +public: + std::vector packets; + static PacketFactory& getInstance(); + Packet* createPacket(Node& src, Node& dst, int size, double generationTime, dataTypeID_t dataType); + void deletePacket(Packet* p); + PacketFactory(PacketFactory const&) = delete; + void operator=(PacketFactory const&) = delete; + +private: + PacketFactory() {} +}; diff --git a/src/ratatoskrUtils/utils/Report.cpp b/src/ratatoskrUtils/utils/Report.cpp new file mode 100644 index 0000000..296593a --- /dev/null +++ b/src/ratatoskrUtils/utils/Report.cpp @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "Report.h" + +Report::Report() +{ +} + +void Report::connect(const std::string& addr, const std::string& port) +{ + networkDisabled = true; + struct addrinfo addrInfoReq {}; + struct addrinfo* addrInfo; + memset(&addrInfoReq, 0, sizeof addrInfoReq); + + addrInfoReq.ai_family = AF_UNSPEC; + addrInfoReq.ai_socktype = SOCK_STREAM; + + int error = getaddrinfo(addr.c_str(), port.c_str(), &addrInfoReq, &addrInfo); + if (error!=0) { + std::cout << "Report: getaddrinfo() failed -> " << gai_strerror(error) << std::endl; + } + else { + socketfd = socket(addrInfo->ai_family, addrInfo->ai_socktype, addrInfo->ai_protocol); + if (socketfd==-1) { + std::cout << "Report: socket() failed -> " << std::strerror(errno) << std::endl; + } + else if (::connect(socketfd, addrInfo->ai_addr, addrInfo->ai_addrlen)==-1) { + std::cout << "Report: connect() failed -> " << std::strerror(errno) << std::endl; + } + else { + networkDisabled = false; + } + } + if (networkDisabled) { + std::cout << "Disabling database reports" << std::endl; + } + freeaddrinfo(addrInfo); + dbid = registerElement("Report", 0); +} + +void Report::close() +{ + logfile.close(); + send(); + ::close(socketfd); + networkDisabled = true; +} + +void Report::startRun(const std::string& name) +{ + addToSendBuffer("run;"+name); +} + +int Report::registerElement(const std::string& type, int id) +{ + addToSendBuffer("reg;"+std::to_string(element_count)+";"+type+";"+std::to_string(id)); + return ++element_count; +} + +void Report::reportEvent(int element_id, const std::string& event, const std::string& data) +{ + addToSendBuffer("rep;"+std::to_string(element_id)+";"+std::to_string(sc_time_stamp().value())+";"+event+";"+data); +} + +void Report::reportAttribute(int element_id, const std::string& name, const std::string& value) +{ + addToSendBuffer("att;"+std::to_string(element_id)+";"+name+";"+value); +} + +void Report::log(bool qualifier, const std::string& message, int type) +{ + if (qualifier) { + if (type & Logtype::COUT) { + std::cout << std::setfill(' ') << std::setw(5) << sc_time_stamp().value()/1000 << "ns: " << message + << std::endl; + } + if (type & Logtype::CERR) { + std::cerr << std::setfill(' ') << std::setw(5) << sc_time_stamp().value()/1000 << "ns: " << message + << std::endl; + } + if (type & Logtype::LOGFILE) { + if (!logfileOpened) { + logfile.open("log.txt"); + logfileOpened = true; + } + logfile << std::setfill(' ') << std::setw(5) << sc_time_stamp().value()/1000 << "ns: " << message + << std::endl; + } + if (type & Logtype::DB) { + //reportEvent(dbid, "log", message); + } + } +} + +void Report::addToSendBuffer(const std::string& str) +{ + if (!networkDisabled && sendBuffer.length()+str.length()>=MAX_BUFFER_SIZE) { + send(); + sendBuffer = ""; + } + sendBuffer += str+"|"; +} + +void Report::send() +{ + try { + //::send(socketfd, sendBuffer.c_str(), sendBuffer.length(), 0); + } + catch (std::exception&) { + std::cout << "Can't send the report!" << std::endl; + } +} diff --git a/src/ratatoskrUtils/utils/Report.h b/src/ratatoskrUtils/utils/Report.h new file mode 100644 index 0000000..3bfffb8 --- /dev/null +++ b/src/ratatoskrUtils/utils/Report.h @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "systemc.h" + +#define MAX_BUFFER_SIZE 1000 //Max Buffer Size in Bytes +#define LOG(x, y) { if(x) {std::ostringstream oss; oss<::max(); + sampleMax = std::numeric_limits::min(); + this->name = name; +} + +float Statistics::average() +{ + return (sampleSum/(float) sampleSize); +} + +float Statistics::min() +{ + return sampleMin; +} + +float Statistics::max() +{ + return sampleMax; +} + +float Statistics::sum() +{ + return sampleSum; +} + +long Statistics::samplesize() +{ + return sampleSize; +} + +bool Statistics::sample(float sample) +{ + sampleSum += sample; + ++sampleSize; + if (sampleMin>sample) + sampleMin = sample; + if (sampleMax>sample) + sampleMax = sample; + return true; +} + +void Statistics::report(ostream& stream) +{ + float avg = average(); + stream << boost::format("%s was on average %0.3f")%name%avg; +} diff --git a/src/ratatoskrUtils/utils/Statistics.h b/src/ratatoskrUtils/utils/Statistics.h new file mode 100755 index 0000000..729d578 --- /dev/null +++ b/src/ratatoskrUtils/utils/Statistics.h @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +#pragma once + +#include +#include +#include +#include + +class Statistics { +public: + explicit Statistics(const std::string& name); + + float average(); + + float min(); + + float max(); + + float sum(); + + long samplesize(); + + bool sample(float sample); + + void report(ostream& stream); + +private: + float sampleSum; + long sampleSize; + float sampleMin; + float sampleMax; + std::string name; +}; diff --git a/src/ratatoskrUtils/utils/Structures.cpp b/src/ratatoskrUtils/utils/Structures.cpp new file mode 100755 index 0000000..4887fd1 --- /dev/null +++ b/src/ratatoskrUtils/utils/Structures.cpp @@ -0,0 +1,338 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "Structures.h" + +const std::vector DIR::XYZ = {DIR::Local, DIR::East, DIR::West, DIR::North, DIR::South, DIR::Up, DIR::Down}; + +Channel::Channel() + : + conPos(0), + vc(0) +{ +} + +Channel::Channel(int dir, int vc) + : + conPos(dir), + vc(vc) +{ +} + +bool Channel::operator<(const Channel& c) const +{ + if (conPos!=c.conPos) { + return conPosconPos==a.conPos && this->vc==a.vc; +} + +bool Channel::operator!=(const Channel& a) const +{ + return !operator==(a); +} + +ostream& operator<<(ostream& os, const Channel& ch) +{ + os << "dir: " << ch.conPos << " vc: " << ch.vc; + return os; +} + +NodeType::NodeType(nodeTypeID_t id, const std::string& model, const std::string& routing, + const std::string& selection, int clk, const std::string& arbiterType) + : + id(id), + model(model), + routing(routing), + selection(selection), + clockDelay(clk), + arbiterType(arbiterType) +{ +} + +/*LayerType::LayerType(int id, int technology) : TODO restructure + id(id), + technology(technology) { +}*/ + +Node::Node(nodeID_t id, Vec3D pos, const std::shared_ptr& type, int layer) + : + id(id), + pos(pos), + type(type), + congestion(0.0), + layer(layer) +{ +} + +Node::Node() + : + id(0), + congestion(0.0), + layer(0) +{ +} + +int Node::getConnPosition(connID_t connID) const +{ + return std::find(connections.begin(), connections.end(), connID)-connections.begin(); +} + +DIR::TYPE Node::getDirOfCon(connID_t connID) const +{ + int pos = getConnPosition(connID); + return dirOfConPos.at(pos); +} + +void Node::setDirOfConn(connID_t connID, DIR::TYPE dir) +{ + int pos = getConnPosition(connID); + dirOfConPos.insert({pos, dir}); +} + +int Node::getConPosOfDir(DIR::TYPE dir) const +{ + if (conPosOfDir.count(dir)==1) + return conPosOfDir.at(dir); + else + return -1; // so the caller can use this method in a condition +} + +void Node::setConPosOfDir(DIR::TYPE dir, connID_t connID) +{ + int pos = getConnPosition(connID); + conPosOfDir.insert({dir, pos}); +} + +DIR::TYPE Node::getDirOfConPos(int conPos) const +{ + return dirOfConPos.at(conPos); +} + +int Node::getConPosOfId(connID_t connID) const +{ + return std::find(connections.begin(), connections.end(), connID)-connections.begin(); +} + +Node* Node::getNodeByPos(const Vec3D& pos) +{ + if (this->pos==pos) + return this; + else return nullptr; +} + +void Node::checkValid() +{ + assert(connectedNodes.size()<=7); + assert(connections.size()<=connectedNodes.size()+1); + assert(conPosOfDir.size()==connections.size()); + + int i = 0; + for (std::pair pair : conPosOfDir) { + assert(std::find(DIR::XYZ.begin(), DIR::XYZ.end(), pair.first)!=DIR::XYZ.end()); + ++i; + } + assert(connections.size()==i); +} + +connID_t Node::getConnWithNode(const Node& connectedNode) +{ + for (auto& conn1: this->connections) { + for (auto& conn2: connectedNode.connections) { + if (conn1==conn2) + return conn1; + } + } + return -1; +} + +Connection::Connection(connID_t id, const std::vector& nodes, const std::vector& vcsCount, + const std::vector& buffersDepth, + const std::vector>& buffersDepths, float length, int width, int depth) + : + id(id), + nodes(nodes), + vcsCount(vcsCount), + buffersDepth(buffersDepth), + buffersDepths(buffersDepths), + length(length), + width(width), + depth(depth) +{ +} + +int Connection::getBufferDepthForNode(nodeID_t nodeID) +{ + int pos = getNodePos(nodeID); + return buffersDepth.at(pos); +} + +int Connection::getBufferDepthForNodeAndVC(nodeID_t nodeID, int vcID) +{ + int pos = getNodePos(nodeID); + return buffersDepths.at(pos).at(vcID); +} + +int Connection::getVCCountForNode(nodeID_t nodeID) +{ + int pos = getNodePos(nodeID); + return vcsCount.at(pos); +} + +int Connection::getNodePos(nodeID_t n_id) +{ + return std::find(nodes.begin(), nodes.end(), n_id)-nodes.begin(); +} + +DataType::DataType(dataTypeID_t id, const std::string& name) + : + id(id), + name(name) +{ +} + +DataRequirement::DataRequirement(dataReqID_t id, dataTypeID_t dataType) + : + id(id), + dataType(dataType), + minCount(-1), + maxCount(-1) +{ +} + +DataDestination::DataDestination(dataDestID_t id, dataTypeID_t dataType, taskID_t destinationTask, int minInterval, + int maxInterval) + : + id(id), + dataType(dataType), + destinationTask(destinationTask), + minInterval(minInterval), + maxInterval(maxInterval), + minCount(-1), + maxCount(-1), + minDelay(0), + maxDelay(0) +{ +} + +bool DataDestination::operator==(const DataDestination& dt) const +{ + return this->id==dt.id; +} + +bool DataDestination::operator<(const DataDestination& dt) const +{ + return this->id& dataDestinations) + : + id(id), + probability(probability), + dataDestinations(dataDestinations) +{ +} + +Task::Task(taskID_t id, nodeID_t nodeID) + : + id(id), + nodeID(nodeID) +{ +} + +Task::Task(taskID_t id, nodeID_t node, const std::vector& requirements, + const std::vector& possibilities) + : + id(id), + nodeID(node), + requirements(requirements), + possibilities(possibilities), + syntheticPhase(0), + minStart(0), + maxStart(0), + minDuration(-1), + maxDuration(-1), + minRepeat(-1), + maxRepeat(-1) +{ +} + +bool Task::operator==(const Task& t) const +{ + return this->id==t.id; +} + +bool Task::operator<(const Task& t) const +{ + return this->idid==credit.id; +} + +Credit& Credit::operator=(const Credit& credit) +{ + if (this==&credit) + return *this; + this->id = credit.id; + this->vc = credit.vc; + return *this; +} diff --git a/src/ratatoskrUtils/utils/Structures.h b/src/ratatoskrUtils/utils/Structures.h new file mode 100755 index 0000000..a2d8a17 --- /dev/null +++ b/src/ratatoskrUtils/utils/Structures.h @@ -0,0 +1,422 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "systemc.h" +#include +#include +#include +#include + +#include "Report.h" + +using nodeID_t = int; +using connID_t = int; +using nodeTypeID_t = int; +using dataTypeID_t = int; +using dataReqID_t = int; +using dataDestID_t = int; +using possID_t = int; +using taskID_t = int; +using synthID_t = int; + +struct DIR { + const static int size = 7; + + enum TYPE { + Local = 0, East = 1, West = 2, North = 3, South = 4, Up = 5, Down = 6 + }; + + static const std::vector XYZ; + + static TYPE toDir(int a) + { + return static_cast(a); + } + + static std::string toString(TYPE a) + { + switch (a) { + case Local: + return "Local"; + case East: + return " East"; + case West: + return " West"; + case North: + return "North"; + case South: + return "South"; + case Up: + return " Up"; + case Down: + return " Down"; + default: + return "Unknown Direction!!!"; + } + } + + static std::string toString(int a) + { + return toString(toDir(a)); + } + + static int getOppositeDir(int d) + { + switch (d) { + case 0: + return 0; + case 1: + return 2; + case 2: + return 1; + case 3: + return 4; + case 4: + return 3; + case 5: + return 6; + case 6: + return 5; + default: + return 0; + } + } +}; + +struct Channel { + int conPos; + int vc; + + Channel(); + + Channel(int dir, int vc); + + bool operator<(const Channel& a) const; + + bool operator==(const Channel& a) const; + + bool operator!=(const Channel& a) const; + + friend ostream& operator<<(ostream& os, const Channel& ch); +}; + +template +struct Vec3D { + T x = 0, y = 0, z = 0; + + Vec3D() = default; + + Vec3D(T x, T y, T z) + : + x(x), y(y), z(z) + { + } + + bool operator<(Vec3D v) const + { + return fabs(x) operator+(const Vec3D v) const + { + return Vec3D(x+v.x, y+v.y, z+v.z); + } + + Vec3D operator-(const Vec3D v) const + { + return Vec3D(x-v.x, y-v.y, z-v.z); + } + + Vec3D abs() const + { + return Vec3D(fabs(this->x), fabs(this->y), fabs(this->z)); + } + + double norm() const + { + return ((x*x)+(y*y)+(z*z)); + } + + double distance(const Vec3D v) const + { + double disx = fabs(x-v.x); + double disy = fabs(y-v.y); + double disz = fabs(z-v.z); + return sqrt((disx*disx)+(disy*disy)+(disz*disz)); + } + + double sameDimDistance(const Vec3D v) const + { + double disx = fabs(x-v.x); + double disy = fabs(y-v.y); + return sqrt((disx*disx)+(disy*disy)); + } + + bool operator==(const Vec3D v) const + { + return ((x==v.x) && (y==v.y) && (z==v.z)); + } + + int sameDimCount(const Vec3D v) const + { + int count = 0; + if (x==v.x) { + ++count; + } + if (y==v.y) { + ++count; + } + if (z==v.z) { + ++count; + } + return count; + } + + int diffDimCount(const Vec3D v) const + { + int count = 0; + if (x!=v.x) { + ++count; + } + if (y!=v.y) { + ++count; + } + if (z!=v.z) { + ++count; + } + return count; + } + + friend ostream& operator<<(ostream& output, const Vec3D& v) + { + output << "(" << v.x << ", " << v.y << ", " << v.z << ")"; + return output; + } + + bool isZero() const + { + return x==0 && y==0 && z==0; + } +}; + +struct NodeType { + nodeTypeID_t id; + std::string model; + std::string routing; + std::string selection; + int clockDelay; + std::string arbiterType; + // std::vector nodes; TODO restructure + + NodeType(nodeTypeID_t id, const std::string& model, const std::string& routing, const std::string& selection, + int clkDelay, const std::string& arbiterType); +}; + +/*struct LayerType { TODO restructure + int id; + LayerType(int id, int technology); +};*/ + +class Node { +public: + nodeID_t id; + Vec3D pos; + std::shared_ptr type; + float congestion; // crossbar utilization 0-1 + std::vector connectedNodes; + std::vector connections; + int layer; + + /* int idType; TODO restructure + LayerType* layer; + std::map> connectionsToNode; //get connection by connected node + std::map conToPos; // get position of connection inside array + */ + Node(nodeID_t id, Vec3D pos, const std::shared_ptr& type, int layer); + + Node(); + + int getConnPosition(connID_t connID) const; + + int getConPosOfDir(DIR::TYPE dir) const; + + void setConPosOfDir(DIR::TYPE dir, connID_t connID); + + DIR::TYPE getDirOfCon(connID_t connID) const; + + DIR::TYPE getDirOfConPos(int conPos) const; + + int getConPosOfId(connID_t connID) const; + + void setDirOfConn(connID_t connID, DIR::TYPE dir); + + connID_t getConnWithNode(const Node& connectedNode); + + Node* getNodeByPos(const Vec3D& pos); + + void checkValid(); + +private: + std::map conPosOfDir; //maps direction names to connection position inside this node's connections + std::map dirOfConPos; //maps connection position (inside this node's connections) to direction name +}; + +struct Connection { + connID_t id; + std::vector nodes; + std::vector vcsCount; // vc count for each end. + std::vector buffersDepth; // one buffer depth for all ends of a connection. + std::vector> buffersDepths; // one buffer depth per end. + float length; + int width; + int depth; + + std::vector bufferUtilization; + + Connection(connID_t id, const std::vector& nodes, const std::vector& vcsCount, + const std::vector& buffersDepth, + const std::vector>& buffersDepths, float length, int width, int depth); + + int getBufferDepthForNode(nodeID_t nodeID); + + int getBufferDepthForNodeAndVC(nodeID_t nodeID, int vcID); + + int getVCCountForNode(nodeID_t nodeID); + + int getNodePos(nodeID_t n_id); +}; + +struct DataType { + dataTypeID_t id; + std::string name; + + DataType(dataTypeID_t id, const std::string& name); +}; + +struct DataRequirement { + dataReqID_t id; + dataTypeID_t dataType; + int minCount; //required amount of DataType to fulfill requirement (to fire) + int maxCount; + + DataRequirement(dataReqID_t id, dataTypeID_t dataType); +}; + +struct DataDestination { + dataDestID_t id; + dataTypeID_t dataType; + //nodeID_t destinationNode; //fyi: "task" in XML ?? + taskID_t destinationTask; //fyi: "task" in XML ?? + int minInterval; //delay between each sent packet + int maxInterval; + int minCount; //generated amount of packets per fire + int maxCount; + int minDelay; //delay between fire and first generated packet + int maxDelay; + + DataDestination() = default; + + DataDestination(dataDestID_t id, dataTypeID_t dataType, nodeID_t destinationNode, int minInterval, int maxInterval); + + bool operator==(const DataDestination& dt) const; + + bool operator<(const DataDestination& dt) const; +}; + +struct DataSendPossibility { + possID_t id; + float probability; + std::vector dataDestinations; + + DataSendPossibility(possID_t id, float probability, const std::vector& dataDestinations); +}; + +struct Task { + taskID_t id; + nodeID_t nodeID; + std::vector requirements; + std::vector possibilities; + int syntheticPhase; + int minStart; // simulation time in ns at which the task starts + int maxStart; + int minDuration; // maximal task duration in ns + int maxDuration; + int minRepeat; // maximal task execution count + int maxRepeat; // task terminates at whatever comes first, maxRepeates or duration + + Task() = default; + + Task(taskID_t id, nodeID_t nodeID); + + Task(taskID_t id, nodeID_t nodeID, const std::vector& requirements, + const std::vector& possibilities); + + bool operator==(const Task& t) const; + + bool operator<(const Task& t) const; +}; + +struct SyntheticPhase { + synthID_t id; + std::string name; + std::string distribution; + float injectionRate; + int minStart; + int maxStart; + int minDuration; + int maxDuration; + int minRepeat; + int maxRepeat; + int minCount; + int maxCount; + int minDelay; + int maxDelay; + int hotspot = -1; + + SyntheticPhase(synthID_t id, const std::string& name, const std::string& distribution, float injectionRate); +}; + +class Credit { +public: + int id; + static int idcnt; + int vc; + + Credit() = default; + + explicit Credit(int vc); + + ~Credit() = default; + + bool operator==(const Credit& credit) const; + + Credit& operator=(const Credit& credit); + + friend ostream& operator<<(ostream& os, const Credit& credit) + { + return os; + } + + friend void sc_trace(sc_trace_file*& tf, const Credit& credit, std::string nm) { }; +}; diff --git a/src/ratatoskrUtils/utils/TrafficTracer.cpp b/src/ratatoskrUtils/utils/TrafficTracer.cpp new file mode 100755 index 0000000..8f5faf0 --- /dev/null +++ b/src/ratatoskrUtils/utils/TrafficTracer.cpp @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +#include "TrafficTracer.h" + +TrafficTracer::TrafficTracer() +{ + if (globalResources.activateFlitTracing){ + tracefile.open("flitTrace_" + std::to_string(globalResources.rd_seed) + ".csv"); + tracefile << boost::format ("time, src, dst, packetid, flitid, type\n"); + } +} + +void TrafficTracer::traceFlit(Flit *flit) { + auto flit_type_to_str = [](enum FlitType ft) { switch(ft){case HEAD: return "H"; case BODY: return "B"; case TAIL: return "T"; case SINGLE: return "S"; default: return "-";} }; + + float injTime = flit->injectionTime/(float) 1000; + tracefile << boost::format("%10.10f, %i, %i, %i, %i, %s\n") + % injTime + % flit->packet->src.id + % flit->packet->dst.id + % flit->packet->idcnt + % flit->id + % flit_type_to_str(flit->type); +} \ No newline at end of file diff --git a/src/ratatoskrUtils/utils/TrafficTracer.h b/src/ratatoskrUtils/utils/TrafficTracer.h new file mode 100755 index 0000000..6e1c7d3 --- /dev/null +++ b/src/ratatoskrUtils/utils/TrafficTracer.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "systemc.h" +#include + +#include "GlobalResources.h" +#include + +class TrafficTracer{ +public: + static TrafficTracer& getInstance() + { + static TrafficTracer instance; + return instance; + } + + void traceFlit(Flit *flit); + +private: + GlobalResources& globalResources = GlobalResources::getInstance(); + + TrafficTracer(); + + ofstream tracefile; +}; \ No newline at end of file diff --git a/src/ratatoskrUtils/utils/portsOpenConst.h b/src/ratatoskrUtils/utils/portsOpenConst.h new file mode 100755 index 0000000..e931437 --- /dev/null +++ b/src/ratatoskrUtils/utils/portsOpenConst.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (C) 2018 Jan Moritz Joseph + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include "systemc.h" + +template +sc_core::sc_signal_in_if const& +portConst(T const& v) // keep the name consistent with vh_open +{ + // Yes, this is an (elaboration-time) memory leak. You can avoid it with some extra effort + auto* sig_p = new sc_core::sc_signal(sc_core::sc_gen_unique_name("portConst")); + sig_p->write(v); + return *sig_p; +} + +static struct { + template + operator sc_core::sc_signal_inout_if&() const + { + return *(new sc_core::sc_signal(sc_core::sc_gen_unique_name("portOpen"))); + } +} const portOpen = {}; diff --git a/src/router/router.cpp b/src/router/router.cpp new file mode 100755 index 0000000..ff345b0 --- /dev/null +++ b/src/router/router.cpp @@ -0,0 +1,393 @@ +/******************************************************************************* + * Copyright (C) 2024 Juan Neyra + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#include "router.h" + +#include +#include +#include "ratatoskrUtils/utils/Structures.h" + +DECLARE_EXTENDED_PHASE(INTERNAL_PROC_PHASE); + +/* Constructor */ +MyRouter::MyRouter(sc_module_name name, uint8_t rout_pos[3], + uint8_t max_pos[3]): + sc_module(name), router_name(name), + init_peq(this, &MyRouter::init_peq_cb), + target_peq(this, &MyRouter::target_peq_cb) { + sc_report_handler::set_actions(R_LOG, SC_INFO, SC_LOG|SC_DISPLAY); + copy(rout_pos, rout_pos + 3, this->rout_pos); + copy(max_pos, max_pos + 3, this->max_pos); + initialize(); +} + +MyRouter::~MyRouter(){ +} + +void MyRouter::initialize(){ + for(int link=0; linkacquire(); + new_trans->set_command(tlm::TLM_WRITE_COMMAND); + new_trans->set_address(trans.get_address()); + new_trans->set_data_ptr(trans.get_data_ptr()); + new_trans->set_data_length(trans.get_data_length()); + new_trans->set_streaming_width(trans.get_streaming_width()); + new_trans->set_byte_enable_ptr(trans.get_byte_enable_ptr()); + new_trans->set_dmi_allowed(false); + new_trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + + // add id to new_transaction + link_extension* ext = new link_extension(); + ext->link = dest_link; // set direction of connected router + new_trans->set_extension(ext); + + // send transaction in socket + tlm_phase phase = BEGIN_REQ; + sc_time delay = sc_time(REQ_INIT_DELAY, UNITS_DELAY); + + tlm_sync_enum status; + status = (*init_socket[dest_link])->nb_transport_fw( + *new_trans, phase, delay); + curr_req[dest_link] = new_trans; + credit_counter[dest_link]--; + // react to result + if(status == TLM_UPDATED) { + init_peq.notify(*new_trans, phase, delay); + } + else if(status == TLM_COMPLETED) { + log_error(link, "Request completed prematurely"); + curr_req[dest_link] = 0; + check_transaction(link, *new_trans); + credit_counter[dest_link]++; + new_trans->release(); + } +} + + +bool MyRouter::send_data(int link, int dest_link, tlm_gp& trans){ + log_info(link,"Send data to link:"+DIR::toString(dest_link)); + // check credits or that previous message is complete + if (credit_counter[dest_link] > 0 && !curr_req[dest_link]){ + send_begin_req(link, trans, dest_link); + return true; + } + else { + if(credit_counter[dest_link] > 0){ + log_error(link,"Waiting for downstream Router!"); + } + else{ log_error(link,"Waiting for END REQUEST"); } + return false; + } +} + +void MyRouter::check_transaction(int link, tlm_gp& trans) { + if(trans.is_response_error()) { + char txt[100]; + sprintf(txt, "Transaction returned with error, response status = %s", + trans.get_response_string().c_str()); + log_error(link, txt); + } + + // Log completed routing + tlm_command cmd = trans.get_command(); + sc_dt::uint64 adr = trans.get_address(); + int* ptr = reinterpret_cast(trans.get_data_ptr()); + std::stringstream stream; + stream << hex << adr << " check, cmd=" << (cmd ? 'W' : 'R') + << ", data=" << hex << *ptr; + log_info(link, stream.str()); + // Allow the memory manager to free the transaction object + trans.release(); +} + +int MyRouter::get_link_from_extension(tlm_gp& trans){ + link_extension* extension; + trans.get_extension(extension); + return extension->link; +} + + +/******************* INIT SOCKET FUNCTIONS ********************/ +tlm_sync_enum MyRouter::nb_transport_bw_cb(int id, tlm_gp& trans, + tlm_phase& phase, sc_time& delay) { + log_info(id, "Backward transport callback start"); + init_peq.notify(trans, phase, delay); + return TLM_ACCEPTED; +} + +void MyRouter::init_peq_cb(tlm_gp& trans, const tlm_phase& phase){ + int link = get_link_from_extension(trans); + log_info(link, "Initiator PEQ callback start"); + log_info(link, "Phase "+string(phase.get_name())+" received"); + if (phase == END_REQ || (&trans == curr_req[link] && + phase == BEGIN_RESP)){ + curr_req[link] = 0; + credit_counter[link]++; + start_pend_req(link); + } + else if (phase == BEGIN_REQ || phase == END_RESP){ + log_error(link,"Illegal transaction phase received by initiator"); + } + + if (phase == BEGIN_RESP) { + check_transaction(link, trans); + send_end_response(link, trans); + } +} + + +void MyRouter::start_pend_req(int rel_link){ + // find pending link + Direction pending_link = Direction::invalid; + for(uint8_t dir=0; dirnb_transport_fw(trans, fw_phase, delay); +} + + +/******************* TARGET SOCKET FUNCTIONS ********************/ +tlm_sync_enum MyRouter::nb_transport_fw_cb(int id, + tlm_gp& trans, tlm_phase& phase, sc_time& delay){ + log_info(id, "Forward transport callback start"); + unsigned int len = trans.get_data_length(); + unsigned char* byt = trans.get_byte_enable_ptr(); + unsigned int wid = trans.get_streaming_width(); + if (byt != 0) { + trans.set_response_status(TLM_BYTE_ENABLE_ERROR_RESPONSE); + return TLM_COMPLETED; + } + if (len > 4 || wid < len) { + trans.set_response_status(TLM_BURST_ERROR_RESPONSE); + return TLM_COMPLETED; + } + target_peq.notify(trans, phase, delay); + return TLM_ACCEPTED; +} + +void MyRouter::target_peq_cb(tlm_gp& trans, const tlm_phase& phase){ + int link = DIR::getOppositeDir(get_link_from_extension(trans)); + log_info(link, "Target PEQ callback start"); + log_info(link, "Phase "+string(phase.get_name())+" received"); + switch (phase) { + case BEGIN_REQ: + trans.acquire(); + send_end_req(link, trans); + break; + case END_RESP: + if (!resp_in_progress[link]){ + log_error(link, + "Illegal transaction phase END_RESP received by target"); + } + trans.release(); + // Target itself is now clear to issue the next BEGIN_RESP + resp_in_progress[link] = false; + if (nxt_resp_pend[link]){ + send_begin_response(link, *nxt_resp_pend[link]); + nxt_resp_pend[link] = 0; + } + break; + case END_REQ: + case BEGIN_RESP: + log_error(link,"Illegal transaction phase received by target"); + break; + default: + if(phase == INTERNAL_PROC_PHASE){ + switching(link, trans); + } + break; + } +} + +tlm_sync_enum MyRouter::send_end_req(int link, tlm_gp& trans){ + log_info(link, "Send end request start"); + // Queue the acceptance and the response with the appropriate latency + sc_time delay = sc_time(REQ_END_DELAY, UNITS_DELAY); + tlm_phase phase = END_REQ; + tlm_sync_enum status = (*target_socket[link])->nb_transport_bw( + trans, phase, delay); + if (status == TLM_COMPLETED) { + log_warn(link,"Request completed, no response to be send"); + trans.release(); + return status; + } + + // Queue internal event to mark beginning of response + delay = delay + sc_time(INTERN_PROC_DELAY, UNITS_DELAY); // Latency + target_peq.notify(trans, INTERNAL_PROC_PHASE, delay); + + return status; +} + +void MyRouter::send_begin_response(int link, tlm_gp& trans){ + log_info(link, "Send begin response start"); + resp_in_progress[link] = true; + tlm_phase phase = BEGIN_RESP; + sc_time zero_delay = SC_ZERO_TIME; + tlm_sync_enum status = (*target_socket[link])->nb_transport_bw( + trans, phase, zero_delay); + + if (status == TLM_UPDATED){ + target_peq.notify(trans, phase, zero_delay); + } + else if (status == TLM_COMPLETED) { + log_warn(link,"Request completed, no response to be send"); + trans.release(); + } +} + +void MyRouter::switching(int link, tlm_gp& trans){ + log_info(link, "Switching start"); + trans.set_response_status(TLM_OK_RESPONSE); + // arbitration and send message to next router + Dir destination = routing(link, trans); + bool data_sent; + if (destination == Dir::num_dirs) { + data_sent = true; + check_transaction(link, trans); + // change to fatal? + log_warn(link, "Routing failed. Message couldn't be delivered"); + } + else{ + data_sent = send_data(link, destination, trans); + } + // validate pending data sent + if (!data_sent) { + if(nxt_send_data_pend[link]) { + log_error(link, + "Attempt to have two pending data send in same destination"); + } + nxt_send_data_pend[link] = &trans; + send_data_in_prog_dest[link] = destination; + } + // validate pending response + if(resp_in_progress[link]) { + if(nxt_resp_pend[link]){ + log_error(link, + "Attempt to have two pending responses in target"); + } + nxt_resp_pend[link] = &trans; + } + else{ send_begin_response(link, trans); } +} + + +Dir MyRouter::xyz_routing(int link, uint8_t dest[3]){ + if (dest[0] < rout_pos[0] && valid_links[Dir::west]){ + return Dir::west; + } + else if (dest[0] > rout_pos[0] && valid_links[Dir::east]){ + return Dir::east; + } + else if (dest[1] < rout_pos[1] && valid_links[Dir::south]){ + return Dir::south; + } + else if (dest[1] > rout_pos[1] && valid_links[Dir::north]){ + return Dir::north; + } + else if (dest[2] < rout_pos[2] && valid_links[Dir::down]){ + return Dir::down; + } + else if (dest[2] > rout_pos[2] && valid_links[Dir::up]){ + return Dir::up; + } + else if (dest[0] == rout_pos[0] && dest[1] == rout_pos[1] && + dest[2] == rout_pos[2]) { + return Dir::local; + } + else { // no ideal routing found + return Dir::num_dirs; + } +} + +Dir MyRouter::routing(int link, tlm_gp& trans){ + int address = trans.get_address(); + uint8_t dest_x = address % max_pos[0]; + uint8_t dest_y = address / max_pos[0]; + uint8_t dest_z = address / (max_pos[0]*max_pos[1]); + uint8_t dest[3] = {dest_x, dest_y, dest_z}; + return xyz_routing(link, dest); +} + + +/******************* LOG FUNCTIONS ********************/ +void MyRouter::log_info(uint8_t link, string msg){ + string str_link = DIR::toString(link); + SC_REPORT_INFO(R_LOG, (router_name+":"+str_link+":"+msg).c_str()); +} + +void MyRouter::log_warn(uint8_t link, string msg){ + string str_link = DIR::toString(link); + SC_REPORT_WARNING(R_LOG, (router_name+":"+str_link+":"+msg).c_str()); +} + +void MyRouter::log_error(uint8_t link, string msg){ + string str_link = DIR::toString(link); + SC_REPORT_ERROR(R_LOG, (router_name+":"+str_link+":"+msg).c_str()); +} + +void MyRouter::log_fatal(uint8_t link, string msg){ + string str_link = DIR::toString(link); + SC_REPORT_FATAL(R_LOG, (router_name+":"+str_link+":"+msg).c_str()); +} diff --git a/src/router/router.h b/src/router/router.h new file mode 100755 index 0000000..33479bc --- /dev/null +++ b/src/router/router.h @@ -0,0 +1,254 @@ +/******************************************************************************* + * Copyright (C) 2024 Juan Neyra + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#ifndef SC_INCLUDE_DYNAMIC_PROCESSES +#define SC_INCLUDE_DYNAMIC_PROCESSES +#endif + +#include +#include +#include "tlm.h" +#include "tlm_utils/simple_initiator_socket.h" +#include "tlm_utils/simple_target_socket.h" +#include "tlm_utils/peq_with_cb_and_phase.h" + +#include "ratatoskrUtils/model/NetworkParticipant.h" +#include "utils/memory_manager.h" +#include "utils/configuration.h" +#include "utils/utils.h" +#include "utils/noc_logger.h" + +using namespace sc_core; +using namespace sc_dt; +using namespace std; +using namespace tlm; +using namespace tlm_utils; + +#define NUM_LINKS Direction::num_dirs +#define MAX_PRIORITY NUM_LINKS - 1 + +// Define an extension for the transactions +// link always point to initiator link of transaction +struct link_extension : tlm_extension { + int link; + virtual tlm_extension_base* clone() const { + return new link_extension(*this); + } + virtual void copy_from(const tlm_extension_base& ext) { + link = static_cast(ext).link; + } +}; + +class MyRouter : public sc_module{ + public: + // TLM + typedef simple_initiator_socket_tagged rout_init_socket; + typedef simple_target_socket_tagged rout_targ_socket; + + rout_init_socket* init_socket[NUM_LINKS]; + rout_targ_socket* target_socket[NUM_LINKS]; + peq_with_cb_and_phase init_peq; + peq_with_cb_and_phase target_peq; + tlm_gp* curr_req[NUM_LINKS]; + tlm_gp* end_req_pend[NUM_LINKS]; + tlm_gp* nxt_resp_pend[NUM_LINKS]; + tlm_gp* nxt_send_data_pend[NUM_LINKS]; + MemoryManager m_mm; + bool resp_in_progress[NUM_LINKS]; + int credit_counter[NUM_LINKS]; + Dir send_data_in_prog_dest[NUM_LINKS]; + + // attributes + string router_name; + uint8_t rout_pos[3]; + uint8_t max_pos[3]; + bool valid_links[NUM_LINKS]; + + SC_HAS_PROCESS(MyRouter); + MyRouter(sc_module_name name, uint8_t rout_pos[3], + uint8_t max_pos[3]); + ~MyRouter(); + + private: + /** + * Configure sockets and set initial values of variables + */ + void initialize(); + + /** + * Send data + * + * @param link active link + * @param dest_link destination link to send the data to + * @param trans TLM generic payload object + */ + bool send_data(int link, int dest_link, tlm_gp& trans); + + /** + * Checks transaction for errors, if no error found, log + * transaction and release transaction object. Called when + * transaction is completed + * + * @param link active link + * @param trans TLM generic payload object + */ + void check_transaction(int link, tlm_gp& trans); + + /** + * Callback function for non blocking transport backward + * + * @param id active link + * @param trans TLM generic payload object + * @param phase TLM current phase + * @param delay TLM expected delay + */ + tlm_sync_enum nb_transport_bw_cb(int id, tlm_gp& trans, + tlm_phase& phase, sc_time& delay); + + /** + * Callback function for non blocking transport forward + * + * @param id active link + * @param trans TLM generic payload object + * @param phase TLM current phase + * @param delay TLM expected delay + */ + tlm_sync_enum nb_transport_fw_cb(int id, tlm_gp& trans, + tlm_phase& phase, sc_time& delay); + + /** + * Callback initiator Payload Event Queue (PEQ) + * + * @param trans TLM generic payload object + * @param phase TLM current phase + */ + void init_peq_cb(tlm_gp& trans, const tlm_phase& phase); + + /** + * Callback target Payload Event Queue (PEQ) + * + * @param trans TLM generic payload object + * @param phase TLM current phase + */ + void target_peq_cb(tlm_gp& trans, const tlm_phase& phase); + + /** + * Begin request + * + * @param link active link + * @param trans TLM generic payload object + * @param dest_link destination link to transmit transaction + */ + void send_begin_req(int link, tlm_gp& trans, int dest_link); + + /** + * Send end request + * + * @param link active link + * @param trans TLM generic payload object + */ + tlm::tlm_sync_enum send_end_req(int link, tlm_gp& trans); + + + /** + * Send begin response + * + * @param link active link + * @param trans TLM generic payload object + */ + void send_begin_response(int link, tlm_gp& trans); + + /** + * Target itself is now clear to resolve pending data send + * Executed when request ends + * + * @param rel_link link that is now free/released to receive data + */ + void start_pend_req(int rel_link); + + + /** + * Send end response + * + * @param link active link + * @param trans TLM generic payload object + */ + void send_end_response(int link, tlm_gp& trans); + + /** + * Process arrived data: finds destination link and transmit it + * + * @param link active link + * @param trans TLM generic payload object + */ + void switching(int link, tlm_gp& trans); + + /** + * xyz routing: x+:east, y+: north, z+: up + * + * @param link active link + * @param dest destination + */ + Dir xyz_routing(int link, uint8_t dest[3]); + + /** + * Routing + * + * @param link active link + * @param trans TLM generic payload object + */ + Dir routing(int link, tlm_gp& trans); + + + /** + * Get link from extension + * + * @param trans TLM generic payload object + */ + int get_link_from_extension(tlm_gp& trans); + + + /** Log info + * @param link active link + * @param msg log message + */ + void log_info(uint8_t link, string msg); + + /** Log warning + * @param link active link + * @param msg log message + */ + void log_warn(uint8_t link, string msg); + + /** Log error + * @param link active link + * @param msg log message + */ + void log_error(uint8_t link, string msg); + + /** Log fatal + * @param link active link + * @param msg log message + */ + void log_fatal(uint8_t link, string msg); +}; \ No newline at end of file diff --git a/src/utils/configuration.h b/src/utils/configuration.h new file mode 100755 index 0000000..f995cf5 --- /dev/null +++ b/src/utils/configuration.h @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (C) 2024 Juan Neyra + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#ifndef SC_INCLUDE_DYNAMIC_PROCESSES +#define SC_INCLUDE_DYNAMIC_PROCESSES +#endif + +#include +#include "tlm.h" + +using namespace sc_dt; + +// router paremters +#define NUM_CREDITS 7 +// router delays +#define REQ_INIT_DELAY 20 +#define REQ_END_DELAY 20 +#define INTERN_PROC_DELAY 20 +#define RESP_END_DELAY 20 +#define UNITS_DELAY SC_NS + +// types +typedef tlm::tlm_generic_payload tlm_gp; diff --git a/src/utils/memory_manager.cpp b/src/utils/memory_manager.cpp new file mode 100755 index 0000000..0621b99 --- /dev/null +++ b/src/utils/memory_manager.cpp @@ -0,0 +1,40 @@ +#include "memory_manager.h" + +// ************************************************************************************** +// User-defined memory manager, which maintains a pool of transactions +// ************************************************************************************** + + +MemoryManager::gp_t* MemoryManager::allocate() { + gp_t* ptr; + if (free_list) { + ptr = free_list->trans; + empties = free_list; + free_list = free_list->next; + } + else { + ptr = new gp_t(this); + } + return ptr; +} + +void MemoryManager::free(gp_t* trans) +{ + if (!empties) { + empties = new access; + empties->next = free_list; + empties->prev = 0; + if (free_list) + free_list->prev = empties; + } + free_list = empties; + free_list->trans = trans; + empties = free_list->prev; +} + +// Generate a random delay (with power-law distribution) to aid testing and stress the protocol +int rand_ps() { + int n = rand() % 100; + n = n * n * n; + return n / 100; +} diff --git a/src/utils/memory_manager.h b/src/utils/memory_manager.h new file mode 100755 index 0000000..3dc7072 --- /dev/null +++ b/src/utils/memory_manager.h @@ -0,0 +1,32 @@ +#pragma once + +#ifndef SC_INCLUDE_DYNAMIC_PROCESSES +#define SC_INCLUDE_DYNAMIC_PROCESSES +#endif + +#include "tlm.h" +#include "systemc" +using namespace sc_core; +using namespace sc_dt; +using namespace std; + +class MemoryManager: public tlm::tlm_mm_interface { + typedef tlm::tlm_generic_payload gp_t; + +public: + MemoryManager() : free_list(0), empties(0) + {} + + gp_t* allocate(); + void free(gp_t* trans); + +private: + struct access { + gp_t* trans; + access* next; + access* prev; + }; + + access* free_list; + access* empties; +}; diff --git a/src/utils/noc_logger.cpp b/src/utils/noc_logger.cpp new file mode 100644 index 0000000..bed412b --- /dev/null +++ b/src/utils/noc_logger.cpp @@ -0,0 +1,91 @@ +#include "noc_logger.h" +#include +#include +#include + +#define NOC_LOG "NOC_LOG" + +using namespace sc_core; +using namespace sc_dt; +using namespace std; + +const string severity_str[5] = {"INFO", "WARNING", "ERROR", "FATAL", ""}; + +void report_handler(const sc_report& report, const sc_actions& actions){ + stringstream ss_msg; + ss_msg << report.get_time() << ": " + << severity_str[report.get_severity()] << ": " + << report.get_msg_type() << ": " << report.get_msg() + << std::endl; + + if (actions & SC_DISPLAY) { + string col_code; + switch (report.get_severity()){ + case SC_INFO: + col_code = ASCII_GREEN; + break; + case SC_WARNING: + col_code = ASCII_YELLOW; + break; + case SC_ERROR: + case SC_FATAL: + col_code = ASCII_RED; + break; + default: + col_code = ""; + break; + } + + if (! report.get_severity()==SC_INFO ){ + string formatted_msg = "\033[0;" + col_code + "m" + + ss_msg.str() + "\033[0m"; + cout << formatted_msg; + } + } + + if (actions & SC_LOG) { + string log_filename = DEF_LOGFILENAME; + if(string(report.get_msg_type()) == N_LOG){ + log_filename = N_LOGFILENAME; + } + else if(string(report.get_msg_type()) == R_LOG){ + log_filename = R_LOGFILENAME; + } + else if(string(report.get_msg_type()) == NI_LOG){ + log_filename = NI_LOGFILENAME; + } + + ofstream log_file; + log_file.open(log_filename, std::ios_base::app); + log_file << ss_msg.str(); + log_file.close(); + } +} + + +void setup_logger(){ + // empty old log files + ofstream log_file; + log_file.open(N_LOGFILENAME); + log_file.close(); + log_file.open(R_LOGFILENAME); + log_file.close(); + log_file.open(NI_LOGFILENAME); + log_file.close(); + log_file.open(DEF_LOGFILENAME); + log_file.close(); + + sc_report_handler::set_handler(report_handler); +} + +/*void creds_log_info(string router_name, uint8_t link, uint8_t num_creds, + bool is_ext){ + string msg = is_ext? ": #external credits" : ": #internal credits"; + SC_REPORT_INFO(NOC_LOG, (router_name + msg + ": on link "+ + str_dir[link]+": "+to_string(num_creds)).c_str()); +}*/ + + +void cout_logger(string msg){ + cout << sc_time_stamp() << ": "<< msg < +#include "configuration.h" +#include "utils.h" + +#define DEF_LOGFILENAME "./out/report.log" + +#define N_LOGFILENAME "./out/noc_conn.log" +#define N_LOG "TLM_NOC" + +#define R_LOGFILENAME "./out/noc_transactions.log" +#define R_LOG "TLM_ROUTER" + +#define NI_LOGFILENAME "./out/ni.log" +#define NI_LOG "TLM_NI" + +#define ASCII_RED "31" +#define ASCII_GREEN "32" +#define ASCII_YELLOW "33" + +const std::string str_dir[Direction::num_dirs] = {"local","east","west","north","south","up","down"}; + +/** + * Handles log messages (writes to console and log) + * + * @param report report object with log information + * @param actions valid actions + */ +void report_handler(const sc_report& report, const sc_actions& actions); + +/** + * Configure sc report handler filename and actions + */ +void setup_logger(); + +//void creds_log_info(std::string router_name, uint8_t link, uint8_t num_creds, bool is_ext); + +/** + * Log to cout + */ +void cout_logger(std::string msg); diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp new file mode 100755 index 0000000..6c453b1 --- /dev/null +++ b/src/utils/utils.cpp @@ -0,0 +1,39 @@ +#include "utils.h" +#include "configuration.h" +#include "ratatoskrUtils/utils/GlobalResources.h" +#include + +using namespace std; + +void get_pos_distances(float distances[3], vector gr_pos[3]){ + GlobalResources& globalResources = GlobalResources::getInstance(); + gr_pos[0] = globalResources.xPositions; + gr_pos[1] = globalResources.yPositions; + gr_pos[2] = globalResources.zPositions; + distances[0] = min_element(gr_pos[0].begin(), gr_pos[0].end())[1]; + distances[1] = min_element(gr_pos[1].begin(), gr_pos[1].end())[1]; + distances[2] = min_element(gr_pos[2].begin(), gr_pos[2].end())[1]; +} + +void convert_pos_to_int(float pos_float[3], uint8_t pos_int[3]){ + float dists[3]; + vector gr_pos[3]; + get_pos_distances(dists, gr_pos); + + pos_int[0] = round(pos_float[0]/dists[0]); + pos_int[1] = round(pos_float[1]/dists[1]); + pos_int[2] = round(pos_float[2]/dists[2]); +} + +void get_max_pos(uint8_t max_pos[3]){ + float dists[3]; + vector gr_pos[3]; + get_pos_distances(dists, gr_pos); + + max_pos[0] = 1+round(max_element(gr_pos[0].begin(), + gr_pos[0].end())[0]/dists[0]); + max_pos[1] = 1+round(max_element(gr_pos[1].begin(), + gr_pos[1].end())[0]/dists[1]); + max_pos[2] = 1+round(max_element(gr_pos[2].begin(), + gr_pos[2].end())[0]/dists[2]); +} \ No newline at end of file diff --git a/src/utils/utils.h b/src/utils/utils.h new file mode 100755 index 0000000..134fad3 --- /dev/null +++ b/src/utils/utils.h @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (C) 2024 Juan Neyra + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +#pragma once + +#include +#include "configuration.h" + +using namespace sc_core; + +enum Direction{ + local = 0, + east, + west, + north, + south, + up, + down, + num_dirs, + invalid = num_dirs +}; + +typedef Direction Dir; + +/** + * Get the distance between two elements for every axis + * + * @param distances array to store the value of distances + */ +void get_pos_distances(float distances[3]); + +/** + * Transform the position in range 0 to 1 to an integer value + * in range 0 to max position-1 + * + * @param pos_float array with the positions as float + * @param pos_float array to store the value of converted positions + */ +void convert_pos_to_int(float pos_float[3], uint8_t pos_int[3]); + +/** + * Gets the maximum positions of the noc + * + * @param max_pos array to store the value of max positions + */ +void get_max_pos(uint8_t max_pos[3]);