feat: project init-tlm and ratatoskr

This commit is contained in:
Retrocamara42 2024-10-01 04:57:16 -05:00
commit 84d706788d
85 changed files with 17729 additions and 0 deletions

3
.gitignore vendored Normal file
View file

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

54
CMakeLists.txt Executable file
View file

@ -0,0 +1,54 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(sim)
SET(CMAKE_PREFIX_PATH /usr/local/systemc-2.3.3/)
set(CMAKE_CXX_STANDARD 17)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -pthread")
set(CMAKE_BUILD_TYPE Release)
INCLUDE_DIRECTORIES(${CMAKE_PREFIX_PATH}/include)
INCLUDE_DIRECTORIES(./src)
FIND_LIBRARY(systemc systemc ${CMAKE_PREFIX_PATH}/lib-linux64)
LINK_DIRECTORIES(${CMAKE_PREFIX_PATH}/lib-linux64)
ADD_DEFINITIONS(-D SC_INCLUDE_DYNAMIC_PROCESSES -D SYSTEMC_DISABLE_COPYRIGHT_MESSAGE -D ENABLE_BUFFER_VC_STATS -D SC_DISABLE_API_VERSION_CHECK)
ADD_EXECUTABLE(${PROJECT_NAME}
src/main.cpp
src/networkInterface/NetworkInterfaceTlm.cpp
src/networkManager/NetworkManager.cpp
src/noc/noc.cpp
src/router/router.cpp
src/utils/memory_manager.cpp
src/utils/utils.cpp
src/utils/noc_logger.cpp
src/ratatoskrUtils/utils/Report.cpp
src/ratatoskrUtils/utils/GlobalReport.cpp
src/ratatoskrUtils/utils/Structures.cpp
src/ratatoskrUtils/utils/PacketFactory.cpp
src/ratatoskrUtils/utils/GlobalResources.cpp
src/ratatoskrUtils/utils/Statistics.cpp
src/ratatoskrUtils/processingElement/ProcessingElement.cpp
src/ratatoskrUtils/processingElement/ProcessingElementVC.cpp
src/ratatoskrUtils/networkInterface/NetworkInterface.cpp
src/ratatoskrUtils/traffic/Packet.cpp
src/ratatoskrUtils/traffic/Flit.cpp
src/ratatoskrUtils/traffic/synthetic/SyntheticPool.cpp
src/ratatoskrUtils/traffic/task/TaskPool.cpp
src/ratatoskrUtils/traffic/TrafficPool.cpp
src/ratatoskrUtils/link/Link.cpp
src/ratatoskrUtils/traffic/netrace/NetracePool.cpp
src/ratatoskrUtils/traffic/netrace/NetracePool.h
src/ratatoskrUtils/traffic/netrace/ntNetrace.h
src/ratatoskrUtils/traffic/netrace/ntNetrace.cpp
src/ratatoskrUtils/traffic/netrace/ntQueue.h
src/ratatoskrUtils/traffic/netrace/ntQueue.cpp
src/ratatoskrUtils/utils/TrafficTracer.cpp
)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} systemc pugixml boost_system zmq boost_program_options)

9
README.md Executable file
View file

@ -0,0 +1,9 @@
# Defines
`cmake -DDEFINE_ENABLE_NETRACE=ON`
enables netrace mode
`cmake -DDEFINE_ENABLE_GUI=ON`
enables GUI mode

9
build.sh Executable file
View file

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

508
config/XYZ_4_4_1_8B_8VC.xml Normal file
View file

@ -0,0 +1,508 @@
<?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="RouterVC"/>
<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>
<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="1"/>
<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="4"/>
<bufferDepth value="8"/>
<vcCount value="8"/>
</port>
</ports>
</con>
<con id="2">
<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="3">
<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="4">
<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="5">
<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="6">
<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="7">
<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="8">
<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="9">
<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="10">
<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="11">
<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="12">
<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="13">
<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="14">
<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="15">
<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="16">
<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="17">
<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="18">
<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="19">
<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="20">
<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="21">
<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="22">
<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="23">
<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>
</connections>
</network-on-chip>

83
config/config.xml Executable file
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>

808
config/data1.xml Executable file
View file

@ -0,0 +1,808 @@
<?xml version="1.0" ?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dataTypes>
<dataType id="0">
<name value="dt_0"/>
</dataType>
<dataType id="1">
<name value="dt_1"/>
</dataType>
<dataType id="2">
<name value="dt_2"/>
</dataType>
<dataType id="3">
<name value="dt_3"/>
</dataType>
</dataTypes>
<tasks>
<task id="0">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="3"/>
<source value="24"/>
<count max="1" min="1"/>
</requirement>
</requires>
</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="3"/>
<source value="24"/>
<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="3"/>
<source value="24"/>
<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="3"/>
<source value="24"/>
<count max="1" min="1"/>
</requirement>
</requires>
</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="3"/>
<source value="28"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
<task id="5">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="3"/>
<source value="28"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
<task id="6">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="3"/>
<source value="28"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
<task id="7">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="3"/>
<source value="28"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
<task id="8">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="3"/>
<source value="32"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
<task id="9">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="3"/>
<source value="32"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
<task id="10">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="3"/>
<source value="32"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
<task id="11">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="3"/>
<source value="32"/>
<count max="1" min="1"/>
</requirement>
</requires>
</task>
<task id="12">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="0"/>
<source value="25"/>
<count max="13161" min="13161"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="3716" min="3716"/>
<type value="1"/>
<task value="14"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="13">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="0"/>
<source value="27"/>
<count max="13161" min="13161"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="3716" min="3716"/>
<type value="1"/>
<task value="15"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="16">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="0"/>
<source value="29"/>
<count max="13161" min="13161"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="3716" min="3716"/>
<type value="1"/>
<task value="18"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="17">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="0"/>
<source value="31"/>
<count max="13161" min="13161"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="3716" min="3716"/>
<type value="1"/>
<task value="19"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="20">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="0"/>
<source value="33"/>
<count max="13161" min="13161"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="3716" min="3716"/>
<type value="1"/>
<task value="22"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="21">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="0"/>
<source value="35"/>
<count max="13161" min="13161"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="3716" min="3716"/>
<type value="1"/>
<task value="23"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="14">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="1"/>
<source value="12"/>
<count max="3716" min="3716"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="929" min="929"/>
<type value="2"/>
<task value="24"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="15">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="1"/>
<source value="13"/>
<count max="3716" min="3716"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="929" min="929"/>
<type value="2"/>
<task value="24"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="18">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="1"/>
<source value="16"/>
<count max="3716" min="3716"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="929" min="929"/>
<type value="2"/>
<task value="28"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="19">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="1"/>
<source value="17"/>
<count max="3716" min="3716"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="929" min="929"/>
<type value="2"/>
<task value="28"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="22">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="1"/>
<source value="20"/>
<count max="3716" min="3716"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="929" min="929"/>
<type value="2"/>
<task value="32"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="23">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="1"/>
<source value="21"/>
<count max="3716" min="3716"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="929" min="929"/>
<type value="2"/>
<task value="32"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="24">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="2"/>
<source value="14"/>
<count max="929" min="929"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="1" min="1"/>
<type value="3"/>
<task value="0"/>
</destination>
<destination id="1">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="1" min="1"/>
<type value="3"/>
<task value="1"/>
</destination>
<destination id="2">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="1" min="1"/>
<type value="3"/>
<task value="2"/>
</destination>
<destination id="3">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="1" min="1"/>
<type value="3"/>
<task value="3"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="28">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="2"/>
<source value="18"/>
<count max="929" min="929"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="1" min="1"/>
<type value="3"/>
<task value="4"/>
</destination>
<destination id="1">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="1" min="1"/>
<type value="3"/>
<task value="5"/>
</destination>
<destination id="2">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="1" min="1"/>
<type value="3"/>
<task value="6"/>
</destination>
<destination id="3">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="1" min="1"/>
<type value="3"/>
<task value="7"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="32">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<requires>
<requirement id="0">
<type value="2"/>
<source value="22"/>
<count max="929" min="929"/>
</requirement>
</requires>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="1" min="1"/>
<type value="3"/>
<task value="8"/>
</destination>
<destination id="1">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="1" min="1"/>
<type value="3"/>
<task value="9"/>
</destination>
<destination id="2">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="1" min="1"/>
<type value="3"/>
<task value="10"/>
</destination>
<destination id="3">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="1" min="1"/>
<type value="3"/>
<task value="11"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="25">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="13161" min="13161"/>
<type value="0"/>
<task value="12"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="26">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="6581" min="6581"/>
<type value="0"/>
<task value="13"/>
</destination>
<destination id="1">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="6581" min="6581"/>
<type value="0"/>
<task value="12"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="27">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="13161" min="13161"/>
<type value="0"/>
<task value="13"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="29">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="13161" min="13161"/>
<type value="0"/>
<task value="16"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="30">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="6581" min="6581"/>
<type value="0"/>
<task value="17"/>
</destination>
<destination id="1">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="6581" min="6581"/>
<type value="0"/>
<task value="16"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="31">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="13161" min="13161"/>
<type value="0"/>
<task value="17"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="33">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="13161" min="13161"/>
<type value="0"/>
<task value="20"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="34">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="6581" min="6581"/>
<type value="0"/>
<task value="21"/>
</destination>
<destination id="1">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="6581" min="6581"/>
<type value="0"/>
<task value="20"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
<task id="35">
<start max="0" min="0"/>
<duration max="-1" min="-1"/>
<repeat max="1" min="1"/>
<generates>
<possibility id="0">
<probability value="1"/>
<destinations>
<destination id="0">
<delay max="100" min="0"/>
<interval max="100" min="100"/>
<count max="13161" min="13161"/>
<type value="0"/>
<task value="21"/>
</destination>
</destinations>
</possibility>
</generates>
</task>
</tasks>
</data>

