Updated project Corona TLM test with Ratatoskr

This commit is contained in:
HelenClaraGeorge 2024-11-11 12:44:10 +01:00
parent 10d82d8f7c
commit ccd88fbfc1
104 changed files with 20371 additions and 1281 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
build
out
sim

56
CMakeLists.txt Normal file
View file

@ -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)

View file

@ -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

View file

@ -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
• Acquire and renew the home token

9
build.sh Normal file
View file

@ -0,0 +1,9 @@
#!/bin/bash
mkdir build
cd build
cmake ..
make -j
cp sim ..
cd ..
rm -rf build

55
config/config.xml Normal file
View file

@ -0,0 +1,55 @@
<?xml version="1.0" ?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<general>
<simulationTime value="1500"/>
<outputToFile value="true">report</outputToFile>
</general>
<noc>
<nocFile>config/net.xml</nocFile>
<flitsPerPacket value="1"/>
<bitWidth value="32"/>
<Vdd value="5"/>
</noc>
<application>
<benchmark>task</benchmark>
<dataFile>config/simple_data.xml</dataFile>
<mapFile>config/simple_map.xml</mapFile>
</application>
<verbose>
<processingElements>
<function_calls value="false"/>
<send_flit value="false"/>
<send_head_flit value="true"/>
<receive_flit value="false"/>
<receive_tail_flit value="true"/>
<throttle value="false"/>
<reset value="false"/>
</processingElements>
<router>
<function_calls value="false"/>
<send_flit value="false"/>
<send_head_flit value="false"/>
<receive_flit value="false"/>
<receive_tail_flit value="false"/>
<throttle value="false"/>
<reset value="false"/>
<assign_channel value="false"/>
<buffer_overflow value="true"/>
</router>
<netrace>
<inject value="true"/>
<eject value="true"/>
<router_receive value="true"/>
</netrace>
<tasks>
<function_calls value="true"/>
<xml_parse value="false"/>
<data_receive value="true"/>
<data_send value="true"/>
<source_execute value="false"/>
</tasks>
</verbose>
<report>
<bufferReportRouters>5 6 9 10</bufferReportRouters>
</report>
</configuration>

1136
config/net.xml Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,55 @@
<?xml version="1.0" ?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<general>
<simulationTime value="1500"/>
<outputToFile value="true">report</outputToFile>
</general>
<noc>
<nocFile>config/simple_test/net.xml</nocFile>
<flitsPerPacket value="1"/>
<bitWidth value="32"/>
<Vdd value="5"/>
</noc>
<application>
<benchmark>task</benchmark>
<dataFile>config/only_config_msg_test/data.xml</dataFile>
<mapFile>config/only_config_msg_test/map.xml</mapFile>
</application>
<verbose>
<processingElements>
<function_calls value="false"/>
<send_flit value="false"/>
<send_head_flit value="true"/>
<receive_flit value="false"/>
<receive_tail_flit value="true"/>
<throttle value="false"/>
<reset value="false"/>
</processingElements>
<router>
<function_calls value="false"/>
<send_flit value="false"/>
<send_head_flit value="false"/>
<receive_flit value="false"/>
<receive_tail_flit value="false"/>
<throttle value="false"/>
<reset value="false"/>
<assign_channel value="false"/>
<buffer_overflow value="true"/>
</router>
<netrace>
<inject value="true"/>
<eject value="true"/>
<router_receive value="true"/>
</netrace>
<tasks>
<function_calls value="true"/>
<xml_parse value="false"/>
<data_receive value="true"/>
<data_send value="true"/>
<source_execute value="false"/>
</tasks>
</verbose>
<report>
<bufferReportRouters>5 6 9 10</bufferReportRouters>
</report>
</configuration>

View file

@ -0,0 +1,92 @@
<?xml version="1.0" ?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dataTypes>
<dataType id="0">
<name value="Packet"/>
</dataType>
<dataType id="1">
<name value="Stream"/>
</dataType>
<dataType id="2">
<name value="ConfigRouter"/>
</dataType>
</dataTypes>
<tasks>
<task id="0">
<start min="0" max="0"/>
<duration min="-1" max="-1"/>
<repeat min="1" max="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="2"/>
<task value="1"/>
<config link="0" destination="3"/>
</destination>
<destination id="1">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="2"/>
<task value="2"/>
<config link="2" destination="3"/>
</destination>
<destination id="2">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="2"/>
<task value="3"/>
<config link="2" destination="0"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="1">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="2"/>
<source value="0"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
<task id="2">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="2"/>
<source value="0"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
<task id="3">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="2"/>
<source value="0"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
</tasks>
</data>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" ?>
<map xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<bind>
<task value="0"/>
<node value="0"/>
</bind>
<bind>
<task value="1"/>
<node value="0"/>
</bind>
<bind>
<task value="2"/>
<node value="1"/>
</bind>
<bind>
<task value="3"/>
<node value="2"/>
</bind>
</map>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,55 @@
<?xml version="1.0" ?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<general>
<simulationTime value="1500"/>
<outputToFile value="true">report</outputToFile>
</general>
<noc>
<nocFile>config/simple_test/net.xml</nocFile>
<flitsPerPacket value="1"/>
<bitWidth value="32"/>
<Vdd value="5"/>
</noc>
<application>
<benchmark>task</benchmark>
<dataFile>config/simple_2_layer_test/data.xml</dataFile>
<mapFile>config/simple_2_layer_test/map.xml</mapFile>
</application>
<verbose>
<processingElements>
<function_calls value="false"/>
<send_flit value="false"/>
<send_head_flit value="true"/>
<receive_flit value="false"/>
<receive_tail_flit value="true"/>
<throttle value="false"/>
<reset value="false"/>
</processingElements>
<router>
<function_calls value="false"/>
<send_flit value="false"/>
<send_head_flit value="false"/>
<receive_flit value="false"/>
<receive_tail_flit value="false"/>
<throttle value="false"/>
<reset value="false"/>
<assign_channel value="false"/>
<buffer_overflow value="true"/>
</router>
<netrace>
<inject value="true"/>
<eject value="true"/>
<router_receive value="true"/>
</netrace>
<tasks>
<function_calls value="true"/>
<xml_parse value="false"/>
<data_receive value="true"/>
<data_send value="true"/>
<source_execute value="false"/>
</tasks>
</verbose>
<report>
<bufferReportRouters>5 6 9 10</bufferReportRouters>
</report>
</configuration>

View file

@ -0,0 +1,145 @@
<?xml version="1.0" ?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dataTypes>
<dataType id="0">
<name value="Packet"/>
</dataType>
<dataType id="1">
<name value="Stream"/>
</dataType>
<dataType id="2">
<name value="ConfigRouter"/>
</dataType>
</dataTypes>
<tasks>
<task id="0">
<start min="0" max="0"/>
<duration min="-1" max="-1"/>
<repeat min="1" max="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="2"/>
<task value="1"/>
<config link="0" destination="3"/>
</destination>
<destination id="1">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="2"/>
<task value="2"/>
<config link="2" destination="3"/>
</destination>
<destination id="2">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="2"/>
<task value="3"/>
<config link="2" destination="0"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="1">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="2"/>
<source value="0"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
<task id="2">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="2"/>
<source value="0"/>
<count max="1" min="1"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="0"/>
<task value="3"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="3">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="2"/>
<source value="2"/>
<count max="1" min="1"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="1"/>
<task value="4"/>
</destination>
<destination id="1">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="1"/>
<task value="4"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="4">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="1"/>
<source value="0"/>
<count max="1" min="1"/>
</requirement>
<requirement id="1">
<type value="1"/>
<source value="0"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
</tasks>
</data>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" ?>
<map xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<bind>
<task value="0"/>
<node value="0"/>
</bind>
<bind>
<task value="1"/>
<node value="1"/>
</bind>
<bind>
<task value="2"/>
<node value="2"/>
</bind>
<bind>
<task value="3"/>
<node value="0"/>
</bind>
<bind>
<task value="4"/>
<node value="2"/>
</bind>
</map>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,70 @@
<?xml version="1.0" ?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dataTypes>
<dataType id="0">
<name value="Packet"/>
</dataType>
<dataType id="1">
<name value="Streaming"/>
</dataType>
</dataTypes>
<tasks>
<task id="0">
<start min="0" max="0"/>
<duration min="-1" max="-1"/>
<repeat min="1" max="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="0"/>
<task value="2"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="1">
<start min="0" max="0"/>
<duration min="-1" max="-1"/>
<repeat min="1" max="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="0"/>
<task value="2"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="2">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="0"/>
<source value="0"/>
<count max="1" min="1"/>
</requirement>
<requirement id="1">
<type value="0"/>
<source value="24"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
</tasks>
</data>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" ?>
<map xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<bind>
<task value="0"/>
<node value="0"/>
</bind>
<bind>
<task value="1"/>
<node value="15"/>
</bind>
<bind>
<task value="2"/>
<node value="25"/>
</bind>
</map>

View file

