tlm_noc_sim/src/networkManager/NetworkManager.cpp

176 lines
7.4 KiB
C++
Raw Normal View History

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"
#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){
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();
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() {
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") {
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);
idNis.push_back(n.id);
2024-10-01 11:57:16 +02:00
std::string pe_name = "pe_" + std::to_string(n.id % numOfPEs);
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;
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-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;
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));
TlmRouter* router = tlmNoc->getRouterNodeId(rout_id);
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));
}
}
}
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();
}
/******************* LOG FUNCTIONS ********************/
void NetworkManager::log_info(string msg){
SC_REPORT_INFO(NM_LOG, (msg).c_str());
}