134
config/data_original.xml Executable file
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 = "1" />
<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 = "1" />
<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 = "1"/>
<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 = "1" />
<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 = "1" />
<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 = "1"/>
<count min = "1" max = "1" />
</requirement>
</requires>
<generates>
</generates>
</task>
</tasks>
</data>

147
config/map1.xml Executable file
View file

@ -0,0 +1,147 @@
<?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="3"/>
</bind>
<bind>
<task value="4"/>
<node value="4"/>
</bind>
<bind>
<task value="5"/>
<node value="5"/>
</bind>
<bind>
<task value="6"/>
<node value="6"/>
</bind>
<bind>
<task value="7"/>
<node value="7"/>
</bind>
<bind>
<task value="8"/>
<node value="8"/>
</bind>
<bind>
<task value="9"/>
<node value="9"/>
</bind>
<bind>
<task value="10"/>
<node value="10"/>
</bind>
<bind>
<task value="11"/>
<node value="11"/>
</bind>
<bind>
<task value="12"/>
<node value="20"/>
</bind>
<bind>
<task value="13"/>
<node value="21"/>
</bind>
<bind>
<task value="14"/>
<node value="22"/>
</bind>
<bind>
<task value="15"/>
<node value="23"/>
</bind>
<bind>
<task value="16"/>
<node value="24"/>
</bind>
<bind>
<task value="17"/>
<node value="25"/>
</bind>
<bind>
<task value="18"/>
<node value="26"/>
</bind>
<bind>
<task value="19"/>
<node value="27"/>
</bind>
<bind>
<task value="20"/>
<node value="28"/>
</bind>
<bind>
<task value="21"/>
<node value="29"/>
</bind>
<bind>
<task value="22"/>
<node value="30"/>
</bind>
<bind>
<task value="23"/>
<node value="31"/>
</bind>
<bind>
<task value="24"/>
<node value="36"/>
</bind>
<bind>
<task value="25"/>
<node value="37"/>
</bind>
<bind>
<task value="26"/>
<node value="38"/>
</bind>
<bind>
<task value="27"/>
<node value="39"/>
</bind>
<bind>
<task value="28"/>
<node value="40"/>
</bind>
<bind>
<task value="29"/>
<node value="41"/>
</bind>
<bind>
<task value="30"/>
<node value="42"/>
</bind>
<bind>
<task value="31"/>
<node value="43"/>
</bind>
<bind>
<task value="32"/>
<node value="44"/>
</bind>
<bind>
<task value="33"/>
<node value="45"/>
</bind>
<bind>
<task value="34"/>
<node value="46"/>
</bind>
<bind>
<task value="35"/>
<node value="47"/>
</bind>
</map>

42
config/map_original.xml Executable file
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>

3248
config/network.xml Executable file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,76 @@
<?xml version="1.0" ?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dataTypes>
<dataType id="0">
<name value="dt_0"/>
</dataType>
<dataType id="1">
<name value="dt_1"/>
</dataType>
<dataType id="2">
<name value="dt_2"/>
</dataType>
<dataType id="3">
<name value="dt_3"/>
</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="1"/>
<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="1"/>
<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="1"/>
<source value="0"/>
<count max="1" min="1"/>
</requirement>
<requirement id="1">
<type value="1"/>
<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="8"/>
</bind>
<bind>
<task value="2"/>
<node value="15"/>
</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>

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="RouterVC"/>
<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>

55
config/simple_test/config.xml Executable 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/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="RouterVC"/>
<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,50 @@
<?xml version="1.0" ?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dataTypes>
<dataType id="0">
<name value="dt_0"/>
</dataType>
<dataType id="1">
<name value="dt_1"/>
</dataType>
<dataType id="2">
<name value="dt_2"/>
</dataType>
<dataType id="3">
<name value="dt_3"/>
</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="1"/>
<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="1"/>
<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>

360
config/structure.xml Executable file
View file

@ -0,0 +1,360 @@
<?xml version="1.0" encoding="UTF-8"?>
<network-on-chip xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="layer.xsd">
<nodeTypes>
<nodeType id="0">
<model value="XYZ"/>
<clockSpeed value="2"/>
</nodeType>
</nodeTypes>
<layerTypes>
<layerType id="0">
<technology value="130"/>
</layerType>
<layerType id="1">
<technology value="130"/>
</layerType>
</layerTypes>
<nodes>
<node id="0">
<xPos value="0"/>
<yPos value="0"/>
<zPos value="0"/>
<nodeType value="0"/>
<layerType value="0"/>
</node>
<node id="1">
<xPos value="1.00"/>
<yPos value="0"/>
<zPos value="0"/>
<nodeType value="0"/>
<layerType value="0"/>
</node>
<node id="2">
<xPos value="0"/>
<yPos value="1.00"/>
<zPos value="0"/>
<nodeType value="0"/>
<layerType value="0"/>
</node>
<node id="3">
<xPos value="1.00"/>
<yPos value="1.00"/>
<zPos value="0"/>
<nodeType value="0"/>
<layerType value="0"/>
</node>
<node id="4">
<xPos value="0"/>
<yPos value="0"/>
<zPos value="1.00"/>
<nodeType value="0"/>
<layerType value="1"/>
</node>
<node id="5">
<xPos value="1.00"/>
<yPos value="0"/>
<zPos value="1.00"/>
<nodeType value="0"/>
<layerType value="1"/>
</node>
<node id="6">
<xPos value="0"/>
<yPos value="1.00"/>
<zPos value="1.00"/>
<nodeType value="0"/>
<layerType value="1"/>
</node>
<node id="7">
<xPos value="1.00"/>
<yPos value="1.00"/>
<zPos value="1.00"/>
<nodeType value="0"/>
<layerType value="1"/>
</node>
</nodes>
<connections>
<con id="0">
<length value="0"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="0"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="1">
<length value="900"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="0"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
<port id="1">
<node value="1"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="2">
<length value="900"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="0"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
<port id="1">
<node value="2"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="3">
<length value="900"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="0"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
<port id="1">
<node value="4"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="4">
<length value="0"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="1"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="5">
<length value="900"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="1"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
<port id="1">
<node value="3"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="6">
<length value="900"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="1"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
<port id="1">
<node value="5"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="7">
<length value="0"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="2"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="8">
<length value="900"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="2"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
<port id="1">
<node value="3"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="9">
<length value="900"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="2"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
<port id="1">
<node value="6"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="10">
<length value="0"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="3"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="11">
<length value="900"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="3"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
<port id="1">
<node value="7"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="12">
<length value="0"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="4"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="13">
<length value="900"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="4"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
<port id="1">
<node value="5"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="14">
<length value="900"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="4"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
<port id="1">
<node value="6"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="15">
<length value="0"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="5"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="16">
<length value="900"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="5"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
<port id="1">
<node value="7"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="17">
<length value="0"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="6"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="18">
<length value="900"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="6"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
<port id="1">
<node value="7"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
<con id="19">
<length value="0"/>
<interface value="0"/>
<ports>
<port id="0">
<node value="7"/>
<bufferDepth value="16"/>
<vcCount value="4"/>
</port>
</ports>
</con>
</connections>
</network-on-chip>

1537
report.txt Executable file

File diff suppressed because it is too large Load diff

59
src/main.cpp Executable file
View file