@ -0,0 +1,55 @@
<?xml version="1.0" ?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<general>
<simulationTime value="1500"/>
<outputToFile value="true">report</outputToFile>
</general>
<noc>
<nocFile>config/simple_test/net.xml</nocFile>
<flitsPerPacket value="1"/>
<bitWidth value="32"/>
<Vdd value="5"/>
</noc>
<application>
<benchmark>task</benchmark>
<dataFile>config/simple_2_point_test/2pt_data.xml</dataFile>
<mapFile>config/simple_2_point_test/2pt_map.xml</mapFile>
</application>
<verbose>
<processingElements>
<function_calls value="false"/>
<send_flit value="false"/>
<send_head_flit value="true"/>
<receive_flit value="false"/>
<receive_tail_flit value="true"/>
<throttle value="false"/>
<reset value="false"/>
</processingElements>
<router>
<function_calls value="false"/>
<send_flit value="false"/>
<send_head_flit value="false"/>
<receive_flit value="false"/>
<receive_tail_flit value="false"/>
<throttle value="false"/>
<reset value="false"/>
<assign_channel value="false"/>
<buffer_overflow value="true"/>
</router>
<netrace>
<inject value="true"/>
<eject value="true"/>
<router_receive value="true"/>
</netrace>
<tasks>
<function_calls value="true"/>
<xml_parse value="false"/>
<data_receive value="true"/>
<data_send value="true"/>
<source_execute value="false"/>
</tasks>
</verbose>
<report>
<bufferReportRouters>5 6 9 10</bufferReportRouters>
</report>
</configuration>

File diff suppressed because it is too large Load diff

44
config/simple_data.xml Normal file
View file

@ -0,0 +1,44 @@
<?xml version="1.0" ?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dataTypes>
<dataType id="0">
<name value="Packet"/>
</dataType>
<dataType id="1">
<name value="Stream"/>
</dataType>
</dataTypes>
<tasks>
<task id="0">
<start min="0" max="0"/>
<duration min="-1" max="-1"/>
<repeat min="1" max="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="0"/>
<task value="1"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="1">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="0"/>
<source value="0"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
</tasks>
</data>

11
config/simple_map.xml Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0" ?>
<map xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<bind>
<task value="0"/>
<node value="0"/>
</bind>
<bind>
<task value="1"/>
<node value="6"/>
</bind>
</map>

View file

@ -0,0 +1,55 @@
<?xml version="1.0" ?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<general>
<simulationTime value="1500"/>
<outputToFile value="true">report</outputToFile>
</general>
<noc>
<nocFile>config/simple_test/net.xml</nocFile>
<flitsPerPacket value="1"/>
<bitWidth value="32"/>
<Vdd value="5"/>
</noc>
<application>
<benchmark>task</benchmark>
<dataFile>config/simple_test/simple_data.xml</dataFile>
<mapFile>config/simple_test/simple_map.xml</mapFile>
</application>
<verbose>
<processingElements>
<function_calls value="false"/>
<send_flit value="false"/>
<send_head_flit value="true"/>
<receive_flit value="false"/>
<receive_tail_flit value="true"/>
<throttle value="false"/>
<reset value="false"/>
</processingElements>
<router>
<function_calls value="false"/>
<send_flit value="false"/>
<send_head_flit value="false"/>
<receive_flit value="false"/>
<receive_tail_flit value="false"/>
<throttle value="false"/>
<reset value="false"/>
<assign_channel value="false"/>
<buffer_overflow value="true"/>
</router>
<netrace>
<inject value="true"/>
<eject value="true"/>
<router_receive value="true"/>
</netrace>
<tasks>
<function_calls value="true"/>
<xml_parse value="false"/>
<data_receive value="true"/>
<data_send value="true"/>
<source_execute value="false"/>
</tasks>
</verbose>
<report>
<bufferReportRouters>5 6 9 10</bufferReportRouters>
</report>
</configuration>

879
config/simple_test/net.xml Normal file
View file

@ -0,0 +1,879 @@
<?xml version="1.0" encoding="UTF-8"?>
<network-on-chip xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="layer.xsd">
<bufferDepthType value="single" /> <!-- single, perVC-->
<nodeTypes>
<nodeType id="0">
<model value="Router"/>
<routing value="XYZ"/>
<clockDelay value="1"/>
</nodeType>
<nodeType id="1">
<model value="ProcessingElement"/>
<clockDelay value="1"/>
</nodeType>
</nodeTypes>
<nodes>
<node id="0">
<xPos value="0.000"/>
<yPos value="0.000"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="0"/>
<layerType value="0"/>
</node>
<node id="1">
<xPos value="0.000"/>
<yPos value="0.333"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="1"/>
<layerType value="0"/>
</node>
<node id="2">
<xPos value="0.000"/>
<yPos value="0.667"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="2"/>
<layerType value="0"/>
</node>
<node id="3">
<xPos value="0.000"/>
<yPos value="1.000"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="3"/>
<layerType value="0"/>
</node>
<node id="4">
<xPos value="0.333"/>
<yPos value="0.000"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="4"/>
<layerType value="0"/>
</node>
<node id="5">
<xPos value="0.333"/>
<yPos value="0.333"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="5"/>
<layerType value="0"/>
</node>
<node id="6">
<xPos value="0.333"/>
<yPos value="0.667"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="6"/>
<layerType value="0"/>
</node>
<node id="7">
<xPos value="0.333"/>
<yPos value="1.000"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="7"/>
<layerType value="0"/>
</node>
<node id="8">
<xPos value="0.667"/>
<yPos value="0.000"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="8"/>
<layerType value="0"/>
</node>
<node id="9">
<xPos value="0.667"/>
<yPos value="0.333"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="9"/>
<layerType value="0"/>
</node>
<node id="10">
<xPos value="0.667"/>
<yPos value="0.667"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="10"/>
<layerType value="0"/>
</node>
<node id="11">
<xPos value="0.667"/>
<yPos value="1.000"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="11"/>
<layerType value="0"/>
</node>
<node id="12">
<xPos value="1.000"/>
<yPos value="0.000"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="12"/>
<layerType value="0"/>
</node>
<node id="13">
<xPos value="1.000"/>
<yPos value="0.333"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="13"/>
<layerType value="0"/>
</node>
<node id="14">
<xPos value="1.000"/>
<yPos value="0.667"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="14"/>
<layerType value="0"/>
</node>
<node id="15">
<xPos value="1.000"/>
<yPos value="1.000"/>
<zPos value="0.000"/>
<nodeType value="0"/>
<idType value="15"/>
<layerType value="0"/>
</node>
<node id="16">
<xPos value="0.000"/>
<yPos value="0.000"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="0"/>
<layerType value="0"/>
</node>
<node id="17">
<xPos value="0.000"/>
<yPos value="0.333"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="1"/>
<layerType value="0"/>
</node>
<node id="18">
<xPos value="0.000"/>
<yPos value="0.667"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="2"/>
<layerType value="0"/>
</node>
<node id="19">
<xPos value="0.000"/>
<yPos value="1.000"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="3"/>
<layerType value="0"/>
</node>
<node id="20">
<xPos value="0.333"/>
<yPos value="0.000"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="4"/>
<layerType value="0"/>
</node>
<node id="21">
<xPos value="0.333"/>
<yPos value="0.333"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="5"/>
<layerType value="0"/>
</node>
<node id="22">
<xPos value="0.333"/>
<yPos value="0.667"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="6"/>
<layerType value="0"/>
</node>
<node id="23">
<xPos value="0.333"/>
<yPos value="1.000"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="7"/>
<layerType value="0"/>
</node>
<node id="24">
<xPos value="0.667"/>
<yPos value="0.000"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="8"/>
<layerType value="0"/>
</node>
<node id="25">
<xPos value="0.667"/>
<yPos value="0.333"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="9"/>
<layerType value="0"/>
</node>
<node id="26">
<xPos value="0.667"/>
<yPos value="0.667"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="10"/>
<layerType value="0"/>
</node>
<node id="27">
<xPos value="0.667"/>
<yPos value="1.000"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="11"/>
<layerType value="0"/>
</node>
<node id="28">
<xPos value="1.000"/>
<yPos value="0.000"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="12"/>
<layerType value="0"/>
</node>
<node id="29">
<xPos value="1.000"/>
<yPos value="0.333"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="13"/>
<layerType value="0"/>
</node>
<node id="30">
<xPos value="1.000"/>
<yPos value="0.667"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="14"/>
<layerType value="0"/>
</node>
<node id="31">
<xPos value="1.000"/>
<yPos value="1.000"/>
<zPos value="0.000"/>
<nodeType value="1"/>
<idType value="15"/>
<layerType value="0"/>
</node>
</nodes>
<connections>
<con id="0">
<interface value="0"/>
<ports>
<port id ="0">
<node value="0"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="16"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="1">
<interface value="0"/>
<ports>
<port id ="0">
<node value="0"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="1"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="2">
<interface value="0"/>
<ports>
<port id ="0">
<node value="0"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="4"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="3">
<interface value="0"/>
<ports>
<port id ="0">
<node value="1"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="17"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="4">
<interface value="0"/>
<ports>
<port id ="0">
<node value="1"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="2"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="5">
<interface value="0"/>
<ports>
<port id ="0">
<node value="1"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="5"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="6">
<interface value="0"/>
<ports>
<port id ="0">
<node value="2"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="18"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="7">
<interface value="0"/>
<ports>
<port id ="0">
<node value="2"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="3"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="8">
<interface value="0"/>
<ports>
<port id ="0">
<node value="2"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="6"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="9">
<interface value="0"/>
<ports>
<port id ="0">
<node value="3"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="19"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="10">
<interface value="0"/>
<ports>
<port id ="0">
<node value="3"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="7"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="11">
<interface value="0"/>
<ports>
<port id ="0">
<node value="4"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="20"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="12">
<interface value="0"/>
<ports>
<port id ="0">
<node value="4"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="5"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="13">
<interface value="0"/>
<ports>
<port id ="0">
<node value="4"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="8"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="14">
<interface value="0"/>
<ports>
<port id ="0">
<node value="5"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="21"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="15">
<interface value="0"/>
<ports>
<port id ="0">
<node value="5"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="6"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="16">
<interface value="0"/>
<ports>
<port id ="0">
<node value="5"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="9"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="17">
<interface value="0"/>
<ports>
<port id ="0">
<node value="6"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="22"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="18">
<interface value="0"/>
<ports>
<port id ="0">
<node value="6"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="7"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="19">
<interface value="0"/>
<ports>
<port id ="0">
<node value="6"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="10"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="20">
<interface value="0"/>
<ports>
<port id ="0">
<node value="7"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="23"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="21">
<interface value="0"/>
<ports>
<port id ="0">
<node value="7"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="11"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="22">
<interface value="0"/>
<ports>
<port id ="0">
<node value="8"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="24"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="23">
<interface value="0"/>
<ports>
<port id ="0">
<node value="8"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="9"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="24">
<interface value="0"/>
<ports>
<port id ="0">
<node value="8"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="12"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="25">
<interface value="0"/>
<ports>
<port id ="0">
<node value="9"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="25"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="26">
<interface value="0"/>
<ports>
<port id ="0">
<node value="9"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="10"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="27">
<interface value="0"/>
<ports>
<port id ="0">
<node value="9"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="13"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="28">
<interface value="0"/>
<ports>
<port id ="0">
<node value="10"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="26"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="29">
<interface value="0"/>
<ports>
<port id ="0">
<node value="10"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="11"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="30">
<interface value="0"/>
<ports>
<port id ="0">
<node value="10"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="14"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="31">
<interface value="0"/>
<ports>
<port id ="0">
<node value="11"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="27"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="32">
<interface value="0"/>
<ports>
<port id ="0">
<node value="11"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="15"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="33">
<interface value="0"/>
<ports>
<port id ="0">
<node value="12"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="28"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="34">
<interface value="0"/>
<ports>
<port id ="0">
<node value="12"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="13"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="35">
<interface value="0"/>
<ports>
<port id ="0">
<node value="13"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="29"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="36">
<interface value="0"/>
<ports>
<port id ="0">
<node value="13"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="14"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="37">
<interface value="0"/>
<ports>
<port id ="0">
<node value="14"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="30"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="38">
<interface value="0"/>
<ports>
<port id ="0">
<node value="14"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="15"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="39">
<interface value="0"/>
<ports>
<port id ="0">
<node value="15"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
<port id ="1">
<node value="31"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
</connections>
</network-on-chip>

