diff --git a/CMakeLists.txt b/CMakeLists.txt
index d2a8141..9924173 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,7 +23,12 @@ ADD_EXECUTABLE(${PROJECT_NAME}
src/networkManager/NetworkManager.cpp
src/noc/noc.cpp
src/router/router.cpp
- src/router/router_cs.cpp
+ src/router/router_cs.cpp
+ src/processingElement/ProcessingElementCS.cpp
+ src/traffic/PacketCS.cpp
+ src/traffic/task/TaskPoolCS.cpp
+ src/utils/PacketFactoryCS.cpp
+ src/utils/GlobalResourcesCS.cpp
src/utils/memory_manager.cpp
src/utils/utils.cpp
src/utils/noc_logger.cpp
diff --git a/config/XYZ_4_4_1_8B_8VC.xml b/config/XYZ_4_4_1_8B_8VC.xml
deleted file mode 100644
index 54540b2..0000000
--- a/config/XYZ_4_4_1_8B_8VC.xml
+++ /dev/null
@@ -1,508 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/config/data1.xml b/config/data1.xml
deleted file mode 100755
index b0faec3..0000000
--- a/config/data1.xml
+++ /dev/null
@@ -1,808 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/config/map1.xml b/config/map1.xml
deleted file mode 100755
index e31574e..0000000
--- a/config/map1.xml
+++ /dev/null
@@ -1,147 +0,0 @@
-
-
diff --git a/config/only_config_msg_test/config.xml b/config/only_config_msg_test/config.xml
new file mode 100755
index 0000000..51921b4
--- /dev/null
+++ b/config/only_config_msg_test/config.xml
@@ -0,0 +1,55 @@
+
+
+
+
+ report
+
+
+ config/simple_test/net.xml
+
+
+
+
+
+ task
+ config/only_config_msg_test/data.xml
+ config/only_config_msg_test/map.xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5 6 9 10
+
+
diff --git a/config/only_config_msg_test/data.xml b/config/only_config_msg_test/data.xml
new file mode 100644
index 0000000..5d88857
--- /dev/null
+++ b/config/only_config_msg_test/data.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/only_config_msg_test/map.xml b/config/only_config_msg_test/map.xml
new file mode 100644
index 0000000..8cb1846
--- /dev/null
+++ b/config/only_config_msg_test/map.xml
@@ -0,0 +1,19 @@
+
+
diff --git a/config/only_config_msg_test/net.xml b/config/only_config_msg_test/net.xml
new file mode 100644
index 0000000..7c7104a
--- /dev/null
+++ b/config/only_config_msg_test/net.xml
@@ -0,0 +1,1612 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/simple_2_layer_test/data.xml b/config/simple_2_layer_test/data.xml
index 8faccf1..0fc5fbc 100644
--- a/config/simple_2_layer_test/data.xml
+++ b/config/simple_2_layer_test/data.xml
@@ -8,13 +8,7 @@
-
-
-
-
-
-
-
+
@@ -32,6 +26,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -49,6 +60,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -57,34 +81,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -98,6 +95,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/simple_2_layer_test/map.xml b/config/simple_2_layer_test/map.xml
index 2973719..7c2fd0a 100644
--- a/config/simple_2_layer_test/map.xml
+++ b/config/simple_2_layer_test/map.xml
@@ -6,14 +6,18 @@
-
+
-
+
+
+
+
+
diff --git a/config/simple_2_layer_test/net.xml b/config/simple_2_layer_test/net.xml
index 7407f52..7c7104a 100644
--- a/config/simple_2_layer_test/net.xml
+++ b/config/simple_2_layer_test/net.xml
@@ -11,9 +11,13 @@
+
+
+
+
+
-
@@ -271,6 +275,134 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -875,5 +1007,606 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/simple_2_point_test/2pt_data.xml b/config/simple_2_point_test/2pt_data.xml
index d06a045..c91fdb8 100644
--- a/config/simple_2_point_test/2pt_data.xml
+++ b/config/simple_2_point_test/2pt_data.xml
@@ -21,7 +21,7 @@
-
+
@@ -41,7 +41,7 @@
-
+
@@ -55,12 +55,12 @@
-
+
-
+
diff --git a/config/structure.xml b/config/structure.xml
deleted file mode 100755
index 1c81b61..0000000
--- a/config/structure.xml
+++ /dev/null
@@ -1,360 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main.cpp b/src/main.cpp
index 2080a2c..667cb93 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -25,7 +25,7 @@
#include
#include "boost/program_options.hpp"
-#include "ratatoskrUtils/utils/GlobalResources.h"
+#include "utils/GlobalResourcesCS.h"
#include "networkManager/NetworkManager.h"
namespace po = boost::program_options;
@@ -46,9 +46,9 @@ int sc_main(int arg_num, char *arg_vec[])
std::string configFolder = vm["configFolder"].as();
// start simulation
+ GlobalResourcesCS& globalResources = GlobalResourcesCS::getInstance();
std::unique_ptr networkManager =
std::make_unique("Layer", configFolder);
- GlobalResources& globalResources = GlobalResources::getInstance();
cout << "Random seed " << globalResources.rd_seed << endl;
cout << endl
<< "Starting Simulation!" << endl;
diff --git a/src/networkInterface/NetworkInterfaceTlm.cpp b/src/networkInterface/NetworkInterfaceTlm.cpp
index 4d5baaf..8958660 100755
--- a/src/networkInterface/NetworkInterfaceTlm.cpp
+++ b/src/networkInterface/NetworkInterfaceTlm.cpp
@@ -53,7 +53,7 @@ NetworkInterfaceTlm::NetworkInterfaceTlm(sc_module_name nm, Node& node,
SC_METHOD(receivePacketFromPE);
sensitive << packetPortContainer->portValidIn.pos();
- for(uint lay=0; layregister_nb_transport_bw(this,
@@ -87,13 +87,14 @@ void NetworkInterfaceTlm::receiveFlitFromRouter(){
void NetworkInterfaceTlm::receivePacketFromPE() {
if (packetPortContainer->portValidIn.posedge()) {
//log_info("receive()");
- Packet* p = packetPortContainer->portDataIn.read();
+ PacketCS* p = dynamic_cast(
+ packetPortContainer->portDataIn.read());
generateFlitsForPacket(p);
packet_send_queue.push(p);
}
}
-void NetworkInterfaceTlm::get_start_end_pos_string(Packet* p,
+void NetworkInterfaceTlm::get_start_end_pos_string(PacketCS* p,
string pos[2]){
pos[0] = to_string(node.pos.x) + "," +
to_string(node.pos.y) + "," + to_string(node.pos.z);
@@ -102,7 +103,11 @@ void NetworkInterfaceTlm::get_start_end_pos_string(Packet* p,
to_string(p->dst.pos.z);
}
-void NetworkInterfaceTlm::generateFlitsForPacket(Packet* p) {
+void NetworkInterfaceTlm::generateFlitsForPacket(Packet* p){
+ /* NOT IMPLEMENTED */
+}
+
+void NetworkInterfaceTlm::generateFlitsForPacket(PacketCS* p) {
int flitsPerPacket = p->size;
for (int i = 0; iacquire();
@@ -134,7 +139,8 @@ tlm_gp* NetworkInterfaceTlm::build_transaction(Packet* p, Flit* f){
link_extension* ext = new link_extension();
ext->link = Direction::local;
ext->data_type = p->dataType;
- ext->is_config_msg = false;
+ ext->packet_id = p->id;
+ ext->flit_id = f->id;
trans->set_extension(ext);
trans->set_command(tlm::TLM_WRITE_COMMAND);
@@ -155,15 +161,16 @@ tlm_gp* NetworkInterfaceTlm::build_transaction(Packet* p, Flit* f){
}
-void NetworkInterfaceTlm::send_flit(Packet* p, Flit* f){
+void NetworkInterfaceTlm::send_flit(PacketCS* p, Flit* f){
tlm_gp* trans = build_transaction(p, f);
credit_counter--;
+ log_info("Credit counter updated: "+to_string(credit_counter));
sc_time delay = sc_time(REQ_INIT_DELAY, UNITS_DELAY);
tlm::tlm_phase send_phase = tlm::BEGIN_REQ;
int lay = p->dataType == TYPE_STREAM ? 1:0;
- log_info("Sending flit of type "+to_string(p->dataType)+
+ log_info("Sending flit of type "+STR_TYPES[p->dataType]+
" to layer "+to_string(lay));
(*initiator[lay])->nb_transport_fw(*trans, send_phase, delay);
}
@@ -175,20 +182,15 @@ int NetworkInterfaceTlm::get_type_from_extension(tlm_gp& trans){
return extension->data_type;
}
-bool NetworkInterfaceTlm::get_is_cfg_from_extension(tlm_gp& trans){
- link_extension* extension;
- trans.get_extension(extension);
- return extension->is_config_msg;
-}
-
bool NetworkInterfaceTlm::check_cs_needed(tlm_gp& trans){
int type = get_type_from_extension(trans);
- return type == TYPE_INIT_STREAM || type == TYPE_END_STREAM;
+ return type == TYPE_ROUT_CONFIG;
};
void NetworkInterfaceTlm::send_cs_rout_conf_msg(tlm_gp& trans){
- tlm::tlm_generic_payload* new_trans = m_mm.allocate();
+ tlm_gp* new_trans = m_mm.allocate();
+ // TODO: maybe use deep_copy_from function
new_trans->acquire();
new_trans->set_command(tlm::TLM_WRITE_COMMAND);
new_trans->set_address(trans.get_address());
@@ -198,12 +200,13 @@ void NetworkInterfaceTlm::send_cs_rout_conf_msg(tlm_gp& trans){
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 = Dir::local; // set direction of connected router
ext->data_type = get_type_from_extension(trans);
- ext->is_config_msg = get_is_cfg_from_extension(trans);
+ ext->packet_id = -1;
+ ext->flit_id = -1;
new_trans->set_extension(ext);
// send transaction in socket
@@ -214,7 +217,7 @@ void NetworkInterfaceTlm::send_cs_rout_conf_msg(tlm_gp& trans){
void NetworkInterfaceTlm::send_data_to_noc(){
// if no flits to transmit, generate them
- Packet* p = packet_send_queue.front();
+ PacketCS* p = packet_send_queue.front();
if (p->toTransmit.empty()){
generateFlitsForPacket(p);
}
@@ -237,7 +240,7 @@ void NetworkInterfaceTlm::send_data_to_noc(){
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]);
+ log_info("Flit sent to "+start_end_pos[1]+" from "+start_end_pos[0]);
globalReport.issueNoCInputDataAmount(sc_time_stamp(),globalResources.bitWidth);
}
@@ -256,7 +259,7 @@ void NetworkInterfaceTlm::thread() {
}
if (!packet_recv_queue.empty()) {
if (packetPortContainer->portFlowControlIn.read()) {
- Packet* p = packet_recv_queue.front();
+ PacketCS* p = packet_recv_queue.front();
packet_recv_queue.pop();
packetPortContainer->portValidOut.write(true);
packetPortContainer->portDataOut.write(p);
@@ -286,6 +289,7 @@ tlm::tlm_sync_enum NetworkInterfaceTlm::nb_transport_bw_cb(int id,
void NetworkInterfaceTlm::init_peq_cb(tlm_gp& trans, const tlm::tlm_phase& phase){
if (phase == tlm::END_REQ) {
credit_counter++;
+ log_info("Credit counter updated: "+to_string(credit_counter));
}
else if (phase == tlm::BEGIN_REQ || phase == tlm::END_RESP)
log_fatal("Illegal transaction phase received by initiator");
@@ -342,61 +346,50 @@ tlm::tlm_sync_enum NetworkInterfaceTlm::nb_transport_fw_cb(int id,
void NetworkInterfaceTlm::receive_and_process_flit(tlm_gp& trans){
trans.set_response_status(tlm::TLM_OK_RESPONSE);
- bool is_config_msg = get_is_cfg_from_extension(trans);
unsigned char* data_ptr = trans.get_data_ptr();
+ Flit* received_flit = reinterpret_cast(data_ptr);
+ PacketCS* p = dynamic_cast(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(is_config_msg){
+ // log arrived flit
+ 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);
+ // send config message when all flits of packet arrive
if(check_cs_needed(trans)){
log_info("Send router configuration message");
send_cs_rout_conf_msg(trans);
}
+ }
+ credit_counter++;
+ log_info("Credit counter updated: "+to_string(credit_counter));
+
+ // send response if not type stream
+ if(p->dataType != TYPE_STREAM){
if(resp_in_progress) {
if(nxt_resp_pend){
- log_fatal("Attempt to have two pending responses in target");
- nxt_resp_pend = &trans;
+ log_fatal("Attempt to have two pending responses in target");
+ nxt_resp_pend = &trans;
}
}
else{ send_response(trans); }
}
- else{
- Flit* received_flit = reinterpret_cast(data_ptr);
- Packet* p = received_flit->packet;
- double time = sc_time_stamp().to_double();
- auto position = find(p->inTransmit.begin(), p->inTransmit.end(), received_flit->id);
- if (position!=p->inTransmit.end())
- p->inTransmit.erase(position);
- p->transmitted.push_back(received_flit->id);
-
- // log arrived flit
- 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++;
-
- // send response if not type stream
- if(p->dataType != TYPE_STREAM){
- 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); }
- }
- }
-
}
@@ -414,6 +407,7 @@ void NetworkInterfaceTlm::target_peq_cb(tlm_gp& trans, const tlm::tlm_phase& pha
}
trans.release();
credit_counter++;
+ log_info("Credit counter updated: "+to_string(credit_counter));
// Target itself is now clear to issue the next BEGIN_RESP
resp_in_progress = false;
if (nxt_resp_pend){
@@ -466,6 +460,7 @@ void NetworkInterfaceTlm::send_response(tlm_gp& trans){
tlm::tlm_sync_enum status = (*target[0])->nb_transport_bw(
trans, bw_phase, delay);
credit_counter--;
+ log_info("Credit counter updated: "+to_string(credit_counter));
if (status == tlm::TLM_UPDATED){
target_peq.notify(trans, bw_phase, delay);
@@ -475,6 +470,7 @@ void NetworkInterfaceTlm::send_response(tlm_gp& trans){
trans.release();
resp_in_progress = false;
credit_counter++;
+ log_info("Credit counter updated: "+to_string(credit_counter));
}
}
diff --git a/src/networkInterface/NetworkInterfaceTlm.h b/src/networkInterface/NetworkInterfaceTlm.h
index 1dad581..d2b2099 100755
--- a/src/networkInterface/NetworkInterfaceTlm.h
+++ b/src/networkInterface/NetworkInterfaceTlm.h
@@ -37,9 +37,10 @@
#include "ratatoskrUtils/networkInterface/NetworkInterface.h"
#include "noc/noc.h"
+#include "traffic/PacketCS.h"
#include "utils/memory_manager.h"
#include "utils/noc_logger.h"
-
+#include "utils/GlobalResourcesCS.h"
using namespace tlm_utils;
@@ -48,8 +49,10 @@ public:
typedef simple_initiator_socket_tagged ni_init_socket;
typedef simple_target_socket_tagged ni_targ_socket;
- std::queue packet_send_queue;
- std::queue packet_recv_queue;
+ GlobalResourcesCS& globalResources = GlobalResourcesCS::getInstance();
+
+ std::queue packet_send_queue;
+ std::queue packet_recv_queue;
string ni_name;
// To PE
@@ -113,7 +116,7 @@ public:
* @param p parent packet of the flit to send
* @param f flit to send
*/
- void send_flit(Packet* p, Flit* f);
+ void send_flit(PacketCS* p, Flit* f);
/**
* Build the transaction tp send. Called by send flit
@@ -123,7 +126,7 @@ public:
*
* @return created transaction
*/
- tlm_gp* build_transaction(Packet* p, Flit* f);
+ tlm_gp* build_transaction(PacketCS* p, Flit* f);
/**
* Get type from extension
@@ -132,13 +135,6 @@ public:
*/
int get_type_from_extension(tlm_gp& trans);
- /**
- * Get variable is_cfg_msg from extension
- *
- * @param trans TLM generic payload object
- */
- bool get_is_cfg_from_extension(tlm_gp& trans);
-
/**
* If message is init streaming, a router_cs needs to be
* configured
@@ -164,14 +160,21 @@ public:
* Not implemented. TLM's target nb_transport_fw_cb callback
* used instead
*/
- void receiveFlitFromRouter();
+ void receiveFlitFromRouter() override;
/**
* Used inside receivePacketFromPE to generate flits
*
* @param p packet from which to generate flits
*/
- void generateFlitsForPacket(Packet *p);
+ void generateFlitsForPacket(Packet *p) override;
+
+ /**
+ * Used inside receivePacketFromPE to generate flits
+ *
+ * @param p packet from which to generate flits
+ */
+ void generateFlitsForPacket(PacketCS *p);
/**
* Gets the node position and the destination of packet
@@ -180,7 +183,7 @@ public:
* @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]);
+ void get_start_end_pos_string(PacketCS* p, string pos[2]);
/**
* Checks transaction for errors, if no error found, log
diff --git a/src/networkManager/NetworkManager.cpp b/src/networkManager/NetworkManager.cpp
index ca2b027..c1fa379 100755
--- a/src/networkManager/NetworkManager.cpp
+++ b/src/networkManager/NetworkManager.cpp
@@ -21,11 +21,14 @@
******************************************************************************/
#include "NetworkManager.h"
#include "ratatoskrUtils/traffic/synthetic/SyntheticPool.h"
-#include "ratatoskrUtils/traffic/task/TaskPool.h"
#include "ratatoskrUtils/traffic/netrace/NetracePool.h"
+#include "processingElement/ProcessingElementCS.h"
+#include "traffic/task/TaskPoolCS.h"
+#include "utils/noc_logger.h"
NetworkManager::NetworkManager(sc_module_name nm, std::string configFolder){
+ setup_logger();
dbid = rep.registerElement("NetworkManager", 0);
tlmNoc = new TlmNoc("TlmNoc", configFolder);
@@ -49,18 +52,17 @@ void NetworkManager::createClocks() {
void NetworkManager::createTrafficPool() {
- unsigned long numOfPEs = globalResources.nodes.size() / 2;
+ get_max_pos(max_pos);
+ // divided by num of layers (assuming equal number of nodes in each layer)
+ unsigned long numOfPEs = globalResources.nodes.size() / (max_pos[2]+1);
#ifndef ENABLE_NETRACE
if (globalResources.benchmark == "task") {
- tp = std::make_unique();
+ tp = std::make_unique();
} else if (globalResources.benchmark == "synthetic") {
tp = std::make_unique();
} else {
FATAL("Please specify correct benchmark type");
}
-#endif
-#ifdef ENABLE_NETRACE
- tp = std::make_unique("NetracePool");
#endif
tp->processingElements.resize(numOfPEs);
}
@@ -71,8 +73,6 @@ void NetworkManager::createNetworkParticipants() {
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));
@@ -80,7 +80,7 @@ void NetworkManager::createNetworkParticipants() {
idNis.push_back(n.id);
std::string pe_name = "pe_" + std::to_string(n.id % numOfPEs);
- ProcessingElementVC *pe = new ProcessingElementVC(pe_name.c_str(), n, tp.get());
+ ProcessingElementCS *pe = new ProcessingElementCS(pe_name.c_str(), n, tp.get());
std::unique_ptr sig1 =
std::make_unique(
("packetSigCon1_" + std::to_string(n.id)).c_str());
@@ -93,6 +93,14 @@ void NetworkManager::createNetworkParticipants() {
packetSignalContainers.push_back(move(sig1));
packetSignalContainers.push_back(move(sig2));
tp->processingElements.at(n.id % numOfPEs) = pe;
+
+ 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 = " initialized in position " +
+ to_string(rout_pos[0]) + "," + to_string(rout_pos[1])+
+ "," + to_string(rout_pos[2]);
+ log_info("NI "+ni_name+msg);
}
}
}
@@ -160,4 +168,10 @@ void NetworkManager::runNoC() {
}
}
tp->start();
-}
\ No newline at end of file
+}
+
+
+/******************* LOG FUNCTIONS ********************/
+void NetworkManager::log_info(string msg){
+ SC_REPORT_INFO(NM_LOG, (msg).c_str());
+}
diff --git a/src/networkManager/NetworkManager.h b/src/networkManager/NetworkManager.h
index a434b4e..7099392 100755
--- a/src/networkManager/NetworkManager.h
+++ b/src/networkManager/NetworkManager.h
@@ -28,7 +28,7 @@
#include "systemc.h"
#include "tlm.h"
-#include "ratatoskrUtils/utils/GlobalResources.h"
+#include "utils/GlobalResourcesCS.h"
#include "ratatoskrUtils/utils/Report.h"
#include "ratatoskrUtils/utils/Structures.h"
#include "ratatoskrUtils/traffic/TrafficPool.h"
@@ -49,7 +49,7 @@ public:
explicit NetworkManager(sc_module_name, std::string);
private:
- GlobalResources& globalResources = GlobalResources::getInstance();
+ GlobalResourcesCS& globalResources = GlobalResourcesCS::getInstance();
Report& rep = Report::getInstance();
int dbid;
std::vector> clocks;
@@ -61,7 +61,8 @@ private:
std::vector unbounded_initiators;
std::vector unbounded_targets;
-
+ uint8_t max_pos[3];
+
/**
* Create clocks for Ratatoskr PEs
*/
@@ -92,4 +93,9 @@ private:
* Initialize routers and starts traffic pool
*/
void runNoC();
+
+ /** Log info
+ * @param msg log message
+ */
+ void log_info(string msg);
};
\ No newline at end of file
diff --git a/src/noc/noc.cpp b/src/noc/noc.cpp
index 46d9378..791e70b 100755
--- a/src/noc/noc.cpp
+++ b/src/noc/noc.cpp
@@ -38,23 +38,27 @@ 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);
+ globalResources_legacy.readConfigFile(config_path);
globalReport.readConfigFile(config_path);
string network_path = "config/"+config_folder+"/net.xml";
//globalResources.noc_file;
globalResources.readNoCLayout(network_path);
+ globalResources_legacy.readNoCLayout(network_path);
globalResources.readTaskAndMapFiles(globalResources.data_file, globalResources.map_file);
+ globalResources_legacy.readTaskAndMapFiles(globalResources.data_file, globalResources.map_file);
globalReport.resizeMatrices();
globalResources.activateFlitTracing = false;
+ globalResources_legacy.activateFlitTracing = false;
globalResources.outputDirectory = "out";
+ globalResources_legacy.outputDirectory = "out";
}
void TlmNoc::initNoc() {
@@ -69,7 +73,9 @@ void TlmNoc::initNoc() {
string msg = " initialized in position " +
to_string(rout_pos[0]) + "," + to_string(rout_pos[1])+
"," + to_string(rout_pos[2]);
- string rout_name = "router_" + to_string(n.id);
+ string rout_name = n.type->model == "Router" ?
+ "router_" : "router_cs_";
+ rout_name += to_string(n.id);
TlmRouter* r = new TlmRouter(rout_name.c_str(), rout_pos, max_pos);
routers.push_back(r);
mapNodeRouter.insert(
@@ -161,8 +167,7 @@ TlmRouter* TlmNoc::getRouter(int id){
}
TlmRouter* TlmNoc::getRouterNodeId(int node_id){
- int rout_id = mapNodeRouter.find(node_id)->first;
- return routers.at(rout_id);
+ return routers.at(mapNodeRouter[node_id]);
}
diff --git a/src/noc/noc.h b/src/noc/noc.h
index a0aa0d6..e9a758a 100755
--- a/src/noc/noc.h
+++ b/src/noc/noc.h
@@ -34,7 +34,7 @@
#include "tlm.h"
#include "ratatoskrUtils/utils/Structures.h"
-#include "ratatoskrUtils/utils/GlobalResources.h"
+#include "utils/GlobalResourcesCS.h"
#include "ratatoskrUtils/utils/GlobalReport.h"
#include "router/router.h"
@@ -68,7 +68,8 @@ private:
std::vector unbounded_initiators;
std::vector unbounded_targets;
- GlobalResources& globalResources = GlobalResources::getInstance();
+ GlobalResourcesCS& globalResources = GlobalResourcesCS::getInstance();
+ GlobalResources& globalResources_legacy = GlobalResources::getInstance();
/**
* Initialize global resources
diff --git a/src/processingElement/ProcessingElementCS.cpp b/src/processingElement/ProcessingElementCS.cpp
new file mode 100644
index 0000000..4502d5b
--- /dev/null
+++ b/src/processingElement/ProcessingElementCS.cpp
@@ -0,0 +1,267 @@
+#include "ProcessingElementCS.h"
+#include "traffic/PacketCS.h"
+
+void ProcessingElementCS::thread(){
+ while(true) {
+ int timeStamp = static_cast(sc_time_stamp().value()/1000);
+ std::vector removeList;
+ // EXPLAIN: check if time of the task has already been passed. If it has passed remove it.
+ for (auto const& tw : destWait) {
+ DataDestinationCS dest = tw.first;
+ TaskCS task = destToTask.at(dest);
+ if (taskTerminationTime.count(task) && taskTerminationTime.at(task)node,
+ dstNode, globalResources.flitsPerPacket,
+ sc_time_stamp().to_double(), dest.dataType, dest.msg);
+ 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);
+
+ TaskCS 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) {
+ if (globalResources.benchmark=="synthetic") {
+ TaskCS task = this->destToTask.at(dw.first);
+ int minInterval = dw.first.minInterval;
+
+ if (timeStamp0) {
+ 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 ProcessingElementCS::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
+ packetFactoryCS.deletePacket(received_packet);
+ }
+ }
+}
+
+// EXPLAIN: select possible destinations and set all timings and packet numbers for these destinations they are saved in destWait
+void ProcessingElementCS::startSending(TaskCS& task)
+{
+ // EXPLAIN: There are multiple possibilities where to send the data. Select one based on probability
+ float rn = globalResources.getRandomFloatBetween(0, 1);
+ int numOfPoss = task.possibilities.size();
+ for (unsigned int i = 0; irn) {
+
+ // EXPLAIN: A possibility is chosen. Set the destinations of this possibility as the dest of the task
+ std::vector destVec = task.possibilities.at(i).dataDestinations;
+ for (DataDestinationCS& dest : destVec) {
+ destToTask[dest] = task;
+ taskToDest[task].insert(dest);
+
+ // EXPLAIN: get random packet count per dest
+ countLeft[dest] = globalResources.getRandomIntBetween(dest.minCount, dest.maxCount);
+
+ // EXPLAIN: random delay time to start sending data to dest
+ int delayTime =
+ static_cast((sc_time_stamp().value()/1000)
+ +globalResources.getRandomIntBetween(dest.minDelay, dest.maxDelay));
+
+ if (taskStartTime.count(task) && taskStartTime.at(task)>delayTime) {
+ destWait[dest] = taskStartTime.at(task);
+ }
+ else {
+ destWait[dest] = delayTime;
+ }
+ // EXPLAIN: schedule event in systemC
+ event.notify(SC_ZERO_TIME);
+ }
+ break;
+ }
+ else {
+ rn -= task.possibilities.at(i).probability;
+ }
+ }
+}
+
+void ProcessingElementCS::checkNeed()
+{
+ // EXPLAIN: iterate through received data
+ for (auto const& data : receivedData) {
+ dataTypeID_t type = data.first;
+ std::vector> removeList;
+
+ // EXPLAIN: check if there are task that need this data
+ if (neededFor.count(type)) {
+
+ // EXPLAIN: iterate over tasks needing the data
+ for (const TaskCS& t : neededFor.at(type)) {
+ std::pair pair = std::make_pair(t, type);
+ neededAmount.at(pair) -= receivedData.at(type);
+ /* This line was commented out because if a task requires several packets from several data types,
+ it says that the task is finished receiving the required packets while in fact, it still needs some packets.
+ receivedData.at(type) = 0;
+ */
+
+ // EXPLAIN: check if the needed amount (datatype for specific task) is reached. If yes remove the pair
+ if (neededAmount.at(pair)<=0) {
+ removeList.push_back(pair);
+ // This line is also commented out for the same reason mentioned above.
+ // receivedData.at(type) = -neededAmount.at(pair);
+ }
+ }
+ }
+ // EXPLAIN: remove data from lists
+ for (auto& p : removeList) {
+ neededFor.erase(p.second);
+ neededAmount.erase(p);
+ needs.at(p.first).erase(p.second);
+
+ // EXPLAIN: check if all data requirements of the task are satisfied. If yes start sending
+ if (needs.at(p.first).empty()) {
+ startSending(p.first);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/processingElement/ProcessingElementCS.h b/src/processingElement/ProcessingElementCS.h
new file mode 100644
index 0000000..eb3e08f
--- /dev/null
+++ b/src/processingElement/ProcessingElementCS.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "ratatoskrUtils/processingElement/ProcessingElementVC.h"
+#include "utils/PacketFactoryCS.h"
+#include "utils/GlobalResourcesCS.h"
+
+class ProcessingElementCS : public ProcessingElementVC {
+public:
+ std::map> neededFor;
+ std::map, int> neededAmount;
+ std::map> needs;
+ std::map receivedData;
+ std::map destToTask;
+ std::map> taskToDest;
+ std::map taskRepeatLeft;
+ std::map taskStartTime;
+ std::map taskTerminationTime;
+ std::map countLeft;
+ std::map destWait;
+
+ GlobalResourcesCS& globalResources = GlobalResourcesCS::getInstance();
+
+ PacketFactoryCS& packetFactoryCS = PacketFactoryCS::getInstance();
+
+ ProcessingElementCS(sc_module_name mn, Node& node, TrafficPool* tp):
+ ProcessingElementVC(mn, node, tp) {};
+
+ void thread() override;
+
+ void execute(TaskCS&);
+
+ void receive() override;
+
+ void startSending(TaskCS&);
+
+ void checkNeed();
+};
diff --git a/src/ratatoskrUtils/processingElement/ProcessingElement.h b/src/ratatoskrUtils/processingElement/ProcessingElement.h
index b68657c..69acec5 100755
--- a/src/ratatoskrUtils/processingElement/ProcessingElement.h
+++ b/src/ratatoskrUtils/processingElement/ProcessingElement.h
@@ -25,6 +25,7 @@
#include
#include
#include "ratatoskrUtils/model/NetworkParticipant.h"
+#include "utils/structures_cs.h"
class TrafficPool;
@@ -43,6 +44,8 @@ public:
virtual void execute(Task&) = 0;
+ virtual void execute(TaskCS&) = 0;
+
virtual void thread() = 0;
};
diff --git a/src/ratatoskrUtils/processingElement/ProcessingElementVC.cpp b/src/ratatoskrUtils/processingElement/ProcessingElementVC.cpp
index 8beb49d..dcd56d7 100755
--- a/src/ratatoskrUtils/processingElement/ProcessingElementVC.cpp
+++ b/src/ratatoskrUtils/processingElement/ProcessingElementVC.cpp
@@ -226,6 +226,7 @@ void ProcessingElementVC::thread()
void ProcessingElementVC::execute(Task& task)
{
+ cout<<"hmm"< dataDestinations;
@@ -352,7 +353,8 @@ struct DataSendPossibility {
DataSendPossibility(possID_t id, float probability, const std::vector& dataDestinations);
};
-struct Task {
+class Task {
+public:
taskID_t id;
nodeID_t nodeID;
std::vector requirements;
diff --git a/src/router/router.cpp b/src/router/router.cpp
index 8c8eb7d..5aa7c4a 100755
--- a/src/router/router.cpp
+++ b/src/router/router.cpp
@@ -75,11 +75,12 @@ tlm_gp* TlmRouter::build_transaction(tlm_gp& trans, int dest_link){
new_trans->set_dmi_allowed(false);
new_trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
- // add id to new_transaction
+ // construct new link extension from old one
link_extension* ext = new link_extension();
+ link_extension* copy_ext;
+ trans.get_extension(copy_ext);
+ ext->copy_from(*copy_ext);
ext->link = dest_link; // set direction of connected router
- ext->data_type = get_type_from_extension(trans);
- ext->is_config_msg = false;
new_trans->set_extension(ext);
return new_trans;
@@ -97,36 +98,33 @@ void TlmRouter::send_begin_req(int link, tlm_gp& trans, int dest_link){
*new_trans, phase, delay);
curr_req[dest_link] = new_trans;
credit_counter[dest_link]--;
+ log_info(link, trans,
+ "credits value updated: " + to_string(credit_counter[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");
+ log_warn(link,trans,"Request completed prematurely");
curr_req[dest_link] = 0;
check_transaction(link, *new_trans);
credit_counter[dest_link]++;
+ log_info(link, trans,
+ "credits value updated: " + to_string(credit_counter[link]));
new_trans->release();
}
}
bool TlmRouter::send_data(int link, int dest_link, tlm_gp& trans){
- log_info(link,"Send data to link:"+DIR::toString(dest_link));
+ log_info(link,trans,"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]){
+ if (credit_counter[dest_link] > 0){
send_begin_req(link, trans, dest_link);
- if(check_cs_needed(link, dest_link, trans)){
- log_info(link,"Send configuration message");
- send_cs_rout_conf_msg(link, dest_link, trans);
- }
return true;
}
else {
- if(credit_counter[dest_link] > 0){
- log_error(link,"Waiting for downstream Router!");
- }
- else{ log_error(link,"Waiting for END REQUEST"); }
+ log_warn(link,trans, "Waiting for downstream Router!");
return false;
}
}
@@ -136,7 +134,7 @@ void TlmRouter::check_transaction(int link, tlm_gp& trans) {
char txt[100];
sprintf(txt, "Transaction returned with error, response status = %s",
trans.get_response_string().c_str());
- log_error(link, txt);
+ log_warn(link,trans,txt);
}
// Log completed routing
@@ -146,7 +144,7 @@ void TlmRouter::check_transaction(int link, tlm_gp& trans) {
std::stringstream stream;
stream << hex << adr << " check, cmd=" << (cmd ? 'W' : 'R')
<< ", data=" << hex << *ptr;
- log_info(link, stream.str());
+ log_info(link,trans, stream.str());
// Allow the memory manager to free the transaction object
trans.release();
}
@@ -157,90 +155,37 @@ int TlmRouter::get_link_from_extension(tlm_gp& trans){
return extension->link;
}
-int TlmRouter::get_type_from_extension(tlm_gp& trans){
- link_extension* extension;
- trans.get_extension(extension);
- return extension->data_type;
-}
-
-bool TlmRouter::get_is_cfg_from_extension(tlm_gp& trans){
- link_extension* extension;
- trans.get_extension(extension);
- return extension->is_config_msg;
-}
-
-/******************* CS CONFIG FUNCTIONS **********************/
-bool TlmRouter::check_cs_needed(int link, int destination, tlm_gp& trans){
- int type = get_type_from_extension(trans);
- return (link != Dir::local && destination != Dir::local) &&
- (type == TYPE_INIT_STREAM || type == TYPE_END_STREAM);
-};
-
-void TlmRouter::send_cs_rout_conf_msg(int link, int destination, tlm_gp& trans){
- int dest_link = Dir::local;
- unsigned char* data = new unsigned char(link | destination<<2);
-
- tlm::tlm_generic_payload* conf_trans = m_mm.allocate();
- conf_trans->acquire();
- conf_trans->set_command(tlm::TLM_WRITE_COMMAND);
- conf_trans->set_address(rout_pos[0] + rout_pos[1]*max_pos[0] +
- rout_pos[2]*max_pos[0]*max_pos[1]);
- conf_trans->set_data_ptr(data);
- conf_trans->set_data_length(1);
- conf_trans->set_streaming_width(4);
- conf_trans->set_byte_enable_ptr(0);
- conf_trans->set_dmi_allowed(false);
- conf_trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
-
- // add id to transaction
- link_extension* ext = new link_extension();
- ext->link = dest_link; // set direction of connected router
- ext->data_type = get_type_from_extension(trans);
- ext->is_config_msg = true;
- conf_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(
- *conf_trans, phase, delay);
- curr_req[dest_link] = conf_trans;
- credit_counter[dest_link]--;
- // react to result
- if(status == TLM_UPDATED) {
- init_peq.notify(*conf_trans, phase, delay);
- }
- else if(status == TLM_COMPLETED) {
- log_error(link, "Request completed prematurely");
- curr_req[dest_link] = 0;
- check_transaction(link, *conf_trans);
- credit_counter[dest_link]++;
- conf_trans->release();
- }
+string TlmRouter::get_id_string_from_extension(tlm_gp& trans){
+ link_extension* ext;
+ trans.get_extension(ext);
+ string str_pck_id = ext->packet_id > 0 ? to_string(ext->packet_id):"none";
+ string str_flt_id = ext->flit_id > 0 ? to_string(ext->flit_id):"none";
+ return "packet " + to_string(ext->packet_id) +
+ ":flit " + to_string(ext->flit_id);
}
/******************* INIT SOCKET FUNCTIONS ********************/
tlm_sync_enum TlmRouter::nb_transport_bw_cb(int id, tlm_gp& trans,
tlm_phase& phase, sc_time& delay) {
- log_info(id, "Backward transport callback start");
+ log_info(id, trans, "Backward transport callback start");
init_peq.notify(trans, phase, delay);
return TLM_ACCEPTED;
}
void TlmRouter::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");
+ log_info(link,trans, "Initiator PEQ callback start");
+ log_info(link,trans, "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);
+ log_info(link, trans,
+ "credits value updated: " + to_string(credit_counter[link]));
+ start_pend_req(link, trans);
}
else if (phase == BEGIN_REQ || phase == END_RESP){
- log_error(link,"Illegal transaction phase received by initiator");
+ log_error(link,trans,"Illegal transaction phase received by initiator");
}
if (phase == BEGIN_RESP) {
@@ -250,7 +195,7 @@ void TlmRouter::init_peq_cb(tlm_gp& trans, const tlm_phase& phase){
}
-void TlmRouter::start_pend_req(int rel_link){
+void TlmRouter::start_pend_req(int rel_link, tlm_gp& trans){
// find pending link
Direction pending_link = Direction::invalid;
for(uint8_t dir=0; dirnb_transport_fw(trans, fw_phase, delay);
@@ -281,7 +226,7 @@ void TlmRouter::send_end_response(int link, tlm_gp& trans){
/******************* TARGET SOCKET FUNCTIONS ********************/
tlm_sync_enum TlmRouter::nb_transport_fw_cb(int id,
tlm_gp& trans, tlm_phase& phase, sc_time& delay){
- log_info(id, "Forward transport callback start");
+ log_info(id, trans, "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();
@@ -299,8 +244,8 @@ tlm_sync_enum TlmRouter::nb_transport_fw_cb(int id,
void TlmRouter::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");
+ log_info(link,trans, "Target PEQ callback start");
+ log_info(link,trans, "Phase "+string(phase.get_name())+" received");
switch (phase) {
case BEGIN_REQ:
trans.acquire();
@@ -308,7 +253,7 @@ void TlmRouter::target_peq_cb(tlm_gp& trans, const tlm_phase& phase){
break;
case END_RESP:
if (!resp_in_progress[link]){
- log_error(link,
+ log_warn(link,trans,
"Illegal transaction phase END_RESP received by target");
}
trans.release();
@@ -321,7 +266,7 @@ void TlmRouter::target_peq_cb(tlm_gp& trans, const tlm_phase& phase){
break;
case END_REQ:
case BEGIN_RESP:
- log_error(link,"Illegal transaction phase received by target");
+ log_error(link,trans,"Illegal transaction phase received by target");
break;
default:
if(phase == INTERNAL_PROC_PHASE){
@@ -332,14 +277,14 @@ void TlmRouter::target_peq_cb(tlm_gp& trans, const tlm_phase& phase){
}
tlm_sync_enum TlmRouter::send_end_req(int link, tlm_gp& trans){
- log_info(link, "Send end request start");
+ log_info(link, trans, "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");
+ log_warn(link,trans,"Request completed, no response to be send");
trans.release();
return status;
}
@@ -352,7 +297,7 @@ tlm_sync_enum TlmRouter::send_end_req(int link, tlm_gp& trans){
}
void TlmRouter::send_begin_response(int link, tlm_gp& trans){
- log_info(link, "Send begin response start");
+ log_info(link,trans, "Send begin response start");
resp_in_progress[link] = true;
tlm_phase phase = BEGIN_RESP;
sc_time zero_delay = SC_ZERO_TIME;
@@ -363,13 +308,13 @@ void TlmRouter::send_begin_response(int link, tlm_gp& trans){
target_peq.notify(trans, phase, zero_delay);
}
else if (status == TLM_COMPLETED) {
- log_warn(link,"Request completed, no response to be send");
+ log_warn(link,trans,"Request completed, no response to be send");
trans.release();
}
}
void TlmRouter::switching(int link, tlm_gp& trans){
- log_info(link, "Switching start");
+ log_info(link,trans, "Switching start");
trans.set_response_status(TLM_OK_RESPONSE);
// arbitration and send message to next router
Dir destination = routing(link, trans);
@@ -378,7 +323,7 @@ void TlmRouter::switching(int link, tlm_gp& trans){
data_sent = true;
check_transaction(link, trans);
// change to fatal?
- log_warn(link, "Routing failed. Message couldn't be delivered");
+ log_warn(link,trans, "Routing failed. Message couldn't be delivered");
}
else{
data_sent = send_data(link, destination, trans);
@@ -386,7 +331,7 @@ void TlmRouter::switching(int link, tlm_gp& trans){
// validate pending data sent
if (!data_sent) {
if(nxt_send_data_pend[link]) {
- log_error(link,
+ log_error(link,trans,
"Attempt to have two pending data send in same destination");
}
nxt_send_data_pend[link] = &trans;
@@ -395,7 +340,7 @@ void TlmRouter::switching(int link, tlm_gp& trans){
// validate pending response
if(resp_in_progress[link]) {
if(nxt_resp_pend[link]){
- log_error(link,
+ log_error(link,trans,
"Attempt to have two pending responses in target");
}
nxt_resp_pend[link] = &trans;
@@ -443,22 +388,26 @@ Dir TlmRouter::routing(int link, tlm_gp& trans){
/******************* LOG FUNCTIONS ********************/
-void TlmRouter::log_info(uint8_t link, string msg){
+void TlmRouter::log_info(uint8_t link, tlm_gp& trans, string msg){
string str_link = DIR::toString(link);
- SC_REPORT_INFO(R_LOG, (router_name+":"+str_link+":"+msg).c_str());
+ string id = get_id_string_from_extension(trans);
+ SC_REPORT_INFO(R_LOG, (router_name+":"+str_link+":"+id+":"+msg).c_str());
}
-void TlmRouter::log_warn(uint8_t link, string msg){
+void TlmRouter::log_warn(uint8_t link, tlm_gp& trans, string msg){
string str_link = DIR::toString(link);
- SC_REPORT_WARNING(R_LOG, (router_name+":"+str_link+":"+msg).c_str());
+ string id = get_id_string_from_extension(trans);
+ SC_REPORT_WARNING(R_LOG, (router_name+":"+str_link+":"+id+":"+msg).c_str());
}
-void TlmRouter::log_error(uint8_t link, string msg){
+void TlmRouter::log_error(uint8_t link, tlm_gp& trans, string msg){
string str_link = DIR::toString(link);
- SC_REPORT_ERROR(R_LOG, (router_name+":"+str_link+":"+msg).c_str());
+ string id = get_id_string_from_extension(trans);
+ SC_REPORT_ERROR(R_LOG, (router_name+":"+str_link+":"+id+":"+msg).c_str());
}
-void TlmRouter::log_fatal(uint8_t link, string msg){
+void TlmRouter::log_fatal(uint8_t link, tlm_gp& trans, string msg){
string str_link = DIR::toString(link);
- SC_REPORT_FATAL(R_LOG, (router_name+":"+str_link+":"+msg).c_str());
+ string id = get_id_string_from_extension(trans);
+ SC_REPORT_FATAL(R_LOG, (router_name+":"+str_link+":"+id+":"+msg).c_str());
}
diff --git a/src/router/router.h b/src/router/router.h
index 1a8625b..b26f0b4 100755
--- a/src/router/router.h
+++ b/src/router/router.h
@@ -47,22 +47,6 @@ using namespace tlm_utils;
DECLARE_EXTENDED_PHASE(INTERNAL_PROC_PHASE);
-// Define an extension for the transactions
-// link always point to initiator link of transaction
-struct link_extension : tlm_extension {
- int link;
- int data_type;
- bool is_config_msg;
- virtual tlm_extension_base* clone() const {
- return new link_extension(*this);
- }
- virtual void copy_from(const tlm_extension_base& ext) {
- link = static_cast(ext).link;
- data_type = static_cast(ext).data_type;
- is_config_msg = static_cast(ext).is_config_msg;
- }
-};
-
class TlmRouter : public sc_module{
public:
// TLM
@@ -114,6 +98,7 @@ class TlmRouter : public sc_module{
* @param link active link
* @param dest_link destination link to send the data to
* @param trans TLM generic payload object
+ * @return true if data was sent, otherwise, false
*/
bool send_data(int link, int dest_link, tlm_gp& trans);
@@ -127,25 +112,6 @@ class TlmRouter : public sc_module{
*/
void check_transaction(int link, tlm_gp& trans);
- /**
- * If message is init streaming, a router_cs needs to be
- * configured
- *
- * @param link active link
- * @param destination destination link to transmit transaction
- * @param trans TLM generic payload object
- */
- bool check_cs_needed(int link, int destination, tlm_gp& trans);
-
- /**
- * Sends router_cs configuration message to local link
- *
- * @param link active link
- * @param destination destination link to transmit transaction
- * @param trans TLM generic payload object
- */
- void send_cs_rout_conf_msg(int link, int destination, tlm_gp& trans);
-
/**
* Callback function for non blocking transport backward
*
@@ -153,6 +119,7 @@ class TlmRouter : public sc_module{
* @param trans TLM generic payload object
* @param phase TLM current phase
* @param delay TLM expected delay
+ * @return transaction status
*/
virtual tlm_sync_enum nb_transport_bw_cb(int id, tlm_gp& trans,
tlm_phase& phase, sc_time& delay);
@@ -164,6 +131,7 @@ class TlmRouter : public sc_module{
* @param trans TLM generic payload object
* @param phase TLM current phase
* @param delay TLM expected delay
+ * @return transaction status
*/
tlm_sync_enum nb_transport_fw_cb(int id, tlm_gp& trans,
tlm_phase& phase, sc_time& delay);
@@ -182,7 +150,7 @@ class TlmRouter : public sc_module{
* @param trans TLM generic payload object
* @param phase TLM current phase
*/
- void target_peq_cb(tlm_gp& trans, const tlm_phase& phase);
+ virtual void target_peq_cb(tlm_gp& trans, const tlm_phase& phase);
/**
* Begin request
@@ -198,6 +166,7 @@ class TlmRouter : public sc_module{
*
* @param link active link
* @param trans TLM generic payload object
+ * @return request status
*/
tlm::tlm_sync_enum send_end_req(int link, tlm_gp& trans);
@@ -215,8 +184,9 @@ class TlmRouter : public sc_module{
* Executed when request ends
*
* @param rel_link link that is now free/released to receive data
+ * @param trans TLM generic payload object
*/
- void start_pend_req(int rel_link);
+ void start_pend_req(int rel_link, tlm_gp& trans);
/**
@@ -240,6 +210,7 @@ class TlmRouter : public sc_module{
*
* @param link active link
* @param dest destination
+ * @return direction to route to
*/
Dir xyz_routing(int link, uint8_t dest[3]);
@@ -248,6 +219,7 @@ class TlmRouter : public sc_module{
*
* @param link active link
* @param trans TLM generic payload object
+ * @return direction to route to
*/
Dir routing(int link, tlm_gp& trans);
@@ -256,44 +228,39 @@ class TlmRouter : public sc_module{
* Get link from extension
*
* @param trans TLM generic payload object
+ * @return link
*/
int get_link_from_extension(tlm_gp& trans);
/**
- * Get type from extension
+ * Get id from extension as a string (id packet + "_" + id flit)
*
* @param trans TLM generic payload object
+ * @return id of packet as string
*/
- int get_type_from_extension(tlm_gp& trans);
-
- /**
- * Get variable is_cfg_msg from extension
- *
- * @param trans TLM generic payload object
- */
- bool get_is_cfg_from_extension(tlm_gp& trans);
+ string get_id_string_from_extension(tlm_gp& trans);
/** Log info
* @param link active link
* @param msg log message
*/
- void log_info(uint8_t link, string msg);
+ void log_info(uint8_t link, tlm_gp& trans, string msg);
/** Log warning
* @param link active link
* @param msg log message
*/
- void log_warn(uint8_t link, string msg);
+ void log_warn(uint8_t link, tlm_gp& trans, string msg);
/** Log error
* @param link active link
* @param msg log message
*/
- void log_error(uint8_t link, string msg);
+ void log_error(uint8_t link, tlm_gp& trans, string msg);
/** Log fatal
* @param link active link
* @param msg log message
*/
- void log_fatal(uint8_t link, string msg);
+ void log_fatal(uint8_t link, tlm_gp& trans, string msg);
};
\ No newline at end of file
diff --git a/src/router/router_cs.cpp b/src/router/router_cs.cpp
index 0fb69ed..f2a847e 100755
--- a/src/router/router_cs.cpp
+++ b/src/router/router_cs.cpp
@@ -21,6 +21,7 @@
******************************************************************************/
#include "router_cs.h"
#include "ratatoskrUtils/utils/Structures.h"
+#include "traffic/PacketCS.h"
TlmRouterCS::TlmRouterCS(sc_module_name name, uint8_t rout_pos[3],
uint8_t max_pos[3]):
@@ -65,7 +66,7 @@ void TlmRouterCS::send_begin_req(int link, tlm_gp& trans, int dest_link){
credit_counter[dest_link]--;
// react to result
if(status == TLM_COMPLETED) {
- log_error(link, "Request completed prematurely");
+ log_error(link, trans, "Request completed prematurely");
curr_req[dest_link] = 0;
check_transaction(link, *new_trans);
credit_counter[dest_link]++;
@@ -74,27 +75,30 @@ void TlmRouterCS::send_begin_req(int link, tlm_gp& trans, int dest_link){
}
-void TlmRouterCS::configure_router(tlm_gp& trans){
+void TlmRouterCS::configure_router(int link, tlm_gp& trans){
+ log_info(link, trans, "Configure router");
// get link and destination
- unsigned char* data = trans.get_data_ptr();
- int link = *data && 3;
- int destination = *data >> 2;
+ unsigned char* data_ptr = trans.get_data_ptr();
+ Flit* rec_flit = reinterpret_cast(data_ptr);
+ PacketCS* rec_packet = reinterpret_cast(rec_flit->packet);
+ int config_link = rec_packet->msg.config_link;
+ int destination = rec_packet->msg.dest_link;
// set auto router map
- set_auto_router_map(link, Dir(destination));
+ set_auto_router_map(config_link, Dir(destination));
}
/******************* INIT SOCKET FUNCTIONS ********************/
tlm_sync_enum TlmRouterCS::nb_transport_bw_cb(int id, tlm_gp& trans,
tlm_phase& phase, sc_time& delay) {
- log_info(id, "Backward transport callback start");
+ log_info(id, trans, "Backward transport callback start CS");
return TLM_ACCEPTED;
}
/******************* TARGET SOCKET FUNCTIONS ********************/
void TlmRouterCS::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");
+ log_info(link, trans, "Target PEQ callback start CS");
+ log_info(link, trans, "Phase "+string(phase.get_name())+" received");
switch (phase) {
case BEGIN_REQ:
trans.acquire();
@@ -105,10 +109,10 @@ void TlmRouterCS::target_peq_cb(tlm_gp& trans, const tlm_phase& phase){
switching(link, trans);
}
else if(phase == CONF_ROUT_PHASE){
- configure_router(trans);
+ configure_router(link, trans);
}
else{
- log_error(link,
+ log_error(link, trans,
"Illegal transaction phase received by target");
}
break;
@@ -116,14 +120,14 @@ void TlmRouterCS::target_peq_cb(tlm_gp& trans, const tlm_phase& phase){
}
tlm_sync_enum TlmRouterCS::send_end_req(int link, tlm_gp& trans){
- log_info(link, "Send end request start");
+ log_info(link, trans, "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");
+ log_warn(link, trans, "Request completed, no response to be send");
trans.release();
return status;
}
@@ -132,13 +136,14 @@ tlm_sync_enum TlmRouterCS::send_end_req(int link, tlm_gp& trans){
int type = get_type_from_extension(trans);
phase = (type == TYPE_STREAM) ? INTERNAL_PROC_PHASE :
CONF_ROUT_PHASE;
+ log_info(link, trans, "Type of processed message: "+STR_TYPES[type]);
target_peq.notify(trans, phase, delay);
return status;
}
void TlmRouterCS::switching(int link, tlm_gp& trans){
- log_info(link, "Switching start");
+ log_info(link, trans, "Switching start");
trans.set_response_status(TLM_OK_RESPONSE);
// arbitration and send message to next router
Dir destination = routing(link, trans);
@@ -147,13 +152,21 @@ void TlmRouterCS::switching(int link, tlm_gp& trans){
data_sent = true;
check_transaction(link, trans);
// change to fatal?
- log_warn(link, "Routing failed. Message couldn't be delivered");
+ log_warn(link, trans, "Routing failed. Message couldn't be delivered");
}
else{
data_sent = send_data(link, destination, trans);
}
// validate pending data sent
if (!data_sent) {
- log_error(link,"Attempt to have pending data in same destination");
+ log_error(link, trans,
+ "Attempt to have pending data in same destination");
}
}
+
+
+int TlmRouterCS::get_type_from_extension(tlm_gp& trans){
+ link_extension* extension;
+ trans.get_extension(extension);
+ return extension->data_type;
+}
diff --git a/src/router/router_cs.h b/src/router/router_cs.h
index 13c6d1a..58d3679 100755
--- a/src/router/router_cs.h
+++ b/src/router/router_cs.h
@@ -73,9 +73,10 @@ class TlmRouterCS : public TlmRouter{
* Called during configure phase. Sets a new direction
* of routing for a given link
*
+ * @param link active link
* @param trans TLM generic payload object
*/
- void configure_router(tlm_gp& trans);
+ void configure_router(int link, tlm_gp& trans);
/**
@@ -121,7 +122,7 @@ class TlmRouterCS : public TlmRouter{
* @param trans TLM generic payload object
* @param phase TLM current phase
*/
- void target_peq_cb(tlm_gp& trans, const tlm_phase& phase);
+ void target_peq_cb(tlm_gp& trans, const tlm_phase& phase) override;
/**
* Send end request
@@ -130,5 +131,13 @@ class TlmRouterCS : public TlmRouter{
* @param trans TLM generic payload object
*/
tlm::tlm_sync_enum send_end_req(int link, tlm_gp& trans);
+
+
+ /**
+ * Get type from extension
+ *
+ * @param trans TLM generic payload object
+ */
+ int get_type_from_extension(tlm_gp& trans);
};
diff --git a/src/traffic/PacketCS.cpp b/src/traffic/PacketCS.cpp
new file mode 100755
index 0000000..0b3adf3
--- /dev/null
+++ b/src/traffic/PacketCS.cpp
@@ -0,0 +1,7 @@
+#include "PacketCS.h"
+
+PacketCS::PacketCS(Node& src, Node& dst, int size, double generationTime,
+ dataTypeID_t dataType, Message msg)
+ : Packet(src, dst, size, generationTime, dataType) {
+ this->msg = msg;
+}
diff --git a/src/traffic/PacketCS.h b/src/traffic/PacketCS.h
new file mode 100755
index 0000000..3879719
--- /dev/null
+++ b/src/traffic/PacketCS.h
@@ -0,0 +1,11 @@
+# pragma once
+
+#include "ratatoskrUtils/traffic/Packet.h"
+#include "utils/structures_cs.h"
+
+struct PacketCS:Packet {
+ Message msg;
+
+ PacketCS(Node& src, Node& dst, int size, double generationTime,
+ dataTypeID_t dataType, Message msg);
+};
diff --git a/src/traffic/task/TaskPoolCS.cpp b/src/traffic/task/TaskPoolCS.cpp
new file mode 100644
index 0000000..aeb4eb4
--- /dev/null
+++ b/src/traffic/task/TaskPoolCS.cpp
@@ -0,0 +1,9 @@
+#include "TaskPoolCS.h"
+
+void TaskPoolCS::start()
+{
+ int numOfPEs = processingElements.size();
+ for (auto& task: globalResources.tasks) {
+ processingElements.at(task.nodeID%numOfPEs)->execute(task);
+ }
+}
diff --git a/src/traffic/task/TaskPoolCS.h b/src/traffic/task/TaskPoolCS.h
new file mode 100644
index 0000000..01f2e69
--- /dev/null
+++ b/src/traffic/task/TaskPoolCS.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "systemc.h"
+
+#include "utils/GlobalResourcesCS.h"
+#include "utils/structures_cs.h"
+#include "ratatoskrUtils/utils/Structures.h"
+#include "ratatoskrUtils/traffic/task/TaskPool.h"
+
+class TaskPoolCS : public TaskPool {
+
+public:
+ GlobalResourcesCS& globalResources = GlobalResourcesCS::getInstance();
+
+ TaskPoolCS(): TaskPool() {};
+
+ TaskPoolCS(int numOfElements): TaskPool(numOfElements) {};
+
+ void start() override;
+};
diff --git a/src/utils/GlobalResourcesCS.cpp b/src/utils/GlobalResourcesCS.cpp
new file mode 100644
index 0000000..8219919
--- /dev/null
+++ b/src/utils/GlobalResourcesCS.cpp
@@ -0,0 +1,722 @@
+/*******************************************************************************
+ * 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 "GlobalResourcesCS.h"
+#include
+#include
+
+GlobalResourcesCS::GlobalResourcesCS()
+ : 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;
+}
+
+GlobalResourcesCS &GlobalResourcesCS::getInstance()
+{
+ static GlobalResourcesCS instance;
+ return instance;
+}
+
+int GlobalResourcesCS::getRandomIntBetween(int min, int max)
+{
+ std::uniform_int_distribution dis(min, max);
+ return dis(*rand);
+}
+
+float GlobalResourcesCS::getRandomFloatBetween(float min, float max)
+{
+ std::uniform_real_distribution dis(min, max);
+ return dis(*rand);
+}
+
+void GlobalResourcesCS::readAttributeIfExists(pugi::xml_node node, const char *child, const char *attribute, int &var)
+{
+ readAttributeIfExists(node.child(child), attribute, var);
+}
+
+void GlobalResourcesCS::readAttributeIfExists(pugi::xml_node node, const char *attribute, int &var)
+{
+ if (!node.attribute(attribute).empty())
+ {
+ var = node.attribute(attribute).as_int();
+ }
+}
+
+int GlobalResourcesCS::readRequiredIntAttribute(pugi::xml_node node, const char *child, const char *attribute)
+{
+ return readRequiredIntAttribute(node.child(child), attribute);
+}
+
+int GlobalResourcesCS::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 GlobalResourcesCS::readRequiredFloatAttribute(pugi::xml_node node, const char *child, const char *attribute)
+{
+ return readRequiredFloatAttribute(node.child(child), attribute);
+}
+
+float GlobalResourcesCS::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
+GlobalResourcesCS::readRequiredStringAttribute(pugi::xml_node node, const char *child, const char *attribute)
+{
+ return readRequiredStringAttribute(node.child(child), attribute);
+}
+
+std::string GlobalResourcesCS::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 GlobalResourcesCS::string_split(const std::string &str, const std::string &delim)
+{
+ std::vector strings;
+ auto start = 0U;
+ auto end = str.find(delim);
+ while (end != std::string::npos)
+ {
+ strings.push_back(str.substr(start, end - start));
+ start = static_cast(end + 1);
+ end = str.find(delim, start);
+ }
+ strings.push_back(str.substr(start, end));
+ return strings;
+}
+
+std::vector GlobalResourcesCS::strs_to_ints(const std::vector &strings)
+{
+ std::vector ints{};
+ for (auto &str : strings)
+ {
+ ints.push_back(std::stoi(str));
+ }
+ return ints;
+}
+
+void GlobalResourcesCS::createRoutingTable()
+{
+ std::string filename;
+ filename = RoutingTable_file;
+
+ std::ifstream infile(filename);
+ std::string line;
+
+ int cpt_line = 0;
+
+ while (std::getline(infile, line))
+ {
+ std::istringstream iss(line);
+ std::string word;
+ int DIR;
+ std::vector v;
+ while (iss >> word)
+ {
+ DIR = std::stoi(word);
+ v.push_back(DIR);
+ }
+
+ RoutingTable.push_back(v);
+ cpt_line += 1;
+ }
+ std::cout << "Routing Table :" << std::endl;
+
+ for (auto vec : RoutingTable)
+ {
+ for (auto x : vec)
+ std::cout << x << " , ";
+ std::cout << std::endl;
+ }
+}
+
+void GlobalResourcesCS::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 GlobalResourcesCS::readNoCLayout(const std::string &nocPath)
+{
+ std::cout << "Reading NoC layout: " << nocPath << endl;
+ assert(access(nocPath.c_str(), F_OK) != -1);
+ pugi::xml_document doc;
+ pugi::xml_parse_result result = doc.load_file(nocPath.c_str());
+ assert(result && "Failed to read NoC file!");
+
+ pugi::xml_node noc_node = doc.child("network-on-chip");
+ bufferDepthType = noc_node.child("bufferDepthType").attribute("value").as_string();
+ if (!bufferDepthType.empty() && (bufferDepthType != "single" && bufferDepthType != "perVC"))
+ {
+ FATAL("The value of bufferDepthType in your network file should be either 'single' or 'perVC'!");
+ }
+
+ // topology
+ topology = noc_node.child_value("topology");
+ routingCircular = std::set({std::string("torus"), std::string("ring")}).count(topology);
+
+ readNodeTypes(noc_node);
+ readNodes(noc_node);
+ readConnections(noc_node);
+ if (!RoutingTable_mode)
+ {
+ fillDirInfoOfNodeConn();
+ }
+ else
+ {
+ fillDirInfoOfNodeConn_DM();
+ }
+
+#ifdef ENABLE_NETRACE
+ int temp_z = noc_node.child("abstract").child("z").attribute("value").as_int();
+ std::vector temp_xs;
+ std::vector temp_ys;
+ int temp;
+ std::stringstream iss;
+ iss = std::stringstream(noc_node.child("abstract").child("y").attribute("value").as_string());
+ while (iss >> temp)
+ temp_xs.push_back(temp);
+ iss = std::stringstream(noc_node.child("abstract").child("x").attribute("value").as_string());
+ while (iss >> temp)
+ temp_ys.push_back(temp);
+ int node_count = 0;
+ for(int i = 0; i < temp_z; i++)
+ node_count += (temp_xs[i] * temp_ys[i]);
+
+ // make sure node_count always larger equal than 64, because netrace simulates 64 nodes
+ // this line is to make it compatible for old simulation (old network.xml do not have xs, ys & z values.)
+ node_count = (node_count > 64)? node_count : 64;
+
+ for (int i = 0; i < node_count; ++i)
+ {
+ netraceNodeToTask.insert(std::pair(i + node_count, i));
+ netraceTaskToNode.insert(std::pair(i, i + node_count));
+ }
+#endif
+}
+
+void GlobalResourcesCS::readNodeTypes(const pugi::xml_node &noc_node)
+{
+ for (pugi::xml_node node : noc_node.child("nodeTypes").children("nodeType"))
+ {
+ dataTypeID_t typeID = node.attribute("id").as_int();
+ std::string model = node.child("model").attribute("value").as_string();
+ if (model.empty())
+ cout << "Model not set properly for nodeType with id " << typeID << endl;
+ std::string routing = node.child("routing").attribute("value").as_string();
+ std::string selection = node.child("selection").attribute("value").as_string();
+ int clkDelay = node.child("clockDelay").attribute("value").as_int();
+ std::string arbiterType = node.child("arbiterType").attribute("value").as_string();
+ auto nodeType = std::make_shared(typeID, model, routing, selection, clkDelay, arbiterType);
+ nodeTypes.emplace_back(nodeType);
+ }
+}
+
+void GlobalResourcesCS::readNodes(const pugi::xml_node &noc_node)
+{
+ for (pugi::xml_node xmlnode : noc_node.child("nodes").children("node"))
+ {
+ nodeID_t nodeID = xmlnode.attribute("id").as_int();
+ std::string name = "node_" + std::to_string(nodeID);
+ float x = xmlnode.child("xPos").attribute("value").as_float();
+ float y = xmlnode.child("yPos").attribute("value").as_float();
+ float z = xmlnode.child("zPos").attribute("value").as_float();
+ xPositions.push_back(x);
+ yPositions.push_back(y);
+ zPositions.push_back(z);
+ nodeTypeID_t nodeTypeID = xmlnode.child("nodeType").attribute("value").as_int();
+ std::shared_ptr nodeType = nodeTypes.at(nodeTypeID);
+ int layer = xmlnode.child("layer").attribute("value").as_int();
+ nodes.emplace_back(nodeID, Vec3D(x, y, z), nodeType, layer);
+ }
+ sortNodesPositions();
+}
+
+void GlobalResourcesCS::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 GlobalResourcesCS::fillDirInfoOfNodeConn()
+{
+ for (Node &node : nodes)
+ {
+ //check for common directions
+ Vec3D distance{};
+ for (int connectedNodeID : node.connectedNodes)
+ {
+ Node connectedNode = nodes.at(connectedNodeID);
+ distance = node.pos - connectedNode.pos;
+ connID_t matching_conn = node.getConnWithNode(connectedNode);
+ DIR::TYPE dir{};
+ if (distance.isZero())
+ { //no axis differs
+ dir = DIR::Local;
+ }
+ else
+ { //one axis differs
+ if (routingCircular && xPositions.size() > 2 && (node.pos.x == 0. && connectedNode.pos.x == 1. && node.pos.y == connectedNode.pos.y))
+ {
+ dir = DIR::West;
+ }
+ else if (routingCircular && xPositions.size() > 2 && (node.pos.x == 1. && connectedNode.pos.x == 0. && node.pos.y == connectedNode.pos.y))
+ {
+ dir = DIR::East;
+ }
+ else if (routingCircular && yPositions.size() > 2 && (node.pos.y == 0. && connectedNode.pos.y == 1. && node.pos.x == connectedNode.pos.x))
+ {
+ dir = DIR::South;
+ }
+ else if (routingCircular && yPositions.size() > 2 && (node.pos.y == 1. && connectedNode.pos.y == 0. && node.pos.x == connectedNode.pos.x))
+ {
+ dir = DIR::North;
+ }
+ else if (distance.x > 0)
+ {
+ dir = DIR::West;
+ }
+ else if (distance.x < 0)
+ {
+ dir = DIR::East;
+ }
+ else if (distance.y < 0)
+ {
+ dir = DIR::North;
+ }
+ else if (distance.y > 0)
+ {
+ dir = DIR::South;
+ }
+ else if (distance.z < 0)
+ {
+ dir = DIR::Up;
+ }
+ else if (distance.z > 0)
+ {
+ dir = DIR::Down;
+ }
+ }
+ node.setConPosOfDir(dir, matching_conn);
+ node.setDirOfConn(matching_conn, dir);
+ }
+ }
+}
+
+// My fillDirInfoOfNodeConn() function. Rely on Direction_Mat.txt file
+
+void GlobalResourcesCS::fillDirInfoOfNodeConn_DM()
+{
+ std::cout << "Start filling direction of nodes \n";
+
+ std::vector> directions_mat;
+ std::ifstream infile(DirectionMat_file);
+ std::string line;
+
+ int cpt_line = 0;
+
+ while (std::getline(infile, line))
+ {
+ std::istringstream iss(line);
+ std::string word;
+ int DIR;
+ std::vector v;
+ while (iss >> word)
+ {
+ DIR = std::stoi(word);
+ v.push_back(DIR);
+ }
+
+ directions_mat.push_back(v);
+ cpt_line += 1;
+ }
+ std::cout << "Direction Matrix :" << std::endl;
+
+ for (auto vec : directions_mat)
+ {
+ for (auto x : vec)
+ std::cout << x << " , ";
+ std::cout << std::endl;
+ }
+
+ for (Node &node : nodes)
+ {
+ for (int connectedNodeID : node.connectedNodes)
+ {
+ Node connectedNode = nodes.at(connectedNodeID);
+ Vec3D distance{};
+ distance = node.pos - connectedNode.pos;
+ connID_t matching_conn = node.getConnWithNode(connectedNode);
+ DIR::TYPE dir{};
+ int d;
+ if (distance.isZero())
+ { //no axis differs
+ dir = DIR::Local;
+ }
+ else
+ {
+ d = directions_mat[node.id][connectedNode.id];
+ if (d == -1)
+ {
+ std::cout << "error, no direction found \n";
+ }
+ else
+ {
+ if (d == 1)
+ {
+ dir = DIR::East;
+ }
+ else
+ {
+ if (d == 2)
+ {
+ dir = DIR::West;
+ }
+ else
+ {
+ if (d == 3)
+ {
+ dir = DIR::North;
+ }
+ else
+ {
+ if (d == 4)
+ {
+ dir = DIR::South;
+ }
+ else
+ {
+ if (d == 5)
+ {
+ dir = DIR::Up;
+ }
+ else
+ {
+ if (d == 6)
+ {
+ dir = DIR::Down;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ node.setConPosOfDir(dir, matching_conn);
+ node.setDirOfConn(matching_conn, dir);
+ }
+ }
+}
+
+void GlobalResourcesCS::readConnections(const pugi::xml_node &noc_node)
+{
+ for (pugi::xml_node xml_con : noc_node.child("connections").children("con"))
+ {
+ connID_t connID = xml_con.attribute("id").as_int();
+ std::vector nodesOfConnection{};
+ std::vector vcsCount{};
+ std::vector buffersDepth{};
+ std::vector> buffersDepths{};
+
+ for (pugi::xml_node xml_port : xml_con.child("ports").children("port"))
+ {
+ nodeID_t connectedNodeID = xml_port.child("node").attribute("value").as_int();
+ nodesOfConnection.push_back(connectedNodeID);
+ int vcCount = xml_port.child("vcCount").attribute("value").as_int();
+ vcsCount.push_back(vcCount);
+ buffersDepth.push_back(xml_port.child("bufferDepth").attribute("value").as_int());
+
+ if (bufferDepthType == "perVC")
+ {
+ std::string str_vec = xml_port.child("buffersDepths").attribute("value").as_string();
+ std::vector strings = string_split(str_vec, ",");
+ if (strings.size() != vcCount)
+ {
+ FATAL("The buffersDepths size is not equal to vcCount!");
+ }
+ std::vector bd = strs_to_ints(strings);
+ buffersDepths.push_back(bd);
+ }
+ }
+
+ assert(nodesOfConnection.size() == 2); // make sure each connection only consists 2 nodes
+
+ float length = xml_con.child("length").attribute("value").as_float();
+ int depth = xml_con.child("depth").attribute("value").as_int();
+ int width = xml_con.child("width").attribute("value").as_int();
+
+ Connection con = Connection(connID, nodesOfConnection, vcsCount, buffersDepth, buffersDepths, length, width,
+ depth);
+
+ int nodesSize = nodesOfConnection.size();
+ con.bufferUtilization.resize(nodesSize);
+ for (nodeID_t nID : con.nodes)
+ {
+ // Now that we know the nodes of each connection, we should reflect this info to the nodes themselves.
+ for (nodeID_t dstNodeID : con.nodes)
+ {
+ if (nID != dstNodeID)
+ nodes.at(nID).connectedNodes.push_back(dstNodeID);
+ }
+ nodes.at(nID).connections.push_back(con.id);
+ }
+
+ connections.push_back(con);
+ }
+}
+
+void GlobalResourcesCS::readTaskAndMapFiles(const std::string &taskFilePath, const std::string &mappingFilePath)
+{
+ std::map bindings = readMappingFile(mappingFilePath);
+ readTaskFile(taskFilePath, bindings);
+}
+
+std::map GlobalResourcesCS::readMappingFile(const std::string &mappingFilePath)
+{
+ std::cout << "Reading Mapping config: " << mappingFilePath << endl;
+ pugi::xml_document doc;
+ pugi::xml_parse_result result = doc.load_file(mappingFilePath.c_str());
+ assert(result && "Failed to read Mapping file!");
+
+ pugi::xml_node map_node = doc.child("map");
+ std::map bindings;
+ for (pugi::xml_node bind_node : map_node.children("bind"))
+ {
+ int taskID = readRequiredIntAttribute(bind_node, "task", "value");
+ int nodeID = readRequiredIntAttribute(bind_node, "node", "value");
+ bindings.emplace(taskID, nodeID);
+ }
+ return bindings;
+}
+
+void GlobalResourcesCS::readTaskFile(const std::string &taskFilePath, const std::map &bindings)
+{
+ //TODO the bindings vector was used to get the destination node and not task, of a current task.. keep it?
+ std::cout << "Reading Data config: " << taskFilePath << endl;
+ pugi::xml_document doc;
+ pugi::xml_parse_result result = doc.load_file(taskFilePath.c_str());
+ assert(result && "Failed to read Data file!");
+ pugi::xml_node data_node = doc.child("data");
+
+ // Read Data Types
+ numberOfTrafficTypes = static_cast(data_node.child("dataTypes").select_nodes("dataType").size());
+ for (pugi::xml_node type_node : data_node.child("dataTypes").children("dataType"))
+ {
+ dataTypeID_t dataTypeID = readRequiredIntAttribute(type_node, "id");
+ std::string name = readRequiredStringAttribute(type_node, "name", "value");
+ dataTypes.emplace_back(dataTypeID, name);
+ }
+ // Read Tasks
+ for (pugi::xml_node task_node : data_node.child("tasks").children("task"))
+ {
+ taskID_t taskID = task_node.attribute("id").as_int();
+ TaskCS task = TaskCS{taskID, bindings.at(taskID)};
+ readAttributeIfExists(task_node, "start", "min", task.minStart);
+ readAttributeIfExists(task_node, "start", "max", task.maxStart);
+ readAttributeIfExists(task_node, "duration", "min", task.minDuration);
+ readAttributeIfExists(task_node, "duration", "max", task.maxDuration);
+ readAttributeIfExists(task_node, "repeat", "min", task.minRepeat);
+ readAttributeIfExists(task_node, "repeat", "max", task.maxRepeat);
+
+ // Read Requirements
+ std::vector requirements{};
+ for (pugi::xml_node requirement_node : task_node.child("requires").children("requirement"))
+ {
+ dataReqID_t reqID = readRequiredIntAttribute(requirement_node, "id");
+ dataTypeID_t typeID = readRequiredIntAttribute(requirement_node, "type", "value");
+ DataRequirement req = DataRequirement{reqID, typeID};
+ readAttributeIfExists(requirement_node, "count", "min", req.minCount);
+ readAttributeIfExists(requirement_node, "count", "max", req.maxCount);
+ readAttributeIfExists(requirement_node, "count", "max", req.maxCount);
+ requirements.push_back(req);
+ }
+ task.requirements = requirements;
+
+ // Read Destinations
+ std::vector possibilities{};
+ for (pugi::xml_node generate_node : task_node.child("generates").children("possibility"))
+ {
+ possID_t possID = readRequiredIntAttribute(generate_node, "id");
+ float probability = readRequiredFloatAttribute(generate_node, "probability", "value");
+ std::vector destinations{};
+ for (pugi::xml_node destination_node : generate_node.child("destinations").children("destination"))
+ {
+ dataDestID_t dataDestID = readRequiredIntAttribute(destination_node, "id");
+ dataTypeID_t typeID = readRequiredIntAttribute(destination_node, "type", "value");
+ taskID_t destTaskID = readRequiredIntAttribute(destination_node, "task", "value");
+ int minInterval = readRequiredIntAttribute(destination_node, "interval", "min");
+ int maxInterval = readRequiredIntAttribute(destination_node, "interval", "max");
+ DataDestinationCS dataDestination = DataDestinationCS{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);
+
+ readAttributeIfExists(destination_node, "config", "link", dataDestination.msg.config_link);
+ readAttributeIfExists(destination_node, "config", "destination", dataDestination.msg.dest_link);
+
+ destinations.push_back(dataDestination);
+ }
+ possibilities.emplace_back(possID, probability, destinations);
+ }
+ task.possibilities = possibilities;
+ tasks.push_back(task);
+ }
+}
+
+std::vector GlobalResourcesCS::getNodesByPos(const Vec3D &pos)
+{
+ std::vector matching_nodes{};
+ for (auto &node : nodes)
+ if (node.getNodeByPos(pos))
+ {
+ matching_nodes.push_back(&node);
+ }
+ return matching_nodes;
+}
+
+GlobalResourcesCS::~GlobalResourcesCS()
+{
+ delete rand;
+}
diff --git a/src/utils/GlobalResourcesCS.h b/src/utils/GlobalResourcesCS.h
new file mode 100644
index 0000000..98dcae4
--- /dev/null
+++ b/src/utils/GlobalResourcesCS.h
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (C) 2018 Jan Moritz Joseph
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ ******************************************************************************/
+#pragma once
+
+#include
+#include
+#include
+#include