@ -0,0 +1,59 @@
/*******************************************************************************
* Copyright (C) 2024 Juan Neyra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#include "systemc.h"
#include <iostream>
#include <fstream>
#include <string>
#include "boost/program_options.hpp"
#include "ratatoskrUtils/utils/GlobalResources.h"
#include "networkManager/NetworkManager.h"
namespace po = boost::program_options;
int sc_main(int arg_num, char *arg_vec[])
{
po::variables_map vm;
po::options_description desc("Allowed Options");
desc.add_options()("configFolder", po::value<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,413 @@
/*******************************************************************************
* Copyright (C) 2024 Juan Neyra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#include "NetworkInterfaceTlm.h"
#include <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,
uint8_t max_pos[3]) : NetworkInterface(nm, node),
credit_counter(NUM_CREDITS), ni_name(nm),
initiator((string(nm)+"_initiator").c_str()),
target((string(nm)+"_target").c_str()),
init_peq(this, &NetworkInterfaceTlm::init_peq_cb),
target_peq(this, &NetworkInterfaceTlm::target_peq_cb),
curr_req(0), resp_in_progress(false),
nxt_resp_pend(0), end_req_pend(0) {
sc_report_handler::set_actions(NI_LOG, SC_INFO, SC_LOG|SC_DISPLAY);
try {
this->id = node.id%(globalResources.nodes.size()/2);
this->dbid = rep.registerElement("ProcessingElement", this->id);
this->node = node;
this->packetPortContainer = new PacketPortContainer(
("NI_PACKET_CONTAINER"+to_string(this->id)).c_str());
copy(max_pos, max_pos + 3, this->max_pos);
}
catch (exception& e) {
log_error(e.what());
}
SC_THREAD(thread);
sensitive << clk.pos() << clk.neg();
SC_METHOD(receivePacketFromPE);
sensitive << packetPortContainer->portValidIn.pos();
initiator.register_nb_transport_bw(this,
&NetworkInterfaceTlm::nb_transport_bw_cb, 0);
target.register_nb_transport_fw(this,
&NetworkInterfaceTlm::nb_transport_fw_cb, 0);
}
NetworkInterfaceTlm::~NetworkInterfaceTlm() {
delete packetPortContainer;
}
void NetworkInterfaceTlm::initialize(){
/* NOT IMPLEMENTED */
}
void NetworkInterfaceTlm::bind(Connection* con, SignalContainer* sigContIn, SignalContainer* sigContOut) {
if (con==nullptr)
packetPortContainer->bind(sigContIn, sigContOut);
}
void NetworkInterfaceTlm::receiveFlitFromRouter(){
/* NOT IMPLEMENTED */
}
void NetworkInterfaceTlm::receivePacketFromPE() {
if (packetPortContainer->portValidIn.posedge()) {
//log_info("receive()");
Packet* p = packetPortContainer->portDataIn.read();
generateFlitsForPacket(p);
packet_send_queue.push(p);
}
}
void NetworkInterfaceTlm::get_start_end_pos_string(Packet* p,
string pos[2]){
pos[0] = to_string(node.pos.x) + "," +
to_string(node.pos.y) + "," + to_string(node.pos.z);
pos[1] = to_string(p->dst.pos.x) + "," +
to_string(p->dst.pos.y) + "," +
to_string(p->dst.pos.z);
}
void NetworkInterfaceTlm::generateFlitsForPacket(Packet* p) {
int flitsPerPacket = p->size;
for (int i = 0; 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);
string start_end_pos[2];
get_start_end_pos_string(p, start_end_pos);
log_info("Flits generated for packet of id "+to_string(p->id)+
" to be sent to "+start_end_pos[1]+" from "+start_end_pos[0]);
}
}
void NetworkInterfaceTlm::send_data_to_noc(){
// if no flits to transmit, generate them
Packet* p = packet_send_queue.front();
if (p->toTransmit.empty()){
generateFlitsForPacket(p);
}
// get current flit to send
flitID_t f_id = p->toTransmit.front();
auto iter = find_if(p->flits.begin(), p->flits.end(),
[&f_id](Flit* f) { return f->id==f_id; });
Flit* current_flit = *iter;
current_flit->injectionTime = sc_time_stamp().to_double();
auto toDelete_pos = find(p->toTransmit.begin(), p->toTransmit.end(), current_flit->id);
p->toTransmit.erase(toDelete_pos);
p->inTransmit.push_back(current_flit->id);
if (p->toTransmit.empty()) {
packet_send_queue.pop();
}
// allocate tlm object
tlm::tlm_generic_payload* trans = m_mm.allocate();
trans->acquire();
// add id to transaction
link_extension* ext = new link_extension();
ext->link = Direction::local;
trans->set_extension(ext);
// send flit
trans->set_command(tlm::TLM_WRITE_COMMAND);
float dst_pos[3] = {p->dst.pos.x, p->dst.pos.y, p->dst.pos.z};
uint8_t int_dest_pos[3];
convert_pos_to_int(dst_pos, int_dest_pos);
trans->set_address(int_dest_pos[0] + int_dest_pos[1]*max_pos[0] +
int_dest_pos[2]*max_pos[0]*max_pos[1]);
trans->set_data_ptr(reinterpret_cast<unsigned char*>
(current_flit));
trans->set_data_length(p->size);
trans->set_streaming_width(4);
trans->set_byte_enable_ptr(0);
trans->set_dmi_allowed(false);
trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
credit_counter--;
sc_time delay = sc_time(REQ_INIT_DELAY, UNITS_DELAY);
tlm::tlm_phase send_phase = tlm::BEGIN_REQ;
initiator->nb_transport_fw(*trans, send_phase, delay);
string start_end_pos[2];
get_start_end_pos_string(p, start_end_pos);
log_info("Flit send to "+start_end_pos[1]+" from "+start_end_pos[0]);
globalReport.issueNoCInputDataAmount(sc_time_stamp(),globalResources.bitWidth);
}
void NetworkInterfaceTlm::thread() {
while(true){
//log_info("send_data_process()");
if (clk.posedge()) {
if (!packet_send_queue.empty()) {
if (credit_counter != 0){
send_data_to_noc();
}
else {
log_info("Waiting for Router!");
}
}
if (!packet_recv_queue.empty()) {
if (packetPortContainer->portFlowControlIn.read()) {
Packet* p = packet_recv_queue.front();
packet_recv_queue.pop();
packetPortContainer->portValidOut.write(true);
packetPortContainer->portDataOut.write(p);
// log arrival of packet
string start_end_pos[2];
get_start_end_pos_string(p, start_end_pos);
log_info("Packet with id " + to_string(p->id) +
" arrived at PE "+start_end_pos[1]);
}
}
}
else if (clk.negedge()) {
packetPortContainer->portValidOut.write(false);
}
wait();
}
}
tlm::tlm_sync_enum NetworkInterfaceTlm::nb_transport_bw_cb(int id,
tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase, sc_time& delay) {
init_peq.notify(trans, phase, delay);
return tlm::TLM_ACCEPTED;
}
void NetworkInterfaceTlm::init_peq_cb(tlm_gp& trans, const tlm::tlm_phase& phase){
if (phase == tlm::END_REQ) {
credit_counter++;
}
else if (phase == tlm::BEGIN_REQ || phase == tlm::END_RESP)
log_fatal("Illegal transaction phase received by initiator");
if (phase == tlm::BEGIN_RESP) {
check_transaction(trans);
// Send final phase transition to target
tlm::tlm_phase fw_phase = tlm::END_RESP;
sc_time delay = sc_time(RESP_END_DELAY, UNITS_DELAY);
initiator->nb_transport_fw(trans, fw_phase, delay);
}
}
// Called on receiving BEGIN_RESP or TLM_COMPLETED
void NetworkInterfaceTlm::check_transaction(tlm_gp& trans) {
if(trans.is_response_error()) {
char txt[100];
sprintf(txt, "Transaction returned with error, response status = %s",
trans.get_response_string().c_str());
log_error(txt);
}
// Log completed routing
tlm_command cmd = trans.get_command();
sc_dt::uint64 adr = trans.get_address();
int* ptr = reinterpret_cast<int*>(trans.get_data_ptr());
std::stringstream stream;
stream << hex << adr << " check, cmd=" << (cmd ? 'W' : 'R')
<< ", data=" << hex << *ptr;
log_info(stream.str());
// Allow the memory manager to free the transaction object
trans.release();
}
tlm::tlm_sync_enum NetworkInterfaceTlm::nb_transport_fw_cb(int id,
tlm_gp& trans, tlm::tlm_phase& phase, sc_time& delay){
unsigned int len = trans.get_data_length();
unsigned char* byt = trans.get_byte_enable_ptr();
unsigned int wid = trans.get_streaming_width();
if (byt != 0) {
trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE );
return tlm::TLM_COMPLETED;
}
if (len > 4 || wid < len) {
trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE );
return tlm::TLM_COMPLETED;
}
target_peq.notify(trans, phase, delay);
return tlm::TLM_ACCEPTED;
}
void NetworkInterfaceTlm::receive_and_process_flit(tlm_gp& trans){
trans.set_response_status(tlm::TLM_OK_RESPONSE);
unsigned char* data_ptr = trans.get_data_ptr();
Flit* received_flit = reinterpret_cast<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;
string flit_type = received_flit->type==SINGLE ? "Single":"Tail";
ss << "Receive Flit " << flit_type << *received_flit;
log_info(ss.str());
}
if (!p->toTransmit.empty() || !p->inTransmit.empty()) {
stringstream ss;
ss << "Received Tail Flit, but still missing flits! "
<< *received_flit;
log_info(ss.str());
}
globalReport.issueNoCOutputDataAmount(sc_time_stamp(),globalResources.bitWidth);
if (p->toTransmit.empty() && p->inTransmit.empty())
packet_recv_queue.push(p);
credit_counter++;
if(resp_in_progress) {
if(nxt_resp_pend){
log_fatal("Attempt to have two pending responses in target");
nxt_resp_pend = &trans;
}
}
else{ send_response(trans); }
}
void NetworkInterfaceTlm::target_peq_cb(tlm_gp& trans, const tlm::tlm_phase& phase){
switch (phase) {
case tlm::BEGIN_REQ:
trans.acquire();
send_end_req(trans);
break;
case tlm::END_RESP:
if (!resp_in_progress){
log_fatal(
"Illegal transaction phase END_RESP received by target");
}
trans.release();
credit_counter++;
// Target itself is now clear to issue the next BEGIN_RESP
resp_in_progress = false;
if (nxt_resp_pend){
send_response(*nxt_resp_pend);
nxt_resp_pend = 0;
}
break;
case tlm::END_REQ:
case tlm::BEGIN_RESP:
log_fatal("Illegal transaction phase received by target");
break;
default:
if(phase == INTERNAL_PROC_PHASE){
receive_and_process_flit(trans);
}
break;
}
}
tlm::tlm_sync_enum NetworkInterfaceTlm::send_end_req(tlm_gp& trans){
// Queue the acceptance and the response with the appropriate latency
tlm::tlm_phase bw_phase = tlm::END_REQ;
sc_time delay = sc_time(REQ_END_DELAY, UNITS_DELAY); // Accept delay
tlm::tlm_sync_enum status = target->nb_transport_bw(trans,
bw_phase, delay);
if (status == tlm::TLM_COMPLETED) {
trans.release();
return status;
}
// Queue internal event to mark beginning of response
delay = delay + sc_time(INTERN_PROC_DELAY, UNITS_DELAY); // Latency
target_peq.notify(trans, INTERNAL_PROC_PHASE, delay);
return status;
}
void NetworkInterfaceTlm::send_response(tlm_gp& trans){
resp_in_progress = true;
sc_time delay = SC_ZERO_TIME;
tlm::tlm_phase bw_phase = tlm::BEGIN_RESP;
tlm::tlm_sync_enum status = target->nb_transport_bw(
trans, bw_phase, delay);
credit_counter--;
if (status == tlm::TLM_UPDATED){
target_peq.notify(trans, bw_phase, delay);
}
else if (status == tlm::TLM_COMPLETED) {
// The initiator has terminated the transaction
trans.release();
resp_in_progress = false;
credit_counter++;
}
}
void NetworkInterfaceTlm::log_info(string msg){
string log_msg = ni_name + ": (Node" +
to_string(node.id)+"): "+msg;
SC_REPORT_INFO(NI_LOG, (log_msg).c_str());
}
void NetworkInterfaceTlm::log_error(string msg){
string log_msg = ni_name + ": (Node" +
to_string(node.id)+"): "+msg;
SC_REPORT_ERROR(NI_LOG, (log_msg).c_str());
}
void NetworkInterfaceTlm::log_fatal(string msg){
string log_msg = ni_name + ": (Node" +
to_string(node.id)+"): "+msg;
SC_REPORT_FATAL(NI_LOG, (log_msg).c_str());
}