View file

@ -0,0 +1,44 @@
<?xml version="1.0" ?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dataTypes>
<dataType id="0">
<name value="Packet"/>
</dataType>
<dataType id="1">
<name value="Stream"/>
</dataType>
</dataTypes>
<tasks>
<task id="0">
<start min="0" max="0"/>
<duration min="-1" max="-1"/>
<repeat min="1" max="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay min="0" max="100"/>
<interval min="100" max="100"/>
<count min="1" max="1"/>
<type value="0"/>
<task value="1"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="1">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="0"/>
<source value="0"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
</tasks>
</data>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" ?>
<map xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<bind>
<task value="0"/>
<node value="0"/>
</bind>
<bind>
<task value="1"/>
<node value="2"/>
</bind>
</map>

View file

@ -0,0 +1,83 @@
<?xml version="1.0" ?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<general>
<simulationTime value="1500"/>
<outputToFile value="true">report</outputToFile>
</general>
<noc>
<nocFile>config/network.xml</nocFile>
<flitsPerPacket value="1"/>
<bitWidth value="32"/>
<Vdd value="5"/>
</noc>
<application>
<benchmark>synthetic</benchmark>
<synthetic>
<phase name="warmup">
<distribution value="uniform"/>
<start max="100" min="100"/>
<duration max="1090" min="1090"/>
<repeat max="-1" min="-1"/>
<delay max="0" min="0"/>
<injectionRate value="0.002"/>
<count max="1" min="1"/>
<hotspot value="0"/>
</phase>
<phase name="run">
<distribution value="uniform"/>
<start max="1100" min="1100"/>
<duration max="101100" min="1500000"/>
<repeat max="-1" min="-1"/>
<delay max="0" min="0"/>
<injectionRate value="0.002"/>
<count max="1" min="1"/>
<hotspot value="0"/>
</phase>
</synthetic>
<dataFile>src/model/config/data.xml</dataFile>
<mapFile>src/model/config/map.xml</mapFile>
<simulationFile>traffic/pipelinePerformance_2D/PipelineResetTB.xml</simulationFile>
<mappingFile>traffic/pipelinePerformance_2D/PipelineResetTBMapping.xml</mappingFile>
<netraceFile>src/model/traffic/netrace/testraces/example.tra.bz2</netraceFile>
<netraceStartRegion value="0"/>
<isUniform value="false"/>
<numberOfTrafficTypes value="5"/>
</application>
<verbose>
<processingElements>
<function_calls value="false"/>
<send_flit value="false"/>
<send_head_flit value="true"/>
<receive_flit value="false"/>
<receive_tail_flit value="true"/>
<throttle value="false"/>
<reset value="false"/>
</processingElements>
<router>
<function_calls value="false"/>
<send_flit value="false"/>
<send_head_flit value="false"/>
<receive_flit value="false"/>
<receive_tail_flit value="false"/>
<throttle value="false"/>
<reset value="false"/>
<assign_channel value="false"/>
<buffer_overflow value="true"/>
</router>
<netrace>
<inject value="true"/>
<eject value="true"/>
<router_receive value="true"/>
</netrace>
<tasks>
<function_calls value="true"/>
<xml_parse value="false"/>
<data_receive value="true"/>
<data_send value="true"/>
<source_execute value="false"/>
</tasks>
</verbose>
<report>
<bufferReportRouters>5 6 9 10 21 22 25 26 37 38 41 42</bufferReportRouters>
</report>
</configuration>

View file

@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dataTypes>
<dataType id="0">
<name value="image"/>
</dataType>
<dataType id="1">
<name value="image part"/>
</dataType>
<dataType id="2">
<name value="feature"/>
</dataType>
</dataTypes>
<tasks>
<task id = "0">
<start min = "0" max = "0"/>
<duration min = "-1" max = "-1"/>
<repeat min = "2" max = "2"/>
<requires>
</requires>
<generates>
<possibility id = "0">
<probability value = "1" />
<destinations>
<destination id = "0">
<delay min = "0" max = "0" />
<interval min = "1000" max = "1000"/>
<count min = "1" max = "1" />
<type value = "0" />
<task value = "1" />
</destination>
<destination id = "1">
<delay min = "0" max = "0" />
<interval min = "1000" max = "1000"/>
<count min = "1" max = "1" />
<type value = "2" />
<task value = "2" />
</destination>
</destinations>
</possibility>
<!-- <possibility id = "1">
<probability value = "0.3" />
<destinations>
<destination id = "0">
<delay min = "0" max = "100" />
<interval min = "1000" max = "1000"/>
<count min = "1" max = "1" />
<type value = "0" />
<task value = "3" />
</destination>
</destinations>
</possibility>-->
</generates>
</task>
<task id = "1">
<start min = "0" max = "0"/>
<duration min = "-1" max = "-1"/>
<repeat min = "1" max = "1"/>
<requires>
<requirement id = "0">
<type value = "0"/>
<source value = "0"/>
<count min = "1" max = "1" />
</requirement>
</requires>
<generates>
<possibility id = "0">
<probability value = "1" />
<destinations>
<destination id = "0">
<delay min = "0" max = "100" />
<interval min = "1000" max = "1000"/>
<count min = "1" max = "1" />
<type value = "0" />
<task value = "3" />
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id = "2">
<start min = "0" max = "0"/>
<duration min = "-1" max = "-1"/>
<repeat min = "1" max = "1"/>
<requires>
<requirement id = "0">
<type value = "2"/>
<source value = "0"/>
<count min = "1" max = "1" />
</requirement>
</requires>
<generates>
<possibility id = "0">
<probability value = "1" />
<destinations>
<destination id = "0">
<delay min = "0" max = "100" />
<interval min = "1000" max = "1000"/>
<count min = "1" max = "1" />
<type value = "0" />
<task value = "3" />
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id = "3">
<start min = "0" max = "0"/>
<duration min = "-1" max = "-1"/>
<repeat min = "1" max = "1"/>
<requires>
<requirement id = "0">
<type value = "0"/>
<count min = "1" max = "1" />
</requirement>
</requires>
<generates>
</generates>
</task>
</tasks>
</data>

View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<map xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<bind>
<task value = "0" />
<node value = "8" />
</bind>
<bind>
<task value = "1" />
<node value = "9" />
</bind>
<bind>
<task value = "2" />
<node value = "10" />
</bind>
<bind>
<task value = "3" />
<node value = "11" />
</bind>
<bind>
<task value = "4" />
<node value = "12" />
</bind>
<bind>
<task value = "5" />
<node value = "13" />
</bind>
<bind>
<task value = "6" />
<node value = "14" />
</bind>
<bind>
<task value = "7" />
<node value = "15" />
</bind>
</map>

File diff suppressed because it is too large Load diff

View file

