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 100644 index 0000000..ffc5dd7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,56 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +PROJECT(sim) + +SET(CMAKE_PREFIX_PATH /usr/local/systemc/) + +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/semaphore_manager.h + src/utils/configuration.h + 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/Makefile b/Makefile deleted file mode 100644 index 258b7e5..0000000 --- a/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -CXX = g++ -CXXFLAGS = -std=c++17 -g -I$(SYSTEMC_HOME)/include -I./include -LDFLAGS = -L$(SYSTEMC_HOME)/lib-linux64 -lsystemc -SRCDIR = src -INCDIR = include -OBJDIR = obj -OUTDIR = out - -SOURCES = $(wildcard $(SRCDIR)/*.cpp) -OBJECTS = $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o) -EXECUTABLE = $(OUTDIR)/noc_simulation - -all: directories $(EXECUTABLE) - -directories: - mkdir -p $(OBJDIR) $(OUTDIR) - -$(EXECUTABLE): $(OBJECTS) main.cpp - $(CXX) $(CXXFLAGS) $(OBJECTS) main.cpp -o $@ $(LDFLAGS) - -$(OBJDIR)/%.o: $(SRCDIR)/%.cpp - $(CXX) $(CXXFLAGS) -c $< -o $@ - -clean: - rm -rf $(OBJDIR) $(OUTDIR) - -.PHONY: all clean directories diff --git a/README.md b/README.md index 369007b..ec533c2 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,17 @@ -# Corona Optical Network on Chip (NoC) Simulation +# Defines + +`cmake -DDEFINE_ENABLE_NETRACE=ON` + +enables netrace mode + +`cmake -DDEFINE_ENABLE_GUI=ON` + +enables GUI mode + +# Corona Optical Network on Chip (NoC) Simulation with Ratatoskr This project simulates the Corona all optical Network-on-Chip (NoC) architecture using SystemC TLM 2.0. -## Project Structure - -Corona_NoC_Optical_230924/ -├── include/ -│ ├── configuration.h -│ ├── core.h -│ ├── router.h -| |__ semaphore_manager.h -├── src/ -│ ├── core.cpp -│ ├── router.cpp -├── main.cpp -├── Makefile -└── README.md - ## Prerequisites - SystemC (version 2.3.3 or later) @@ -32,10 +27,11 @@ Corona_NoC_Optical_230924/ export SYSTEMC_HOME=/path/to/your/systemc/installation ## Compilation -make + ./build.sh -## Output - ./out/noc_simulation +## Output simple test + ./sim --configFolder . + # Log file @@ -97,4 +93,4 @@ In general, if we consider any particular cluster ‘n’, there will be a numbe • Release broadcast token when broadcast message transmission is finished • Detects for messages on home channel ‘n’ (Reading data) • Detecting the broadcast channel for broadcast messages -• Acquire and renew the home token \ No newline at end of file +• Acquire and renew the home token diff --git a/build.sh b/build.sh new file mode 100644 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/config.xml b/config/config.xml new file mode 100644 index 0000000..621afd8 --- /dev/null +++ b/config/config.xml @@ -0,0 +1,55 @@ + + + + + report + + + config/net.xml + + + + + + task + config/simple_data.xml + config/simple_map.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 6 9 10 + + diff --git a/config/net.xml b/config/net.xml new file mode 100644 index 0000000..fc66cae --- /dev/null +++ b/config/net.xml @@ -0,0 +1,1136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/only_config_msg_test/config.xml b/config/only_config_msg_test/config.xml new file mode 100644 index 0000000..51921b4 --- /dev/null +++ b/config/only_config_msg_test/config.xml @@ -0,0 +1,55 @@ + + + + + report + + + config/simple_test/net.xml + + + + + + task + config/only_config_msg_test/data.xml + config/only_config_msg_test/map.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 6 9 10 + + diff --git a/config/only_config_msg_test/data.xml b/config/only_config_msg_test/data.xml new file mode 100644 index 0000000..5d88857 --- /dev/null +++ b/config/only_config_msg_test/data.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/only_config_msg_test/map.xml b/config/only_config_msg_test/map.xml new file mode 100644 index 0000000..8cb1846 --- /dev/null +++ b/config/only_config_msg_test/map.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/config/only_config_msg_test/net.xml b/config/only_config_msg_test/net.xml new file mode 100644 index 0000000..7c7104a --- /dev/null +++ b/config/only_config_msg_test/net.xml @@ -0,0 +1,1612 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/simple_2_layer_test/config.xml b/config/simple_2_layer_test/config.xml new file mode 100644 index 0000000..c9fe69b --- /dev/null +++ b/config/simple_2_layer_test/config.xml @@ -0,0 +1,55 @@ + + + + + report + + + config/simple_test/net.xml + + + + + + task + config/simple_2_layer_test/data.xml + config/simple_2_layer_test/map.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 6 9 10 + + diff --git a/config/simple_2_layer_test/data.xml b/config/simple_2_layer_test/data.xml new file mode 100644 index 0000000..0fc5fbc --- /dev/null +++ b/config/simple_2_layer_test/data.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/simple_2_layer_test/map.xml b/config/simple_2_layer_test/map.xml new file mode 100644 index 0000000..7c2fd0a --- /dev/null +++ b/config/simple_2_layer_test/map.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/simple_2_layer_test/net.xml b/config/simple_2_layer_test/net.xml new file mode 100644 index 0000000..7c7104a --- /dev/null +++ b/config/simple_2_layer_test/net.xml @@ -0,0 +1,1612 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..c91fdb8 --- /dev/null +++ b/config/simple_2_point_test/2pt_data.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..ca03596 --- /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 100644 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..5d47d14 --- /dev/null +++ b/config/simple_2_point_test/net.xml @@ -0,0 +1,1136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/simple_data.xml b/config/simple_data.xml new file mode 100644 index 0000000..e01c948 --- /dev/null +++ b/config/simple_data.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/simple_map.xml b/config/simple_map.xml new file mode 100644 index 0000000..0f8bf48 --- /dev/null +++ b/config/simple_map.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/config/simple_test/config.xml b/config/simple_test/config.xml new file mode 100644 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..7407f52 --- /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..e01c948 --- /dev/null +++ b/config/simple_test/simple_data.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/synthetic_test/config.xml b/config/synthetic_test/config.xml new file mode 100644 index 0000000..871c7e0 --- /dev/null +++ b/config/synthetic_test/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/synthetic_test/data_original.xml b/config/synthetic_test/data_original.xml new file mode 100644 index 0000000..6e5a628 --- /dev/null +++ b/config/synthetic_test/data_original.xml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/synthetic_test/map_original.xml b/config/synthetic_test/map_original.xml new file mode 100644 index 0000000..20a9bb3 --- /dev/null +++ b/config/synthetic_test/map_original.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/synthetic_test/net.xml b/config/synthetic_test/net.xml new file mode 100644 index 0000000..f91ea32 --- /dev/null +++ b/config/synthetic_test/net.xml @@ -0,0 +1,3248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/include/configuration.h b/include/configuration.h deleted file mode 100644 index 839b71c..0000000 --- a/include/configuration.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -using namespace sc_core; // For sc_time - -// Global parameters to generalize the design -#define ROUTER_NO 4 // Number of routers -#define CORE_NO 4 // Number of cores per router -#define CORE_FIFO_CAPACITY 8 // Capacity of FIFO in router that receive data from cores -#define ROUTER_RECEIVE_FIFO_CAPACITY 2 // Capacity of FIFO in router that receive data from other routers -#define LOG_NAME "MY_LOG" - -struct my_payload : public tlm::tlm_generic_payload { - unsigned int src_core; // Source core ID - unsigned int src_router; // Source router ID - unsigned int dst_core; // Destination core ID - unsigned int dst_router; // Destination router ID - int data; // Data value (random number) - sc_core::sc_time timestamp; // Timestamp field - - // Default constructor - my_payload() : src_core(0), src_router(0), dst_core(0), dst_router(0), data(0), timestamp(SC_ZERO_TIME) { - set_data_ptr(reinterpret_cast(&data)); - set_data_length(sizeof(data)); - set_streaming_width(sizeof(data)); - } - - // Constructor with random data - my_payload(unsigned int source_core, unsigned int src_router_id, unsigned int dst_core_id, unsigned int destination_router_id, int data, sc_time time = SC_ZERO_TIME) - : src_core(source_core), src_router(src_router_id), dst_core(dst_core_id), dst_router(destination_router_id), data(data) { - set_data_ptr(reinterpret_cast(&data)); - set_data_length(sizeof(data)); - set_streaming_width(sizeof(data)); - } - - // Function to update timestamp at any stage - void update_timestamp(sc_time new_time) { - timestamp = new_time; - } -}; - - -// Define the payload type -// struct my_payload : public tlm::tlm_generic_payload { -// unsigned int dst_core; -// unsigned int dst_router; -// int data; - -// my_payload() : dst_core(0), dst_router(0), data(0) { -// set_data_ptr(reinterpret_cast(&data)); -// set_data_length(sizeof(data)); -// set_streaming_width(sizeof(data)); -// } - -// my_payload(int d) : dst_core(0), dst_router(0), data(d) { -// set_data_ptr(reinterpret_cast(&data)); -// set_data_length(sizeof(data)); -// set_streaming_width(sizeof(data)); -// } - diff --git a/include/core.h b/include/core.h deleted file mode 100644 index a40554e..0000000 --- a/include/core.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // For rand() -#include // For time() - -#include "configuration.h" - - -// Initiator module (processor core) -SC_MODULE(core) { - tlm_utils::simple_initiator_socket socket; - tlm_utils::simple_target_socket target_socket; - unsigned int source_router_id; // Source router ID for this core - unsigned int source_core_id; - - SC_CTOR(core); - - // Thread for sending data - void thread(); - - /// Forwarding function for receiving data from router - tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay); - - void log_info(std::string msg); - void log_error(std::string msg); -}; diff --git a/include/semaphore_manager.h b/include/semaphore_manager.h deleted file mode 100644 index 08fe9de..0000000 --- a/include/semaphore_manager.h +++ /dev/null @@ -1,124 +0,0 @@ -// semaphore_manager.h -#ifndef SEMAPHORE_MANAGER_H -#define SEMAPHORE_MANAGER_H - -#include -#include -#include -#include -#include -#include -#include "configuration.h" - -using namespace sc_core; - -class semaphore_manager : public sc_module { -public: - SC_HAS_PROCESS(semaphore_manager); - - semaphore_manager(sc_module_name name) : sc_module(name) { - semaphore_owners.resize(ROUTER_NO, 0); // Start with all tokens at router 0 - request_queues.resize(ROUTER_NO); // Initialize a queue for each semaphore - queue_entries.resize(ROUTER_NO); // Set for each semaphore to track queued routers - semaphore_status.resize(ROUTER_NO, false); // All semaphores are initially free - std::fill_n(last_router_owner, ROUTER_NO, -1); // Initialize all last owners to -1 - SC_THREAD(update_semaphores); // Start automatic ownership update thread - sc_report_handler::set_log_file_name("out/report.log"); - sc_report_handler::set_actions(LOG_NAME, SC_INFO, SC_LOG|SC_DISPLAY); - } - - // Request a token for a semaphore with round-robin and priority ordering - bool request_token(int router_id, int semaphore_id) { - //wait(SC_ZERO_TIME); - std::lock_guard lock(mutex); // Ensure atomic access - if (semaphore_id >= 0 && semaphore_id < ROUTER_NO) { - - wait(SC_ZERO_TIME); - // Give priority if the request follows round-robin order from the last owner - if (semaphore_owners[semaphore_id] == router_id || semaphore_owners[semaphore_id] == -1 || (!semaphore_status[semaphore_id] && request_queues[semaphore_id].empty())) - { - log_info("Token for destination router " + std::to_string(semaphore_id) + " granted to Router " + std::to_string(router_id)); - semaphore_owners[semaphore_id] = router_id; - semaphore_status[semaphore_id] = true; // Mark semaphore as in use - last_router_owner[semaphore_id] = router_id; // Update the last owner - return true; - } else { - if (queue_entries[semaphore_id].find(router_id) == queue_entries[semaphore_id].end()) { - request_queues[semaphore_id].push(router_id); - queue_entries[semaphore_id].insert(router_id); // Track in the set - log_info("Router " + std::to_string(router_id) + " added to queue for semaphore " + std::to_string(semaphore_id)); - } - - } - } - return false; - } - - // Release the token and pass it to the next in the round-robin or queue order - bool release_token(int router_id, int semaphore_id) { - std::lock_guard lock(mutex); // Ensure atomic access - if (semaphore_id >= 0 && semaphore_id < ROUTER_NO) { - if (semaphore_owners[semaphore_id] == router_id) { - log_info("Router " + std::to_string(router_id) + " released token for destination router " + std::to_string(semaphore_id)); - semaphore_status[semaphore_id] = false; // Mark semaphore as free - - //wait(0, SC_NS); - - if (!request_queues[semaphore_id].empty()) { - int next_router = request_queues[semaphore_id].front(); - request_queues[semaphore_id].pop(); - queue_entries[semaphore_id].erase(next_router); // Remove from set when dequeued - semaphore_owners[semaphore_id] = next_router; - semaphore_status[semaphore_id] = true; // Mark semaphore as in use - log_info("Token for destination router " + std::to_string(semaphore_id) + " passed to Router " + std::to_string(next_router)); - //request_token(next_router, semaphore_id); - - } else { - semaphore_owners[semaphore_id] = -1; - // Assign to next router in round-robin if idle - // semaphore_owners[semaphore_id] = (semaphore_owners[semaphore_id] + 1) % ROUTER_NO; - // log_info("Token for destination router " + std::to_string(semaphore_id) + " passed to Router " + std::to_string(semaphore_owners[semaphore_id])); - } - return true; - } - } - return false; - } - - // Periodic update function to rotate token ownership in round-robin if tokens are idle - void update_semaphores() { - while (true) { - wait(20, SC_NS); - for (int i = 0; i < ROUTER_NO; ++i) { - std::lock_guard lock(mutex); // Ensure atomic update - if ((!semaphore_status[i] && (semaphore_owners[i] == -1 || request_queues[i].empty()))) { - semaphore_owners[i] = (last_router_owner[i] + 1) % ROUTER_NO; - log_info("Updated owner of semaphore " + std::to_string(i) + " to Router " + std::to_string(semaphore_owners[i])); - last_router_owner[i] = semaphore_owners[i]; - - } - } - } - } - - -private: - std::vector semaphore_owners; // Tracks router ownership (-1 means no owner) - std::vector> request_queues; // Queue of pending requests per semaphore - std::vector semaphore_status; // Semaphore availability - sc_mutex mutex; // Mutex to ensure atomic operations - std::vector> queue_entries; // Track entries in each queue to prevent duplicates - int last_router_owner[ROUTER_NO]; // Array to track last owner for round-robin assignment - - //print log messages - void log_info(std::string msg){ - SC_REPORT_INFO(LOG_NAME, msg.c_str()); - } - - void log_error(std::string msg){ - SC_REPORT_ERROR(LOG_NAME, msg.c_str()); - } - -}; - -#endif // SEMAPHORE_MANAGER_H diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 4041bbf..0000000 --- a/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // For rand() -#include // For time() - -#include "configuration.h" -#include "router.h" -#include "core.h" -#include "semaphore_manager.h" - -int sc_main(int argc, char* argv[]) { - - // Create a semaphore manager instance - semaphore_manager sem_mgr("SemaphoreManager"); - // Instantiate ROUTER_NO routers - router* routers[ROUTER_NO]; - std::vector router_sems; - std::vector*> router_out_fifos; - for (int i = 0; i < ROUTER_NO; ++i) { - std::string router_name = "router" + std::to_string(i); - routers[i] = new router(router_name.c_str()); - - // Assign the router ID - routers[i]-> router_id = i; - - // Store semaphores and out_fifos in vectors - router_sems.push_back(&routers[i]->sem); - router_out_fifos.push_back(&routers[i]->out_fifo); - - routers[i]->set_semaphore_manager(&sem_mgr); // Pass semaphore manager to each router - } - - // Set up pointers to other routers' semaphores and out_fifos for each router - for (int i = 0; i < ROUTER_NO; i++) { - routers[i]->other_sems = router_sems; - routers[i]->other_out_fifos = router_out_fifos; - } - - // Instantiate ROUTER_NO*CORE_NO cores (CORE_NO per router) - core* cores[ROUTER_NO][CORE_NO]; // ROUTER_NO routers, each with CORE_NO cores - for (int i = 0; i < ROUTER_NO; ++i) { // Router index - for (int j = 0; j < CORE_NO; ++j) { // Core index within each router - std::string core_name = "core" + std::to_string(i) + "_" + std::to_string(j); - cores[i][j] = new core(core_name.c_str()); - cores[i][j]->source_router_id = i; // Set source router ID - cores[i][j]->source_core_id = j; // Set source router ID - } - } - - // Bind cores to their respective routers - for (int i = 0; i < ROUTER_NO; ++i) { // Router index - for (int j = 0; j < CORE_NO; ++j) { // Core index within each router - cores[i][j]->socket.bind(routers[i]->sockets[j]); // Core's socket to router's target socket - routers[i]->core_sockets[j].bind(cores[i][j]->target_socket); // Router's initiator socket to core's target socket - routers[i]->current_router_id= i; - } - } - - // Start the simulation - sc_core::sc_start(400, SC_NS); - //sc_start(); - - // Clean up memory to avoid leaks - for (int i = 0; i < ROUTER_NO; ++i) { - for (int j = 0; j < CORE_NO; ++j) { - delete cores[i][j]; // Delete each core - } - - delete routers[i]; // Delete each router - - } - - return 0; -} - diff --git a/obj/core.o b/obj/core.o deleted file mode 100644 index fbff322..0000000 Binary files a/obj/core.o and /dev/null differ diff --git a/obj/router.o b/obj/router.o deleted file mode 100644 index a0f614d..0000000 Binary files a/obj/router.o and /dev/null differ diff --git a/out/noc_simulation b/out/noc_simulation deleted file mode 100644 index 6b8fd49..0000000 Binary files a/out/noc_simulation and /dev/null differ diff --git a/out/report.log b/out/report.log index 42fb6c1..66e8ec9 100644 --- a/out/report.log +++ b/out/report.log @@ -1,778 +1,12 @@ -0 s: Info: MY_LOG: Core 0 of Source Router: 0: Processing data 76 for router 3 and core 3 at time: 0 s -0 s: Info: MY_LOG: Router router0: Received transaction with data: 76 at time: 0 s -0 s: Info: MY_LOG: Core core0_0: Transaction successful, data sent: 76 at time: 0 s -0 s: Info: MY_LOG: Core 1 of Source Router: 0: Processing data 95 for router 2 and core 1 at time: 0 s -0 s: Info: MY_LOG: Router router0: Received transaction with data: 95 at time: 0 s -0 s: Info: MY_LOG: Core core0_1: Transaction successful, data sent: 95 at time: 0 s -0 s: Info: MY_LOG: Core 2 of Source Router: 0: Processing data 5 for router 1 and core 3 at time: 0 s -0 s: Info: MY_LOG: Router router0: Received transaction with data: 5 at time: 0 s -0 s: Info: MY_LOG: Core core0_2: Transaction successful, data sent: 5 at time: 0 s -0 s: Info: MY_LOG: Core 3 of Source Router: 0: Processing data 27 for router 3 and core 2 at time: 0 s -0 s: Info: MY_LOG: Router router0: Received transaction with data: 27 at time: 0 s -0 s: Info: MY_LOG: Core core0_3: Transaction successful, data sent: 27 at time: 0 s -0 s: Info: MY_LOG: Core 0 of Source Router: 1: Processing data 22 for router 2 and core 2 at time: 0 s -0 s: Info: MY_LOG: Router router1: Received transaction with data: 22 at time: 0 s -0 s: Info: MY_LOG: Core core1_0: Transaction successful, data sent: 22 at time: 0 s -0 s: Info: MY_LOG: Core 1 of Source Router: 1: Processing data 4 for router 0 and core 2 at time: 0 s -0 s: Info: MY_LOG: Router router1: Received transaction with data: 4 at time: 0 s -0 s: Info: MY_LOG: Core core1_1: Transaction successful, data sent: 4 at time: 0 s -0 s: Info: MY_LOG: Core 2 of Source Router: 1: Processing data 37 for router 3 and core 0 at time: 0 s -0 s: Info: MY_LOG: Router router1: Received transaction with data: 37 at time: 0 s -0 s: Info: MY_LOG: Core core1_2: Transaction successful, data sent: 37 at time: 0 s -0 s: Info: MY_LOG: Core 3 of Source Router: 1: Processing data 95 for router 2 and core 3 at time: 0 s -0 s: Info: MY_LOG: Router router1: Received transaction with data: 95 at time: 0 s -0 s: Info: MY_LOG: Core core1_3: Transaction successful, data sent: 95 at time: 0 s -0 s: Info: MY_LOG: Core 0 of Source Router: 2: Processing data 23 for router 3 and core 2 at time: 0 s -0 s: Info: MY_LOG: Router router2: Received transaction with data: 23 at time: 0 s -0 s: Info: MY_LOG: Core core2_0: Transaction successful, data sent: 23 at time: 0 s -0 s: Info: MY_LOG: Core 1 of Source Router: 2: Processing data 41 for router 3 and core 2 at time: 0 s -0 s: Info: MY_LOG: Router router2: Received transaction with data: 41 at time: 0 s -0 s: Info: MY_LOG: Core core2_1: Transaction successful, data sent: 41 at time: 0 s -0 s: Info: MY_LOG: Core 2 of Source Router: 2: Processing data 16 for router 3 and core 0 at time: 0 s -0 s: Info: MY_LOG: Router router2: Received transaction with data: 16 at time: 0 s -0 s: Info: MY_LOG: Core core2_2: Transaction successful, data sent: 16 at time: 0 s -0 s: Info: MY_LOG: Core 3 of Source Router: 2: Processing data 17 for router 3 and core 1 at time: 0 s -0 s: Info: MY_LOG: Router router2: Received transaction with data: 17 at time: 0 s -0 s: Info: MY_LOG: Core core2_3: Transaction successful, data sent: 17 at time: 0 s -0 s: Info: MY_LOG: Core 0 of Source Router: 3: Processing data 74 for router 0 and core 0 at time: 0 s -0 s: Info: MY_LOG: Router router3: Received transaction with data: 74 at time: 0 s -0 s: Info: MY_LOG: Core core3_0: Transaction successful, data sent: 74 at time: 0 s -0 s: Info: MY_LOG: Core 1 of Source Router: 3: Processing data 88 for router 1 and core 2 at time: 0 s -0 s: Info: MY_LOG: Router router3: Received transaction with data: 88 at time: 0 s -0 s: Info: MY_LOG: Core core3_1: Transaction successful, data sent: 88 at time: 0 s -0 s: Info: MY_LOG: Core 2 of Source Router: 3: Processing data 91 for router 0 and core 3 at time: 0 s -0 s: Info: MY_LOG: Router router3: Received transaction with data: 91 at time: 0 s -0 s: Info: MY_LOG: Core core3_2: Transaction successful, data sent: 91 at time: 0 s -0 s: Info: MY_LOG: Core 3 of Source Router: 3: Processing data 40 for router 0 and core 1 at time: 0 s -0 s: Info: MY_LOG: Router router3: Received transaction with data: 40 at time: 0 s -0 s: Info: MY_LOG: Core core3_3: Transaction successful, data sent: 40 at time: 0 s -0 s: Info: MY_LOG: Token for destination router 3 granted to Router 0 -0 s: Info: MY_LOG: router0 forwarded data: 76 to Router_3 -0 s: Info: MY_LOG: Token for destination router 2 granted to Router 1 -0 s: Info: MY_LOG: router1 forwarded data: 22 to Router_2 -0 s: Info: MY_LOG: Token for destination router 0 granted to Router 3 -0 s: Info: MY_LOG: router3 forwarded data: 74 to Router_0 -0 s: Info: MY_LOG: Router 2 added to queue for semaphore 3 -0 s: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 23 -5 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 23 -10 ns: Info: MY_LOG: Router 1 released token for destination router 2 -10 ns: Info: MY_LOG: Router 2: Received transaction with data: 22 from Router 1 after a delay of:10 ns -10 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 22 to core 2 -10 ns: Info: MY_LOG: Core 2 of parent Router: 2: Processing transaction and received data: 22 -10 ns: Info: MY_LOG: Router router2: Core 2 completed transaction, data: 22 -10 ns: Info: MY_LOG: Router 0: Received transaction with data: 74 from Router 3 after a delay of:10 ns -10 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 74 to core 0 -10 ns: Info: MY_LOG: Core 0 of parent Router: 0: Processing transaction and received data: 74 -10 ns: Info: MY_LOG: Router router0: Core 0 completed transaction, data: 74 -10 ns: Info: MY_LOG: Router 1 added to queue for semaphore 0 -10 ns: Info: MY_LOG: Router router1: Semaphore for Router_0 is unavailable. Retrying with data: 4 -10 ns: Info: MY_LOG: Router 3 released token for destination router 0 -10 ns: Info: MY_LOG: Token for destination router 0 passed to Router 1 -10 ns: Info: MY_LOG: Token for destination router 1 granted to Router 3 -10 ns: Info: MY_LOG: router3 forwarded data: 88 to Router_1 -10 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 23 -15 ns: Info: MY_LOG: Token for destination router 0 granted to Router 1 -15 ns: Info: MY_LOG: router1 forwarded data: 4 to Router_0 -15 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 23 -20 ns: Info: MY_LOG: Updated owner of semaphore 2 to Router 2 -20 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 23 -25 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 23 -30 ns: Info: MY_LOG: Router 0 released token for destination router 3 -30 ns: Info: MY_LOG: Token for destination router 3 passed to Router 2 -30 ns: Info: MY_LOG: Router 3: Received transaction with data: 76 from Router 0 after a delay of:30 ns -30 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 76 to core 3 -30 ns: Info: MY_LOG: Core 3 of parent Router: 3: Processing transaction and received data: 76 -30 ns: Info: MY_LOG: Router router3: Core 3 completed transaction, data: 76 -30 ns: Info: MY_LOG: Router 1: Received transaction with data: 88 from Router 3 after a delay of:20 ns -30 ns: Info: MY_LOG: Router router1: Forwarding transaction with data: 88 to core 2 -30 ns: Info: MY_LOG: Core 2 of parent Router: 1: Processing transaction and received data: 88 -30 ns: Info: MY_LOG: Router router1: Core 2 completed transaction, data: 88 -30 ns: Info: MY_LOG: Token for destination router 2 granted to Router 0 -30 ns: Info: MY_LOG: router0 forwarded data: 95 to Router_2 -30 ns: Info: MY_LOG: Router 3 released token for destination router 1 -30 ns: Info: MY_LOG: Router 3 added to queue for semaphore 0 -30 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 91 -30 ns: Info: MY_LOG: Token for destination router 3 granted to Router 2 -30 ns: Info: MY_LOG: router2 forwarded data: 23 to Router_3 -35 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 91 -40 ns: Info: MY_LOG: Updated owner of semaphore 1 to Router 0 -40 ns: Info: MY_LOG: Router 2 released token for destination router 3 -40 ns: Info: MY_LOG: Router 3: Received transaction with data: 23 from Router 2 after a delay of:10 ns -40 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 23 to core 2 -40 ns: Info: MY_LOG: Core 2 of parent Router: 3: Processing transaction and received data: 23 -40 ns: Info: MY_LOG: Router router3: Core 2 completed transaction, data: 23 -40 ns: Info: MY_LOG: Token for destination router 3 granted to Router 2 -40 ns: Info: MY_LOG: router2 forwarded data: 41 to Router_3 -40 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 91 -45 ns: Info: MY_LOG: Router 1 released token for destination router 0 -45 ns: Info: MY_LOG: Token for destination router 0 passed to Router 3 -45 ns: Info: MY_LOG: Router 0: Received transaction with data: 4 from Router 1 after a delay of:30 ns -45 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 4 to core 2 -45 ns: Info: MY_LOG: Core 2 of parent Router: 0: Processing transaction and received data: 4 -45 ns: Info: MY_LOG: Router router0: Core 2 completed transaction, data: 4 -45 ns: Info: MY_LOG: Router 1 added to queue for semaphore 3 -45 ns: Info: MY_LOG: Router router1: Semaphore for Router_3 is unavailable. Retrying with data: 37 -45 ns: Info: MY_LOG: Token for destination router 0 granted to Router 3 -45 ns: Info: MY_LOG: router3 forwarded data: 91 to Router_0 -50 ns: Info: MY_LOG: Router 0 released token for destination router 2 -50 ns: Info: MY_LOG: Router 2: Received transaction with data: 95 from Router 0 after a delay of:20 ns -50 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 95 to core 1 -50 ns: Info: MY_LOG: Core 1 of parent Router: 2: Processing transaction and received data: 95 -50 ns: Info: MY_LOG: Router router2: Core 1 completed transaction, data: 95 -50 ns: Info: MY_LOG: Router 3: Received transaction with data: 41 from Router 2 after a delay of:10 ns -50 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 41 to core 2 -50 ns: Info: MY_LOG: Core 2 of parent Router: 3: Processing transaction and received data: 41 -50 ns: Info: MY_LOG: Router router3: Core 2 completed transaction, data: 41 -50 ns: Info: MY_LOG: Token for destination router 1 granted to Router 0 -50 ns: Info: MY_LOG: router0 forwarded data: 5 to Router_1 -50 ns: Info: MY_LOG: Router 2 released token for destination router 3 -50 ns: Info: MY_LOG: Token for destination router 3 passed to Router 1 -50 ns: Info: MY_LOG: Router 2 added to queue for semaphore 3 -50 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 16 -50 ns: Info: MY_LOG: Token for destination router 3 granted to Router 1 -50 ns: Info: MY_LOG: router1 forwarded data: 37 to Router_3 -55 ns: Info: MY_LOG: Router 3 released token for destination router 0 -55 ns: Info: MY_LOG: Router 0: Received transaction with data: 91 from Router 3 after a delay of:10 ns -55 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 91 to core 3 -55 ns: Info: MY_LOG: Core 3 of parent Router: 0: Processing transaction and received data: 91 -55 ns: Info: MY_LOG: Router router0: Core 3 completed transaction, data: 91 -55 ns: Info: MY_LOG: Token for destination router 0 granted to Router 3 -55 ns: Info: MY_LOG: router3 forwarded data: 40 to Router_0 -55 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 16 -60 ns: Info: MY_LOG: Router 0 released token for destination router 1 -60 ns: Info: MY_LOG: Router 1: Received transaction with data: 5 from Router 0 after a delay of:10 ns -60 ns: Info: MY_LOG: Router router1: Forwarding transaction with data: 5 to core 3 -60 ns: Info: MY_LOG: Core 3 of parent Router: 1: Processing transaction and received data: 5 -60 ns: Info: MY_LOG: Router router1: Core 3 completed transaction, data: 5 -60 ns: Info: MY_LOG: Router 0 added to queue for semaphore 3 -60 ns: Info: MY_LOG: Router router0: Semaphore for Router_3 is unavailable. Retrying with data: 27 -60 ns: Info: MY_LOG: Updated owner of semaphore 1 to Router 1 -60 ns: Info: MY_LOG: Updated owner of semaphore 2 to Router 1 -60 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 16 -65 ns: Info: MY_LOG: Router 3 released token for destination router 0 -65 ns: Info: MY_LOG: Router 0: Received transaction with data: 40 from Router 3 after a delay of:10 ns -65 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 40 to core 1 -65 ns: Info: MY_LOG: Core 1 of parent Router: 0: Processing transaction and received data: 40 -65 ns: Info: MY_LOG: Router router0: Core 1 completed transaction, data: 40 -65 ns: Info: MY_LOG: Router router0: Semaphore for Router_3 is unavailable. Retrying with data: 27 -65 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 16 -70 ns: Info: MY_LOG: Router 1 released token for destination router 3 -70 ns: Info: MY_LOG: Token for destination router 3 passed to Router 2 -70 ns: Info: MY_LOG: Router 3: Received transaction with data: 37 from Router 1 after a delay of:20 ns -70 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 37 to core 0 -70 ns: Info: MY_LOG: Core 0 of parent Router: 3: Processing transaction and received data: 37 -70 ns: Info: MY_LOG: Router router3: Core 0 completed transaction, data: 37 -70 ns: Info: MY_LOG: Token for destination router 2 granted to Router 1 -70 ns: Info: MY_LOG: router1 forwarded data: 95 to Router_2 -70 ns: Info: MY_LOG: Router router0: Semaphore for Router_3 is unavailable. Retrying with data: 27 -70 ns: Info: MY_LOG: Token for destination router 3 granted to Router 2 -70 ns: Info: MY_LOG: router2 forwarded data: 16 to Router_3 -75 ns: Info: MY_LOG: Router router0: Semaphore for Router_3 is unavailable. Retrying with data: 27 -80 ns: Info: MY_LOG: Updated owner of semaphore 0 to Router 0 -80 ns: Info: MY_LOG: Updated owner of semaphore 1 to Router 2 -80 ns: Info: MY_LOG: Router 1 released token for destination router 2 -80 ns: Info: MY_LOG: Router 2 released token for destination router 3 -80 ns: Info: MY_LOG: Token for destination router 3 passed to Router 0 -80 ns: Info: MY_LOG: Router 2: Received transaction with data: 95 from Router 1 after a delay of:10 ns -80 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 95 to core 3 -80 ns: Info: MY_LOG: Core 3 of parent Router: 2: Processing transaction and received data: 95 -80 ns: Info: MY_LOG: Router router2: Core 3 completed transaction, data: 95 -80 ns: Info: MY_LOG: Router 3: Received transaction with data: 16 from Router 2 after a delay of:10 ns -80 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 16 to core 0 -80 ns: Info: MY_LOG: Core 0 of parent Router: 3: Processing transaction and received data: 16 -80 ns: Info: MY_LOG: Router router3: Core 0 completed transaction, data: 16 -80 ns: Info: MY_LOG: Router 2 added to queue for semaphore 3 -80 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 17 -80 ns: Info: MY_LOG: Token for destination router 3 granted to Router 0 -80 ns: Info: MY_LOG: router0 forwarded data: 27 to Router_3 -85 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 17 -90 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 17 -95 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 17 -100 ns: Info: MY_LOG: Core 3 of Source Router: 2: Processing data 74 for router 0 and core 3 at time: 100 ns -100 ns: Info: MY_LOG: Router router2: Received transaction with data: 74 at time: 100 ns -100 ns: Info: MY_LOG: Core core2_3: Transaction successful, data sent: 74 at time: 100 ns -100 ns: Info: MY_LOG: Core 1 of Source Router: 0: Processing data 28 for router 1 and core 2 at time: 100 ns -100 ns: Info: MY_LOG: Router router0: Received transaction with data: 28 at time: 100 ns -100 ns: Info: MY_LOG: Core core0_1: Transaction successful, data sent: 28 at time: 100 ns -100 ns: Info: MY_LOG: Core 0 of Source Router: 2: Processing data 55 for router 0 and core 1 at time: 100 ns -100 ns: Info: MY_LOG: Router router2: Received transaction with data: 55 at time: 100 ns -100 ns: Info: MY_LOG: Core core2_0: Transaction successful, data sent: 55 at time: 100 ns -100 ns: Info: MY_LOG: Core 1 of Source Router: 1: Processing data 21 for router 2 and core 3 at time: 100 ns -100 ns: Info: MY_LOG: Router router1: Received transaction with data: 21 at time: 100 ns -100 ns: Info: MY_LOG: Core core1_1: Transaction successful, data sent: 21 at time: 100 ns -100 ns: Info: MY_LOG: Core 3 of Source Router: 0: Processing data 100 for router 1 and core 3 at time: 100 ns -100 ns: Info: MY_LOG: Router router0: Received transaction with data: 100 at time: 100 ns -100 ns: Info: MY_LOG: Core core0_3: Transaction successful, data sent: 100 at time: 100 ns -100 ns: Info: MY_LOG: Core 2 of Source Router: 3: Processing data 84 for router 0 and core 1 at time: 100 ns -100 ns: Info: MY_LOG: Router router3: Received transaction with data: 84 at time: 100 ns -100 ns: Info: MY_LOG: Core core3_2: Transaction successful, data sent: 84 at time: 100 ns -100 ns: Info: MY_LOG: Core 2 of Source Router: 0: Processing data 23 for router 1 and core 1 at time: 100 ns -100 ns: Info: MY_LOG: Router router0: Received transaction with data: 23 at time: 100 ns -100 ns: Info: MY_LOG: Core core0_2: Transaction successful, data sent: 23 at time: 100 ns -100 ns: Info: MY_LOG: Core 1 of Source Router: 2: Processing data 4 for router 0 and core 0 at time: 100 ns -100 ns: Info: MY_LOG: Router router2: Received transaction with data: 4 at time: 100 ns -100 ns: Info: MY_LOG: Core core2_1: Transaction successful, data sent: 4 at time: 100 ns -100 ns: Info: MY_LOG: Core 2 of Source Router: 2: Processing data 73 for router 3 and core 2 at time: 100 ns -100 ns: Info: MY_LOG: Router router2: Received transaction with data: 73 at time: 100 ns -100 ns: Info: MY_LOG: Core core2_2: Transaction successful, data sent: 73 at time: 100 ns -100 ns: Info: MY_LOG: Core 0 of Source Router: 3: Processing data 78 for router 0 and core 3 at time: 100 ns -100 ns: Info: MY_LOG: Router router3: Received transaction with data: 78 at time: 100 ns -100 ns: Info: MY_LOG: Core core3_0: Transaction successful, data sent: 78 at time: 100 ns -100 ns: Info: MY_LOG: Core 3 of Source Router: 1: Processing data 42 for router 2 and core 0 at time: 100 ns -100 ns: Info: MY_LOG: Router router1: Received transaction with data: 42 at time: 100 ns -100 ns: Info: MY_LOG: Core core1_3: Transaction successful, data sent: 42 at time: 100 ns -100 ns: Info: MY_LOG: Core 1 of Source Router: 3: Processing data 32 for router 1 and core 1 at time: 100 ns -100 ns: Info: MY_LOG: Router router3: Received transaction with data: 32 at time: 100 ns -100 ns: Info: MY_LOG: Core core3_1: Transaction successful, data sent: 32 at time: 100 ns -100 ns: Info: MY_LOG: Core 2 of Source Router: 1: Processing data 55 for router 3 and core 0 at time: 100 ns -100 ns: Info: MY_LOG: Router router1: Received transaction with data: 55 at time: 100 ns -100 ns: Info: MY_LOG: Core core1_2: Transaction successful, data sent: 55 at time: 100 ns -100 ns: Info: MY_LOG: Core 0 of Source Router: 0: Processing data 54 for router 3 and core 1 at time: 100 ns -100 ns: Info: MY_LOG: Router router0: Received transaction with data: 54 at time: 100 ns -100 ns: Info: MY_LOG: Core core0_0: Transaction successful, data sent: 54 at time: 100 ns -100 ns: Info: MY_LOG: Core 0 of Source Router: 1: Processing data 65 for router 0 and core 1 at time: 100 ns -100 ns: Info: MY_LOG: Router router1: Received transaction with data: 65 at time: 100 ns -100 ns: Info: MY_LOG: Core core1_0: Transaction successful, data sent: 65 at time: 100 ns -100 ns: Info: MY_LOG: Core 3 of Source Router: 3: Processing data 37 for router 2 and core 2 at time: 100 ns -100 ns: Info: MY_LOG: Router router3: Received transaction with data: 37 at time: 100 ns -100 ns: Info: MY_LOG: Core core3_3: Transaction successful, data sent: 37 at time: 100 ns -100 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 17 -100 ns: Info: MY_LOG: Updated owner of semaphore 0 to Router 1 -100 ns: Info: MY_LOG: Updated owner of semaphore 1 to Router 3 -100 ns: Info: MY_LOG: Updated owner of semaphore 2 to Router 2 -100 ns: Info: MY_LOG: Token for destination router 0 granted to Router 3 -100 ns: Info: MY_LOG: router3 forwarded data: 84 to Router_0 -100 ns: Info: MY_LOG: Token for destination router 2 granted to Router 1 -100 ns: Info: MY_LOG: router1 forwarded data: 21 to Router_2 -105 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 17 -110 ns: Info: MY_LOG: Router 0 released token for destination router 3 -110 ns: Info: MY_LOG: Token for destination router 3 passed to Router 2 -110 ns: Info: MY_LOG: Router 3: Received transaction with data: 27 from Router 0 after a delay of:30 ns -110 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 27 to core 2 -110 ns: Info: MY_LOG: Core 2 of parent Router: 3: Processing transaction and received data: 27 -110 ns: Info: MY_LOG: Router router3: Core 2 completed transaction, data: 27 -110 ns: Info: MY_LOG: Router 0: Received transaction with data: 84 from Router 3 after a delay of:10 ns -110 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 84 to core 1 -110 ns: Info: MY_LOG: Core 1 of parent Router: 0: Processing transaction and received data: 84 -110 ns: Info: MY_LOG: Router router0: Core 1 completed transaction, data: 84 -110 ns: Info: MY_LOG: Router 2: Received transaction with data: 21 from Router 1 after a delay of:10 ns -110 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 21 to core 3 -110 ns: Info: MY_LOG: Core 3 of parent Router: 2: Processing transaction and received data: 21 -110 ns: Info: MY_LOG: Router router2: Core 3 completed transaction, data: 21 -110 ns: Info: MY_LOG: Token for destination router 1 granted to Router 0 -110 ns: Info: MY_LOG: router0 forwarded data: 28 to Router_1 -110 ns: Info: MY_LOG: Router 3 released token for destination router 0 -110 ns: Info: MY_LOG: Token for destination router 0 granted to Router 3 -110 ns: Info: MY_LOG: router3 forwarded data: 78 to Router_0 -110 ns: Info: MY_LOG: Token for destination router 3 granted to Router 2 -110 ns: Info: MY_LOG: router2 forwarded data: 17 to Router_3 -110 ns: Info: MY_LOG: Router 1 released token for destination router 2 -110 ns: Info: MY_LOG: Token for destination router 2 granted to Router 1 -110 ns: Info: MY_LOG: router1 forwarded data: 42 to Router_2 -120 ns: Info: MY_LOG: Router 0 released token for destination router 1 -120 ns: Info: MY_LOG: Router 1: Received transaction with data: 28 from Router 0 after a delay of:10 ns -120 ns: Info: MY_LOG: Router router1: Forwarding transaction with data: 28 to core 2 -120 ns: Info: MY_LOG: Core 2 of parent Router: 1: Processing transaction and received data: 28 -120 ns: Info: MY_LOG: Router router1: Core 2 completed transaction, data: 28 -120 ns: Info: MY_LOG: Router 0: Received transaction with data: 78 from Router 3 after a delay of:10 ns -120 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 78 to core 3 -120 ns: Info: MY_LOG: Core 3 of parent Router: 0: Processing transaction and received data: 78 -120 ns: Info: MY_LOG: Router router0: Core 3 completed transaction, data: 78 -120 ns: Info: MY_LOG: Router 3: Received transaction with data: 17 from Router 2 after a delay of:10 ns -120 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 17 to core 1 -120 ns: Info: MY_LOG: Core 1 of parent Router: 3: Processing transaction and received data: 17 -120 ns: Info: MY_LOG: Router router3: Core 1 completed transaction, data: 17 -120 ns: Info: MY_LOG: Router 2: Received transaction with data: 42 from Router 1 after a delay of:10 ns -120 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 42 to core 0 -120 ns: Info: MY_LOG: Core 0 of parent Router: 2: Processing transaction and received data: 42 -120 ns: Info: MY_LOG: Router router2: Core 0 completed transaction, data: 42 -120 ns: Info: MY_LOG: Token for destination router 1 granted to Router 0 -120 ns: Info: MY_LOG: router0 forwarded data: 100 to Router_1 -120 ns: Info: MY_LOG: Router 3 released token for destination router 0 -120 ns: Info: MY_LOG: Router 3 added to queue for semaphore 1 -120 ns: Info: MY_LOG: Router router3: Semaphore for Router_1 is unavailable. Retrying with data: 32 -120 ns: Info: MY_LOG: Router 1 released token for destination router 2 -120 ns: Info: MY_LOG: Router 1 added to queue for semaphore 3 -120 ns: Info: MY_LOG: Router router1: Semaphore for Router_3 is unavailable. Retrying with data: 55 -120 ns: Info: MY_LOG: Router 2 released token for destination router 3 -120 ns: Info: MY_LOG: Token for destination router 3 passed to Router 1 -120 ns: Info: MY_LOG: Token for destination router 0 granted to Router 2 -120 ns: Info: MY_LOG: router2 forwarded data: 74 to Router_0 -125 ns: Info: MY_LOG: Router router3: Semaphore for Router_1 is unavailable. Retrying with data: 32 -125 ns: Info: MY_LOG: Token for destination router 3 granted to Router 1 -125 ns: Info: MY_LOG: router1 forwarded data: 55 to Router_3 -130 ns: Info: MY_LOG: Router 0 released token for destination router 1 -130 ns: Info: MY_LOG: Token for destination router 1 passed to Router 3 -130 ns: Info: MY_LOG: Router 1: Received transaction with data: 100 from Router 0 after a delay of:10 ns -130 ns: Info: MY_LOG: Router router1: Forwarding transaction with data: 100 to core 3 -130 ns: Info: MY_LOG: Core 3 of parent Router: 1: Processing transaction and received data: 100 -130 ns: Info: MY_LOG: Router router1: Core 3 completed transaction, data: 100 -130 ns: Info: MY_LOG: Router 0 added to queue for semaphore 1 -130 ns: Info: MY_LOG: Router router0: Semaphore for Router_1 is unavailable. Retrying with data: 23 -130 ns: Info: MY_LOG: Token for destination router 1 granted to Router 3 -130 ns: Info: MY_LOG: router3 forwarded data: 32 to Router_1 -135 ns: Info: MY_LOG: Router router0: Semaphore for Router_1 is unavailable. Retrying with data: 23 -140 ns: Info: MY_LOG: Updated owner of semaphore 2 to Router 2 -140 ns: Info: MY_LOG: Router 2 released token for destination router 0 -140 ns: Info: MY_LOG: Router 0: Received transaction with data: 74 from Router 2 after a delay of:20 ns -140 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 74 to core 3 -140 ns: Info: MY_LOG: Core 3 of parent Router: 0: Processing transaction and received data: 74 -140 ns: Info: MY_LOG: Router router0: Core 3 completed transaction, data: 74 -140 ns: Info: MY_LOG: Token for destination router 0 granted to Router 2 -140 ns: Info: MY_LOG: router2 forwarded data: 55 to Router_0 -140 ns: Info: MY_LOG: Router router0: Semaphore for Router_1 is unavailable. Retrying with data: 23 -145 ns: Info: MY_LOG: Router 1 released token for destination router 3 -145 ns: Info: MY_LOG: Router 3: Received transaction with data: 55 from Router 1 after a delay of:20 ns -145 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 55 to core 0 -145 ns: Info: MY_LOG: Core 0 of parent Router: 3: Processing transaction and received data: 55 -145 ns: Info: MY_LOG: Router router3: Core 0 completed transaction, data: 55 -145 ns: Info: MY_LOG: Router 1 added to queue for semaphore 0 -145 ns: Info: MY_LOG: Router router1: Semaphore for Router_0 is unavailable. Retrying with data: 65 -145 ns: Info: MY_LOG: Router router0: Semaphore for Router_1 is unavailable. Retrying with data: 23 -150 ns: Info: MY_LOG: Router 3 released token for destination router 1 -150 ns: Info: MY_LOG: Token for destination router 1 passed to Router 0 -150 ns: Info: MY_LOG: Router 1: Received transaction with data: 32 from Router 3 after a delay of:20 ns -150 ns: Info: MY_LOG: Router router1: Forwarding transaction with data: 32 to core 1 -150 ns: Info: MY_LOG: Core 1 of parent Router: 1: Processing transaction and received data: 32 -150 ns: Info: MY_LOG: Router router1: Core 1 completed transaction, data: 32 -150 ns: Info: MY_LOG: Token for destination router 2 granted to Router 3 -150 ns: Info: MY_LOG: router3 forwarded data: 37 to Router_2 -150 ns: Info: MY_LOG: Router router1: Semaphore for Router_0 is unavailable. Retrying with data: 65 -150 ns: Info: MY_LOG: Token for destination router 1 granted to Router 0 -150 ns: Info: MY_LOG: router0 forwarded data: 23 to Router_1 -155 ns: Info: MY_LOG: Router router1: Semaphore for Router_0 is unavailable. Retrying with data: 65 -160 ns: Info: MY_LOG: Router 2 released token for destination router 0 -160 ns: Info: MY_LOG: Token for destination router 0 passed to Router 1 -160 ns: Info: MY_LOG: Router 0: Received transaction with data: 55 from Router 2 after a delay of:20 ns -160 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 55 to core 1 -160 ns: Info: MY_LOG: Core 1 of parent Router: 0: Processing transaction and received data: 55 -160 ns: Info: MY_LOG: Router router0: Core 1 completed transaction, data: 55 -160 ns: Info: MY_LOG: Router 1: Received transaction with data: 23 from Router 0 after a delay of:10 ns -160 ns: Info: MY_LOG: Router router1: Forwarding transaction with data: 23 to core 1 -160 ns: Info: MY_LOG: Core 1 of parent Router: 1: Processing transaction and received data: 23 -160 ns: Info: MY_LOG: Router router1: Core 1 completed transaction, data: 23 -160 ns: Info: MY_LOG: Router 2 added to queue for semaphore 0 -160 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 4 -160 ns: Info: MY_LOG: Updated owner of semaphore 3 to Router 2 -160 ns: Info: MY_LOG: Token for destination router 0 granted to Router 1 -160 ns: Info: MY_LOG: router1 forwarded data: 65 to Router_0 -160 ns: Info: MY_LOG: Router 0 released token for destination router 1 -160 ns: Info: MY_LOG: Token for destination router 3 granted to Router 0 -160 ns: Info: MY_LOG: router0 forwarded data: 54 to Router_3 -165 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 4 -170 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 4 -175 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 4 -180 ns: Info: MY_LOG: Router 3 released token for destination router 2 -180 ns: Info: MY_LOG: Updated owner of semaphore 1 to Router 1 -180 ns: Info: MY_LOG: Updated owner of semaphore 2 to Router 0 -180 ns: Info: MY_LOG: Router 2: Received transaction with data: 37 from Router 3 after a delay of:30 ns -180 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 37 to core 2 -180 ns: Info: MY_LOG: Core 2 of parent Router: 2: Processing transaction and received data: 37 -180 ns: Info: MY_LOG: Router router2: Core 2 completed transaction, data: 37 -180 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 4 -185 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 4 -190 ns: Info: MY_LOG: Router 3: Received transaction with data: 54 from Router 0 after a delay of:30 ns -190 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 54 to core 1 -190 ns: Info: MY_LOG: Core 1 of parent Router: 3: Processing transaction and received data: 54 -190 ns: Info: MY_LOG: Router router3: Core 1 completed transaction, data: 54 -190 ns: Info: MY_LOG: Router 0: Received transaction with data: 65 from Router 1 after a delay of:30 ns -190 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 65 to core 1 -190 ns: Info: MY_LOG: Core 1 of parent Router: 0: Processing transaction and received data: 65 -190 ns: Info: MY_LOG: Router router0: Core 1 completed transaction, data: 65 -190 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 4 -190 ns: Info: MY_LOG: Router 0 released token for destination router 3 -190 ns: Info: MY_LOG: Router 1 released token for destination router 0 -190 ns: Info: MY_LOG: Token for destination router 0 passed to Router 2 -195 ns: Info: MY_LOG: Token for destination router 0 granted to Router 2 -195 ns: Info: MY_LOG: router2 forwarded data: 4 to Router_0 -200 ns: Info: MY_LOG: Core 3 of Source Router: 1: Processing data 42 for router 2 and core 3 at time: 200 ns -200 ns: Info: MY_LOG: Router router1: Received transaction with data: 42 at time: 200 ns -200 ns: Info: MY_LOG: Core core1_3: Transaction successful, data sent: 42 at time: 200 ns -200 ns: Info: MY_LOG: Updated owner of semaphore 1 to Router 2 -200 ns: Info: MY_LOG: Updated owner of semaphore 2 to Router 1 -200 ns: Info: MY_LOG: Updated owner of semaphore 3 to Router 1 -200 ns: Info: MY_LOG: Core 1 of Source Router: 0: Processing data 81 for router 1 and core 1 at time: 200 ns -200 ns: Info: MY_LOG: Router router0: Received transaction with data: 81 at time: 200 ns -200 ns: Info: MY_LOG: Core core0_1: Transaction successful, data sent: 81 at time: 200 ns -200 ns: Info: MY_LOG: Core 3 of Source Router: 2: Processing data 25 for router 0 and core 0 at time: 200 ns -200 ns: Info: MY_LOG: Router router2: Received transaction with data: 25 at time: 200 ns -200 ns: Info: MY_LOG: Core core2_3: Transaction successful, data sent: 25 at time: 200 ns -200 ns: Info: MY_LOG: Core 3 of Source Router: 0: Processing data 43 for router 3 and core 2 at time: 200 ns -200 ns: Info: MY_LOG: Router router0: Received transaction with data: 43 at time: 200 ns -200 ns: Info: MY_LOG: Core core0_3: Transaction successful, data sent: 43 at time: 200 ns -200 ns: Info: MY_LOG: Core 2 of Source Router: 3: Processing data 55 for router 0 and core 2 at time: 200 ns -200 ns: Info: MY_LOG: Router router3: Received transaction with data: 55 at time: 200 ns -200 ns: Info: MY_LOG: Core core3_2: Transaction successful, data sent: 55 at time: 200 ns -200 ns: Info: MY_LOG: Core 2 of Source Router: 2: Processing data 89 for router 1 and core 3 at time: 200 ns -200 ns: Info: MY_LOG: Router router2: Received transaction with data: 89 at time: 200 ns -200 ns: Info: MY_LOG: Core core2_2: Transaction successful, data sent: 89 at time: 200 ns -200 ns: Info: MY_LOG: Core 1 of Source Router: 2: Processing data 43 for router 0 and core 3 at time: 200 ns -200 ns: Info: MY_LOG: Router router2: Received transaction with data: 43 at time: 200 ns -200 ns: Info: MY_LOG: Core core2_1: Transaction successful, data sent: 43 at time: 200 ns -200 ns: Info: MY_LOG: Core 3 of Source Router: 3: Processing data 63 for router 0 and core 2 at time: 200 ns -200 ns: Info: MY_LOG: Router router3: Received transaction with data: 63 at time: 200 ns -200 ns: Info: MY_LOG: Core core3_3: Transaction successful, data sent: 63 at time: 200 ns -200 ns: Info: MY_LOG: Core 0 of Source Router: 3: Processing data 33 for router 0 and core 3 at time: 200 ns -200 ns: Info: MY_LOG: Router router3: Received transaction with data: 33 at time: 200 ns -200 ns: Info: MY_LOG: Core core3_0: Transaction successful, data sent: 33 at time: 200 ns -200 ns: Info: MY_LOG: Core 0 of Source Router: 2: Processing data 25 for router 0 and core 1 at time: 200 ns -200 ns: Info: MY_LOG: Router router2: Received transaction with data: 25 at time: 200 ns -200 ns: Info: MY_LOG: Core core2_0: Transaction successful, data sent: 25 at time: 200 ns -200 ns: Info: MY_LOG: Core 1 of Source Router: 3: Processing data 28 for router 2 and core 3 at time: 200 ns -200 ns: Info: MY_LOG: Router router3: Received transaction with data: 28 at time: 200 ns -200 ns: Info: MY_LOG: Core core3_1: Transaction successful, data sent: 28 at time: 200 ns -200 ns: Info: MY_LOG: Core 2 of Source Router: 1: Processing data 64 for router 2 and core 0 at time: 200 ns -200 ns: Info: MY_LOG: Router router1: Received transaction with data: 64 at time: 200 ns -200 ns: Info: MY_LOG: Core core1_2: Transaction successful, data sent: 64 at time: 200 ns -200 ns: Info: MY_LOG: Core 0 of Source Router: 0: Processing data 39 for router 2 and core 0 at time: 200 ns -200 ns: Info: MY_LOG: Router router0: Received transaction with data: 39 at time: 200 ns -200 ns: Info: MY_LOG: Core core0_0: Transaction successful, data sent: 39 at time: 200 ns -200 ns: Info: MY_LOG: Core 2 of Source Router: 0: Processing data 45 for router 2 and core 3 at time: 200 ns -200 ns: Info: MY_LOG: Router router0: Received transaction with data: 45 at time: 200 ns -200 ns: Info: MY_LOG: Core core0_2: Transaction successful, data sent: 45 at time: 200 ns -200 ns: Info: MY_LOG: Core 0 of Source Router: 1: Processing data 25 for router 0 and core 3 at time: 200 ns -200 ns: Info: MY_LOG: Router router1: Received transaction with data: 25 at time: 200 ns -200 ns: Info: MY_LOG: Core core1_0: Transaction successful, data sent: 25 at time: 200 ns -200 ns: Info: MY_LOG: Core 1 of Source Router: 1: Processing data 71 for router 2 and core 0 at time: 200 ns -200 ns: Info: MY_LOG: Router router1: Received transaction with data: 71 at time: 200 ns -200 ns: Info: MY_LOG: Core core1_1: Transaction successful, data sent: 71 at time: 200 ns -200 ns: Info: MY_LOG: Token for destination router 2 granted to Router 1 -200 ns: Info: MY_LOG: router1 forwarded data: 42 to Router_2 -200 ns: Info: MY_LOG: Token for destination router 1 granted to Router 0 -200 ns: Info: MY_LOG: router0 forwarded data: 81 to Router_1 -200 ns: Info: MY_LOG: Router 3 added to queue for semaphore 0 -200 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 55 -205 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 55 -210 ns: Info: MY_LOG: Router 1 released token for destination router 2 -210 ns: Info: MY_LOG: Router 2: Received transaction with data: 42 from Router 1 after a delay of:10 ns -210 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 42 to core 3 -210 ns: Info: MY_LOG: Core 3 of parent Router: 2: Processing transaction and received data: 42 -210 ns: Info: MY_LOG: Router router2: Core 3 completed transaction, data: 42 -210 ns: Info: MY_LOG: Router 1: Received transaction with data: 81 from Router 0 after a delay of:10 ns -210 ns: Info: MY_LOG: Router router1: Forwarding transaction with data: 81 to core 1 -210 ns: Info: MY_LOG: Core 1 of parent Router: 1: Processing transaction and received data: 81 -210 ns: Info: MY_LOG: Router router1: Core 1 completed transaction, data: 81 -210 ns: Info: MY_LOG: Token for destination router 2 granted to Router 1 -210 ns: Info: MY_LOG: router1 forwarded data: 64 to Router_2 -210 ns: Info: MY_LOG: Router 0 released token for destination router 1 -210 ns: Info: MY_LOG: Token for destination router 3 granted to Router 0 -210 ns: Info: MY_LOG: router0 forwarded data: 43 to Router_3 -210 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 55 -215 ns: Info: MY_LOG: Router 2 released token for destination router 0 -215 ns: Info: MY_LOG: Token for destination router 0 passed to Router 3 -215 ns: Info: MY_LOG: Router 0: Received transaction with data: 4 from Router 2 after a delay of:20 ns -215 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 4 to core 0 -215 ns: Info: MY_LOG: Core 0 of parent Router: 0: Processing transaction and received data: 4 -215 ns: Info: MY_LOG: Router router0: Core 0 completed transaction, data: 4 -215 ns: Info: MY_LOG: Router 2 added to queue for semaphore 3 -215 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 73 -215 ns: Info: MY_LOG: Token for destination router 0 granted to Router 3 -215 ns: Info: MY_LOG: router3 forwarded data: 55 to Router_0 -220 ns: Info: MY_LOG: Router 1 released token for destination router 2 -220 ns: Info: MY_LOG: Router 2: Received transaction with data: 64 from Router 1 after a delay of:10 ns -220 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 64 to core 0 -220 ns: Info: MY_LOG: Core 0 of parent Router: 2: Processing transaction and received data: 64 -220 ns: Info: MY_LOG: Router router2: Core 0 completed transaction, data: 64 -220 ns: Info: MY_LOG: Router 1 added to queue for semaphore 0 -220 ns: Info: MY_LOG: Router router1: Semaphore for Router_0 is unavailable. Retrying with data: 25 -220 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 73 -220 ns: Info: MY_LOG: Updated owner of semaphore 1 to Router 1 -220 ns: Info: MY_LOG: Updated owner of semaphore 2 to Router 2 -225 ns: Info: MY_LOG: Router 3 released token for destination router 0 -225 ns: Info: MY_LOG: Token for destination router 0 passed to Router 1 -225 ns: Info: MY_LOG: Router 0: Received transaction with data: 55 from Router 3 after a delay of:10 ns -225 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 55 to core 2 -225 ns: Info: MY_LOG: Core 2 of parent Router: 0: Processing transaction and received data: 55 -225 ns: Info: MY_LOG: Router router0: Core 2 completed transaction, data: 55 -225 ns: Info: MY_LOG: Router 3 added to queue for semaphore 0 -225 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 63 -225 ns: Info: MY_LOG: Token for destination router 0 granted to Router 1 -225 ns: Info: MY_LOG: router1 forwarded data: 25 to Router_0 -225 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 73 -230 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 63 -230 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 73 -235 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 63 -235 ns: Info: MY_LOG: Router router2: Semaphore for Router_3 is unavailable. Retrying with data: 73 -240 ns: Info: MY_LOG: Updated owner of semaphore 1 to Router 2 -240 ns: Info: MY_LOG: Updated owner of semaphore 2 to Router 3 -240 ns: Info: MY_LOG: Router 0 released token for destination router 3 -240 ns: Info: MY_LOG: Token for destination router 3 passed to Router 2 -240 ns: Info: MY_LOG: Router 3: Received transaction with data: 43 from Router 0 after a delay of:30 ns -240 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 43 to core 2 -240 ns: Info: MY_LOG: Core 2 of parent Router: 3: Processing transaction and received data: 43 -240 ns: Info: MY_LOG: Router router3: Core 2 completed transaction, data: 43 -240 ns: Info: MY_LOG: Token for destination router 2 granted to Router 0 -240 ns: Info: MY_LOG: router0 forwarded data: 39 to Router_2 -240 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 63 -240 ns: Info: MY_LOG: Token for destination router 3 granted to Router 2 -240 ns: Info: MY_LOG: router2 forwarded data: 73 to Router_3 -245 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 63 -250 ns: Info: MY_LOG: Router 2 released token for destination router 3 -250 ns: Info: MY_LOG: Router 3: Received transaction with data: 73 from Router 2 after a delay of:10 ns -250 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 73 to core 2 -250 ns: Info: MY_LOG: Core 2 of parent Router: 3: Processing transaction and received data: 73 -250 ns: Info: MY_LOG: Router router3: Core 2 completed transaction, data: 73 -250 ns: Info: MY_LOG: Router 2 added to queue for semaphore 0 -250 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 25 -250 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 63 -255 ns: Info: MY_LOG: Router 1 released token for destination router 0 -255 ns: Info: MY_LOG: Token for destination router 0 passed to Router 3 -255 ns: Info: MY_LOG: Router 0: Received transaction with data: 25 from Router 1 after a delay of:30 ns -255 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 25 to core 3 -255 ns: Info: MY_LOG: Core 3 of parent Router: 0: Processing transaction and received data: 25 -255 ns: Info: MY_LOG: Router router0: Core 3 completed transaction, data: 25 -255 ns: Info: MY_LOG: Router 1 added to queue for semaphore 2 -255 ns: Info: MY_LOG: Router router1: Semaphore for Router_2 is unavailable. Retrying with data: 71 -255 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 25 -255 ns: Info: MY_LOG: Token for destination router 0 granted to Router 3 -255 ns: Info: MY_LOG: router3 forwarded data: 63 to Router_0 -260 ns: Info: MY_LOG: Updated owner of semaphore 1 to Router 3 -260 ns: Info: MY_LOG: Updated owner of semaphore 3 to Router 3 -260 ns: Info: MY_LOG: Router 0 released token for destination router 2 -260 ns: Info: MY_LOG: Token for destination router 2 passed to Router 1 -260 ns: Info: MY_LOG: Router 2: Received transaction with data: 39 from Router 0 after a delay of:20 ns -260 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 39 to core 0 -260 ns: Info: MY_LOG: Core 0 of parent Router: 2: Processing transaction and received data: 39 -260 ns: Info: MY_LOG: Router router2: Core 0 completed transaction, data: 39 -260 ns: Info: MY_LOG: Router 0 added to queue for semaphore 2 -260 ns: Info: MY_LOG: Router router0: Semaphore for Router_2 is unavailable. Retrying with data: 45 -260 ns: Info: MY_LOG: Token for destination router 2 granted to Router 1 -260 ns: Info: MY_LOG: router1 forwarded data: 71 to Router_2 -260 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 25 -265 ns: Info: MY_LOG: Router 3 released token for destination router 0 -265 ns: Info: MY_LOG: Token for destination router 0 passed to Router 2 -265 ns: Info: MY_LOG: Router 0: Received transaction with data: 63 from Router 3 after a delay of:10 ns -265 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 63 to core 2 -265 ns: Info: MY_LOG: Core 2 of parent Router: 0: Processing transaction and received data: 63 -265 ns: Info: MY_LOG: Router router0: Core 2 completed transaction, data: 63 -265 ns: Info: MY_LOG: Router 3 added to queue for semaphore 0 -265 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 33 -265 ns: Info: MY_LOG: Router router0: Semaphore for Router_2 is unavailable. Retrying with data: 45 -265 ns: Info: MY_LOG: Token for destination router 0 granted to Router 2 -265 ns: Info: MY_LOG: router2 forwarded data: 25 to Router_0 -270 ns: Info: MY_LOG: Router 1 released token for destination router 2 -270 ns: Info: MY_LOG: Token for destination router 2 passed to Router 0 -270 ns: Info: MY_LOG: Router 2: Received transaction with data: 71 from Router 1 after a delay of:10 ns -270 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 71 to core 0 -270 ns: Info: MY_LOG: Core 0 of parent Router: 2: Processing transaction and received data: 71 -270 ns: Info: MY_LOG: Router router2: Core 0 completed transaction, data: 71 -270 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 33 -270 ns: Info: MY_LOG: Token for destination router 2 granted to Router 0 -270 ns: Info: MY_LOG: router0 forwarded data: 45 to Router_2 -275 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 33 -280 ns: Info: MY_LOG: Updated owner of semaphore 1 to Router 0 -280 ns: Info: MY_LOG: Updated owner of semaphore 3 to Router 0 -280 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 33 -285 ns: Info: MY_LOG: Router 2 released token for destination router 0 -285 ns: Info: MY_LOG: Token for destination router 0 passed to Router 3 -285 ns: Info: MY_LOG: Router 0: Received transaction with data: 25 from Router 2 after a delay of:20 ns -285 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 25 to core 0 -285 ns: Info: MY_LOG: Core 0 of parent Router: 0: Processing transaction and received data: 25 -285 ns: Info: MY_LOG: Router router0: Core 0 completed transaction, data: 25 -285 ns: Info: MY_LOG: Token for destination router 1 granted to Router 2 -285 ns: Info: MY_LOG: router2 forwarded data: 89 to Router_1 -285 ns: Info: MY_LOG: Token for destination router 0 granted to Router 3 -285 ns: Info: MY_LOG: router3 forwarded data: 33 to Router_0 -290 ns: Info: MY_LOG: Router 0 released token for destination router 2 -290 ns: Info: MY_LOG: Router 2: Received transaction with data: 45 from Router 0 after a delay of:20 ns -290 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 45 to core 3 -290 ns: Info: MY_LOG: Core 3 of parent Router: 2: Processing transaction and received data: 45 -290 ns: Info: MY_LOG: Router router2: Core 3 completed transaction, data: 45 -295 ns: Info: MY_LOG: Router 3 released token for destination router 0 -295 ns: Info: MY_LOG: Router 0: Received transaction with data: 33 from Router 3 after a delay of:10 ns -295 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 33 to core 3 -295 ns: Info: MY_LOG: Core 3 of parent Router: 0: Processing transaction and received data: 33 -295 ns: Info: MY_LOG: Router router0: Core 3 completed transaction, data: 33 -295 ns: Info: MY_LOG: Token for destination router 2 granted to Router 3 -295 ns: Info: MY_LOG: router3 forwarded data: 28 to Router_2 -300 ns: Info: MY_LOG: Core 3 of Source Router: 3: Processing data 68 for router 0 and core 1 at time: 300 ns -300 ns: Info: MY_LOG: Router router3: Received transaction with data: 68 at time: 300 ns -300 ns: Info: MY_LOG: Core core3_3: Transaction successful, data sent: 68 at time: 300 ns -300 ns: Info: MY_LOG: Updated owner of semaphore 0 to Router 0 -300 ns: Info: MY_LOG: Updated owner of semaphore 3 to Router 1 -300 ns: Info: MY_LOG: Core 3 of Source Router: 0: Processing data 95 for router 3 and core 0 at time: 300 ns -300 ns: Info: MY_LOG: Router router0: Received transaction with data: 95 at time: 300 ns -300 ns: Info: MY_LOG: Core core0_3: Transaction successful, data sent: 95 at time: 300 ns -300 ns: Info: MY_LOG: Core 2 of Source Router: 3: Processing data 85 for router 2 and core 0 at time: 300 ns -300 ns: Info: MY_LOG: Router router3: Received transaction with data: 85 at time: 300 ns -300 ns: Info: MY_LOG: Core core3_2: Transaction successful, data sent: 85 at time: 300 ns -300 ns: Info: MY_LOG: Core 3 of Source Router: 2: Processing data 9 for router 3 and core 3 at time: 300 ns -300 ns: Info: MY_LOG: Router router2: Received transaction with data: 9 at time: 300 ns -300 ns: Info: MY_LOG: Core core2_3: Transaction successful, data sent: 9 at time: 300 ns -300 ns: Info: MY_LOG: Core 1 of Source Router: 1: Processing data 7 for router 2 and core 1 at time: 300 ns -300 ns: Info: MY_LOG: Router router1: Received transaction with data: 7 at time: 300 ns -300 ns: Info: MY_LOG: Core core1_1: Transaction successful, data sent: 7 at time: 300 ns -300 ns: Info: MY_LOG: Core 1 of Source Router: 2: Processing data 20 for router 0 and core 3 at time: 300 ns -300 ns: Info: MY_LOG: Router router2: Received transaction with data: 20 at time: 300 ns -300 ns: Info: MY_LOG: Core core2_1: Transaction successful, data sent: 20 at time: 300 ns -300 ns: Info: MY_LOG: Core 0 of Source Router: 3: Processing data 7 for router 1 and core 2 at time: 300 ns -300 ns: Info: MY_LOG: Router router3: Received transaction with data: 7 at time: 300 ns -300 ns: Info: MY_LOG: Core core3_0: Transaction successful, data sent: 7 at time: 300 ns -300 ns: Info: MY_LOG: Core 0 of Source Router: 1: Processing data 50 for router 2 and core 1 at time: 300 ns -300 ns: Info: MY_LOG: Router router1: Received transaction with data: 50 at time: 300 ns -300 ns: Info: MY_LOG: Core core1_0: Transaction successful, data sent: 50 at time: 300 ns -300 ns: Info: MY_LOG: Core 1 of Source Router: 3: Processing data 87 for router 0 and core 2 at time: 300 ns -300 ns: Info: MY_LOG: Router router3: Received transaction with data: 87 at time: 300 ns -300 ns: Info: MY_LOG: Core core3_1: Transaction successful, data sent: 87 at time: 300 ns -300 ns: Info: MY_LOG: Core 2 of Source Router: 1: Processing data 20 for router 0 and core 2 at time: 300 ns -300 ns: Info: MY_LOG: Router router1: Received transaction with data: 20 at time: 300 ns -300 ns: Info: MY_LOG: Core core1_2: Transaction successful, data sent: 20 at time: 300 ns -300 ns: Info: MY_LOG: Core 3 of Source Router: 1: Processing data 40 for router 3 and core 2 at time: 300 ns -300 ns: Info: MY_LOG: Router router1: Received transaction with data: 40 at time: 300 ns -300 ns: Info: MY_LOG: Core core1_3: Transaction successful, data sent: 40 at time: 300 ns -300 ns: Info: MY_LOG: Core 0 of Source Router: 0: Processing data 13 for router 3 and core 0 at time: 300 ns -300 ns: Info: MY_LOG: Router router0: Received transaction with data: 13 at time: 300 ns -300 ns: Info: MY_LOG: Core core0_0: Transaction successful, data sent: 13 at time: 300 ns -300 ns: Info: MY_LOG: Core 2 of Source Router: 0: Processing data 31 for router 1 and core 0 at time: 300 ns -300 ns: Info: MY_LOG: Router router0: Received transaction with data: 31 at time: 300 ns -300 ns: Info: MY_LOG: Core core0_2: Transaction successful, data sent: 31 at time: 300 ns -300 ns: Info: MY_LOG: Core 0 of Source Router: 2: Processing data 81 for router 1 and core 1 at time: 300 ns -300 ns: Info: MY_LOG: Router router2: Received transaction with data: 81 at time: 300 ns -300 ns: Info: MY_LOG: Core core2_0: Transaction successful, data sent: 81 at time: 300 ns -300 ns: Info: MY_LOG: Core 2 of Source Router: 2: Processing data 0 for router 1 and core 3 at time: 300 ns -300 ns: Info: MY_LOG: Router router2: Received transaction with data: 0 at time: 300 ns -300 ns: Info: MY_LOG: Core core2_2: Transaction successful, data sent: 0 at time: 300 ns -300 ns: Info: MY_LOG: Core 1 of Source Router: 0: Processing data 92 for router 2 and core 1 at time: 300 ns -300 ns: Info: MY_LOG: Router router0: Received transaction with data: 92 at time: 300 ns -300 ns: Info: MY_LOG: Core core0_1: Transaction successful, data sent: 92 at time: 300 ns -300 ns: Info: MY_LOG: Token for destination router 3 granted to Router 0 -300 ns: Info: MY_LOG: router0 forwarded data: 95 to Router_3 -300 ns: Info: MY_LOG: Router 1 added to queue for semaphore 2 -300 ns: Info: MY_LOG: Router router1: Semaphore for Router_2 is unavailable. Retrying with data: 7 -305 ns: Info: MY_LOG: Router router1: Semaphore for Router_2 is unavailable. Retrying with data: 7 -310 ns: Info: MY_LOG: Router router1: Semaphore for Router_2 is unavailable. Retrying with data: 7 -315 ns: Info: MY_LOG: Router 2 released token for destination router 1 -315 ns: Info: MY_LOG: Router 1: Received transaction with data: 89 from Router 2 after a delay of:30 ns -315 ns: Info: MY_LOG: Router router1: Forwarding transaction with data: 89 to core 3 -315 ns: Info: MY_LOG: Core 3 of parent Router: 1: Processing transaction and received data: 89 -315 ns: Info: MY_LOG: Router router1: Core 3 completed transaction, data: 89 -315 ns: Info: MY_LOG: Token for destination router 0 granted to Router 2 -315 ns: Info: MY_LOG: router2 forwarded data: 43 to Router_0 -315 ns: Info: MY_LOG: Router router1: Semaphore for Router_2 is unavailable. Retrying with data: 7 -320 ns: Info: MY_LOG: Updated owner of semaphore 1 to Router 3 -320 ns: Info: MY_LOG: Router router1: Semaphore for Router_2 is unavailable. Retrying with data: 7 -325 ns: Info: MY_LOG: Router 3 released token for destination router 2 -325 ns: Info: MY_LOG: Token for destination router 2 passed to Router 1 -325 ns: Info: MY_LOG: Router 2: Received transaction with data: 28 from Router 3 after a delay of:30 ns -325 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 28 to core 3 -325 ns: Info: MY_LOG: Core 3 of parent Router: 2: Processing transaction and received data: 28 -325 ns: Info: MY_LOG: Router router2: Core 3 completed transaction, data: 28 -325 ns: Info: MY_LOG: Router 3 added to queue for semaphore 0 -325 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 68 -325 ns: Info: MY_LOG: Token for destination router 2 granted to Router 1 -325 ns: Info: MY_LOG: router1 forwarded data: 7 to Router_2 -330 ns: Info: MY_LOG: Router 0 released token for destination router 3 -330 ns: Info: MY_LOG: Router 3: Received transaction with data: 95 from Router 0 after a delay of:30 ns -330 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 95 to core 0 -330 ns: Info: MY_LOG: Core 0 of parent Router: 3: Processing transaction and received data: 95 -330 ns: Info: MY_LOG: Router router3: Core 0 completed transaction, data: 95 -330 ns: Info: MY_LOG: Token for destination router 3 granted to Router 0 -330 ns: Info: MY_LOG: router0 forwarded data: 13 to Router_3 -330 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 68 -335 ns: Info: MY_LOG: Router 2 released token for destination router 0 -335 ns: Info: MY_LOG: Token for destination router 0 passed to Router 3 -335 ns: Info: MY_LOG: Router 0: Received transaction with data: 43 from Router 2 after a delay of:20 ns -335 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 43 to core 3 -335 ns: Info: MY_LOG: Core 3 of parent Router: 0: Processing transaction and received data: 43 -335 ns: Info: MY_LOG: Router router0: Core 3 completed transaction, data: 43 -335 ns: Info: MY_LOG: Router 2: Received transaction with data: 7 from Router 1 after a delay of:10 ns -335 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 7 to core 1 -335 ns: Info: MY_LOG: Core 1 of parent Router: 2: Processing transaction and received data: 7 -335 ns: Info: MY_LOG: Router router2: Core 1 completed transaction, data: 7 -335 ns: Info: MY_LOG: Router 2 added to queue for semaphore 0 -335 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 25 -335 ns: Info: MY_LOG: Router 1 released token for destination router 2 -335 ns: Info: MY_LOG: Token for destination router 2 granted to Router 1 -335 ns: Info: MY_LOG: router1 forwarded data: 50 to Router_2 -335 ns: Info: MY_LOG: Token for destination router 0 granted to Router 3 -335 ns: Info: MY_LOG: router3 forwarded data: 68 to Router_0 -340 ns: Info: MY_LOG: Updated owner of semaphore 1 to Router 0 -340 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 25 -345 ns: Info: MY_LOG: Router 1 released token for destination router 2 -345 ns: Info: MY_LOG: Router 2: Received transaction with data: 50 from Router 1 after a delay of:10 ns -345 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 50 to core 1 -345 ns: Info: MY_LOG: Core 1 of parent Router: 2: Processing transaction and received data: 50 -345 ns: Info: MY_LOG: Router router2: Core 1 completed transaction, data: 50 -345 ns: Info: MY_LOG: Router 0: Received transaction with data: 68 from Router 3 after a delay of:10 ns -345 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 68 to core 1 -345 ns: Info: MY_LOG: Core 1 of parent Router: 0: Processing transaction and received data: 68 -345 ns: Info: MY_LOG: Router router0: Core 1 completed transaction, data: 68 -345 ns: Info: MY_LOG: Router 1 added to queue for semaphore 0 -345 ns: Info: MY_LOG: Router router1: Semaphore for Router_0 is unavailable. Retrying with data: 20 -345 ns: Info: MY_LOG: Router 3 released token for destination router 0 -345 ns: Info: MY_LOG: Token for destination router 0 passed to Router 2 -345 ns: Info: MY_LOG: Token for destination router 2 granted to Router 3 -345 ns: Info: MY_LOG: router3 forwarded data: 85 to Router_2 -345 ns: Info: MY_LOG: Token for destination router 0 granted to Router 2 -345 ns: Info: MY_LOG: router2 forwarded data: 25 to Router_0 -350 ns: Info: MY_LOG: Router router1: Semaphore for Router_0 is unavailable. Retrying with data: 20 -355 ns: Info: MY_LOG: Router router1: Semaphore for Router_0 is unavailable. Retrying with data: 20 -360 ns: Info: MY_LOG: Router 0 released token for destination router 3 -360 ns: Info: MY_LOG: Router 3: Received transaction with data: 13 from Router 0 after a delay of:30 ns -360 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 13 to core 0 -360 ns: Info: MY_LOG: Core 0 of parent Router: 3: Processing transaction and received data: 13 -360 ns: Info: MY_LOG: Router router3: Core 0 completed transaction, data: 13 -360 ns: Info: MY_LOG: Token for destination router 1 granted to Router 0 -360 ns: Info: MY_LOG: router0 forwarded data: 31 to Router_1 -360 ns: Info: MY_LOG: Updated owner of semaphore 3 to Router 1 -360 ns: Info: MY_LOG: Router router1: Semaphore for Router_0 is unavailable. Retrying with data: 20 -365 ns: Info: MY_LOG: Router 2 released token for destination router 0 -365 ns: Info: MY_LOG: Token for destination router 0 passed to Router 1 -365 ns: Info: MY_LOG: Router 0: Received transaction with data: 25 from Router 2 after a delay of:20 ns -365 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 25 to core 1 -365 ns: Info: MY_LOG: Core 1 of parent Router: 0: Processing transaction and received data: 25 -365 ns: Info: MY_LOG: Router router0: Core 1 completed transaction, data: 25 -365 ns: Info: MY_LOG: Token for destination router 3 granted to Router 2 -365 ns: Info: MY_LOG: router2 forwarded data: 9 to Router_3 -365 ns: Info: MY_LOG: Token for destination router 0 granted to Router 1 -365 ns: Info: MY_LOG: router1 forwarded data: 20 to Router_0 -370 ns: Info: MY_LOG: Router 0 released token for destination router 1 -370 ns: Info: MY_LOG: Router 1: Received transaction with data: 31 from Router 0 after a delay of:10 ns -370 ns: Info: MY_LOG: Router router1: Forwarding transaction with data: 31 to core 0 -370 ns: Info: MY_LOG: Core 0 of parent Router: 1: Processing transaction and received data: 31 -370 ns: Info: MY_LOG: Router router1: Core 0 completed transaction, data: 31 -370 ns: Info: MY_LOG: Router 0 added to queue for semaphore 2 -370 ns: Info: MY_LOG: Router router0: Semaphore for Router_2 is unavailable. Retrying with data: 92 -375 ns: Info: MY_LOG: Router 3 released token for destination router 2 -375 ns: Info: MY_LOG: Token for destination router 2 passed to Router 0 -375 ns: Info: MY_LOG: Router 2: Received transaction with data: 85 from Router 3 after a delay of:30 ns -375 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 85 to core 0 -375 ns: Info: MY_LOG: Core 0 of parent Router: 2: Processing transaction and received data: 85 -375 ns: Info: MY_LOG: Router router2: Core 0 completed transaction, data: 85 -375 ns: Info: MY_LOG: Router 3: Received transaction with data: 9 from Router 2 after a delay of:10 ns -375 ns: Info: MY_LOG: Router router3: Forwarding transaction with data: 9 to core 3 -375 ns: Info: MY_LOG: Core 3 of parent Router: 3: Processing transaction and received data: 9 -375 ns: Info: MY_LOG: Router router3: Core 3 completed transaction, data: 9 -375 ns: Info: MY_LOG: Token for destination router 1 granted to Router 3 -375 ns: Info: MY_LOG: router3 forwarded data: 7 to Router_1 -375 ns: Info: MY_LOG: Router 2 released token for destination router 3 -375 ns: Info: MY_LOG: Router 2 added to queue for semaphore 0 -375 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 20 -375 ns: Info: MY_LOG: Token for destination router 2 granted to Router 0 -375 ns: Info: MY_LOG: router0 forwarded data: 92 to Router_2 -380 ns: Info: MY_LOG: Updated owner of semaphore 3 to Router 3 -380 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 20 -385 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 20 -390 ns: Info: MY_LOG: Router router2: Semaphore for Router_0 is unavailable. Retrying with data: 20 -395 ns: Info: MY_LOG: Router 3 released token for destination router 1 -395 ns: Info: MY_LOG: Router 1: Received transaction with data: 7 from Router 3 after a delay of:20 ns -395 ns: Info: MY_LOG: Router router1: Forwarding transaction with data: 7 to core 2 -395 ns: Info: MY_LOG: Core 2 of parent Router: 1: Processing transaction and received data: 7 -395 ns: Info: MY_LOG: Router router1: Core 2 completed transaction, data: 7 -395 ns: Info: MY_LOG: Router 0: Received transaction with data: 20 from Router 1 after a delay of:30 ns -395 ns: Info: MY_LOG: Router router0: Forwarding transaction with data: 20 to core 2 -395 ns: Info: MY_LOG: Core 2 of parent Router: 0: Processing transaction and received data: 20 -395 ns: Info: MY_LOG: Router router0: Core 2 completed transaction, data: 20 -395 ns: Info: MY_LOG: Router 2: Received transaction with data: 92 from Router 0 after a delay of:20 ns -395 ns: Info: MY_LOG: Router router2: Forwarding transaction with data: 92 to core 1 -395 ns: Info: MY_LOG: Core 1 of parent Router: 2: Processing transaction and received data: 92 -395 ns: Info: MY_LOG: Router router2: Core 1 completed transaction, data: 92 -395 ns: Info: MY_LOG: Router 3 added to queue for semaphore 0 -395 ns: Info: MY_LOG: Router router3: Semaphore for Router_0 is unavailable. Retrying with data: 87 -395 ns: Info: MY_LOG: Router 1 released token for destination router 0 -395 ns: Info: MY_LOG: Token for destination router 0 passed to Router 2 -395 ns: Info: MY_LOG: Token for destination router 3 granted to Router 1 -395 ns: Info: MY_LOG: router1 forwarded data: 40 to Router_3 -395 ns: Info: MY_LOG: Router 0 released token for destination router 2 -395 ns: Info: MY_LOG: Token for destination router 0 granted to Router 2 -395 ns: Info: MY_LOG: router2 forwarded data: 20 to Router_0 +59 ns: INFO: MY_LOG: Flits generated for packet of id 0 to be sent to 0.000000,0.667000,0.000000 from 0.000000,0.000000,0.000000 +59 ns: INFO: MY_LOG: Network Interface 0 of Source Router: 0: Processing packet flit with ID: 1 for router 3 and Network Interface 12 at time: 59 ns +59 ns: INFO: MY_LOG: Router Layer.NocTlm.router0: Received transaction with data at time: 59 ns +59 ns: INFO: MY_LOG: Network Interface core0_0: Transaction successful, flit sent ID: 1 at time: 59 ns +59 ns: INFO: MY_LOG: router id: 0, dest Router id: 3 +59 ns: INFO: MY_LOG: Token for destination router 3 granted to Router 0 +59 ns: INFO: MY_LOG: Router: 0 forwarded data with ID: 1 to Router_3 +89 ns: INFO: MY_LOG: Router 0 released token for destination router 3 +89 ns: INFO: MY_LOG: Router 3: Received transaction with data: 1 from Router 0 after a delay of:30 ns +89 ns: INFO: MY_LOG: Router 3: Forwarding transaction with data: 1 to Processing Element 12 +89 ns: INFO: MY_LOG: Network Interface 12 of parent Router: 3: Processing transaction and received flit ID: 1 +89 ns: INFO: MY_LOG: Router 3: Network Interface 12 completed transaction, data ID: 1 diff --git a/report.txt b/report.txt new file mode 100644 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/core.cpp b/src/core.cpp deleted file mode 100644 index e19ff2f..0000000 --- a/src/core.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include "core.h" - -// Initiator module (processor core) -core::core(sc_module_name name) { - sc_report_handler::set_log_file_name("out/report.log"); - sc_report_handler::set_actions(LOG_NAME, SC_INFO, SC_LOG|SC_DISPLAY); - SC_THREAD(thread); - target_socket.register_nb_transport_fw(this, &core::nb_transport_fw); -} - -// Thread for sending data -void core::thread() { - - // Initialize random seed (only once per run, for all cores) - static bool seeded = false; - if (!seeded) { - srand(time(0)); // Seed the random number generator - seeded = true; - } - - // Infinite loop for sending data - while (true) { - my_payload* trans = nullptr; - // Core ID and source router ID from main logic - unsigned int source_core = source_core_id; - unsigned int src_router_id = source_router_id; // Source router from the main logic - - sc_time delay = SC_ZERO_TIME; // Start with zero delay - sc_time inter_transaction_delay = sc_time(90, SC_NS); // Delay between transactions - // Loop to retry the same transaction - bool retry = false; - do { - if (!retry) { - // Generate random data between 0 and 100 - int data = rand() % 101; - - // Random destination router (ensuring it's different from source router) - unsigned int destination_router_id; - do { - destination_router_id = rand() % ROUTER_NO; // Random router ID between 0 and ROUTER_NO-1 - } while (destination_router_id == src_router_id); // Ensure it's not the same as source router - - // Destination core ID (random between 0 and CORE_NO-1) - unsigned int dst_core_id = rand() % CORE_NO; - - // Create payload with generated values - trans = new my_payload(source_core, src_router_id, dst_core_id, destination_router_id, data); - trans->update_timestamp(sc_time_stamp()); // Set the current simulation time - - // Construct the address (calculation based on router/core IDs) - unsigned int offset = 0x20; // offset - unsigned int address = (destination_router_id << 12) | (dst_core_id << 8) | offset; - trans->set_address(address); - - // Print which core is currently sending the data - log_info( "Core " + std::to_string(source_core) + " of Source Router: " + std::to_string(source_router_id) - + ": Processing data " + std::to_string(trans->data) + " for router " + std::to_string(destination_router_id) - + " and core " + std::to_string(dst_core_id) + " at time: " + trans->timestamp.to_string()); - } - - // Set up the rest of the transaction - trans->set_byte_enable_ptr(nullptr); - trans->set_dmi_allowed(false); - trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); - - - tlm::tlm_phase phase = tlm::BEGIN_REQ; // Transaction phase - tlm::tlm_sync_enum status = socket->nb_transport_fw(*trans, phase, delay); // Non-blocking transport - - if (status == tlm::TLM_COMPLETED || phase == tlm::END_REQ) { - log_info("Core " + std::string(name()) + ": Transaction successful, data sent: " + std::to_string(trans->data) + " at time: " + sc_time_stamp().to_string()); - delete trans; // Clean up the transaction - retry = false; // Move on to the next transaction - wait(inter_transaction_delay); - } else if (status == tlm::TLM_ACCEPTED) { - log_info("Core " + std::string(name()) + ": Transaction accepted, waiting for completion."); - wait(delay); // Wait for response - retry = false; // No need to retry, accepted transaction will continue - } else if (status == tlm::TLM_UPDATED && phase == tlm::BEGIN_REQ) { - log_info("Core " + std::string(name()) + ": FIFO full, retrying..."); - //wait(delay); // Wait for some time before retrying - // --i; // Retry the same transaction - wait(delay + sc_time(20, SC_NS)); // Add some delay before retrying - // wait(router->core_fifo_event); - retry = true; // Retry the same transaction - } - - } while (retry); - - - wait(delay); - } -} - -/// Forwarding function for receiving data from router -tlm::tlm_sync_enum core::nb_transport_fw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay) { - if (phase == tlm::BEGIN_REQ) { - my_payload* my_trans = dynamic_cast(&trans); - - // Print which core is processing the received data - log_info("Core " + std::to_string(source_core_id) + " of parent Router: " + std::to_string(source_router_id) - + ": Processing transaction " + "and received data: " + std::to_string(my_trans->data)); - - // log_info("Core " + std::string(name()) + ": Received transaction, data: " + std::to_string(my_trans->data)); - - - // Send acknowledgment or status back - trans.set_response_status(tlm::TLM_OK_RESPONSE); - - // Log the received data and remove the payload - delete my_trans; - return tlm::TLM_COMPLETED; - } - return tlm::TLM_ACCEPTED; -} - - - -void core::log_info(std::string msg){ - SC_REPORT_INFO(LOG_NAME, msg.c_str()); -} - -void core::log_error(std::string msg){ - SC_REPORT_ERROR(LOG_NAME, msg.c_str()); -} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..42692f6 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (C) 2024 + * + * 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" +// #include +// using namespace boost::placeholders; + +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 100644 index 0000000..df574cc --- /dev/null +++ b/src/networkInterface/NetworkInterfaceTlm.cpp @@ -0,0 +1,306 @@ +/******************************************************************************* + * Copyright (C) 2024 + * + * 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) : + NetworkInterface(nm, node), lastReceivedCreditID(-1), credit_counter(0), ni_name(nm), resp_in_progress(false) + { + target_socket.register_nb_transport_fw(this, &NetworkInterfaceTlm::nb_transport_fw); ////from core + //sc_report_handler::set_actions(NI_LOG, SC_INFO, SC_LOG|SC_DISPLAY); + sc_report_handler::set_log_file_name("out/report.log"); //from core + sc_report_handler::set_actions(LOG_NAME, SC_INFO, SC_LOG|SC_DISPLAY); //from core + + try { + this->id = source_core_id; + this->dbid = rep.registerElement("ProcessingElement", this->id); + this->node = node; + this->packetPortContainer = new PacketPortContainer( + ("NI_PACKET_CONTAINER"+std::to_string(this->id)).c_str()); + //copy(max_pos, max_pos + 3, this->max_pos); + } + catch (exception& e) { + log_error("Initialization Error: " + string(e.what())); + } + SC_THREAD(thread); + sensitive << clk.pos() << clk.neg(); + + SC_METHOD(receivePacketFromPE); + sensitive << packetPortContainer->portValidIn.pos(); + +} + +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(globalReport.verbose_pe_function_calls, "NI" << this->id << "(Node" << node.id << ")\t\t- receive()"); + Packet* packet = packetPortContainer->portDataIn.read(); + generateFlitsForPacket(packet); + packet_send_queue.push(packet); + } +} + +void NetworkInterfaceTlm::getDestination(Packet* p, std::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); + + std::string start_end_pos[2]; + getDestination(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_packet_to_router() { + // 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(); + } + + my_payload* trans = nullptr; + + unsigned int src_core_id = p->src.id; + unsigned int src_router_id = src_core_id/CORE_NO; + unsigned int dst_core_id = p->dst.id; + unsigned int destination_router_id = dst_core_id/CORE_NO; + sc_time delay = sc_time(0, SC_NS); + + trans = new my_payload(src_core_id, src_router_id, dst_core_id, destination_router_id, current_flit, sc_time_stamp()); + // Construct the address (calculation based on router/core IDs) + unsigned int offset = 0x20; // offset + unsigned int address = (destination_router_id << 12) | (dst_core_id << 8) | offset; + trans->set_address(address); + log_info( "Network Interface " + std::to_string(src_core_id) + " of Source Router: " + std::to_string(source_router_id) + + ": Processing packet flit with ID: " + std::to_string(trans->data->id) + " for router " + std::to_string(destination_router_id) + + " and Network Interface " + std::to_string(dst_core_id) + " at time: " + trans->timestamp.to_string()); + + + // Set up the rest of the transaction + trans->set_data_length(p->size); + trans->set_streaming_width(4); + trans->set_byte_enable_ptr(nullptr); + trans->set_dmi_allowed(false); + trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + tlm::tlm_phase phase = tlm::BEGIN_REQ; // Transaction phase + tlm::tlm_sync_enum status = socket->nb_transport_fw(*trans, phase, delay); // Non-blocking transport + + + bool retry = false; + do { + if (!retry) { + tlm::tlm_sync_enum status = socket->nb_transport_fw(*trans, phase, delay); // Non-blocking transport + + if (status == tlm::TLM_COMPLETED || phase == tlm::END_REQ) { + log_info("Network Interface " + ni_name + ": Transaction successful, flit sent ID: " + std::to_string(trans->data->id) + " at time: " + sc_time_stamp().to_string()); + delete trans; // Clean up the transaction + retry = false; // Move on to the next transaction + //wait(50, SC_NS); + } else if (status == tlm::TLM_ACCEPTED) { + log_info("Network Interface " + ni_name + ": Transaction accepted, waiting for completion."); + wait(0, SC_NS); // Wait for response + retry = false; // No need to retry, accepted transaction will continue + } else if (status == tlm::TLM_UPDATED && phase == tlm::BEGIN_REQ) { + log_info("Network Interface " + ni_name + ": FIFO full, retrying..."); + wait(delay + sc_time(20, SC_NS)); // Add some delay before retrying + retry = true; // Retry the same transaction + } + } + + + + }while(retry); + + wait(0,SC_NS); +} + + +void NetworkInterfaceTlm::thread() { + while(true){ + //log_info("send_data_process()"); + if (clk.posedge()) { + if (!packet_send_queue.empty()) { + //if (credit_counter != 0){ + send_packet_to_router(); + //} + //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 + std::string start_end_pos[2]; + getDestination(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_fw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay) { + if (phase == tlm::BEGIN_REQ) { + my_payload* my_trans = dynamic_cast(&trans); + + // Print which core is processing the received data + log_info("Network Interface " + std::to_string(source_core_id) + " of parent Router: " + std::to_string(source_router_id) + + ": Processing transaction " + "and received flit ID: " + std::to_string(my_trans->data->id)); + + // Send acknowledgment or status back + trans.set_response_status(tlm::TLM_OK_RESPONSE); + + // Log the received data and remove the payload + delete my_trans; + return tlm::TLM_COMPLETED; + } + return tlm::TLM_ACCEPTED; + } + + +void NetworkInterfaceTlm::receive_and_process_flit(tlm::tlm_generic_payload& 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; + std::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::log_info(std::string msg){ + // string log_msg = ni_name + ": (Node" + + // to_string(node.id)+"): "+ msg; + SC_REPORT_INFO(LOG_NAME, (msg).c_str()); +} + +void NetworkInterfaceTlm::log_error(std::string msg){ + // string log_msg = ni_name + ": (Node" + + // to_string(node.id)+"): "+ msg; + SC_REPORT_ERROR(LOG_NAME, (msg).c_str()); +} + +void NetworkInterfaceTlm::log_fatal(std::string msg){ + // string log_msg = ni_name + ": (Node" + + // to_string(node.id)+"): "+ msg; + SC_REPORT_FATAL(LOG_NAME, (msg).c_str()); +} \ No newline at end of file diff --git a/src/networkInterface/NetworkInterfaceTlm.h b/src/networkInterface/NetworkInterfaceTlm.h new file mode 100644 index 0000000..2a1afc3 --- /dev/null +++ b/src/networkInterface/NetworkInterfaceTlm.h @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (C) 2024 + * + * 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. + ******************************************************************************/ +/** NetworkInterfaceTlm, which is a specialized version of NetworkInterface + +NetworkInterfaceTlm handles the communication between the router and processing element (PE) in the NoC system. +It manages the sending and receiving of data packets and the flow control between these components. */ + +#pragma once +#ifndef SC_INCLUDE_DYNAMIC_PROCESSES +#define SC_INCLUDE_DYNAMIC_PROCESSES +#endif + +#include "systemc.h" +#include "tlm.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include // For time() + +#include "ratatoskrUtils/utils/Structures.h" +#include "ratatoskrUtils/container/PacketContainer.h" +#include "ratatoskrUtils/utils/TrafficTracer.h" +#include "ratatoskrUtils/utils/GlobalResources.h" /// +#include "ratatoskrUtils/networkInterface/NetworkInterface.h" +#include "utils/configuration.h" + +//#include "noc/noc.h" +#include "utils/noc_logger.h" + +class NetworkInterfaceTlm : public NetworkInterface { +public: + + tlm_utils::simple_initiator_socket socket; //from core + tlm_utils::simple_target_socket target_socket; //from core + unsigned int source_router_id; //from core + unsigned int source_core_id; //from core + + //typedef simple_initiator_socket_tagged ni_init_socket; + //typedef simple_target_socket_tagged ni_targ_socket; + + std::queue packet_send_queue; //This is a queue where the network interface stores packets that need to be sent. + std::queue packet_recv_queue; //This is a queue for storing received packets, waiting to be processed. + + + std::string ni_name; + sc_in clk; + int credit_counter; + bool resp_in_progress; + + + PacketPortContainer* packetPortContainer; //This manages packet-level communication with the processing element (PE). + int creditCounter; //This keeps track of the available credits (flow control units) that manage how much data the network interface can send to the router. + int lastReceivedCreditID; //This records the last received credit ID from the router to ensure proper flow control and avoid overloading the network. + TrafficTracer& trafficTracer = TrafficTracer::getInstance(); //A reference to a global traffic tracing system. This helps log and analyze the flow of data (packets and flits) through the network interface for performance monitoring. + + SC_HAS_PROCESS(NetworkInterfaceTlm); + + NetworkInterfaceTlm(sc_module_name nm, Node& node); + + ~NetworkInterfaceTlm() override; + + +//Overridden Functions: These functions are inherited from the base NetworkInterface class and are specialized for this NetworkInterfaceVC class: + void initialize() override; //Initializes the network interface. This might involve setting initial values, like clearing the send and receive queues. + + void bind(Connection* conn, SignalContainer* sigContIn, + SignalContainer* sigContOut) override; //This binds the network interface to other components (connections, signals) in the system. + + void thread() override; //A process that will run in the SystemC simulation. It controls the main operations of the network interface, like handling packet transmission and reception. + + void send_packet_to_router(); + + void receivePacketFromPE() override; //This function handles the reception of packets from the processing element (PE). These packets are placed in the packet_send_queue to be sent over the network. + + void receiveFlitFromRouter() override; //Not implemented, another TLM function is used insted. Originally, This function deals with receiving flits from the router and reconstructing them into packets that can be processed by the PE. + + void generateFlitsForPacket(Packet *p) override; //Converts a packet into flits to be sent over the network to the router. + + void getDestination(Packet* p, std::string pos[2]); + + void receive_and_process_flit(tlm::tlm_generic_payload& trans); + + /// Forwarding function for receiving data from router + tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay); + + void log_info(std::string msg); + void log_error(std::string msg); + void log_fatal(std::string msg); + +}; + diff --git a/src/networkManager/NetworkManager.cpp b/src/networkManager/NetworkManager.cpp new file mode 100644 index 0000000..6800351 --- /dev/null +++ b/src/networkManager/NetworkManager.cpp @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (C) 2024 + * + * 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 "utils/noc_logger.h" + +NetworkManager::NetworkManager(sc_module_name nm, std::string configFolder){ + setup_logger(); + dbid = rep.registerElement("NetworkManager", 0); + tlmNoc = new NocTlm("NocTlm", 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 = CORE_NO * 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 == "Router") { + int id = n.id; + + for (int j = 0; j < CORE_NO; ++j) { + int index = tlmNoc->cores[id][j]->source_core_id % numOfPEs; + + NetworkInterfaceTlm* ni = tlmNoc->cores[id][j]; + if (!ni) continue; // Ensure ni is valid + + std::string pe_name = "pe_" + std::to_string(n.id) + "_" + std::to_string(j); + ProcessingElementVC *pe = new ProcessingElementVC(pe_name.c_str(), n, tp.get(), index); + + auto sig1 = std::make_unique( + ("packetSigCon1_" + std::to_string(n.id) + "_" + std::to_string(j)).c_str()); + auto sig2 = std::make_unique( + ("packetSigCon2_" + std::to_string(n.id) + "_" + std::to_string(j)).c_str()); + + ni->bind(nullptr, sig1.get(), sig2.get()); + pe->bind(nullptr, sig2.get(), sig1.get()); + ni->clk(*clocks.at(n.type->id)); + + networkParticipants.push_back(dynamic_cast(pe)); + packetSignalContainers.push_back(move(sig1)); + packetSignalContainers.push_back(move(sig2)); + + if (index < tp->processingElements.size()) { + tp->processingElements[index] = pe; + } + } + } + } +} + + +// void NetworkManager::createNetworkParticipants() { +// int numOfPEs = tp->processingElements.size(); +// for (Node &n : globalResources.nodes) { +// if (n.type->model == "RouterVC") { +// int id = n.id; + +// for (int j = 0; j < CORE_NO; ++j) { // Core index within each router +// NetworkInterfaceTlm* ni = tlmNoc->cores[id][j]; + +// std::string pe_name = "pe_" + std::to_string(n.id); +// 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(cores[id][j]->source_core_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(); +} + +NetworkManager::~NetworkManager() { + for (auto &r : networkParticipants) + delete r; + networkParticipants.clear(); +} + +void NetworkManager::log_info(std::string msg){ + SC_REPORT_INFO(NM_LOG, (msg).c_str()); +} \ No newline at end of file diff --git a/src/networkManager/NetworkManager.h b/src/networkManager/NetworkManager.h new file mode 100644 index 0000000..6024fe9 --- /dev/null +++ b/src/networkManager/NetworkManager.h @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (C) 2024 + * + * 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 + +#include "systemc.h" +#include "tlm.h" +#include "ratatoskrUtils/utils/Structures.h" +#include "ratatoskrUtils/utils/GlobalResources.h" +#include "ratatoskrUtils/utils/Report.h" +#include "ratatoskrUtils/traffic/TrafficPool.h" + +#include "networkInterface/NetworkInterfaceTlm.h" + +#include "ratatoskrUtils/traffic/synthetic/SyntheticPool.h" +#include "ratatoskrUtils/traffic/task/TaskPool.h" +#include "ratatoskrUtils/traffic/netrace/NetracePool.h" + +#include "router/router.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); + + ~NetworkManager() override; + +private: + GlobalResources& globalResources = GlobalResources::getInstance(); + //GlobalReport& globalReport = GlobalReport::getInstance(); //// + Report& rep = Report::getInstance(); + int dbid; + std::vector> clocks; + std::unique_ptr tp; + NocTlm* tlmNoc; + std::vector networkParticipants; + std::vector idNis; + std::vector> packetSignalContainers; + //std::vector> links; //// + + void createClocks(); //Create clocks for Ratatoskr PEs + + void createTrafficPool(); //Create the traffic pool with the tasks for PEs + + void createNetworkParticipants(); //Create Network Participants (creates PE and NI, and connects them) + + //void createLinks(); //Connects Network Interface to Routers in NoC + + void runNoC(); //Initialize routers and starts traffic pool + + void log_info(std::string msg); +}; \ No newline at end of file diff --git a/src/noc/noc.cpp b/src/noc/noc.cpp new file mode 100644 index 0000000..556cbdc --- /dev/null +++ b/src/noc/noc.cpp @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (C) 2024 + * + * 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. + ******************************************************************************/ + +// NocTlm.cpp +#include "noc.h" +#include "utils/noc_logger.h" +#include "utils/utils.h" + +NocTlm::NocTlm(sc_module_name nm, std::string config_folder): sc_module(nm) { + setup_logger(); + // Create a semaphore manager instance + sem_mgr = new semaphore_manager("SemaphoreManager"); + initializeGlobalResources(config_folder); + setup_routers_and_cores(); + sc_report_handler::set_actions(N_LOG, SC_INFO, SC_LOG|SC_DISPLAY); + +} + +NocTlm::~NocTlm() { + // Clean up memory to avoid leaks + for (int i = 0; i < ROUTER_NO; ++i) { + for (int j = 0; j < CORE_NO; ++j) { + delete cores[i][j]; // Delete each core (NI) + } + delete routers[i]; // Delete each router + } +} + +void NocTlm::initializeGlobalResources(std::string config_folder) { + // initialize global resources and rep + globalResources = GlobalResources::getInstance(); + GlobalReport &globalReport = GlobalReport::getInstance(); + Report &rep = Report::getInstance(); + sleep(1); + + std::string config_path = "config/"+config_folder+"/config.xml";//"config/config.xml"; + globalResources.readConfigFile(config_path); + globalReport.readConfigFile(config_path); + + std::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 NocTlm::setup_routers_and_cores() { + // Instantiate ROUTER_NO routers + //globalResources.nodes.size() + for (Node &n : globalResources.nodes) { + if (n.type->model == "Router"){ + int id = n.id; + std::string router_name = "router" + std::to_string(id); + routers[id] = new router(router_name.c_str()); + + // Store semaphores and out_fifos in vectors + router_sems.push_back(&routers[id]->sem); + router_out_fifos.push_back(&routers[id]->out_fifo); + routers[id]->set_semaphore_manager(sem_mgr); // Pass semaphore manager to each router + } + } + + // Set up pointers to other routers' semaphores and out_fifos for each router + for (Node &n : globalResources.nodes) { + if (n.type->model == "Router"){ + int id = n.id; + routers[id]->other_sems = router_sems; + routers[id]->other_out_fifos = router_out_fifos; + } + } + + // Instantiate ROUTER_NO * CORE_NO cores (CORE_NO per router) + for (Node &n : globalResources.nodes) { + if (n.type->model == "Router"){ + int id = n.id; + for (int j = 0; j < CORE_NO; ++j) { // Core index within each router + std::string core_name = "core" + std::to_string(id) + "_" + std::to_string(j); + cores[id][j] = new NetworkInterfaceTlm(core_name.c_str(), n); + cores[id][j]->source_router_id = id; // Set source router ID + cores[id][j]->source_core_id = CORE_NO*id + j; // Set source core ID + } + } + } + + // Bind cores to their respective routers + for (Node &n : globalResources.nodes) { + if (n.type->model == "Router"){ + int id = n.id; + for (int j = 0; j < CORE_NO; ++j) { // Core index within each router + cores[id][j]->socket.bind(routers[id]->sockets[j]); // Core's socket to router's target socket + routers[id]->core_sockets[j].bind(cores[id][j]->target_socket); // Router's initiator socket to core's target socket + routers[id]->current_router_id = id; + } + } + } +} + +void NocTlm::log_info(std::string msg){ + SC_REPORT_INFO(N_LOG, (msg).c_str()); +} + +void NocTlm::log_warn(std::string msg){ + SC_REPORT_WARNING(N_LOG, (msg).c_str()); +} + +void NocTlm::log_error(std::string msg){ + SC_REPORT_ERROR(N_LOG, (msg).c_str()); +} \ No newline at end of file diff --git a/src/noc/noc.h b/src/noc/noc.h new file mode 100644 index 0000000..0272479 --- /dev/null +++ b/src/noc/noc.h @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (C) 2024 + * + * 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. + ******************************************************************************/ + +// NocTlm.h +// #ifndef NOCTLM_H +// #define NOCTLM_H +#pragma once + +#ifndef SC_INCLUDE_DYNAMIC_PROCESSES +#define SC_INCLUDE_DYNAMIC_PROCESSES +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils/configuration.h" +#include "utils/semaphore_manager.h" +#include "router/router.h" +#include "networkInterface/NetworkInterfaceTlm.h" +#include "ratatoskrUtils/utils/Structures.h" +#include "ratatoskrUtils/utils/GlobalReport.h" +#include "ratatoskrUtils/utils/GlobalResources.h" +using namespace tlm; + +class NocTlm : public sc_core::sc_module { +public: + + SC_HAS_PROCESS(NocTlm); + + // Constructor and destructor + explicit NocTlm(sc_module_name, std::string); + ~NocTlm() override; + + uint8_t max_pos[3]; + std::map mapNodePERouter; + + void initializeGlobalResources(std::string config_folder); + + GlobalResources& globalResources = GlobalResources::getInstance(); + + router* routers[ROUTER_NO]; + NetworkInterfaceTlm* cores[ROUTER_NO][CORE_NO]; + std::vector router_sems; + std::vector*> router_out_fifos; + semaphore_manager* sem_mgr; + + // Method to initialize the routers and cores + void setup_routers_and_cores(); + + void log_info(std::string msg); + + void log_warn(std::string msg); + + void log_error(std::string msg); + + + +}; + +// #endif // NOCTLM_H diff --git a/src/ratatoskrUtils/container/ClassicContainer.h b/src/ratatoskrUtils/container/ClassicContainer.h new file mode 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 index 0000000..b1e5ebc --- /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, int node_id) + : + node(node), + trafficPool(tp) +{ + this->id = node_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 100644 index 0000000..b6fff50 --- /dev/null +++ b/src/ratatoskrUtils/processingElement/ProcessingElement.h @@ -0,0 +1,51 @@ +/******************************************************************************* + * 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, int node_id); + + virtual void receive() = 0; + + virtual void execute(Task&) = 0; + + //virtual void execute(TaskCS&) = 0; + + virtual void thread() = 0; +}; + diff --git a/src/ratatoskrUtils/processingElement/ProcessingElementVC.cpp b/src/ratatoskrUtils/processingElement/ProcessingElementVC.cpp new file mode 100644 index 0000000..83dbdd9 --- /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, int node_id) + : + ProcessingElement(mn, node, tp, node_id) +{ + 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 100644 index 0000000..c175d89 --- /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, int node_id); + + ~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 100644 index 0000000..20296f5 --- /dev/null +++ b/src/ratatoskrUtils/traffic/Flit.cpp @@ -0,0 +1,90 @@ +/******************************************************************************* + * 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" +#include "utils/configuration.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 = CORE_NO*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 100644 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 100644 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 100644 index 0000000..9c305eb --- /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); + + virtual ~Packet(); +}; diff --git a/src/ratatoskrUtils/traffic/TrafficPool.cpp b/src/ratatoskrUtils/traffic/TrafficPool.cpp new file mode 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 index 0000000..fab9134 --- /dev/null +++ b/src/ratatoskrUtils/utils/GlobalResources.cpp @@ -0,0 +1,719 @@ +/******************************************************************************* + * 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(); + Task task = Task{taskID, bindings.at(taskID)}; + readAttributeIfExists(task_node, "start", "min", task.minStart); + readAttributeIfExists(task_node, "start", "max", task.maxStart); + readAttributeIfExists(task_node, "duration", "min", task.minDuration); + readAttributeIfExists(task_node, "duration", "max", task.maxDuration); + readAttributeIfExists(task_node, "repeat", "min", task.minRepeat); + readAttributeIfExists(task_node, "repeat", "max", task.maxRepeat); + + // Read Requirements + std::vector 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 index 0000000..b529c42 --- /dev/null +++ b/src/ratatoskrUtils/utils/Structures.h @@ -0,0 +1,424 @@ +/******************************************************************************* + * 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; +}; + +class DataSendPossibility { +public: + possID_t id; + float probability; + std::vector dataDestinations; + + DataSendPossibility(possID_t id, float probability, const std::vector& dataDestinations); +}; + +class Task { +public: + 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 100644 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 100644 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 100644 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.cpp b/src/router/router.cpp similarity index 69% rename from src/router.cpp rename to src/router/router.cpp index 2f3e186..daefb88 100644 --- a/src/router.cpp +++ b/src/router/router.cpp @@ -1,8 +1,29 @@ +/******************************************************************************* + * Copyright (C) 2024 + * + * 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" // Router module with FIFOs, semaphores, and capacity control for receive FIFO router::router(sc_module_name name) -: in_fifo(CORE_FIFO_CAPACITY), out_fifo(ROUTER_RECEIVE_FIFO_CAPACITY), sem(1), router_id(-1) // default router id +: in_fifo(CORE_FIFO_CAPACITY), out_fifo(ROUTER_RECEIVE_FIFO_CAPACITY), sem(1), current_router_id(-1) // default router id { sc_report_handler::set_log_file_name("out/report.log"); sc_report_handler::set_actions(LOG_NAME, SC_INFO, SC_LOG|SC_DISPLAY); @@ -18,7 +39,7 @@ router::router(sc_module_name name) tlm::tlm_sync_enum router::nb_transport_fw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay) { if (phase == tlm::BEGIN_REQ) { if (in_fifo.num_free() == 0) { - log_info("Router "+std::string(name())+": Input FIFO full, cannot accept transaction with data: "+std::to_string(dynamic_cast(&trans)->data)); + log_info("Router "+ std::string(name()) +": Input FIFO full, cannot accept transaction with data: "); delay = sc_time(5, SC_NS); // Delay before retry //wait(core_fifo_event); return tlm::TLM_UPDATED; // Indicate to retry later @@ -47,7 +68,7 @@ tlm::tlm_sync_enum router::nb_transport_fw(tlm::tlm_generic_payload& trans, tlm: // Push the transaction into the input FIFO by blocking write in_fifo.write(my_trans); //in_fifo_event.notify(sc_core::SC_ZERO_TIME); - log_info("Router " + std::string(name()) + ": Received transaction with data: " + std::to_string(my_trans->data) + log_info("Router " + std::string(name()) + ": Received transaction with data " + " at time: " + current_time.to_string()); phase = tlm::END_REQ; // Mark the end of the request phase @@ -86,14 +107,15 @@ void router::process_core_fifo() { while (!success) { //wait(SC_ZERO_TIME); - if (sem_mgr->request_token(router_id, destination_router_id)) { + log_info("router id: " + std::to_string(current_router_id) + ", dest Router id: "+std::to_string(destination_router_id)); + if (sem_mgr->request_token(current_router_id, destination_router_id)) { if (other_out_fifos[destination_router_id]->num_free() > 0) { other_sems[destination_router_id]-> wait(); int dest_fifo_space = other_out_fifos[destination_router_id]->num_free(); // If there's space and the semaphore is available, send the payload - log_info(std::string(name()) + " forwarded data: " + std::to_string(payload->data) + log_info("Router: " +std::to_string(current_router_id) + " forwarded data with ID: " + std::to_string(payload->data->id) + " to Router_" + std::to_string(destination_router_id)); sc_core::sc_time delay_T = sc_core::sc_time((destination_router_id -current_router + ROUTER_NO) % ROUTER_NO * 10, SC_NS); sc_core::sc_time recv_time = sc_time_stamp() + delay_T; @@ -103,19 +125,19 @@ void router::process_core_fifo() { success = true; // Successfully sent the payload, exit the loop other_sems[destination_router_id]->post(); // Release the semaphore // Release the semaphore after forwarding - sem_mgr->release_token(router_id, destination_router_id); + sem_mgr->release_token(current_router_id, destination_router_id); } else { - log_info("Router " + std::string(name()) + ": Destination router Router_" + std::to_string(destination_router_id) + "'s out_fifo full. Retrying with data: " + std::to_string(payload->data)); + log_info("Router " + std::to_string(current_router_id) + ": Destination router Router_" + std::to_string(destination_router_id) + "'s out_fifo full. Retrying with data (ID): " + std::to_string(payload->data->id)); other_sems[destination_router_id]->post(); // Release the semaphore - sem_mgr->release_token(router_id, destination_router_id); // Release and retry + sem_mgr->release_token(current_router_id, destination_router_id); // Release and retry wait(sc_time(5, SC_NS)); // Wait before retrying } } else { - log_info("Router " + std::string(name()) + ": Semaphore for Router_" + std::to_string(destination_router_id) + " is unavailable. Retrying with data: " + std::to_string(payload->data)); + log_info("Router " + std::to_string(current_router_id) + ": Semaphore for Router_" + std::to_string(destination_router_id) + " is unavailable. Retrying with data (ID): " + std::to_string(payload->data->id)); wait(sc_time(5, SC_NS)); // Wait before retrying } } @@ -146,11 +168,11 @@ void router::process_router_receive_fifo() { unsigned int src_router = payload->src_router; sc_core::sc_time timestamp = payload->timestamp; - if (destination_core_id >= CORE_NO) { - log_error("Router " + std::string(name()) + ": Invalid destination core ID: " + std::to_string(destination_core_id)); - delete payload; - continue; - } + // if (destination_core_id >= CORE_NO) { + // log_error("Router " + std::string(name()) + ": Invalid destination core ID: " + std::to_string(destination_core_id)); + // delete payload; + // continue; + // } int delay_T = (dest_router_id -src_router + ROUTER_NO) % ROUTER_NO * D; // if(timestamp==prev_timestamp){ @@ -162,7 +184,7 @@ void router::process_router_receive_fifo() { // wait(delay_T, SC_NS); // Simulate delay for receiving the data - log_info("Router " + std::to_string(dest_router_id)+ ": Received transaction with data: " + std::to_string(payload->data) + log_info("Router " + std::to_string(dest_router_id)+ ": Received transaction with data: " + std::to_string(payload->data->id) + " from Router " + std::to_string(payload->src_router) + " after a delay of:" + std::to_string(delay_T) + " ns" ); prev_src_id = src_router; @@ -171,28 +193,28 @@ void router::process_router_receive_fifo() { - log_info("Router " + std::string(name())+ ": Forwarding transaction with data: " + std::to_string(payload->data) - + " to core " + std::to_string(destination_core_id)); + log_info("Router " + std::to_string(current_router_id) + ": Forwarding transaction with data: " + std::to_string(payload->data->id) + + " to Processing Element " + std::to_string(destination_core_id)); // Send the payload to the corresponding core using non-blocking TLM tlm::tlm_phase phase = tlm::BEGIN_REQ; sc_time delay = SC_ZERO_TIME; - tlm::tlm_sync_enum status = core_sockets[destination_core_id]->nb_transport_fw(*payload, phase, delay); + tlm::tlm_sync_enum status = core_sockets[destination_core_id % CORE_NO]->nb_transport_fw(*payload, phase, delay); if (status == tlm::TLM_COMPLETED) { - log_info("Router " + std::string(name()) + ": Core " + std::to_string(destination_core_id) - + " completed transaction, data: " + std::to_string(payload->data)); + log_info("Router " + std::to_string(current_router_id) + ": Network Interface " + std::to_string(destination_core_id) + + " completed transaction, data ID: " + std::to_string(payload->data->id)); //// other_sems[dest_router_id]->post(); } else if (status == tlm::TLM_ACCEPTED) { - log_info("Router " + std::string(name()) + ": Core " + std::to_string(destination_core_id) + log_info("Router " + std::to_string(current_router_id) + ": Network Interface " + std::to_string(destination_core_id) + " accepted transaction, waiting for completion."); } else if (status == tlm::TLM_UPDATED) { - log_info("Router " + std::string(name()) + ": Core " + std::to_string(destination_core_id) + log_info("Router " + std::to_string(current_router_id) + ": Network Interface " + std::to_string(destination_core_id) + " updated transaction, waiting for completion."); } else { - log_error("Router " + std::string(name()) + ": Unexpected response from core " + std::to_string(destination_core_id)); + log_error("Router " + std::to_string(current_router_id) + ": Unexpected response from Network Interface " + std::to_string(destination_core_id)); delete payload; } diff --git a/include/router.h b/src/router/router.h similarity index 59% rename from include/router.h rename to src/router/router.h index 6c357ca..c7b6c16 100644 --- a/include/router.h +++ b/src/router/router.h @@ -1,3 +1,24 @@ +/******************************************************************************* + * Copyright (C) 2024 + * + * 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 @@ -13,8 +34,8 @@ #include // For rand() #include // For time() -#include "configuration.h" -#include "semaphore_manager.h" +#include "utils/configuration.h" +#include "utils/semaphore_manager.h" using namespace sc_core; @@ -30,7 +51,7 @@ SC_MODULE(router) { // Declare the semaphore for access control sc_core::sc_semaphore sem; - int router_id; + //int router_id; const int D = 10; // Base delay for each router communication (in ns) diff --git a/src/utils/configuration.h b/src/utils/configuration.h new file mode 100644 index 0000000..46a3ee2 --- /dev/null +++ b/src/utils/configuration.h @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (C) 2024 + * + * 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 "ratatoskrUtils/utils/Structures.h" +#include +#include + +using namespace sc_core; // For sc_time + +// Global parameters to generalize the design +#define ROUTER_NO 4 // Number of routers +#define CORE_NO 4 // Number of cores per router +#define CORE_FIFO_CAPACITY 8 // Capacity of FIFO in router that receive data from cores +#define ROUTER_RECEIVE_FIFO_CAPACITY 4 // Capacity of FIFO in router that receive data from other routers +#define LOG_NAME "MY_LOG" +#define NI_LOG "TLM_NI" + + +struct my_payload : public tlm::tlm_generic_payload { + unsigned int src_core; // Source core ID + unsigned int src_router; // Source router ID + unsigned int dst_core; // Destination core ID + unsigned int dst_router; // Destination router ID + Flit* data; // Data value + sc_core::sc_time timestamp; // Timestamp field + + // Default constructor + my_payload() : src_core(0), src_router(0), dst_core(0), dst_router(0), data(nullptr), timestamp(SC_ZERO_TIME) { + set_data_ptr(reinterpret_cast(&data)); + set_data_length(sizeof(data)); + set_streaming_width(sizeof(data)); + } + + // Constructor with random data + my_payload(unsigned int source_core, unsigned int src_router_id, unsigned int dst_core_id, unsigned int destination_router_id, Flit* flit_data, sc_time time = SC_ZERO_TIME) + : src_core(source_core), src_router(src_router_id), dst_core(dst_core_id), dst_router(destination_router_id), data(flit_data), timestamp(time) { + set_data_ptr(reinterpret_cast(&data)); + set_data_length(sizeof(data)); + set_streaming_width(sizeof(data)); + } + + // Function to update timestamp at any stage + void update_timestamp(sc_time new_time) { + timestamp = new_time; + } +}; + + diff --git a/src/utils/memory_manager.cpp b/src/utils/memory_manager.cpp new file mode 100644 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 100644 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..82a83cf --- /dev/null +++ b/src/utils/noc_logger.cpp @@ -0,0 +1,96 @@ +#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; + } + else if(string(report.get_msg_type()) == NM_LOG){ + log_filename = NM_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(NM_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 NM_LOGFILENAME "./out/nm_conn.log" +#define NM_LOG "NetworkManager" + +#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/semaphore_manager.h b/src/utils/semaphore_manager.h new file mode 100644 index 0000000..326f6ba --- /dev/null +++ b/src/utils/semaphore_manager.h @@ -0,0 +1,151 @@ +/******************************************************************************* + * Copyright (C) 2024 + * + * 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. + ******************************************************************************/ +// semaphore_manager.h +#ifndef SEMAPHORE_MANAGER_H +#define SEMAPHORE_MANAGER_H + +#include +#include +#include +#include +#include +#include +#include "configuration.h" + +using namespace sc_core; + +class semaphore_manager : public sc_module { +public: + SC_HAS_PROCESS(semaphore_manager); + + semaphore_manager(sc_module_name name) : sc_module(name) { + semaphore_owners.resize(ROUTER_NO, -1); // Start with all tokens at router 0 + request_queues.resize(ROUTER_NO); // Initialize a queue for each semaphore + queue_entries.resize(ROUTER_NO); // Set for each semaphore to track queued routers + semaphore_status.resize(ROUTER_NO, false); // All semaphores are initially free + std::fill_n(last_router_owner, ROUTER_NO, -1); // Initialize all last owners to -1 + //SC_THREAD(update_semaphores); // Start automatic ownership update thread + sc_report_handler::set_log_file_name("out/report.log"); + sc_report_handler::set_actions(LOG_NAME, SC_INFO, SC_LOG|SC_DISPLAY); + } + + // Request a token for a semaphore with round-robin and priority ordering + bool request_token(int router_id, int semaphore_id) { + //wait(SC_ZERO_TIME); + std::lock_guard lock(mutex); // Ensure atomic access + if (semaphore_id >= 0 && semaphore_id < ROUTER_NO) { + + wait(SC_ZERO_TIME); + // Give priority as the request follows round-robin order from the last owner + if (semaphore_owners[semaphore_id] == router_id || (semaphore_owners[semaphore_id] == -1 && request_queues[semaphore_id].empty()))//semaphore_owners[semaphore_id] == -1 || (!semaphore_status[semaphore_id] && request_queues[semaphore_id].empty())) + { + log_info("Token for destination router " + std::to_string(semaphore_id) + " granted to Router " + std::to_string(router_id)); + semaphore_owners[semaphore_id] = router_id; + semaphore_status[semaphore_id] = true; // Mark semaphore as in use + last_router_owner[semaphore_id] = router_id; // Update the last owner + return true; + } else { + if (queue_entries[semaphore_id].find(router_id) == queue_entries[semaphore_id].end()) { + request_queues[semaphore_id].push(router_id); + queue_entries[semaphore_id].insert(router_id); // Track in the set + log_info("Router " + std::to_string(router_id) + " added to queue for semaphore " + std::to_string(semaphore_id)); + } + + } + } + return false; + } + + // Release the token and pass it to the next in the round-robin + bool release_token(int router_id, int semaphore_id) { + std::lock_guard lock(mutex); // Ensure atomic access + if (semaphore_id >= 0 && semaphore_id < ROUTER_NO) { + if (semaphore_owners[semaphore_id] == router_id) { + log_info("Router " + std::to_string(router_id) + " released token for destination router " + std::to_string(semaphore_id)); + // semaphore_status[semaphore_id] = false; // Mark semaphore as free + + if (!request_queues[semaphore_id].empty()) { + // Start searching from the next router in clockwise order + int next_router = -1; + int start_router = (router_id + 1) % ROUTER_NO; // Start clockwise from the next router + + // Search for the first router in queue that is in clockwise order + for (int i = 0; i < ROUTER_NO; ++i) { + int candidate_router = (start_router + i) % ROUTER_NO; + + // Check if this candidate is in the queue + if (queue_entries[semaphore_id].find(candidate_router) != queue_entries[semaphore_id].end()) { + next_router = candidate_router; + break; + } + } + + if (next_router != -1) { + // Assign the token to the found router + semaphore_owners[semaphore_id] = next_router; + semaphore_status[semaphore_id] = true; // Mark semaphore as in use + + // Remove next_router from the queue and queue_entries + std::queue temp_queue; + while (!request_queues[semaphore_id].empty()) { + int current_router = request_queues[semaphore_id].front(); + request_queues[semaphore_id].pop(); + + if (current_router != next_router) { + temp_queue.push(current_router); // Keep all others in the queue + } + } + request_queues[semaphore_id] = temp_queue; + queue_entries[semaphore_id].erase(next_router); // Remove from set + + log_info("Token for destination router " + std::to_string(semaphore_id) + " passed to Router " + std::to_string(next_router)); + } + } else { + semaphore_owners[semaphore_id] = -1; // No one else is waiting, so free the token + semaphore_status[semaphore_id] = false; // Mark semaphore as free + } + return true; + } + } + return false; +} + +private: + std::vector semaphore_owners; // Tracks router ownership (-1 means no owner) + std::vector> request_queues; // Queue of pending requests per semaphore + std::vector semaphore_status; // Semaphore availability + sc_mutex mutex; // Mutex to ensure atomic operations + std::vector> queue_entries; // Track entries in each queue to prevent duplicates + int last_router_owner[ROUTER_NO]; // Array to track last owner for round-robin assignment + + //print log messages + void log_info(std::string msg){ + SC_REPORT_INFO(LOG_NAME, msg.c_str()); + } + + void log_error(std::string msg){ + SC_REPORT_ERROR(LOG_NAME, msg.c_str()); + } + +}; + +#endif // SEMAPHORE_MANAGER_H diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp new file mode 100644 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 100644 index 0000000..19e8d4e --- /dev/null +++ b/src/utils/utils.h @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (C) 2024 + * + * 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]);