View file

@ -0,0 +1,218 @@
/*******************************************************************************
* Copyright (C) 2024 Juan Neyra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#pragma once
#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
#define SC_INCLUDE_DYNAMIC_PROCESSES
#endif
#include "systemc.h"
#include "tlm.h"
#include <queue>
#include <algorithm>
#include <functional>
#include "ratatoskrUtils/utils/Structures.h"
#include "ratatoskrUtils/utils/TrafficTracer.h"
#include "ratatoskrUtils/container/PacketContainer.h"
#include "ratatoskrUtils/networkInterface/NetworkInterface.h"
#include "noc/noc.h"
#include "utils/memory_manager.h"
#include "utils/noc_logger.h"
using namespace tlm_utils;
class NetworkInterfaceTlm : public NetworkInterface {
public:
typedef simple_initiator_socket_tagged<NetworkInterfaceTlm> ni_init_socket;
typedef simple_target_socket_tagged<NetworkInterfaceTlm> ni_targ_socket;
std::queue<Packet*> packet_send_queue;
std::queue<Packet*> packet_recv_queue;
string ni_name;
// To PE
sc_in<bool> clk;
PacketPortContainer* packetPortContainer;
// To Router
ni_init_socket initiator;
ni_targ_socket target;
tlm_utils::peq_with_cb_and_phase<NetworkInterfaceTlm> init_peq;
tlm_utils::peq_with_cb_and_phase<NetworkInterfaceTlm> target_peq;
tlm_gp* curr_req;
tlm_gp* end_req_pend;
tlm_gp* nxt_resp_pend;
tlm_gp* nxt_send_data_pend;
bool resp_in_progress;
bool send_data_in_progress;
int credit_counter;
Dir send_data_in_prog_dest;
MemoryManager m_mm;
uint8_t max_pos[3];
sc_event_or_list ev_msg_arrv;
SC_HAS_PROCESS(NetworkInterfaceTlm);
NetworkInterfaceTlm(sc_module_name nm, Node& node, uint8_t max_pos[3]);
~NetworkInterfaceTlm() override;
/**
* Not implemented, nothing to initialize, come from parent class
*/
void initialize() override;
/**
* Binds packet port container to Processing Element
*
* @param con connection struct
* @param sigContIn input signals for port
* @param sigContOut output signal for port
*/
void bind(Connection* conn, SignalContainer* sigContIn,
SignalContainer* sigContOut) override;
/**
* Main SC THREAD. Has logic to send and receive flits
*/
void thread() override;
/**
* Gets current flit to transmit and send it to the router in noc
*/
void send_data_to_noc();
/**
* Generates flits when a packet arrives
*/
void receivePacketFromPE() override;
/**
* Not implemented. TLM's target nb_transport_fw_cb callback
* used instead
*/
void receiveFlitFromRouter();
/**
* Used inside receivePacketFromPE to generate flits
*
* @param p packet from which to generate flits
*/
void generateFlitsForPacket(Packet *p);
/**
* Gets the node position and the destination of packet
* as strings
*
* @param p packet from which to extract destination
* @param pos stores the start (0) and end position (1)
*/
void get_start_end_pos_string(Packet* p, string pos[2]);
/**
* Checks transaction for errors, if no error found, log
* transaction and release transaction object. Called when
* transaction is completed
*
* @param trans TLM transaction object
*/
void check_transaction(tlm_gp& trans);
/**
* Logs the arrival of a flit
*
* @param trans TLM transaction object
*/
void receive_and_process_flit(tlm_gp& trans);
/**
* Callback function for non blocking transport forward
*
* @param id active link
* @param trans TLM generic payload object
* @param phase TLM current phase
* @param delay TLM expected delay
*/
tlm::tlm_sync_enum nb_transport_fw_cb(int id, tlm_gp& trans,
tlm::tlm_phase& phase, sc_time& delay);
/**
* Callback function for non blocking transport backward
*
* @param id active link
* @param trans TLM generic payload object
* @param phase TLM current phase
* @param delay TLM expected delay
*/
tlm::tlm_sync_enum nb_transport_bw_cb(int id, tlm_gp& trans,
tlm::tlm_phase& phase, sc_time& delay);
/**
* Callback initiator Payload Event Queue (PEQ)
*
* @param trans TLM generic payload object
* @param phase TLM current phase
*/
void init_peq_cb(tlm_gp& trans, const tlm::tlm_phase& phase);
/**
* Callback target Payload Event Queue (PEQ)
*
* @param trans TLM generic payload object
* @param phase TLM current phase
*/
void target_peq_cb(tlm_gp& trans, const tlm::tlm_phase& phase);
/**
* Send end request
*
* @param trans TLM generic payload object
*/
tlm::tlm_sync_enum send_end_req(tlm_gp& trans);
/**
* Send begin response
*
* @param link active link
* @param trans TLM generic payload object
*/
void send_response(tlm_gp& trans);
/** Log info
* @param msg log message
*/
void log_info(string msg);
/** Log error
* @param msg log message
*/
void log_error(string msg);
/** Log fatal
* @param msg log message
*/
void log_fatal(string msg);
};

View file

@ -0,0 +1,134 @@
/*******************************************************************************
* Copyright (C) 2024 Juan Neyra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#include "NetworkManager.h"
#include "ratatoskrUtils/traffic/synthetic/SyntheticPool.h"
#include "ratatoskrUtils/traffic/task/TaskPool.h"
#include "ratatoskrUtils/traffic/netrace/NetracePool.h"
NetworkManager::NetworkManager(sc_module_name nm, std::string configFolder){
dbid = rep.registerElement("NetworkManager", 0);
tlmNoc = new TlmNoc("TlmNoc", configFolder);
networkParticipants.resize(globalResources.nodes.size());
createTrafficPool();
createClocks();
createNetworkParticipants();
createLinks();
runNoC();
}
void NetworkManager::createClocks() {
clocks.resize(globalResources.nodeTypes.size());
for (const auto &nodeType : globalResources.nodeTypes) {
clocks.at(nodeType->id) = std::make_unique<sc_clock>(
("NodeType" + std::to_string(nodeType->id) + "Clock").c_str(),
nodeType->clockDelay, SC_NS);
}
}
void NetworkManager::createTrafficPool() {
unsigned long numOfPEs = globalResources.nodes.size() / 2;
#ifndef ENABLE_NETRACE
if (globalResources.benchmark == "task") {
tp = std::make_unique<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 == "ProcessingElement") {
// Creating an network interface
std::string ni_name = "ni_" + std::to_string(n.id % numOfPEs);
uint8_t max_pos[3];
get_max_pos(max_pos);
NetworkInterfaceTlm *ni = new NetworkInterfaceTlm(
ni_name.c_str(), n, max_pos);
ni->clk(*clocks.at(n.type->id));
networkParticipants.at(n.id) = dynamic_cast<NetworkParticipant *>(ni);
std::string pe_name = "pe_" + std::to_string(n.id % numOfPEs);
ProcessingElementVC *pe = new ProcessingElementVC(pe_name.c_str(), n, tp.get());
std::unique_ptr<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(n.id % numOfPEs) = pe;
}
}
}
void NetworkManager::createLinks() {
int link_id = 0;
for (auto &c : globalResources.connections) {
int connNodesSize = c.nodes.size();
if (connNodesSize == 2) { //might extend to bus architecture
// gets nodes for connections
Node &node1 = globalResources.nodes.at(c.nodes.at(0));
Node &node2 = globalResources.nodes.at(c.nodes.at(1));
bool is_node1_pe = node1.type->model == "ProcessingElement";
bool is_node2_pe = node2.type->model == "ProcessingElement";
if (is_node1_pe || is_node2_pe){
int ni_id = is_node1_pe ? node1.id : node2.id;
int rout_id = is_node1_pe ? node2.id : node1.id;
NetworkInterfaceTlm* ni =
dynamic_cast<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();
}

View file

@ -0,0 +1,82 @@
/*******************************************************************************
* Copyright (C) 2024 Juan Neyra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#pragma once
#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
#define SC_INCLUDE_DYNAMIC_PROCESSES
#endif
#include "systemc.h"
#include "tlm.h"
#include "ratatoskrUtils/utils/GlobalResources.h"
#include "ratatoskrUtils/utils/Report.h"
#include "ratatoskrUtils/utils/Structures.h"
#include "ratatoskrUtils/traffic/TrafficPool.h"
#include "networkInterface/NetworkInterfaceTlm.h"
#include "noc/noc.h"
using namespace tlm;
class NetworkManager : public sc_module{
public:
SC_HAS_PROCESS(NetworkManager);
explicit NetworkManager(sc_module_name, std::string);
private:
GlobalResources& globalResources = GlobalResources::getInstance();
Report& rep = Report::getInstance();
int dbid;
std::vector<std::unique_ptr<sc_clock>> clocks;
std::unique_ptr<TrafficPool> tp;
TlmNoc* tlmNoc;
std::vector<NetworkParticipant*> networkParticipants;
std::vector<std::unique_ptr<PacketSignalContainer>> packetSignalContainers;
/**
* Create clocks for Ratatoskr PEs
*/
void createClocks();
/**
* Create the traffic pool with the tasks for PEs
*/
void createTrafficPool();
/**
* Create Network Participants (creates PE and NI, and
* connects them)
*/
void createNetworkParticipants();
/**
* Connects Network Interface to Routers in NoC
*/
void createLinks();
/**
* Initialize routers and starts traffic pool
*/
void runNoC();
};