@ -1,64 +0,0 @@
#pragma once
#include <systemc.h>
#include <tlm.h>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
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<unsigned char*>(&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<unsigned char*>(&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<unsigned char*>(&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<unsigned char*>(&data));
// set_data_length(sizeof(data));
// set_streaming_width(sizeof(data));
// }

View file

@ -1,35 +0,0 @@
#pragma once
#include <systemc.h>
#include <tlm.h>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
#include <queue>
#include <iostream>
#include <vector>
#include <string>
#include <iostream>
#include <cstdlib> // For rand()
#include <ctime> // For time()
#include "configuration.h"
// Initiator module (processor core)
SC_MODULE(core) {
tlm_utils::simple_initiator_socket<core> socket;
tlm_utils::simple_target_socket<core> 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);
};

View file

@ -1,124 +0,0 @@
// semaphore_manager.h
#ifndef SEMAPHORE_MANAGER_H
#define SEMAPHORE_MANAGER_H
#include <systemc>
#include <vector>
#include <queue>
#include <iostream>
#include <mutex>
#include <unordered_set>
#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<sc_mutex> 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<sc_mutex> 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<sc_mutex> 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<int> semaphore_owners; // Tracks router ownership (-1 means no owner)
std::vector<std::queue<int>> request_queues; // Queue of pending requests per semaphore
std::vector<bool> semaphore_status; // Semaphore availability
sc_mutex mutex; // Mutex to ensure atomic operations
std::vector<std::unordered_set<int>> 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

View file

@ -1,82 +0,0 @@
#include <systemc.h>
#include <tlm.h>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
#include <queue>
#include <iostream>
#include <vector>
#include <string>
#include <iostream>
#include <cstdlib> // For rand()
#include <ctime> // 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<sc_core::sc_semaphore*> router_sems;
std::vector<sc_core::sc_fifo<my_payload*>*> 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;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -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

1537
report.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -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<my_payload*>(&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());
}

61
src/main.cpp Normal file
View file

@ -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 <iostream>
#include <fstream>
#include <string>
#include "boost/program_options.hpp"
#include "ratatoskrUtils/utils/GlobalResources.h"
#include "networkManager/NetworkManager.h"
// #include <boost/bind/bind.hpp>
// 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<std::string>()->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<std::string>();
// start simulation
std::unique_ptr<NetworkManager> networkManager =
std::make_unique<NetworkManager>("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;
}

View file

@ -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 <iostream>
#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; i<flitsPerPacket; ++i) {
FlitType flitType;
if (flitsPerPacket==1)
flitType = SINGLE;
else if (i%flitsPerPacket==0)
flitType = HEAD;
else if (i%flitsPerPacket==flitsPerPacket-1)
flitType = TAIL;
else
flitType = BODY;
int seqNum = i%flitsPerPacket;
Flit* current_flit = new Flit(flitType, seqNum, p, p->dataType, 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<my_payload*>(&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<Flit*>(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());
}

View file

@ -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 <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
#include <queue>
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <ctime> // 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<NetworkInterfaceTlm> socket; //from core
tlm_utils::simple_target_socket<NetworkInterfaceTlm> target_socket; //from core
unsigned int source_router_id; //from core
unsigned int source_core_id; //from core
//typedef simple_initiator_socket_tagged<NetworkInterfaceTlm> ni_init_socket;
//typedef simple_target_socket_tagged<NetworkInterfaceTlm> ni_targ_socket;
std::queue<Packet*> packet_send_queue; //This is a queue where the network interface stores packets that need to be sent.
std::queue<Packet*> packet_recv_queue; //This is a queue for storing received packets, waiting to be processed.
std::string ni_name;
sc_in<bool> 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);
};

View file

@ -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<sc_clock>(
("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<TaskPool>();
} else if (globalResources.benchmark == "synthetic") {
tp = std::make_unique<SyntheticPool>();
} else {
FATAL("Please specify correct benchmark type");
}
#endif
// #ifdef ENABLE_NETRACE
// tp = std::make_unique<NetracePool>("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<PacketSignalContainer>(
("packetSigCon1_" + std::to_string(n.id) + "_" + std::to_string(j)).c_str());
auto sig2 = std::make_unique<PacketSignalContainer>(
("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<NetworkParticipant *>(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<PacketSignalContainer> sig1 =
// std::make_unique<PacketSignalContainer>(
// ("packetSigCon1_" + std::to_string(n.id)).c_str());
// std::unique_ptr<PacketSignalContainer> sig2 =
// std::make_unique<PacketSignalContainer>(
// ("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<NetworkParticipant *>(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<NetworkInterfaceTlm *>(
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());
}

View file

@ -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 <ratatoskrUtils/processingElement/ProcessingElementVC.h>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#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<std::unique_ptr<sc_clock>> clocks;
std::unique_ptr<TrafficPool> tp;
NocTlm* tlmNoc;
std::vector<NetworkParticipant*> networkParticipants;
std::vector<int> idNis;
std::vector<std::unique_ptr<PacketSignalContainer>> packetSignalContainers;
//std::vector<std::unique_ptr<Link>> 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);
};

130
src/noc/noc.cpp Normal file
View file

@ -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());
}

86
src/noc/noc.h Normal file
View file

@ -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 <systemc.h>
#include <tlm.h>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
#include <queue>
#include <iostream>
#include <vector>
#include <string>
#include <map>
#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<int, int> mapNodePERouter;
void initializeGlobalResources(std::string config_folder);
GlobalResources& globalResources = GlobalResources::getInstance();
router* routers[ROUTER_NO];
NetworkInterfaceTlm* cores[ROUTER_NO][CORE_NO];
std::vector<sc_core::sc_semaphore*> router_sems;
std::vector<sc_core::sc_fifo<my_payload*>*> 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

View file

@ -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<bool> sigValid;
sc_signal<std::vector<bool>*> sigFlowControl;
sc_signal<Flit*> sigData;
sc_signal<int> sigVc;
ClassicSignalContainer(sc_module_name nm)
:
SignalContainer(nm)
{
};
~ClassicSignalContainer()
{
};
};
class ClassicPortContainer : public PortContainer {
public:
sc_in<bool> portValidIn;
sc_in<std::vector<bool>*> portFlowControlIn;
sc_in<Flit*> portDataIn;
sc_in<int> portVcIn;
sc_out<bool> portValidOut;
sc_out<std::vector<bool>*> portFlowControlOut;
sc_out<Flit*> portDataOut;
sc_out<int> portVcOut;
ClassicPortContainer(sc_module_name nm)
:
PortContainer(nm)
{
};
~ClassicPortContainer()
{
};
void bind(SignalContainer* sIn, SignalContainer* sOut)
{
auto cscin = dynamic_cast<ClassicSignalContainer*>(sIn);
auto cscout = dynamic_cast<ClassicSignalContainer*>(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<ClassicSignalContainer*>(sIn);
assert(cscin);
portValidIn(cscin->sigValid);
portFlowControlIn(cscin->sigFlowControl);
portDataIn(cscin->sigData);
portVcIn(cscin->sigVc);
portValidOut(portOpen);
portFlowControlOut(portOpen);
portDataOut(portOpen);
portVcOut(portOpen);
}
};

View file

@ -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;
};

View file

@ -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<bool> sigValid;
sc_signal<bool> sigFlowControlValid;
sc_signal<Credit> sigFlowControl;
sc_signal<Flit*> sigData;
sc_signal<int> sigVc;
explicit FlitSignalContainer(const sc_module_name& nm)
:
SignalContainer(nm)
{
}
~FlitSignalContainer() override = default;
};
class FlitPortContainer : public PortContainer {
public:
sc_in<bool> portValidIn;
sc_in<bool> portFlowControlValidIn;
sc_in<Credit> portFlowControlIn;
sc_in<Flit*> portDataIn;
sc_in<int> portVcIn;
sc_out<bool> portValidOut;
sc_out<bool> portFlowControlValidOut;
sc_out<Credit> portFlowControlOut;
sc_out<Flit*> portDataOut;
sc_out<int> portVcOut;
explicit FlitPortContainer(const sc_module_name& nm)
:
PortContainer(nm)
{
}
~FlitPortContainer() override = default;
void bind(SignalContainer* sIn, SignalContainer* sOut) override
{
auto cscin = dynamic_cast<FlitSignalContainer*>(sIn);
auto cscout = dynamic_cast<FlitSignalContainer*>(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<FlitSignalContainer*>(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);
}
};

View file

@ -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<bool> sigValid;
sc_signal<bool> sigFlowControl;
sc_signal<Packet*> sigData;
explicit PacketSignalContainer(const sc_module_name& nm)
:
SignalContainer(nm)
{
};
~PacketSignalContainer() override = default;
};
class PacketPortContainer : public PortContainer {
public:
sc_in<bool> portValidIn;
sc_in<bool> portFlowControlIn;
sc_in<Packet*> portDataIn;
sc_out<bool> portValidOut;
sc_out<bool> portFlowControlOut;
sc_out<Packet*> portDataOut;
explicit PacketPortContainer(const sc_module_name& nm)
:
PortContainer(nm)
{
}
~PacketPortContainer() override = default;
void bind(SignalContainer* sIn, SignalContainer* sOut) override
{
auto cscin = dynamic_cast<PacketSignalContainer*>(sIn);
auto cscout = dynamic_cast<PacketSignalContainer*>(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<PacketSignalContainer*>(sIn);
assert(cscin);
portValidIn(cscin->sigValid);
portFlowControlIn(cscin->sigFlowControl);
portDataIn(cscin->sigData);
portValidOut(portOpen);
portFlowControlOut(portOpen);
portDataOut(portOpen);
}
};

View file

@ -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);
}

View file

@ -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 <iostream>
#include <fstream>
#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<bool> 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();
};

View file

@ -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 <set>
#include <ratatoskrUtils/utils/PacketFactory.h>
#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;
};

View file

@ -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);
}

View file

@ -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 <queue>
#include <algorithm>
#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;
};

View file

