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