185
src/noc/noc.cpp Executable file
View file

@ -0,0 +1,185 @@
/*******************************************************************************
* Copyright (C) 2024 Juan Neyra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#include "noc.h"
#include "utils/noc_logger.h"
#include "utils/utils.h"
using namespace std;
TlmNoc::TlmNoc(sc_module_name nm, string config_folder): sc_module(nm){
setup_logger();
sc_report_handler::set_actions(N_LOG, SC_INFO, SC_LOG|SC_DISPLAY);
initializeGlobalResources(config_folder);
initNoc();
connectNoc();
}
TlmNoc::~TlmNoc() {
}
void TlmNoc::initializeGlobalResources(string config_folder) {
// initialize global resources and rep
globalResources = GlobalResources::getInstance();
GlobalReport &globalReport = GlobalReport::getInstance();
Report &rep = Report::getInstance();
sleep(1);
string config_path = "config/"+config_folder+"/config.xml";//"config/config.xml";
globalResources.readConfigFile(config_path);
globalReport.readConfigFile(config_path);
string network_path = "config/"+config_folder+"/net.xml";
//globalResources.noc_file;
globalResources.readNoCLayout(network_path);
globalResources.readTaskAndMapFiles(globalResources.data_file, globalResources.map_file);
globalReport.resizeMatrices();
globalResources.activateFlitTracing = false;
globalResources.outputDirectory = "out";
}
void TlmNoc::initNoc() {
uint8_t max_pos[3];
get_max_pos(max_pos);
for (Node &n : globalResources.nodes) {
if (n.type->model == "RouterVC") {
string name = "router_" + to_string(n.id);
float float_rout_pos[3] = {n.pos.x, n.pos.y, n.pos.z};
uint8_t rout_pos[3];
convert_pos_to_int(float_rout_pos, rout_pos);
string msg = name + " initialized in position " +
to_string(rout_pos[0]) + "," + to_string(rout_pos[1]) +
"," + to_string(rout_pos[2]);
log_info(msg);
MyRouter *r = new MyRouter(name.c_str(), rout_pos, max_pos);
routers.push_back(r);
int id = routers.size()-1;
mapNodeRouter.insert(
pair<int,int>(n.id, int(routers.size())-1));
}
}
}
void TlmNoc::connectRouters(Node node1, Node node2, int link){
int n1_id = mapNodeRouter[node1.id];
int n2_id = mapNodeRouter[node2.id];
if(node1.type->model == "RouterVC" &&
node2.type->model == "RouterVC"){
int connDir = node1.getDirOfCon(link);
int opposDir = DIR::getOppositeDir(connDir);
routers[n1_id]->init_socket[connDir]->bind(
*routers[n2_id]->target_socket[opposDir]);
routers[n2_id]->init_socket[opposDir]->bind(
*routers[n1_id]->target_socket[connDir]);
routers[n1_id]->valid_links[connDir] = true;
routers[n2_id]->valid_links[opposDir] = true;
log_conn(routers[n1_id]->router_name,routers[n2_id]->router_name,
DIR::toString(connDir), DIR::toString(opposDir));
}
else{
int r_id = node1.type->model == "RouterVC" ? n1_id:n2_id;
api_initiators.push_back(routers[r_id]->init_socket[DIR::Local]);
api_targets.push_back(routers[r_id]->target_socket[DIR::Local]);
routers[r_id]->valid_links[DIR::Local] = true;
log_conn(routers[r_id]->router_name, "noc interface",
DIR::toString(DIR::Local), "external");
}
}
void TlmNoc::connectUnbounded(){
// connecting unbounded routers
for (uint8_t id=0; id < routers.size(); id++){
for (uint8_t dir=0; dir < Direction::num_dirs; dir++){
if (!routers[id]->valid_links[dir]){
tlm_init_socket* unbound_init = new tlm_init_socket(
("unb_init_"+to_string(id)+"_"+to_string(dir)).c_str());
unbound_init->bind(*routers[id]->target_socket[dir]);
unbounded_initiators.push_back(unbound_init);
tlm_targ_socket* unbound_targ = new tlm_targ_socket(
("unb_targ_"+to_string(id)+"_"+to_string(dir)).c_str());
routers[id]->init_socket[dir]->bind(*unbound_targ);
unbounded_targets.push_back(unbound_targ);
log_conn(routers[id]->router_name, "unbounded_" +
to_string(id)+"_"+to_string(dir),
DIR::toString(dir), "unbounded");
}
}
}
}
void TlmNoc::connectNoc(){
int link_id = 0;
for (auto &c : globalResources.connections) {
if(c.nodes.size() == 2){
Node &node1 = globalResources.nodes.at(c.nodes.at(0));
Node &node2 = globalResources.nodes.at(c.nodes.at(1));
connectRouters(node1, node2, c.id);
link_id += 2;
} else {
log_error("Unsupported number of endpoints in connection "
+ to_string(c.id));
}
}
connectUnbounded();
}
MyRouter* TlmNoc::getRouter(int id){
return routers.at(id);
}
MyRouter* TlmNoc::getRouterNodeId(int node_id){
int rout_id = mapNodeRouter.find(node_id)->first;
return routers.at(rout_id);
}
/******************* LOG FUNCTIONS ********************/
void TlmNoc::log_info(string msg){
SC_REPORT_INFO(N_LOG, (msg).c_str());
}
void TlmNoc::log_warn(string msg){
SC_REPORT_WARNING(N_LOG, (msg).c_str());
}
void TlmNoc::log_error(string msg){
SC_REPORT_ERROR(N_LOG, (msg).c_str());
}
void TlmNoc::log_conn(string router1, string router2,
string link1, string link2){
string msg = router1 + " on link " + link1 + " connected to " +
router2 + " on link " + link2;
log_info(msg);
}

125
src/noc/noc.h Executable file
View file

@ -0,0 +1,125 @@
/*******************************************************************************
* Copyright (C) 2024 Juan Neyra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#pragma once
#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
#define SC_INCLUDE_DYNAMIC_PROCESSES
#endif
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include "systemc.h"
#include "tlm.h"
#include "ratatoskrUtils/utils/Structures.h"
#include "ratatoskrUtils/utils/GlobalResources.h"
#include "router/router.h"
using namespace tlm;
class TlmNoc : public sc_module {
public:
typedef tlm_utils::simple_initiator_socket_tagged<MyRouter> tlm_init_socket;
typedef tlm_utils::simple_target_socket_tagged<MyRouter> tlm_targ_socket;
SC_HAS_PROCESS(TlmNoc);
explicit TlmNoc(sc_module_name, string);
~TlmNoc() override;
std::vector<tlm_init_socket*> api_initiators;
std::vector<tlm_targ_socket*> api_targets;
uint8_t max_pos[3];
std::map<int, int> mapNodeRouter;
MyRouter* getRouter(int id);
MyRouter* getRouterNodeId(int node_id);
private:
std::vector<MyRouter*> routers;
uint8_t num_rout_x;
uint8_t num_rout_y;
uint8_t num_rout_z;
std::vector<tlm_init_socket*> unbounded_initiators;
std::vector<tlm_targ_socket*> unbounded_targets;
GlobalResources& globalResources = GlobalResources::getInstance();
/**
* Initialize global resources
*/
void initializeGlobalResources(string config_folder);
/**
* Initialize variable in noc
*/
void initNoc();
/**
* Connects two routers or a router and a core (network interface)
*
* @param node1 first node to connect
* @param node2 second node to connect
* @param link link of first node that will be connected
*/
void connectRouters(Node node1, Node node2, int link);
/**
* Connects unbounded links to dummy initiators and targets
*/
void connectUnbounded();
/**
* Connects all routers using GlobalResources object
*/
void connectNoc();
/** Log info
* @param msg log message
*/
void log_info(string msg);
/** Log warning
* @param msg log message
*/
void log_warn(string msg);
/** Log error
* @param msg log message
*/
void log_error(string msg);
/** Log a connection between two routers
* @param router1 name of router 1
* @param router2 name of router 2
* @param link1 name of connected link in router 1
* @param link2 name of connected link in router 2
*/
void log_conn(string router1, string router2,
string link1, string link2);
};

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