@ -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);
}

View file

@ -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 <queue>
#include <algorithm>
#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;
};

View file

@ -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 <ratatoskrUtils/processingElement/ProcessingElementVC.h>
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<int>(sc_time_stamp().value()/1000);
std::vector<DataDestination> 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)<timeStamp) {
removeList.push_back(dest);
}
}
// EXPLAIN: removing task
for (auto& dest : removeList) {
Task task = destToTask.at(dest);
destToTask.erase(dest);
taskToDest.erase(task);
taskRepeatLeft.erase(task);
taskStartTime.erase(task);
taskTerminationTime.erase(task);
countLeft.erase(dest);
destWait.erase(dest);
}
// EXPLAIN: loop through all destination that are waiting
for (auto const& pair : destWait) {
DataDestination dest = pair.first;
// EXPLAIN: check if the current time is smaller or equal to the time of the destination if yes generate packet
if (pair.second<=timeStamp) {
Task t = globalResources.tasks.at(dest.destinationTask);
Node dstNode = globalResources.nodes.at(t.nodeID);
Packet* p = packetFactory.createPacket(this->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 (timeStamp<task.minStart) {
nextCall = task.minStart+globalResources.getRandomIntBetween(0, minInterval-1);
}
else {
int numIntervalsPassed = (timeStamp-task.minStart)/minInterval;
int intervalBeginning = task.minStart+(numIntervalsPassed*minInterval);
nextCall = intervalBeginning+minInterval+globalResources.getRandomIntBetween(0, minInterval-1);
}
}
else { // if not synthetic, then execute the original behavior
nextCall = dw.second;
}
}
}
if (nextCall==0) { // limit packet rate
nextCall = 1;
}
if (nextCall!=-1) {
event.notify(nextCall-timeStamp, SC_NS);
}
wait(event);
}
#endif
#ifdef ENABLE_NETRACE
ntNetrace ntnetrace;
int flitsLastPacket= globalResources.flitsPerPacket;
float bytesPerFlit = (float) globalResources.bitWidth / 8.0f;
float bytesPerPacket = ((float) globalResources.flitsPerPacket - 1.0f) * bytesPerFlit; // -1.0f for header flit
nt_packet_t trace_packet;
Node dstNode;
//definition of the netrace mode, in which the PE forwards packets to the NIs. Packets are generated in the central NetracePool.
while(true){
if (globalResources.netraceNodeToTask.find(this->node.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; i<numOfPoss; ++i) {
if (task.possibilities.at(i).probability>rn) {
// EXPLAIN: A possibility is chosen. Set the destinations of this possibility as the dest of the task
std::vector<DataDestination> 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<int>((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<std::pair<Task, dataTypeID_t>> 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<Task, dataTypeID_t> 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;
}

View file

@ -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 <algorithm>
#include <queue>
#include <random>
#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 <ratatoskrUtils/container/PacketContainer.h>
#ifdef ENABLE_NETRACE
#include <ratatoskrUtils/traffic/netrace/NetracePool.h>
#endif
#include "ProcessingElement.h"
class ProcessingElementVC : public ProcessingElement {
public:
sc_event event;
PacketPortContainer* packetPortContainer;
std::map<dataTypeID_t, std::set<Task>> neededFor;
std::map<std::pair<Task, dataTypeID_t>, int> neededAmount;
std::map<Task, std::set<dataTypeID_t>> needs;
std::map<dataTypeID_t, int> receivedData;
std::map<DataDestination, Task> destToTask;
std::map<Task, std::set<DataDestination>> taskToDest;
std::map<Task, int> taskRepeatLeft;
std::map<Task, int> taskStartTime;
std::map<Task, int> taskTerminationTime;
std::map<DataDestination, int> countLeft;
std::map<DataDestination, int> destWait;
#ifdef ENABLE_NETRACE
std::queue<std::pair<queue_node_t, unsigned long long int>> ntInject;
std::queue<std::pair<queue_node_t, unsigned long long int>> 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();
};

View file

@ -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()
{
}

View file

@ -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 <string>
#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();
};

View file

@ -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();
}

View file

@ -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 <string>
#include <iosfwd>
#include <ostream>
#include <queue>
#include <set>
#include <vector>
#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<int> traversedRouters;
std::vector<flitID_t> toTransmit;
std::vector<flitID_t> inTransmit;
std::vector<flitID_t> transmitted;
std::vector<Flit*> 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();
};

View file

@ -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.
}

View file

@ -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<ProcessingElement*> processingElements;
TrafficPool();
~TrafficPool();
virtual void start() = 0;
virtual void clear(Task*) = 0;
};

View file

@ -0,0 +1 @@
testraces/*

View file

@ -0,0 +1,3 @@
add netrace source code here
http://www.cs.utexas.edu/~netrace/

View file

@ -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 <ratatoskrUtils/processingElement/ProcessingElementVC.h>
#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<int>(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);
}
}

View file

@ -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();
};

View file

@ -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 <iostream>
#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"<<std::endl;
}
}
nt_header_t* ntNetrace::nt_read_trheader() {
#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 char pad;
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[8];
};
#pragma pack(pop)
int err = 0;
char strerr[180];
// Read Header
struct nt_header_pack* in_header = (nt_header_pack*) malloc( sizeof(struct nt_header_pack) );
fseek( nt_input_tracefile, 0, SEEK_SET );
if( (err = fread( in_header, sizeof(struct nt_header_pack), 1, nt_input_tracefile )) < 0 ) {
sprintf( strerr, "failed to read trace file header: err = %d", err );
std::cout << strerr << std::endl;
}
// Copy data from struct to header
nt_header_t* to_return = (nt_header_t*) malloc( sizeof(nt_header_t) );
memset( to_return, 0, sizeof(nt_header_t) );
to_return->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 <<std::endl;
}
// Read Rest of Header
if( to_return->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 <<strerr << std::endl;
}
} else {
to_return->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" <<std::endl;
}
} else {
std::cout << "must open trace file with nt_open_trfile before seeking" << std::endl;
}
}
nt_packet_t* ntNetrace::nt_read_packet( void ) {
#pragma pack(push,1)
struct nt_packet_pack {
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;
};
#pragma pack(pop)
int err = 0;
unsigned int i;
char strerr[180];
nt_packet_t* to_return = NULL;
if( nt_input_tracefile != NULL ) {
to_return = nt_packet_malloc();
if( (err = fread( to_return, 1, sizeof(struct nt_packet_pack), nt_input_tracefile )) < 0 ) {
sprintf(strerr, "failed to read packet: err = %d", err);
std::cout << strerr << std::endl;
}
if( err > 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" <<std::endl;
}
return NULL;
}
void ntNetrace::nt_read_ahead( unsigned long long int current_cycle ) {
unsigned long long int read_to_cycle = current_cycle + NT_READ_AHEAD;
if( read_to_cycle < current_cycle ) {
std::cout << "trying to read too far ahead... overflowed :(" <<std::endl;
}
if( read_to_cycle > 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" <<std::endl;
}
return NULL;
}
nt_dep_ref_node_t* ntNetrace::nt_get_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;
for( dep_ptr = nt_dependency_array[index]; dep_ptr != NULL; dep_ptr = dep_ptr->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" <<std::endl;
}
return NULL;
}
float ntNetrace::nt_get_trversion() {
if( nt_input_tracefile != NULL ) {
return nt_input_trheader->version;
} else {
std::cout << "must open trace file with nt_open_trfile before version is available" <<std::endl;
}
return 0.0f;
}
nt_packet_t* ntNetrace::nt_packet_malloc() {
// Allocate large array (1+ pages) to reduce # system calls
return (nt_packet_t*) malloc( sizeof(nt_packet_t) );
}
nt_dependency_t* ntNetrace::nt_dependency_malloc( unsigned char num_deps ) {
// Allocate large array (1+ pages) to reduce # system calls
return (nt_dependency_t*) malloc( num_deps * sizeof(nt_dependency_t) );
}
int ntNetrace::nt_get_src_type( nt_packet_t* packet ) {
return (int) ( packet->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" <<std::endl;
}
return -1;
}
void* ntNetrace::_nt_checked_malloc( size_t n, char* file, int line ) {
void* ptr;
ptr = malloc( n );
if( ptr == NULL ) {
fprintf( stderr, "ERROR: bad allocation at %s:%d\n", file, line );
exit(0);
}
return ptr;
}
int ntNetrace::nt_little_endian() {
int to_return = 1;
union {
int number;
char bytes[sizeof(int)];
} u;
unsigned int i;
u.number = (int)0;
for( i = 0; i < sizeof(int); i++ ) {
u.number |= (int)(i + 1) << (8 * i);
}
for( i = 0; i < sizeof(int); i++ ) {
if( (unsigned int)u.bytes[i] != i+1 ) {
to_return = 0;
break;
}
}
return to_return;
}
void ntNetrace::_nt_error( const char* str, char* file, int line ) {
#ifdef DEBUG_ON
fprintf( stderr, "WARNING: In %s:%d: %s\n", file, line, str );
#else
fprintf( stderr, "ERROR: In %s:%d: %s\n", file, line, str );
exit(0);
#endif
}
// Backend functions for creating trace files
void ntNetrace::nt_dump_header( nt_header_t* header, FILE* fp ) {
#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 char pad;
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[8];
};
#pragma pack(pop)
if( header != NULL ) {
struct nt_header_pack* out_header = (nt_header_pack*) malloc( sizeof(struct nt_header_pack) );
out_header->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" <<std::endl;
}
}
void ntNetrace::nt_dump_packet( nt_packet_t* packet, FILE* fp ) {
#pragma pack(push,1)
struct nt_read_pack {
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;
};
#pragma pack(pop)
if( packet != NULL ) {
fwrite( packet, sizeof(struct nt_read_pack), 1, fp );
fwrite( packet->deps, sizeof(nt_dependency_t), packet->num_deps, fp );
} else {
std::cout << "dumping NULL packet" <<std::endl;
}
}

View file

@ -0,0 +1,195 @@
/*
* 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
*/
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#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<std::string> 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<int> 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<std::string> 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* );
};

