2024-10-01 11:57:16 +02:00
|
|
|
/*******************************************************************************
|
|
|
|
* 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/netrace/NetracePool.h"
|
2024-10-22 11:19:30 +02:00
|
|
|
#include "processingElement/ProcessingElementCS.h"
|
|
|
|
#include "traffic/task/TaskPoolCS.h"
|
|
|
|
#include "utils/noc_logger.h"
|
2024-10-01 11:57:16 +02:00
|
|
|
|
|
|
|
|
|
|
|
NetworkManager::NetworkManager(sc_module_name nm, std::string configFolder){
|
2024-10-22 11:19:30 +02:00
|
|
|
setup_logger();
|
2024-10-01 11:57:16 +02:00
|
|
|
dbid = rep.registerElement("NetworkManager", 0);
|
|
|
|
tlmNoc = new TlmNoc("TlmNoc", configFolder);
|
|
|
|
|
|
|
|
networkParticipants.resize(globalResources.nodes.size());
|
|
|
|
createTrafficPool();
|
|
|
|
createClocks();
|
|
|
|
createNetworkParticipants();
|
|
|
|
createLinks();
|
2024-10-13 10:06:33 +02:00
|
|
|
connectUnboundedNi();
|
2024-10-01 11:57:16 +02:00
|
|
|
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() {
|
2024-10-22 11:19:30 +02:00
|
|
|
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);
|
2024-10-01 11:57:16 +02:00
|
|
|
if (globalResources.benchmark == "task") {
|
2024-10-22 11:19:30 +02:00
|
|
|
tp = std::make_unique<TaskPoolCS>();
|
2024-10-01 11:57:16 +02:00
|
|
|
} else if (globalResources.benchmark == "synthetic") {
|
|
|
|
tp = std::make_unique<SyntheticPool>();
|
|
|
|
} else {
|
|
|
|
FATAL("Please specify correct benchmark type");
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
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);
|
2024-10-13 10:06:33 +02:00
|
|
|
idNis.push_back(n.id);
|
2024-10-01 11:57:16 +02:00
|
|
|
|
|
|
|
std::string pe_name = "pe_" + std::to_string(n.id % numOfPEs);
|
2024-10-22 11:19:30 +02:00
|
|
|
ProcessingElementCS *pe = new ProcessingElementCS(pe_name.c_str(), n, tp.get());
|
2024-10-01 11:57:16 +02:00
|
|
|
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;
|
2024-10-22 11:19:30 +02:00
|
|
|
|
|
|
|
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);
|
2024-10-01 11:57:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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";
|
2024-10-13 10:06:33 +02:00
|
|
|
|
2024-10-01 11:57:16 +02:00
|
|
|
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;
|
2024-10-13 10:06:33 +02:00
|
|
|
std::string rout_type = is_node1_pe ?
|
|
|
|
node2.type->model : node1.type->model;
|
|
|
|
uint8_t lay = rout_type=="Router" ? 0 : 1;
|
|
|
|
|
2024-10-01 11:57:16 +02:00
|
|
|
NetworkInterfaceTlm* ni =
|
|
|
|
dynamic_cast<NetworkInterfaceTlm *>(
|
|
|
|
networkParticipants.at(ni_id));
|
2024-10-06 16:55:36 +02:00
|
|
|
TlmRouter* router = tlmNoc->getRouterNodeId(rout_id);
|
2024-10-13 10:06:33 +02:00
|
|
|
ni->initiator[lay]->bind(*router->target_socket[DIR::Local]);
|
|
|
|
router->init_socket[DIR::Local]->bind(*ni->target[lay]);
|
|
|
|
ni->valid_socket[lay] = true;
|
|
|
|
link_id += 2;
|
2024-10-01 11:57:16 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
LOG(true,"Unsupported number of endpoints in connection "+to_string(c.id));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-13 10:06:33 +02:00
|
|
|
void NetworkManager::connectUnboundedNi(){
|
|
|
|
// connecting unbounded network interfaces
|
|
|
|
for (uint8_t i=0; i < idNis.size(); i++){
|
|
|
|
for (uint8_t lay=0; lay < NUM_ACC_LAYERS; lay++){
|
|
|
|
NetworkInterfaceTlm* ni = dynamic_cast<NetworkInterfaceTlm*>(
|
|
|
|
networkParticipants.at(idNis[i]));
|
|
|
|
if (!ni->valid_socket[lay]){
|
|
|
|
ni_init_socket* unbound_init = new ni_init_socket(
|
|
|
|
("unb_ni_init_"+to_string(idNis[i])+"_"+to_string(lay)).c_str());
|
|
|
|
unbound_init->bind(*ni->target[lay]);
|
|
|
|
unbounded_initiators.push_back(unbound_init);
|
|
|
|
|
|
|
|
ni_targ_socket* unbound_targ = new ni_targ_socket(
|
|
|
|
("unb_ni_targ_"+to_string(idNis[i])+"_"+to_string(lay)).c_str());
|
|
|
|
ni->initiator[lay]->bind(*unbound_targ);
|
|
|
|
unbounded_targets.push_back(unbound_targ);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-10-01 11:57:16 +02:00
|
|
|
void NetworkManager::runNoC() {
|
|
|
|
for (auto &r : networkParticipants) {
|
|
|
|
if (r) {
|
|
|
|
r->initialize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tp->start();
|
2024-10-22 11:19:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************* LOG FUNCTIONS ********************/
|
|
|
|
void NetworkManager::log_info(string msg){
|
|
|
|
SC_REPORT_INFO(NM_LOG, (msg).c_str());
|
|
|
|
}
|