114
src/ratatoskrUtils/link/Link.cpp Executable file
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);
}

62
src/ratatoskrUtils/link/Link.h Executable file
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)
:
node(node),
trafficPool(tp)
{
this->id = node.id%(globalResources.nodes.size()/2);
this->dbid = rep.registerElement("NetworkInterface", this->id);
rep.reportAttribute(dbid, "pos_x", std::to_string(node.pos.x));
rep.reportAttribute(dbid, "pos_y", std::to_string(node.pos.y));
rep.reportAttribute(dbid, "pos_z", std::to_string(node.pos.z));
rep.reportAttribute(dbid, "clock", std::to_string(node.type->clockDelay));
rep.reportAttribute(dbid, "type", node.type->model);
}

View file

@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright (C) 2018 joseph
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#pragma once
#include "systemc.h"
#include <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);
virtual void receive() = 0;
virtual void execute(Task&) = 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)
:
ProcessingElement(mn, node, tp)
{
this->packetPortContainer = new PacketPortContainer(("NI_PACKET_CONTAINER"+std::to_string(this->id)).c_str());
SC_THREAD(thread);
SC_METHOD(receive);
sensitive << packetPortContainer->portValidIn.pos();
}
void ProcessingElementVC::initialize()
{
packetPortContainer->portValidOut.write(false);
packetPortContainer->portFlowControlOut.write(true);
// sc_spawn(sc_bind(&SyntheticPool::sendThread, this, con.first,
// con.second,initDelay,sp.waveCount,sp.waveDelay,sp.pkgPerWave, sp.name));
}
void ProcessingElementVC::thread()
{
#ifndef ENABLE_NETRACE
while(true) {
int timeStamp = static_cast<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);
~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,89 @@
/*******************************************************************************
* Copyright (C) 2018 joseph
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#include "Flit.h"
#include "Packet.h"
#include "TrafficPool.h"
long long Flit::idcnt = 0;
Flit::Flit(FlitType type, long long seq_nb, Packet* p)
:
type(type),
seq_nb(seq_nb),
packet(p),
id(++idcnt),
dataType(-1),
injectionTime(0),
headFlit(nullptr)
{
this->dbid = rep.registerElement("Flit", this->id);
rep.reportAttribute(dbid, "flit_packet", std::to_string(p->id));
rep.reportAttribute(dbid, "flit_type", std::to_string(type));
rep.reportAttribute(dbid, "flit_seq", std::to_string(seq_nb));
if (type==FlitType::HEAD || type==FlitType::SINGLE)
this->headFlit = this;
else
this->headFlit = p->flits.at(0);
}
Flit::Flit(FlitType type, long long seq_nb, Packet* p, dataTypeID_t dataType, double generationTime)
:
Flit(type, seq_nb, p)
{
this->generationTime = generationTime;
this->dataType = dataType;
}
ostream& operator<<(ostream& os, const Flit& flit)
{
int processingElementsSize = GlobalResources::getInstance().nodes.size()/2;
os << "[";
switch (flit.type) {
case HEAD:
os << "H";
break;
case BODY:
os << "B";
break;
case TAIL:
os << "T";
break;
case SINGLE:
os << "S";
break;
}
os << "_" << flit.id << ": " << flit.packet->src.id%processingElementsSize << "-->"
<< flit.packet->dst.id%processingElementsSize << "]";
return os;
}
void sc_trace(sc_trace_file*& tf, const Flit& flit, std::string nm)
{
sc_trace(tf, flit.type, nm+".type");
sc_trace(tf, flit.seq_nb, nm+".seq_nb");
sc_trace(tf, flit.id, nm+".id");
}
Flit::~Flit()
{
}

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);
~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,720 @@
/*******************************************************************************
* Copyright (C) 2018 Jan Moritz Joseph
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#include "GlobalResources.h"
#include <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();
std::cout<<taskID;
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,422 @@
/*******************************************************************************
* Copyright (C) 2018 Jan Moritz Joseph
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#pragma once
#include "systemc.h"
#include <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;
};
struct DataSendPossibility {
possID_t id;
float probability;
std::vector<DataDestination> dataDestinations;
DataSendPossibility(possID_t id, float probability, const std::vector<DataDestination>& dataDestinations);
};
struct Task {
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 = {};

393
src/router/router.cpp Executable file
View file

@ -0,0 +1,393 @@
/*******************************************************************************
* Copyright (C) 2024 Juan Neyra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#include "router.h"
#include <cassert>
#include <array>
#include "ratatoskrUtils/utils/Structures.h"
DECLARE_EXTENDED_PHASE(INTERNAL_PROC_PHASE);
/* Constructor */
MyRouter::MyRouter(sc_module_name name, uint8_t rout_pos[3],
uint8_t max_pos[3]):
sc_module(name), router_name(name),
init_peq(this, &MyRouter::init_peq_cb),
target_peq(this, &MyRouter::target_peq_cb) {
sc_report_handler::set_actions(R_LOG, SC_INFO, SC_LOG|SC_DISPLAY);
copy(rout_pos, rout_pos + 3, this->rout_pos);
copy(max_pos, max_pos + 3, this->max_pos);
initialize();
}
MyRouter::~MyRouter(){
}
void MyRouter::initialize(){
for(int link=0; link<NUM_LINKS; link++){
init_socket[link] = new rout_init_socket((router_name+"_"+
to_string(link)+"_init").c_str());
(*init_socket[link]).register_nb_transport_bw(this,
&MyRouter::nb_transport_bw_cb, link);
target_socket[link] = new rout_targ_socket((router_name+"_"+
to_string(link)+"_targ").c_str());
(*target_socket[link]).register_nb_transport_fw(this,
&MyRouter::nb_transport_fw_cb, link);
valid_links[link] = false;
resp_in_progress[link] = false;
nxt_resp_pend[link] = 0;
end_req_pend[link] = 0;
nxt_send_data_pend[link] = 0;
curr_req[link] = 0;
send_data_in_prog_dest[link] = Direction::invalid;
credit_counter[link] = NUM_CREDITS;
}
}
/******************* COMMON FUNCTIONS ********************/
void MyRouter::send_begin_req(int link, tlm_gp& trans, int dest_link){
// create new transaction
tlm::tlm_generic_payload* new_trans = m_mm.allocate();
new_trans->acquire();
new_trans->set_command(tlm::TLM_WRITE_COMMAND);
new_trans->set_address(trans.get_address());
new_trans->set_data_ptr(trans.get_data_ptr());
new_trans->set_data_length(trans.get_data_length());
new_trans->set_streaming_width(trans.get_streaming_width());
new_trans->set_byte_enable_ptr(trans.get_byte_enable_ptr());
new_trans->set_dmi_allowed(false);
new_trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
// add id to new_transaction
link_extension* ext = new link_extension();
ext->link = dest_link; // set direction of connected router
new_trans->set_extension(ext);
// send transaction in socket
tlm_phase phase = BEGIN_REQ;
sc_time delay = sc_time(REQ_INIT_DELAY, UNITS_DELAY);
tlm_sync_enum status;
status = (*init_socket[dest_link])->nb_transport_fw(
*new_trans, phase, delay);
curr_req[dest_link] = new_trans;
credit_counter[dest_link]--;
// react to result
if(status == TLM_UPDATED) {
init_peq.notify(*new_trans, phase, delay);
}
else if(status == TLM_COMPLETED) {
log_error(link, "Request completed prematurely");
curr_req[dest_link] = 0;
check_transaction(link, *new_trans);
credit_counter[dest_link]++;
new_trans->release();
}
}
bool MyRouter::send_data(int link, int dest_link, tlm_gp& trans){
log_info(link,"Send data to link:"+DIR::toString(dest_link));
// check credits or that previous message is complete
if (credit_counter[dest_link] > 0 && !curr_req[dest_link]){
send_begin_req(link, trans, dest_link);
return true;
}
else {
if(credit_counter[dest_link] > 0){
log_error(link,"Waiting for downstream Router!");
}
else{ log_error(link,"Waiting for END REQUEST"); }
return false;
}
}
void MyRouter::check_transaction(int link, tlm_gp& trans) {
if(trans.is_response_error()) {
char txt[100];
sprintf(txt, "Transaction returned with error, response status = %s",
trans.get_response_string().c_str());
log_error(link, txt);
}
// Log completed routing
tlm_command cmd = trans.get_command();
sc_dt::uint64 adr = trans.get_address();
int* ptr = reinterpret_cast<int*>(trans.get_data_ptr());
std::stringstream stream;
stream << hex << adr << " check, cmd=" << (cmd ? 'W' : 'R')
<< ", data=" << hex << *ptr;
log_info(link, stream.str());
// Allow the memory manager to free the transaction object
trans.release();
}
int MyRouter::get_link_from_extension(tlm_gp& trans){
link_extension* extension;
trans.get_extension<link_extension>(extension);
return extension->link;
}
/******************* INIT SOCKET FUNCTIONS ********************/
tlm_sync_enum MyRouter::nb_transport_bw_cb(int id, tlm_gp& trans,
tlm_phase& phase, sc_time& delay) {
log_info(id, "Backward transport callback start");
init_peq.notify(trans, phase, delay);
return TLM_ACCEPTED;
}
void MyRouter::init_peq_cb(tlm_gp& trans, const tlm_phase& phase){
int link = get_link_from_extension(trans);
log_info(link, "Initiator PEQ callback start");
log_info(link, "Phase "+string(phase.get_name())+" received");
if (phase == END_REQ || (&trans == curr_req[link] &&
phase == BEGIN_RESP)){
curr_req[link] = 0;
credit_counter[link]++;
start_pend_req(link);
}
else if (phase == BEGIN_REQ || phase == END_RESP){
log_error(link,"Illegal transaction phase received by initiator");
}
if (phase == BEGIN_RESP) {
check_transaction(link, trans);
send_end_response(link, trans);
}
}
void MyRouter::start_pend_req(int rel_link){
// find pending link
Direction pending_link = Direction::invalid;
for(uint8_t dir=0; dir<Direction::num_dirs; dir++){
// check pending link valid and send data
if(send_data_in_prog_dest[dir] == rel_link){
pending_link = Direction(dir);
bool data_sent = send_data(pending_link, rel_link,
*nxt_send_data_pend[pending_link]);
if (!data_sent){
log_error(pending_link,
"Credit counter was freed, but data can't be sent");
}
nxt_send_data_pend[pending_link] = 0;
send_data_in_prog_dest[dir] = Direction::invalid;
break;
}
}
}
void MyRouter::send_end_response(int link, tlm_gp& trans){
log_info(link, "Send end response start");
tlm_phase fw_phase = END_RESP;
sc_time delay = sc_time(RESP_END_DELAY, UNITS_DELAY);
(*init_socket[link])->nb_transport_fw(trans, fw_phase, delay);
}
/******************* TARGET SOCKET FUNCTIONS ********************/
tlm_sync_enum MyRouter::nb_transport_fw_cb(int id,
tlm_gp& trans, tlm_phase& phase, sc_time& delay){
log_info(id, "Forward transport callback start");
unsigned int len = trans.get_data_length();
unsigned char* byt = trans.get_byte_enable_ptr();
unsigned int wid = trans.get_streaming_width();
if (byt != 0) {
trans.set_response_status(TLM_BYTE_ENABLE_ERROR_RESPONSE);
return TLM_COMPLETED;
}
if (len > 4 || wid < len) {
trans.set_response_status(TLM_BURST_ERROR_RESPONSE);
return TLM_COMPLETED;
}
target_peq.notify(trans, phase, delay);
return TLM_ACCEPTED;
}
void MyRouter::target_peq_cb(tlm_gp& trans, const tlm_phase& phase){
int link = DIR::getOppositeDir(get_link_from_extension(trans));
log_info(link, "Target PEQ callback start");
log_info(link, "Phase "+string(phase.get_name())+" received");
switch (phase) {
case BEGIN_REQ:
trans.acquire();
send_end_req(link, trans);
break;
case END_RESP:
if (!resp_in_progress[link]){
log_error(link,
"Illegal transaction phase END_RESP received by target");
}
trans.release();
// Target itself is now clear to issue the next BEGIN_RESP
resp_in_progress[link] = false;
if (nxt_resp_pend[link]){
send_begin_response(link, *nxt_resp_pend[link]);
nxt_resp_pend[link] = 0;
}
break;
case END_REQ:
case BEGIN_RESP:
log_error(link,"Illegal transaction phase received by target");
break;
default:
if(phase == INTERNAL_PROC_PHASE){
switching(link, trans);
}
break;
}
}
tlm_sync_enum MyRouter::send_end_req(int link, tlm_gp& trans){
log_info(link, "Send end request start");
// Queue the acceptance and the response with the appropriate latency
sc_time delay = sc_time(REQ_END_DELAY, UNITS_DELAY);
tlm_phase phase = END_REQ;
tlm_sync_enum status = (*target_socket[link])->nb_transport_bw(
trans, phase, delay);
if (status == TLM_COMPLETED) {
log_warn(link,"Request completed, no response to be send");
trans.release();
return status;
}
// Queue internal event to mark beginning of response
delay = delay + sc_time(INTERN_PROC_DELAY, UNITS_DELAY); // Latency
target_peq.notify(trans, INTERNAL_PROC_PHASE, delay);
return status;
}
void MyRouter::send_begin_response(int link, tlm_gp& trans){
log_info(link, "Send begin response start");
resp_in_progress[link] = true;
tlm_phase phase = BEGIN_RESP;
sc_time zero_delay = SC_ZERO_TIME;
tlm_sync_enum status = (*target_socket[link])->nb_transport_bw(
trans, phase, zero_delay);
if (status == TLM_UPDATED){
target_peq.notify(trans, phase, zero_delay);
}
else if (status == TLM_COMPLETED) {
log_warn(link,"Request completed, no response to be send");
trans.release();
}
}
void MyRouter::switching(int link, tlm_gp& trans){
log_info(link, "Switching start");
trans.set_response_status(TLM_OK_RESPONSE);
// arbitration and send message to next router
Dir destination = routing(link, trans);
bool data_sent;
if (destination == Dir::num_dirs) {
data_sent = true;
check_transaction(link, trans);
// change to fatal?
log_warn(link, "Routing failed. Message couldn't be delivered");
}
else{
data_sent = send_data(link, destination, trans);
}
// validate pending data sent
if (!data_sent) {
if(nxt_send_data_pend[link]) {
log_error(link,
"Attempt to have two pending data send in same destination");
}
nxt_send_data_pend[link] = &trans;
send_data_in_prog_dest[link] = destination;
}
// validate pending response
if(resp_in_progress[link]) {
if(nxt_resp_pend[link]){
log_error(link,
"Attempt to have two pending responses in target");
}
nxt_resp_pend[link] = &trans;
}
else{ send_begin_response(link, trans); }
}
Dir MyRouter::xyz_routing(int link, uint8_t dest[3]){
if (dest[0] < rout_pos[0] && valid_links[Dir::west]){
return Dir::west;
}
else if (dest[0] > rout_pos[0] && valid_links[Dir::east]){
return Dir::east;
}
else if (dest[1] < rout_pos[1] && valid_links[Dir::south]){
return Dir::south;
}
else if (dest[1] > rout_pos[1] && valid_links[Dir::north]){
return Dir::north;
}
else if (dest[2] < rout_pos[2] && valid_links[Dir::down]){
return Dir::down;
}
else if (dest[2] > rout_pos[2] && valid_links[Dir::up]){
return Dir::up;
}
else if (dest[0] == rout_pos[0] && dest[1] == rout_pos[1] &&
dest[2] == rout_pos[2]) {
return Dir::local;
}
else { // no ideal routing found
return Dir::num_dirs;
}
}
Dir MyRouter::routing(int link, tlm_gp& trans){
int address = trans.get_address();
uint8_t dest_x = address % max_pos[0];
uint8_t dest_y = address / max_pos[0];
uint8_t dest_z = address / (max_pos[0]*max_pos[1]);
uint8_t dest[3] = {dest_x, dest_y, dest_z};
return xyz_routing(link, dest);
}
/******************* LOG FUNCTIONS ********************/
void MyRouter::log_info(uint8_t link, string msg){
string str_link = DIR::toString(link);
SC_REPORT_INFO(R_LOG, (router_name+":"+str_link+":"+msg).c_str());
}
void MyRouter::log_warn(uint8_t link, string msg){
string str_link = DIR::toString(link);
SC_REPORT_WARNING(R_LOG, (router_name+":"+str_link+":"+msg).c_str());
}
void MyRouter::log_error(uint8_t link, string msg){
string str_link = DIR::toString(link);
SC_REPORT_ERROR(R_LOG, (router_name+":"+str_link+":"+msg).c_str());
}
void MyRouter::log_fatal(uint8_t link, string msg){
string str_link = DIR::toString(link);
SC_REPORT_FATAL(R_LOG, (router_name+":"+str_link+":"+msg).c_str());
}

254
src/router/router.h Executable file
View file

@ -0,0 +1,254 @@
/*******************************************************************************
* Copyright (C) 2024 Juan Neyra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#pragma once
#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
#define SC_INCLUDE_DYNAMIC_PROCESSES
#endif
#include <systemc>
#include <string>
#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
#include "tlm_utils/peq_with_cb_and_phase.h"
#include "ratatoskrUtils/model/NetworkParticipant.h"
#include "utils/memory_manager.h"
#include "utils/configuration.h"
#include "utils/utils.h"
#include "utils/noc_logger.h"
using namespace sc_core;
using namespace sc_dt;
using namespace std;
using namespace tlm;
using namespace tlm_utils;
#define NUM_LINKS Direction::num_dirs
#define MAX_PRIORITY NUM_LINKS - 1
// Define an extension for the transactions
// link always point to initiator link of transaction
struct link_extension : tlm_extension<link_extension> {
int link;
virtual tlm_extension_base* clone() const {
return new link_extension(*this);
}
virtual void copy_from(const tlm_extension_base& ext) {
link = static_cast<const link_extension&>(ext).link;
}
};
class MyRouter : public sc_module{
public:
// TLM
typedef simple_initiator_socket_tagged<MyRouter> rout_init_socket;
typedef simple_target_socket_tagged<MyRouter> rout_targ_socket;
rout_init_socket* init_socket[NUM_LINKS];
rout_targ_socket* target_socket[NUM_LINKS];
peq_with_cb_and_phase<MyRouter> init_peq;
peq_with_cb_and_phase<MyRouter> target_peq;
tlm_gp* curr_req[NUM_LINKS];
tlm_gp* end_req_pend[NUM_LINKS];
tlm_gp* nxt_resp_pend[NUM_LINKS];
tlm_gp* nxt_send_data_pend[NUM_LINKS];
MemoryManager m_mm;
bool resp_in_progress[NUM_LINKS];
int credit_counter[NUM_LINKS];
Dir send_data_in_prog_dest[NUM_LINKS];
// attributes
string router_name;
uint8_t rout_pos[3];
uint8_t max_pos[3];
bool valid_links[NUM_LINKS];
SC_HAS_PROCESS(MyRouter);
MyRouter(sc_module_name name, uint8_t rout_pos[3],
uint8_t max_pos[3]);
~MyRouter();
private:
/**
* Configure sockets and set initial values of variables
*/
void initialize();
/**
* Send data
*
* @param link active link
* @param dest_link destination link to send the data to
* @param trans TLM generic payload object
*/
bool send_data(int link, int dest_link, tlm_gp& trans);
/**
* Checks transaction for errors, if no error found, log
* transaction and release transaction object. Called when
* transaction is completed
*
* @param link active link
* @param trans TLM generic payload object
*/
void check_transaction(int link, tlm_gp& trans);
/**
* Callback function for non blocking transport backward
*
* @param id active link
* @param trans TLM generic payload object
* @param phase TLM current phase
* @param delay TLM expected delay
*/
tlm_sync_enum nb_transport_bw_cb(int id, tlm_gp& trans,
tlm_phase& phase, sc_time& delay);
/**
* Callback function for non blocking transport forward
*
* @param id active link
* @param trans TLM generic payload object
* @param phase TLM current phase
* @param delay TLM expected delay
*/
tlm_sync_enum nb_transport_fw_cb(int id, tlm_gp& trans,
tlm_phase& phase, sc_time& delay);
/**
* Callback initiator Payload Event Queue (PEQ)
*
* @param trans TLM generic payload object
* @param phase TLM current phase
*/
void init_peq_cb(tlm_gp& trans, const tlm_phase& phase);
/**
* Callback target Payload Event Queue (PEQ)
*
* @param trans TLM generic payload object
* @param phase TLM current phase
*/
void target_peq_cb(tlm_gp& trans, const tlm_phase& phase);
/**
* Begin request
*
* @param link active link
* @param trans TLM generic payload object
* @param dest_link destination link to transmit transaction
*/
void send_begin_req(int link, tlm_gp& trans, int dest_link);
/**
* Send end request
*
* @param link active link
* @param trans TLM generic payload object
*/
tlm::tlm_sync_enum send_end_req(int link, tlm_gp& trans);
/**
* Send begin response
*
* @param link active link
* @param trans TLM generic payload object
*/
void send_begin_response(int link, tlm_gp& trans);
/**
* Target itself is now clear to resolve pending data send
* Executed when request ends
*
* @param rel_link link that is now free/released to receive data
*/
void start_pend_req(int rel_link);
/**
* Send end response
*
* @param link active link
* @param trans TLM generic payload object
*/
void send_end_response(int link, tlm_gp& trans);
/**
* Process arrived data: finds destination link and transmit it
*
* @param link active link
* @param trans TLM generic payload object
*/
void switching(int link, tlm_gp& trans);
/**
* xyz routing: x+:east, y+: north, z+: up
*
* @param link active link
* @param dest destination
*/
Dir xyz_routing(int link, uint8_t dest[3]);
/**
* Routing
*
* @param link active link
* @param trans TLM generic payload object
*/
Dir routing(int link, tlm_gp& trans);
/**
* Get link from extension
*
* @param trans TLM generic payload object
*/
int get_link_from_extension(tlm_gp& trans);
/** Log info
* @param link active link
* @param msg log message
*/
void log_info(uint8_t link, string msg);
/** Log warning
* @param link active link
* @param msg log message
*/
void log_warn(uint8_t link, string msg);
/** Log error
* @param link active link
* @param msg log message
*/
void log_error(uint8_t link, string msg);
/** Log fatal
* @param link active link
* @param msg log message
*/
void log_fatal(uint8_t link, string msg);
};