View file

@ -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 <iostream>
#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;
}
}
}
}

View file

@ -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<queue_node_type, unsigned long long int>(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* );
};

View file

@ -0,0 +1,38 @@
#include <utility>
/*******************************************************************************
* 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 <string>
#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);
}
};

View file

@ -0,0 +1,309 @@
#include <random>
/*******************************************************************************
* 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<int, int> 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<const int, int> con : srcToDst) {
DataType* dataType = new DataType(dataTypeId, std::to_string(dataTypeId));
++dataTypeId;
std::vector<DataDestination*> 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<std::pair<float, std::vector<DataDestination*>>> 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<int, int>
SyntheticPool::uniform(taskID_t& taskId, int& phaseId,
dataDestID_t& dataDestId, int maxClockDelay, const SyntheticPhase& sp)
{
int numOfPEs = processingElements.size();
for (unsigned int i = 0; i<numOfPEs; ++i) {
Task task = Task(taskId, processingElements.at(i)->node.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<int>(std::floor((float) maxClockDelay/sp.injectionRate));
int maxInterval = static_cast<int>(std::floor((float) maxClockDelay/sp.injectionRate));
if (sp.minRepeat==-1 && sp.maxRepeat==-1) {
task.minRepeat = static_cast<int>(std::floor(
(float) (task.minDuration-task.minStart)/(float) minInterval));
task.maxRepeat = static_cast<int>(std::floor(
(float) (task.maxDuration-task.minStart)/(float) maxInterval));
}
else {
task.minRepeat = sp.minRepeat;
task.maxRepeat = sp.maxRepeat;
}
std::vector<DataSendPossibility> 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; j<numOfPEs; ++j) {
if (i!=j) { // a PE should not send data to itself.
Node n = processingElements.at(j)->node;
int minInterval = std::floor((float) maxClockDelay/sp.injectionRate);
int maxInterval = std::floor((float) maxClockDelay/sp.injectionRate);
std::vector<DataDestination> 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<int, int>();
}
std::map<int, int> SyntheticPool::bitComplement()
{
std::map<int, int> srcToDst{};
int numOfPEs = processingElements.size();
for (int i = 0; i<numOfPEs; ++i) {
srcToDst[i] = numOfPEs-i-1;
}
return srcToDst;
}
std::map<int, int> SyntheticPool::transpose()
{
std::map<int, int> srcToDst{};
int numOfPEs = processingElements.size();
for (int i = 0; i<numOfPEs; ++i) {
srcToDst[i] = (i << int(ceil(log2(numOfPEs)/2)))%(numOfPEs-1);
}
return srcToDst;
}
std::map<int, int> SyntheticPool::tornado()
{
std::map<int, int> srcToDst{};
std::vector<float>* xPos = &globalResources.xPositions;
std::vector<float>* yPos = &globalResources.yPositions;
std::vector<float>* zPos = &globalResources.zPositions;
int numOfPEs = processingElements.size();
for (int i = 0; i<numOfPEs; ++i) {
Vec3D<float> srcPos = processingElements.at(i)->node.pos;
Vec3D<float> 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<Node*> 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<int, int> 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<int, int> srcToDst{};
for (int i = 0; i<numOfPEs; ++i) {
srcToDst[i] = hotSpot;
}
return srcToDst;*/
int numOfPEs = processingElements.size();
nodeID_t hotspot = globalResources.syntheticPhases.at(phaseId).hotspot;
if (hotspot == -1)
hotspot = globalResources.getRandomIntBetween(0, numOfPEs - 1);
for (unsigned int i = 0; i<numOfPEs; ++i) {
Task task = Task(taskId, processingElements.at(i)->node.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<int>(std::floor((float) maxClockDelay/sp.injectionRate));
int maxInterval = static_cast<int>(std::floor((float) maxClockDelay/sp.injectionRate));
if (sp.minRepeat==-1 && sp.maxRepeat==-1) {
task.minRepeat = static_cast<int>(std::floor(
(float) (task.minDuration-task.minStart)/(float) minInterval));
task.maxRepeat = static_cast<int>(std::floor(
(float) (task.maxDuration-task.minStart)/(float) maxInterval));
}
else {
task.minRepeat = sp.minRepeat;
task.maxRepeat = sp.maxRepeat;
}
std::vector<DataSendPossibility> 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<DataDestination> 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<int, int>();
}
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<Task> phaseTasks(start, end);
std::shuffle(phaseTasks.begin(), phaseTasks.end(), *globalResources.rand);
for (Task& task : phaseTasks) {
processingElements.at(task.nodeID%numOfPEs)->execute(task);
}
}
SyntheticPool::~SyntheticPool()
{
}

View file

@ -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<int, int>
uniform(taskID_t& taskId, int& phaseId, dataDestID_t& dataDestId, int maxClockDelay,
const SyntheticPhase& sp);
std::map<int, int> transpose();
std::map<int, int> tornado();
std::map<int, int> hotSpot(taskID_t& taskId, int& phaseId, dataDestID_t& dataDestId, int maxClockDelay,
const SyntheticPhase& sp);
std::map<int, int> bitComplement();
};

View file

@ -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 <string>
#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)
{
}
};

View file

@ -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 <ratatoskrUtils/traffic/task/TaskPool.h>
#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*)
{
}

View file

@ -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 <ratatoskrUtils/traffic/task/TaskPacket.h>
#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;
};

View file