43
src/utils/configuration.h Executable file
View file

@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (C) 2024 Juan Neyra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#pragma once
#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
#define SC_INCLUDE_DYNAMIC_PROCESSES
#endif
#include <systemc>
#include "tlm.h"
using namespace sc_dt;
// router paremters
#define NUM_CREDITS 7
// router delays
#define REQ_INIT_DELAY 20
#define REQ_END_DELAY 20
#define INTERN_PROC_DELAY 20
#define RESP_END_DELAY 20
#define UNITS_DELAY SC_NS
// types
typedef tlm::tlm_generic_payload tlm_gp;

40
src/utils/memory_manager.cpp Executable file
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;
}

32
src/utils/memory_manager.h Executable file
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;
};

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

@ -0,0 +1,91 @@
#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;
}
ofstream log_file;
log_file.open(log_filename, std::ios_base::app);
log_file << ss_msg.str();
log_file.close();
}
}
void setup_logger(){
// empty old log files
ofstream log_file;
log_file.open(N_LOGFILENAME);
log_file.close();
log_file.open(R_LOGFILENAME);
log_file.close();
log_file.open(NI_LOGFILENAME);
log_file.close();
log_file.open(DEF_LOGFILENAME);
log_file.close();
sc_report_handler::set_handler(report_handler);
}
/*void creds_log_info(string router_name, uint8_t link, uint8_t num_creds,
bool is_ext){
string msg = is_ext? ": #external credits" : ": #internal credits";
SC_REPORT_INFO(NOC_LOG, (router_name + msg + ": on link "+
str_dir[link]+": "+to_string(num_creds)).c_str());
}*/
void cout_logger(string msg){
cout << sc_time_stamp() << ": "<< msg <<endl;
}