@ -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 <cstdlib>
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<globalResources.numberOfTrafficTypes; ++var) {
stream << boost::format("%7iD%6iID")%var%var;
}
stream << boost::format("\n");
for (auto matrixelement : transmissionMatrix) {
float field = (float) matrixelement/(float) clockCyclesOfLink;
if (colit==0) {
if (rowit==0) {
stream << boost::format("IDLE\t");
}
else if (rowit==1) {
stream << boost::format("HEAD\t");
}
else if (rowit==2) {
stream << boost::format("HID\t");
}
else if (rowit%2==0) {
int trafficType = (rowit-3)/2;
stream << boost::format("%iID\t")%trafficType;
}
else if (rowit%2==1) {
int trafficType = (rowit-3)/2;
stream << boost::format("%iD\t")%trafficType;
}
++rowit;
stream << boost::format("[%7.4f, ")%field;
}
else if (colit==linkTransmissionsMatrixNumberOfStates-1) {
stream << boost::format("%7.4f ]\n")%field;
}
else {
stream << boost::format("%7.4f,")%field;
}
++colit;
if (colit==linkTransmissionsMatrixNumberOfStates) {
colit = 0;
}
}
}
void GlobalReport::reportLinkMatrices(ostream& stream)
{
auto numberOfLinks = linkTransmissionMatrices.size();
for (unsigned int var = 0; var<numberOfLinks; ++var) {
reportLinkMatrix(var, stream);
}
}
void GlobalReport::reportLinkMatricesCSV(ostream& stream)
{
int numberOfElements = static_cast<int>(pow(linkTransmissionsMatrixNumberOfStates, 2));
stream << boost::format("link_id");
for (int var = 0; var<numberOfElements-1; ++var) {
stream << boost::format(", %i")%var;
}
stream << boost::format(", %i\n")%(numberOfElements-1);
for (auto matrix : linkTransmissionMatrices) {
stream << boost::format("%i, ")%matrix.first;
for (auto it = matrix.second.begin(); it!=matrix.second.end(); ++it) {
int value = static_cast<int>(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<newLatency) {
maxNetworkLatency = newLatency;
}
}
void GlobalReport::reportMaxNetworkLatencySystemLevel()
{
cout << "The maximum network latency was: " << maxNetworkLatency << endl;
}
void GlobalReport::updateVCUsageHist(int routerId, int dir, int numOfActiveVCs)
{
int counter = VCsUsageHist.at(routerId).at(dir).at(numOfActiveVCs);
VCsUsageHist[routerId][dir][numOfActiveVCs] = ++counter;
}
void GlobalReport::reportVCUsageHist(std::string& csvFileName, int routerId)
{
ofstream csvFile;
csvFile.open(csvFileName);
int firstDim = VCsUsageHist[routerId].size();
for (unsigned int dir = 0; dir<firstDim; ++dir) {
csvFile << DIR::toString(dir) << ",";
int secondDim = VCsUsageHist[routerId][dir].size();
for (unsigned int value = 0; value<secondDim; ++value) {
if (value<secondDim-1)
csvFile << VCsUsageHist[routerId][dir][value] << ",";
else
csvFile << VCsUsageHist[routerId][dir][value] << "\n";
}
}
csvFile.close();
}
void GlobalReport::updateBuffUsagePerVCHist(int routerId, int dir, int vc, int bufferOccupation)
{
long counter = bufferUsagePerVCHist.at(routerId).at(dir).at(vc).at(bufferOccupation);
bufferUsagePerVCHist[routerId][dir][vc][bufferOccupation] = ++counter;
}
void GlobalReport::reportBuffPerVCUsageHist(std::string& csvFileName, int routerId, int dir)
{
ofstream csvFile;
csvFile.open(csvFileName);
// Write the header
csvFile << "Buffer\\VC,";
int secondDim = bufferUsagePerVCHist[routerId][dir].size();
for (unsigned int vc = 0; vc<secondDim; ++vc) { // foreach vc
csvFile << vc;
if (vc<secondDim-1)
csvFile << ",";
else
csvFile << "\n";
}
// Write the matrix
for (unsigned int buffer = 1; buffer<=MAX_BUFFER_DEPTH; ++buffer) { // foreach buffer
for (unsigned int column = 0; column<=secondDim; ++column) { // foreach column
if (column==0)
csvFile << buffer << ", ";
else {
csvFile << bufferUsagePerVCHist[routerId][dir][column-1][buffer];
if (column<secondDim)
csvFile << ",";
else
csvFile << "\n";
}
}
}
csvFile.close();
}
void GlobalReport::reportAllRoutersUsageHist()
{
std::vector<int> routers_ids{};
if (!bufferReportRouters.empty()) {
routers_ids = bufferReportRouters;
}
else {
int num_nodes = globalResources.nodes.size();
for (unsigned int i = 0; i<num_nodes; ++i) {
if (globalResources.nodes[i].type->model=="RouterVC") {
routers_ids.push_back(i);
}
}
}
int numSimulatedRouters = static_cast<unsigned int>(globalResources.nodes.size()/2);
int num_routers = routers_ids.size();
for (unsigned int i = 0; i<num_routers; ++i) {
int router_id = routers_ids[i];
if (router_id < numSimulatedRouters) {
std::string csvFileName;
int isFolderCreated = system(std::string("mkdir -p " + globalResources.outputDirectory + "/VCUsage/").c_str());
if (isFolderCreated!=0) {
std::cerr << "VCUsage folder was not created!" << std::endl;
std::exit(EXIT_FAILURE);
}
csvFileName = globalResources.outputDirectory + "/VCUsage/"+std::to_string(router_id)+".csv";
reportVCUsageHist(csvFileName, router_id);
isFolderCreated = system(std::string("mkdir -p " + globalResources.outputDirectory + "/BuffUsage/").c_str());
if (isFolderCreated!=0) {
std::cerr << "VCUsage folder was not created!" << std::endl;
std::exit(EXIT_FAILURE);
}
if (!bufferUsagePerVCHist.at(router_id).empty()) {
int nodeConnsSize = globalResources.nodes[router_id].connections.size();
for (unsigned int conPos = 0; conPos<nodeConnsSize; ++conPos) {
int dir_int = globalResources.nodes[router_id].getDirOfConPos(conPos);
std::string dir_str = DIR::toString(globalResources.nodes[router_id].getDirOfConPos(conPos));
boost::trim(dir_str);
csvFileName = globalResources.outputDirectory + "/BuffUsage/" + std::to_string(router_id) + "_" + dir_str + ".csv";
reportBuffPerVCUsageHist(csvFileName, router_id, dir_int);
}
}
} else {
cout << endl << "Warning: You configured that router with id " << router_id << " is to be reported, but that router does not exist." << endl;
cout << " Router ignored. Please update config/config.xml, <bufferReportRouters>" << 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<unsigned int>(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<numOfLinks; ++link_id) {
int numberElements = static_cast<int>(pow(linkTransmissionsMatrixNumberOfStates, 2));
std::vector<long> 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; i<numOfClocks; ++i) {
stream << std::fixed << (clockCounts.at(i));
if (i<clockCounts.size()-1)
stream << ", ";
else
stream << "]\n";
}
}
void GlobalReport::increaseClockCount(int layer)
{
this->clockCounts.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<buffer_router_push_pwr_d.size(); ++id) {
csvfile << id << "," << buffer_router_push_pwr_d.at(id) << "," << buffer_router_pop_pwr_d.at(id)
<< "," << buffer_router_front_pwr_d.at(id) << "," << routing_pwr_d.at(id) << ","
<< crossbar_pwr_d.at(id) << "\n";
}
}
void GlobalReport::issueNoCInputDataAmount(sc_time time, int dataAmount){
auto node = noCInputDataAmount.extract(time);
if (!node.empty()) {
node.mapped() = node.mapped() + dataAmount;
noCInputDataAmount.insert(std::move(node));
} else {
noCInputDataAmount.insert(std::move(std::make_pair(time, dataAmount)));
}
};
void GlobalReport::issueNoCOutputDataAmount(sc_time time, int dataAmount){
auto node = noCOutputDataAmount.extract(time);
if (!node.empty()) {
node.mapped() = node.mapped() + dataAmount;
noCOutputDataAmount.insert(std::move(node));
} else {
noCOutputDataAmount.insert(std::move(std::make_pair(time, dataAmount)));
}
};
void GlobalReport::reportNoCBandwidthInput(ostream& csvfile) {
csvfile << boost::format("time, bits\n");
double binSize = 500.0;
double binStart = 0.0;
int bitsInBin = 0;
Statistics averageInputBandwidth("InputBandwidth");
for( auto const& [key, val] : noCInputDataAmount )
{
csvfile << boost::format("%i, %i\n") % key.to_double() % val;
if (key.to_double()/1000.0 < binStart + binSize){
bitsInBin += val;
} else{
averageInputBandwidth.sample((float) bitsInBin / binSize * 1000); // bit/Nanosec to Mbit/sec
binStart += binSize;
bitsInBin = val;
}
}
cout << "Average Input Bandwidth " << averageInputBandwidth.average() << " Mb/sec" << endl;
};
void GlobalReport::reportNoCBandwidthOutput(ostream& csvfile) {
csvfile << boost::format("time, bits\n");
double binSize = 500.0;
double binStart = 0.0;
int bitsInBin = 0;
Statistics averageOutputBandwidth("OutputBandwidth");
binStart = 0;
bitsInBin = 0;
for( auto const& [key, val] : noCOutputDataAmount )
{
csvfile << boost::format("%i, %i\n")%key.to_double()%val;
if (key.to_double()/1000.0 < binStart + binSize){
bitsInBin += val;
} else{
averageOutputBandwidth.sample((float) bitsInBin / binSize * 1000); // bit/Nanosec to Mbit/sec
binStart += binSize;
bitsInBin = val;
}
}
cout << "Average Output Bandwidth " << averageOutputBandwidth.average() << " Mb/sec" << endl;
};

View file

@ -0,0 +1,220 @@
/*******************************************************************************
* 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 <map>
#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>
#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<int, std::vector<long> > linkTransmissionMatrices;
int linkTransmissionsMatrixNumberOfStates;
//Router state vectors and matrices
std::map<int, int> 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<std::vector<std::vector<long>>> 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<std::vector<std::vector<std::vector<long>>>> 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<int> 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<double> buffer_router_push_pwr_d; // per flit pushed on buffer
std::vector<double> buffer_router_pop_pwr_d; // per flit popped of buffer (not for lookup)
std::vector<double> buffer_router_front_pwr_d; // per flit data received from buffer (only count if flit exists)
std::vector<double> buffer_router_pwr_s; // leakage per router cycle per buffer
//Power consumption of routing Algorithm (determined by routing algorithm)
std::vector<double> routing_pwr_d; //per routing function called
std::vector<double> 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<double> crossbar_pwr_d; // per sent flit
std::vector<double> crossbar_pwr_s; // Leakage per Router Cycle
//Power consumption of Network Interface (determined by flit size)
std::vector<double> ni_pwr_d; // per local flit sent or received
std::vector<double> 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<long long> clockCounts;
//Bandwidth measurement
std::map<sc_time, int> noCInputDataAmount;
std::map<sc_time, int> noCOutputDataAmount;
GlobalReport();
};

View file

@ -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 <iostream>
#include <iomanip>
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<int> dis(min, max);
return dis(*rand);
}
float GlobalResources::getRandomFloatBetween(float min, float max)
{
std::uniform_real_distribution<float> 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<std::string> GlobalResources::string_split(const std::string &str, const std::string &delim)
{
std::vector<std::string> 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<unsigned int>(end + 1);
end = str.find(delim, start);
}
strings.push_back(str.substr(start, end));
return strings;
}
std::vector<int> GlobalResources::strs_to_ints(const std::vector<std::string> &strings)
{
std::vector<int> 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<int> 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>({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<int> temp_xs;
std::vector<int> 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<nodeID_t, int>(i + node_count, i));
netraceTaskToNode.insert(std::pair<nodeID_t, int>(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<NodeType>(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> nodeType = nodeTypes.at(nodeTypeID);
int layer = xmlnode.child("layer").attribute("value").as_int();
nodes.emplace_back(nodeID, Vec3D<float>(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<float> 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<std::vector<int>> 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<int> 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<float> 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<nodeID_t> nodesOfConnection{};
std::vector<int> vcsCount{};
std::vector<int> buffersDepth{};
std::vector<std::vector<int>> 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<std::string> strings = string_split(str_vec, ",");
if (strings.size() != vcCount)
{
FATAL("The buffersDepths size is not equal to vcCount!");
}
std::vector<int> 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<taskID_t, nodeID_t> bindings = readMappingFile(mappingFilePath);
readTaskFile(taskFilePath, bindings);
}
std::map<taskID_t, nodeID_t> 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<taskID_t, nodeID_t> 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<int, int> &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<int>(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<DataRequirement> 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<DataSendPossibility> 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<DataDestination> 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<Node *> GlobalResources::getNodesByPos(const Vec3D<float> &pos)
{
std::vector<Node *> matching_nodes{};
for (auto &node : nodes)
if (node.getNodeByPos(pos))
{
matching_nodes.push_back(&node);
}
return matching_nodes;
}
GlobalResources::~GlobalResources()
{
delete rand;
}

View file

@ -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 <string>
#include <vector>
#include <set>
#include <map>
#include <unistd.h>
#include <random>
#include <sys/stat.h>
#include "Structures.h"
#include "pugixml.hpp"
// my includes
#include <cmath>
#include <list>
#include <fstream>
#include <sstream>
#include <iostream>
class GlobalResources
{
public:
std::vector<float> xPositions;
std::vector<float> yPositions;
std::vector<float> 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<std::vector<int>> 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<nodeID_t, int> netraceNodeToTask;
std::map<int, nodeID_t> 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<std::shared_ptr<NodeType>> nodeTypes;
std::vector<Node> nodes;
std::vector<Connection> connections;
std::vector<Task> tasks;
std::vector<DataType> dataTypes;
std::vector<SyntheticPhase> 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<Node *> getNodesByPos(const Vec3D<float> &pos);
private:
GlobalResources();
~GlobalResources();
std::vector<std::string> string_split(const std::string &str, const std::string &delim);
std::vector<int> strs_to_ints(const std::vector<std::string> &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<int, int> &bindings);
std::map<int, int> 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();
};

View file

@ -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;
}
}

View file

@ -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 <vector>
#include <ratatoskrUtils/traffic/Packet.h>
class PacketFactory {
public:
std::vector<Packet*> 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() {}
};

View file

@ -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;
}
}

View file

@ -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 <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <cerrno>
#include <fstream>
#include <iostream>
#include <iomanip>
#include "systemc.h"
#define MAX_BUFFER_SIZE 1000 //Max Buffer Size in Bytes
#define LOG(x, y) { if(x) {std::ostringstream oss; oss<<y; Report::getInstance().log(x,oss.str());}}
#define FATAL(x) { LOG(true,x); std::cout<<"Terminating"<<std::endl; Report::getInstance().close(); exit(EXIT_FAILURE);}
enum Logtype {
COUT = 1 << 0,
CERR = 1 << 1,
LOGFILE = 1 << 2,
DB = 1 << 3
};
class Report {
public:
static Report& getInstance()
{
static Report instance;
return instance;
}
void connect(const std::string& server, const std::string& port);
void startRun(const std::string& name);
int registerElement(const std::string& type, int id);
void reportEvent(int element_id, const std::string& event, const std::string& data);
void reportAttribute(int element_id, const std::string& name, const std::string& value);
void log(bool qualifier, const std::string& message, int type = COUT | DB);
void close();
private:
bool networkDisabled = true;
int socketfd = 0;
int element_count = 0;
std::ofstream logfile;
bool logfileOpened = false;
std::string sendBuffer;
int dbid = 0;
Report();
void addToSendBuffer(const std::string& str);
void send();
};

View file

@ -0,0 +1,73 @@
/*******************************************************************************
* 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 "Statistics.h"
Statistics::Statistics(const std::string& name)
{
sampleSum = 0.0f;
sampleSize = 0;
sampleMin = std::numeric_limits<float>::max();
sampleMax = std::numeric_limits<float>::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;
}

View file

@ -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 <systemc.h>
#include <boost/format.hpp>
#include <limits.h>
#include <ostream>
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;
};

View file

@ -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::TYPE> 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 conPos<c.conPos;
}
else if (vc!=c.vc) {
return vc<c.vc;
}
return false;
}
bool Channel::operator==(const Channel& a) const
{
return this->conPos==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<float> pos, const std::shared_ptr<NodeType>& 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<float>& 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<DIR::TYPE, int> 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<nodeID_t>& nodes, const std::vector<int>& vcsCount,
const std::vector<int>& buffersDepth,
const std::vector<std::vector<int>>& 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<dt.id;
}
DataSendPossibility::DataSendPossibility(possID_t id, float probability,
const std::vector<DataDestination>& 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<DataRequirement>& requirements,
const std::vector<DataSendPossibility>& 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->id<t.id;
}
SyntheticPhase::SyntheticPhase(synthID_t id, const std::string& name, const std::string& distribution,
float injectionRate)
:
id(id),
name(name),
distribution(distribution),
injectionRate(injectionRate),
minStart(0),
maxStart(0),
minDuration(-1),
maxDuration(-1),
minRepeat(-1),
maxRepeat(-1),
minCount(-1),
maxCount(-1),
minDelay(0),
maxDelay(0),
hotspot(-1)
{
}
int Credit::idcnt = 0;
Credit::Credit(int vc)
:vc(vc)
{
id = (idcnt++)%INT_MAX;
}
bool Credit::operator==(const Credit& credit) const
{
return this->id==credit.id;
}
Credit& Credit::operator=(const Credit& credit)
{
if (this==&credit)
return *this;
this->id = credit.id;
this->vc = credit.vc;
return *this;
}

View file

@ -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 <vector>
#include <string>
#include <sstream>
#include <map>
#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<TYPE> XYZ;
static TYPE toDir(int a)
{
return static_cast<TYPE>(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<typename T>
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<T> v) const
{
return fabs(x)<fabs(v.x) ||
(fabs(x)==fabs(v.x) && (fabs(y)<fabs(v.y) || (fabs(y)==fabs(v.y) && fabs(z)<fabs(v.z))));
}
Vec3D<T> operator+(const Vec3D<T> v) const
{
return Vec3D<T>(x+v.x, y+v.y, z+v.z);
}
Vec3D<T> operator-(const Vec3D<T> v) const
{
return Vec3D<T>(x-v.x, y-v.y, z-v.z);
}
Vec3D<T> abs() const
{
return Vec3D<T>(fabs(this->x), fabs(this->y), fabs(this->z));
}
double norm() const
{
return ((x*x)+(y*y)+(z*z));
}
double distance(const Vec3D<T> 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<T> v) const
{
double disx = fabs(x-v.x);
double disy = fabs(y-v.y);
return sqrt((disx*disx)+(disy*disy));
}
bool operator==(const Vec3D<T> v) const
{
return ((x==v.x) && (y==v.y) && (z==v.z));
}
int sameDimCount(const Vec3D<T> 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<T> 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<T>& 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<Node*> 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<float> pos;
std::shared_ptr<NodeType> type;
float congestion; // crossbar utilization 0-1
std::vector<nodeID_t> connectedNodes;
std::vector<connID_t> connections;
int layer;
/* int idType; TODO restructure
LayerType* layer;
std::map<Node *, std::vector<int>> connectionsToNode; //get connection by connected node
std::map<connID_t, int> conToPos; // get position of connection inside array
*/
Node(nodeID_t id, Vec3D<float> pos, const std::shared_ptr<NodeType>& 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<float>& pos);
void checkValid();
private:
std::map<DIR::TYPE, int> conPosOfDir; //maps direction names to connection position inside this node's connections
std::map<int, DIR::TYPE> dirOfConPos; //maps connection position (inside this node's connections) to direction name
};
struct Connection {
connID_t id;
std::vector<nodeID_t> nodes;
std::vector<int> vcsCount; // vc count for each end.
std::vector<int> buffersDepth; // one buffer depth for all ends of a connection.
std::vector<std::vector<int>> buffersDepths; // one buffer depth per end.
float length;
int width;
int depth;
std::vector<int> bufferUtilization;
Connection(connID_t id, const std::vector<nodeID_t>& nodes, const std::vector<int>& vcsCount,
const std::vector<int>& buffersDepth,
const std::vector<std::vector<int>>& 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<DataDestination> dataDestinations;
DataSendPossibility(possID_t id, float probability, const std::vector<DataDestination>& dataDestinations);
};
class Task {
public:
taskID_t id;
nodeID_t nodeID;
std::vector<DataRequirement> requirements;
std::vector<DataSendPossibility> 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<DataRequirement>& requirements,
const std::vector<DataSendPossibility>& 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) { };
};

View file

@ -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);
}