63
src/utils/noc_logger.h Normal file
View file

@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright (C) 2024 Juan Neyra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#pragma once
#include <systemc>
#include "configuration.h"
#include "utils.h"
#define DEF_LOGFILENAME "./out/report.log"
#define N_LOGFILENAME "./out/noc_conn.log"
#define N_LOG "TLM_NOC"
#define R_LOGFILENAME "./out/noc_transactions.log"
#define R_LOG "TLM_ROUTER"
#define NI_LOGFILENAME "./out/ni.log"
#define NI_LOG "TLM_NI"
#define ASCII_RED "31"
#define ASCII_GREEN "32"
#define ASCII_YELLOW "33"
const std::string str_dir[Direction::num_dirs] = {"local","east","west","north","south","up","down"};
/**
* Handles log messages (writes to console and log)
*
* @param report report object with log information
* @param actions valid actions
*/
void report_handler(const sc_report& report, const sc_actions& actions);
/**
* Configure sc report handler filename and actions
*/
void setup_logger();
//void creds_log_info(std::string router_name, uint8_t link, uint8_t num_creds, bool is_ext);
/**
* Log to cout
*/
void cout_logger(std::string msg);

39
src/utils/utils.cpp Executable file
View file

@ -0,0 +1,39 @@
#include "utils.h"
#include "configuration.h"
#include "ratatoskrUtils/utils/GlobalResources.h"
#include <fstream>
using namespace std;
void get_pos_distances(float distances[3], vector<float> gr_pos[3]){
GlobalResources& globalResources = GlobalResources::getInstance();
gr_pos[0] = globalResources.xPositions;
gr_pos[1] = globalResources.yPositions;
gr_pos[2] = globalResources.zPositions;
distances[0] = min_element(gr_pos[0].begin(), gr_pos[0].end())[1];
distances[1] = min_element(gr_pos[1].begin(), gr_pos[1].end())[1];
distances[2] = min_element(gr_pos[2].begin(), gr_pos[2].end())[1];
}
void convert_pos_to_int(float pos_float[3], uint8_t pos_int[3]){
float dists[3];
vector<float> gr_pos[3];
get_pos_distances(dists, gr_pos);
pos_int[0] = round(pos_float[0]/dists[0]);
pos_int[1] = round(pos_float[1]/dists[1]);
pos_int[2] = round(pos_float[2]/dists[2]);
}
void get_max_pos(uint8_t max_pos[3]){
float dists[3];
vector<float> gr_pos[3];
get_pos_distances(dists, gr_pos);
max_pos[0] = 1+round(max_element(gr_pos[0].begin(),
gr_pos[0].end())[0]/dists[0]);
max_pos[1] = 1+round(max_element(gr_pos[1].begin(),
gr_pos[1].end())[0]/dists[1]);
max_pos[2] = 1+round(max_element(gr_pos[2].begin(),
gr_pos[2].end())[0]/dists[2]);
}

64
src/utils/utils.h Executable file
View file

@ -0,0 +1,64 @@
/*******************************************************************************
* Copyright (C) 2024 Juan Neyra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#pragma once
#include <systemc>
#include "configuration.h"
using namespace sc_core;
enum Direction{
local = 0,
east,
west,
north,
south,
up,
down,
num_dirs,
invalid = num_dirs
};
typedef Direction Dir;
/**
* Get the distance between two elements for every axis
*
* @param distances array to store the value of distances
*/
void get_pos_distances(float distances[3]);
/**
* Transform the position in range 0 to 1 to an integer value
* in range 0 to max position-1
*
* @param pos_float array with the positions as float
* @param pos_float array to store the value of converted positions
*/
void convert_pos_to_int(float pos_float[3], uint8_t pos_int[3]);
/**
* Gets the maximum positions of the noc
*
* @param max_pos array to store the value of max positions
*/
void get_max_pos(uint8_t max_pos[3]);