View file

@ -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 <boost/format.hpp>
#include "GlobalResources.h"
#include <ratatoskrUtils/traffic/Packet.h>
class TrafficTracer{
public:
static TrafficTracer& getInstance()
{
static TrafficTracer instance;
return instance;
}
void traceFlit(Flit *flit);
private:
GlobalResources& globalResources = GlobalResources::getInstance();
TrafficTracer();
ofstream tracefile;
};

View file

@ -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<typename T>
sc_core::sc_signal_in_if<T> 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<T>(sc_core::sc_gen_unique_name("portConst"));
sig_p->write(v);
return *sig_p;
}
static struct {
template<typename T>
operator sc_core::sc_signal_inout_if<T>&() const
{
return *(new sc_core::sc_signal<T>(sc_core::sc_gen_unique_name("portOpen")));
}
} const portOpen = {};

View file

@ -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<my_payload*>(&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;
}

View file

@ -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 <systemc.h>
@ -13,8 +34,8 @@
#include <cstdlib> // For rand()
#include <ctime> // 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)

73
src/utils/configuration.h Normal file
View file

@ -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 <systemc.h>
#include <tlm.h>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
#include "ratatoskrUtils/utils/Structures.h"
#include <ratatoskrUtils/utils/TrafficTracer.h>
#include <ratatoskrUtils/utils/GlobalResources.h>
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<unsigned char*>(&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<unsigned char*>(&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;
}
};

View file

@ -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;
}

View file

@ -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;
};

96
src/utils/noc_logger.cpp Normal file
View file

@ -0,0 +1,96 @@
#include "noc_logger.h"
#include <iostream>
#include <fstream>
#include <sstream>
#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 <<endl;
}

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