feat: adding circuit switching routers and NI
This commit is contained in:
parent
2785db31d2
commit
ae0665f69e
14 changed files with 707 additions and 103 deletions
|
@ -2,16 +2,10 @@
|
|||
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<dataTypes>
|
||||
<dataType id="0">
|
||||
<name value="dt_0"/>
|
||||
<name value="Packet"/>
|
||||
</dataType>
|
||||
<dataType id="1">
|
||||
<name value="dt_1"/>
|
||||
</dataType>
|
||||
<dataType id="2">
|
||||
<name value="dt_2"/>
|
||||
</dataType>
|
||||
<dataType id="3">
|
||||
<name value="dt_3"/>
|
||||
<name value="Streaming"/>
|
||||
</dataType>
|
||||
</dataTypes>
|
||||
<tasks>
|
||||
|
|
|
@ -2,16 +2,10 @@
|
|||
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<dataTypes>
|
||||
<dataType id="0">
|
||||
<name value="dt_0"/>
|
||||
<name value="Packet"/>
|
||||
</dataType>
|
||||
<dataType id="1">
|
||||
<name value="dt_1"/>
|
||||
</dataType>
|
||||
<dataType id="2">
|
||||
<name value="dt_2"/>
|
||||
</dataType>
|
||||
<dataType id="3">
|
||||
<name value="dt_3"/>
|
||||
<name value="Stream"/>
|
||||
</dataType>
|
||||
</dataTypes>
|
||||
<tasks>
|
||||
|
|
|
@ -123,6 +123,43 @@ void NetworkInterfaceTlm::generateFlitsForPacket(Packet* p) {
|
|||
}
|
||||
}
|
||||
|
||||
tlm_gp* NetworkInterfaceTlm::build_transaction(Packet* p, Flit* f){
|
||||
// allocate tlm object
|
||||
tlm_gp* trans = m_mm.allocate();
|
||||
trans->acquire();
|
||||
// add id to transaction
|
||||
link_extension* ext = new link_extension();
|
||||
ext->link = Direction::local;
|
||||
ext->data_type = p->dataType;
|
||||
trans->set_extension(ext);
|
||||
|
||||
trans->set_command(tlm::TLM_WRITE_COMMAND);
|
||||
|
||||
float dst_pos[3] = {p->dst.pos.x, p->dst.pos.y, p->dst.pos.z};
|
||||
uint8_t int_dest_pos[3];
|
||||
convert_pos_to_int(dst_pos, int_dest_pos);
|
||||
trans->set_address(int_dest_pos[0] + int_dest_pos[1]*max_pos[0] +
|
||||
int_dest_pos[2]*max_pos[0]*max_pos[1]);
|
||||
trans->set_data_ptr(reinterpret_cast<unsigned char*>(f));
|
||||
trans->set_data_length(p->size);
|
||||
trans->set_streaming_width(4);
|
||||
trans->set_byte_enable_ptr(0);
|
||||
trans->set_dmi_allowed(false);
|
||||
trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
|
||||
|
||||
return trans;
|
||||
}
|
||||
|
||||
|
||||
void NetworkInterfaceTlm::send_flit(Packet* p, Flit* f){
|
||||
tlm_gp* trans = build_transaction(p, f);
|
||||
credit_counter--;
|
||||
|
||||
sc_time delay = sc_time(REQ_INIT_DELAY, UNITS_DELAY);
|
||||
tlm::tlm_phase send_phase = tlm::BEGIN_REQ;
|
||||
initiator->nb_transport_fw(*trans, send_phase, delay);
|
||||
}
|
||||
|
||||
void NetworkInterfaceTlm::send_data_to_noc(){
|
||||
// if no flits to transmit, generate them
|
||||
Packet* p = packet_send_queue.front();
|
||||
|
@ -144,40 +181,12 @@ void NetworkInterfaceTlm::send_data_to_noc(){
|
|||
packet_send_queue.pop();
|
||||
}
|
||||
|
||||
// allocate tlm object
|
||||
tlm::tlm_generic_payload* trans = m_mm.allocate();
|
||||
trans->acquire();
|
||||
// add id to transaction
|
||||
link_extension* ext = new link_extension();
|
||||
ext->link = Direction::local;
|
||||
trans->set_extension(ext);
|
||||
// send flit
|
||||
trans->set_command(tlm::TLM_WRITE_COMMAND);
|
||||
|
||||
float dst_pos[3] = {p->dst.pos.x, p->dst.pos.y, p->dst.pos.z};
|
||||
uint8_t int_dest_pos[3];
|
||||
convert_pos_to_int(dst_pos, int_dest_pos);
|
||||
trans->set_address(int_dest_pos[0] + int_dest_pos[1]*max_pos[0] +
|
||||
int_dest_pos[2]*max_pos[0]*max_pos[1]);
|
||||
trans->set_data_ptr(reinterpret_cast<unsigned char*>
|
||||
(current_flit));
|
||||
trans->set_data_length(p->size);
|
||||
trans->set_streaming_width(4);
|
||||
trans->set_byte_enable_ptr(0);
|
||||
trans->set_dmi_allowed(false);
|
||||
trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
|
||||
|
||||
credit_counter--;
|
||||
|
||||
sc_time delay = sc_time(REQ_INIT_DELAY, UNITS_DELAY);
|
||||
tlm::tlm_phase send_phase = tlm::BEGIN_REQ;
|
||||
initiator->nb_transport_fw(*trans, send_phase, delay);
|
||||
send_flit(p, current_flit);
|
||||
|
||||
string start_end_pos[2];
|
||||
get_start_end_pos_string(p, start_end_pos);
|
||||
log_info("Flit send to "+start_end_pos[1]+" from "+start_end_pos[0]);
|
||||
globalReport.issueNoCInputDataAmount(sc_time_stamp(),globalResources.bitWidth);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -303,7 +312,7 @@ void NetworkInterfaceTlm::receive_and_process_flit(tlm_gp& trans){
|
|||
<< *received_flit;
|
||||
log_info(ss.str());
|
||||
}
|
||||
globalReport.issueNoCOutputDataAmount(sc_time_stamp(),globalResources.bitWidth);
|
||||
//globalReport.issueNoCOutputDataAmount(sc_time_stamp(),globalResources.bitWidth);
|
||||
if (p->toTransmit.empty() && p->inTransmit.empty())
|
||||
packet_recv_queue.push(p);
|
||||
credit_counter++;
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
// To PE
|
||||
sc_in<bool> clk;
|
||||
PacketPortContainer* packetPortContainer;
|
||||
// To Router
|
||||
// To NoC
|
||||
ni_init_socket initiator;
|
||||
ni_targ_socket target;
|
||||
tlm_utils::peq_with_cb_and_phase<NetworkInterfaceTlm> init_peq;
|
||||
|
@ -104,6 +104,24 @@ public:
|
|||
*/
|
||||
void send_data_to_noc();
|
||||
|
||||
/**
|
||||
* Sends flit to noc
|
||||
*
|
||||
* @param p parent packet of the flit to send
|
||||
* @param f flit to send
|
||||
*/
|
||||
void send_flit(Packet* p, Flit* f);
|
||||
|
||||
/**
|
||||
* Build the transaction tp send. Called by send flit
|
||||
*
|
||||
* @param p parent packet of the flit to send
|
||||
* @param f flit to send
|
||||
*
|
||||
* @return created transaction
|
||||
*/
|
||||
tlm_gp* build_transaction(Packet* p, Flit* f);
|
||||
|
||||
/**
|
||||
* Generates flits when a packet arrives
|
||||
*/
|
||||
|
@ -141,7 +159,7 @@ public:
|
|||
void check_transaction(tlm_gp& trans);
|
||||
|
||||
/**
|
||||
* Logs the arrival of a flit
|
||||
* Logs the arrival of a flit. After processing, sends a response
|
||||
*
|
||||
* @param trans TLM transaction object
|
||||
*/
|
||||
|
|
151
src/networkInterface/NetworkInterfaceTlmCS.cpp
Executable file
151
src/networkInterface/NetworkInterfaceTlmCS.cpp
Executable file
|
@ -0,0 +1,151 @@
|
|||
/*******************************************************************************
|
||||
* 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 "NetworkInterfaceTlmCS.h"
|
||||
|
||||
DECLARE_EXTENDED_PHASE(INTERNAL_PROC_PHASE);
|
||||
|
||||
NetworkInterfaceTlmCS::NetworkInterfaceTlmCS(sc_module_name nm,
|
||||
Node& node, uint8_t max_pos[3]) :
|
||||
NetworkInterfaceTlm(nm, node, max_pos) {
|
||||
initiator_cs.register_nb_transport_bw(this,
|
||||
&NetworkInterfaceTlmCS::nb_transport_bw_cb, 0);
|
||||
target_cs.register_nb_transport_fw(this,
|
||||
&NetworkInterfaceTlmCS::nb_transport_fw_cb, 0);
|
||||
}
|
||||
|
||||
NetworkInterfaceTlmCS::~NetworkInterfaceTlmCS() {
|
||||
}
|
||||
|
||||
// Flits are now chunks of data, but in programming,
|
||||
// they can still be treated the same way
|
||||
void NetworkInterfaceTlmCS::send_flit(Packet* p, Flit* f){
|
||||
tlm_gp* trans = build_transaction(p, f);
|
||||
credit_counter--;
|
||||
|
||||
sc_time delay = sc_time(REQ_INIT_DELAY, UNITS_DELAY);
|
||||
tlm::tlm_phase send_phase = tlm::BEGIN_REQ;
|
||||
|
||||
if(p->dataType == TYPE_STREAM){
|
||||
initiator_cs->nb_transport_fw(*trans, send_phase, delay);
|
||||
}
|
||||
else{
|
||||
initiator->nb_transport_fw(*trans, send_phase, delay);
|
||||
}
|
||||
}
|
||||
|
||||
bool NetworkInterfaceTlmCS::check_cs_needed(tlm_gp& trans){
|
||||
int type = get_type_from_extension(trans);
|
||||
return type == TYPE_INIT_STREAM || type == TYPE_END_STREAM;
|
||||
};
|
||||
|
||||
void NetworkInterfaceTlmCS::send_cs_rout_conf_msg(tlm_gp& trans){
|
||||
tlm::tlm_generic_payload* new_trans = m_mm.allocate();
|
||||
new_trans->acquire();
|
||||
new_trans->set_command(tlm::TLM_WRITE_COMMAND);
|
||||
new_trans->set_address(trans.get_address());
|
||||
new_trans->set_data_ptr(trans.get_data_ptr());
|
||||
new_trans->set_data_length(trans.get_data_length());
|
||||
new_trans->set_streaming_width(trans.get_streaming_width());
|
||||
new_trans->set_byte_enable_ptr(trans.get_byte_enable_ptr());
|
||||
new_trans->set_dmi_allowed(false);
|
||||
new_trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
|
||||
|
||||
// add id to new_transaction
|
||||
link_extension* ext = new link_extension();
|
||||
ext->link = dest_link; // set direction of connected router
|
||||
ext->data_type = get_type_from_extension(trans);
|
||||
new_trans->set_extension(ext);
|
||||
|
||||
// send transaction in socket
|
||||
tlm_phase phase = BEGIN_REQ;
|
||||
sc_time delay = sc_time(REQ_INIT_DELAY, UNITS_DELAY);
|
||||
initiator_cs->nb_transport_fw(*new_trans, phase, delay);
|
||||
}
|
||||
|
||||
|
||||
void NetworkInterfaceTlmCS::receive_and_process_flit(tlm_gp& trans){
|
||||
trans.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
unsigned char* data_ptr = trans.get_data_ptr();
|
||||
Flit* received_flit = reinterpret_cast<Flit*>(data_ptr);
|
||||
Packet* p = received_flit->packet;
|
||||
double time = sc_time_stamp().to_double();
|
||||
|
||||
auto position = find(p->inTransmit.begin(), p->inTransmit.end(), received_flit->id);
|
||||
if (position!=p->inTransmit.end())
|
||||
p->inTransmit.erase(position);
|
||||
p->transmitted.push_back(received_flit->id);
|
||||
|
||||
// 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 configuration message to cs_router
|
||||
if(check_cs_needed(link, trans)){
|
||||
send_cs_rout_conf_msg(trans);
|
||||
}
|
||||
|
||||
// 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); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tlm::tlm_sync_enum NetworkInterfaceTlmCS::send_end_req(tlm_gp& trans){
|
||||
// Queue the acceptance and the response with the appropriate latency
|
||||
tlm::tlm_phase bw_phase = tlm::END_REQ;
|
||||
sc_time delay = sc_time(REQ_END_DELAY, UNITS_DELAY); // Accept delay
|
||||
|
||||
tlm::tlm_sync_enum status = target->nb_transport_bw(trans,
|
||||
bw_phase, delay);
|
||||
if (status == tlm::TLM_COMPLETED) {
|
||||
trans.release();
|
||||
return status;
|
||||
}
|
||||
|
||||
// Queue internal event to mark beginning of response
|
||||
delay = p->dataType != TYPE_STREAM ?
|
||||
delay + sc_time(INTERN_PROC_DELAY, UNITS_DELAY) :
|
||||
SC_ZERO_TIME; // no processing on stream
|
||||
target_peq.notify(trans, INTERNAL_PROC_PHASE, delay);
|
||||
return status;
|
||||
}
|
66
src/networkInterface/NetworkInterfaceTlmCS.h
Executable file
66
src/networkInterface/NetworkInterfaceTlmCS.h
Executable file
|
@ -0,0 +1,66 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2024 Juan Neyra
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
|
||||
#define SC_INCLUDE_DYNAMIC_PROCESSES
|
||||
#endif
|
||||
|
||||
#include "NetworkInterfaceTlm.h"
|
||||
#include "utils/memory_manager.h"
|
||||
|
||||
class NetworkInterfaceTlmCS : public NetworkInterfaceTlm {
|
||||
public:
|
||||
SC_HAS_PROCESS(NetworkInterfaceTlmCS);
|
||||
|
||||
NetworkInterfaceTlmCS(sc_module_name nm, Node& node, uint8_t max_pos[3]);
|
||||
|
||||
~NetworkInterfaceTlmCS() override;
|
||||
|
||||
// To Circuit Switching NoC
|
||||
ni_init_socket initiator_cs;
|
||||
ni_targ_socket target_cs;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Sends flit to packet switching noc or circuit switching noc
|
||||
*
|
||||
* @param p parent packet of the flit to send
|
||||
* @param f flit to send
|
||||
*/
|
||||
void send_flit(Packet* p, Flit* f) override;
|
||||
|
||||
/**
|
||||
* Logs the arrival of a flit. After processing, sends a
|
||||
* response if needed
|
||||
*
|
||||
* @param trans TLM transaction object
|
||||
*/
|
||||
void receive_and_process_flit(tlm_gp& trans) override;
|
||||
|
||||
/**
|
||||
* Send end request
|
||||
*
|
||||
* @param trans TLM generic payload object
|
||||
*/
|
||||
tlm::tlm_sync_enum send_end_req(tlm_gp& trans) override;
|
||||
};
|
|
@ -96,7 +96,6 @@ void NetworkManager::createNetworkParticipants() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
void NetworkManager::createLinks() {
|
||||
int link_id = 0;
|
||||
for (auto &c : globalResources.connections) {
|
||||
|
@ -113,7 +112,7 @@ void NetworkManager::createLinks() {
|
|||
NetworkInterfaceTlm* ni =
|
||||
dynamic_cast<NetworkInterfaceTlm *>(
|
||||
networkParticipants.at(ni_id));
|
||||
MyRouter* router = tlmNoc->getRouterNodeId(rout_id);
|
||||
TlmRouter* router = tlmNoc->getRouterNodeId(rout_id);
|
||||
ni->initiator.bind(*router->target_socket[DIR::Local]);
|
||||
router->init_socket[DIR::Local]->bind(ni->target);
|
||||
}
|
||||
|
|
|
@ -62,8 +62,7 @@ void TlmNoc::initNoc() {
|
|||
get_max_pos(max_pos);
|
||||
|
||||
for (Node &n : globalResources.nodes) {
|
||||
if (n.type->model == "RouterVC") {
|
||||
string name = "router_" + to_string(n.id);
|
||||
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);
|
||||
|
@ -72,7 +71,15 @@ void TlmNoc::initNoc() {
|
|||
to_string(rout_pos[0]) + "," + to_string(rout_pos[1]) +
|
||||
"," + to_string(rout_pos[2]);
|
||||
log_info(msg);
|
||||
MyRouter *r = new MyRouter(name.c_str(), rout_pos, max_pos);
|
||||
TlmRouter *r;
|
||||
if (n.type->model == "Router") {
|
||||
string name = "router_" + to_string(n.id);
|
||||
r = new TlmRouter(name.c_str(), rout_pos, max_pos);
|
||||
}
|
||||
else {
|
||||
string name = "routercs_" + to_string(n.id);
|
||||
r = new TlmRouterCS(name.c_str(), rout_pos, max_pos);
|
||||
}
|
||||
routers.push_back(r);
|
||||
int id = routers.size()-1;
|
||||
mapNodeRouter.insert(
|
||||
|
@ -85,8 +92,8 @@ void TlmNoc::initNoc() {
|
|||
void TlmNoc::connectRouters(Node node1, Node node2, int link){
|
||||
int n1_id = mapNodeRouter[node1.id];
|
||||
int n2_id = mapNodeRouter[node2.id];
|
||||
if(node1.type->model == "RouterVC" &&
|
||||
node2.type->model == "RouterVC"){
|
||||
if((node1.type->model=="Router" || node1.type->model=="RouterCS") &&
|
||||
(node2.type->model=="Router" || node1.type->model=="RouterCS")){
|
||||
int connDir = node1.getDirOfCon(link);
|
||||
int opposDir = DIR::getOppositeDir(connDir);
|
||||
|
||||
|
@ -100,7 +107,8 @@ void TlmNoc::connectRouters(Node node1, Node node2, int link){
|
|||
DIR::toString(connDir), DIR::toString(opposDir));
|
||||
}
|
||||
else{
|
||||
int r_id = node1.type->model == "RouterVC" ? n1_id:n2_id;
|
||||
int r_id = (node1.type->model == "Router" ||
|
||||
node1.type->model == "RouterCS") ? 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;
|
||||
|
@ -153,11 +161,11 @@ void TlmNoc::connectNoc(){
|
|||
connectUnbounded();
|
||||
}
|
||||
|
||||
MyRouter* TlmNoc::getRouter(int id){
|
||||
TlmRouter* TlmNoc::getRouter(int id){
|
||||
return routers.at(id);
|
||||
}
|
||||
|
||||
MyRouter* TlmNoc::getRouterNodeId(int node_id){
|
||||
TlmRouter* TlmNoc::getRouterNodeId(int node_id){
|
||||
int rout_id = mapNodeRouter.find(node_id)->first;
|
||||
return routers.at(rout_id);
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@ using namespace tlm;
|
|||
|
||||
class TlmNoc : public sc_module {
|
||||
public:
|
||||
typedef tlm_utils::simple_initiator_socket_tagged<MyRouter> tlm_init_socket;
|
||||
typedef tlm_utils::simple_target_socket_tagged<MyRouter> tlm_targ_socket;
|
||||
typedef tlm_utils::simple_initiator_socket_tagged<TlmRouter> tlm_init_socket;
|
||||
typedef tlm_utils::simple_target_socket_tagged<TlmRouter> tlm_targ_socket;
|
||||
|
||||
SC_HAS_PROCESS(TlmNoc);
|
||||
|
||||
|
@ -55,11 +55,11 @@ public:
|
|||
std::vector<tlm_targ_socket*> api_targets;
|
||||
uint8_t max_pos[3];
|
||||
std::map<int, int> mapNodeRouter;
|
||||
MyRouter* getRouter(int id);
|
||||
MyRouter* getRouterNodeId(int node_id);
|
||||
TlmRouter* getRouter(int id);
|
||||
TlmRouter* getRouterNodeId(int node_id);
|
||||
|
||||
private:
|
||||
std::vector<MyRouter*> routers;
|
||||
std::vector<TlmRouter*> routers;
|
||||
uint8_t num_rout_x;
|
||||
uint8_t num_rout_y;
|
||||
uint8_t num_rout_z;
|
||||
|
|
|
@ -25,39 +25,36 @@
|
|||
#include <array>
|
||||
#include "ratatoskrUtils/utils/Structures.h"
|
||||
|
||||
DECLARE_EXTENDED_PHASE(INTERNAL_PROC_PHASE);
|
||||
|
||||
/* Constructor */
|
||||
MyRouter::MyRouter(sc_module_name name, uint8_t rout_pos[3],
|
||||
TlmRouter::TlmRouter(sc_module_name name, uint8_t rout_pos[3],
|
||||
uint8_t max_pos[3]):
|
||||
sc_module(name), router_name(name),
|
||||
init_peq(this, &MyRouter::init_peq_cb),
|
||||
target_peq(this, &MyRouter::target_peq_cb) {
|
||||
init_peq(this, &TlmRouter::init_peq_cb),
|
||||
target_peq(this, &TlmRouter::target_peq_cb) {
|
||||
sc_report_handler::set_actions(R_LOG, SC_INFO, SC_LOG|SC_DISPLAY);
|
||||
copy(rout_pos, rout_pos + 3, this->rout_pos);
|
||||
copy(max_pos, max_pos + 3, this->max_pos);
|
||||
initialize();
|
||||
}
|
||||
|
||||
MyRouter::~MyRouter(){
|
||||
TlmRouter::~TlmRouter(){
|
||||
}
|
||||
|
||||
void MyRouter::initialize(){
|
||||
void TlmRouter::initialize(){
|
||||
for(int link=0; link<NUM_LINKS; link++){
|
||||
init_socket[link] = new rout_init_socket((router_name+"_"+
|
||||
to_string(link)+"_init").c_str());
|
||||
(*init_socket[link]).register_nb_transport_bw(this,
|
||||
&MyRouter::nb_transport_bw_cb, link);
|
||||
&TlmRouter::nb_transport_bw_cb, link);
|
||||
|
||||
target_socket[link] = new rout_targ_socket((router_name+"_"+
|
||||
to_string(link)+"_targ").c_str());
|
||||
(*target_socket[link]).register_nb_transport_fw(this,
|
||||
&MyRouter::nb_transport_fw_cb, link);
|
||||
&TlmRouter::nb_transport_fw_cb, link);
|
||||
|
||||
valid_links[link] = false;
|
||||
resp_in_progress[link] = false;
|
||||
nxt_resp_pend[link] = 0;
|
||||
end_req_pend[link] = 0;
|
||||
nxt_send_data_pend[link] = 0;
|
||||
curr_req[link] = 0;
|
||||
send_data_in_prog_dest[link] = Direction::invalid;
|
||||
|
@ -66,8 +63,7 @@ void MyRouter::initialize(){
|
|||
}
|
||||
|
||||
/******************* COMMON FUNCTIONS ********************/
|
||||
void MyRouter::send_begin_req(int link, tlm_gp& trans, int dest_link){
|
||||
// create new transaction
|
||||
tlm_gp* TlmRouter::build_transaction(tlm_gp& trans, int dest_link){
|
||||
tlm::tlm_generic_payload* new_trans = m_mm.allocate();
|
||||
new_trans->acquire();
|
||||
new_trans->set_command(tlm::TLM_WRITE_COMMAND);
|
||||
|
@ -82,8 +78,15 @@ void MyRouter::send_begin_req(int link, tlm_gp& trans, int dest_link){
|
|||
// add id to new_transaction
|
||||
link_extension* ext = new link_extension();
|
||||
ext->link = dest_link; // set direction of connected router
|
||||
ext->data_type = get_type_from_extension(trans);
|
||||
new_trans->set_extension(ext);
|
||||
|
||||
return new_trans;
|
||||
}
|
||||
|
||||
void TlmRouter::send_begin_req(int link, tlm_gp& trans, int dest_link){
|
||||
tlm_gp* new_trans = build_transaction(trans, dest_link);
|
||||
|
||||
// send transaction in socket
|
||||
tlm_phase phase = BEGIN_REQ;
|
||||
sc_time delay = sc_time(REQ_INIT_DELAY, UNITS_DELAY);
|
||||
|
@ -107,11 +110,14 @@ void MyRouter::send_begin_req(int link, tlm_gp& trans, int dest_link){
|
|||
}
|
||||
|
||||
|
||||
bool MyRouter::send_data(int link, int dest_link, tlm_gp& trans){
|
||||
bool TlmRouter::send_data(int link, int dest_link, tlm_gp& trans){
|
||||
log_info(link,"Send data to link:"+DIR::toString(dest_link));
|
||||
// check credits or that previous message is complete
|
||||
if (credit_counter[dest_link] > 0 && !curr_req[dest_link]){
|
||||
send_begin_req(link, trans, dest_link);
|
||||
if(check_cs_needed(link, trans)){
|
||||
send_cs_rout_conf_msg(link, dest_link, trans);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
@ -123,7 +129,7 @@ bool MyRouter::send_data(int link, int dest_link, tlm_gp& trans){
|
|||
}
|
||||
}
|
||||
|
||||
void MyRouter::check_transaction(int link, tlm_gp& trans) {
|
||||
void TlmRouter::check_transaction(int link, tlm_gp& trans) {
|
||||
if(trans.is_response_error()) {
|
||||
char txt[100];
|
||||
sprintf(txt, "Transaction returned with error, response status = %s",
|
||||
|
@ -143,22 +149,78 @@ void MyRouter::check_transaction(int link, tlm_gp& trans) {
|
|||
trans.release();
|
||||
}
|
||||
|
||||
int MyRouter::get_link_from_extension(tlm_gp& trans){
|
||||
int TlmRouter::get_link_from_extension(tlm_gp& trans){
|
||||
link_extension* extension;
|
||||
trans.get_extension<link_extension>(extension);
|
||||
return extension->link;
|
||||
}
|
||||
|
||||
int TlmRouter::get_type_from_extension(tlm_gp& trans){
|
||||
link_extension* extension;
|
||||
trans.get_extension<link_extension>(extension);
|
||||
return extension->data_type;
|
||||
}
|
||||
|
||||
/******************* 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;
|
||||
int* data = new int(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(sizeof(int));
|
||||
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);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/******************* INIT SOCKET FUNCTIONS ********************/
|
||||
tlm_sync_enum MyRouter::nb_transport_bw_cb(int id, tlm_gp& trans,
|
||||
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");
|
||||
init_peq.notify(trans, phase, delay);
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
void MyRouter::init_peq_cb(tlm_gp& trans, const tlm_phase& phase){
|
||||
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");
|
||||
|
@ -179,7 +241,7 @@ void MyRouter::init_peq_cb(tlm_gp& trans, const tlm_phase& phase){
|
|||
}
|
||||
|
||||
|
||||
void MyRouter::start_pend_req(int rel_link){
|
||||
void TlmRouter::start_pend_req(int rel_link){
|
||||
// find pending link
|
||||
Direction pending_link = Direction::invalid;
|
||||
for(uint8_t dir=0; dir<Direction::num_dirs; dir++){
|
||||
|
@ -199,7 +261,7 @@ void MyRouter::start_pend_req(int rel_link){
|
|||
}
|
||||
}
|
||||
|
||||
void MyRouter::send_end_response(int link, tlm_gp& trans){
|
||||
void TlmRouter::send_end_response(int link, tlm_gp& trans){
|
||||
log_info(link, "Send end response start");
|
||||
tlm_phase fw_phase = END_RESP;
|
||||
sc_time delay = sc_time(RESP_END_DELAY, UNITS_DELAY);
|
||||
|
@ -208,7 +270,7 @@ void MyRouter::send_end_response(int link, tlm_gp& trans){
|
|||
|
||||
|
||||
/******************* TARGET SOCKET FUNCTIONS ********************/
|
||||
tlm_sync_enum MyRouter::nb_transport_fw_cb(int id,
|
||||
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");
|
||||
unsigned int len = trans.get_data_length();
|
||||
|
@ -226,7 +288,7 @@ tlm_sync_enum MyRouter::nb_transport_fw_cb(int id,
|
|||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
void MyRouter::target_peq_cb(tlm_gp& trans, const tlm_phase& phase){
|
||||
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");
|
||||
|
@ -260,7 +322,7 @@ void MyRouter::target_peq_cb(tlm_gp& trans, const tlm_phase& phase){
|
|||
}
|
||||
}
|
||||
|
||||
tlm_sync_enum MyRouter::send_end_req(int link, tlm_gp& trans){
|
||||
tlm_sync_enum TlmRouter::send_end_req(int link, tlm_gp& trans){
|
||||
log_info(link, "Send end request start");
|
||||
// Queue the acceptance and the response with the appropriate latency
|
||||
sc_time delay = sc_time(REQ_END_DELAY, UNITS_DELAY);
|
||||
|
@ -280,7 +342,7 @@ tlm_sync_enum MyRouter::send_end_req(int link, tlm_gp& trans){
|
|||
return status;
|
||||
}
|
||||
|
||||
void MyRouter::send_begin_response(int link, tlm_gp& trans){
|
||||
void TlmRouter::send_begin_response(int link, tlm_gp& trans){
|
||||
log_info(link, "Send begin response start");
|
||||
resp_in_progress[link] = true;
|
||||
tlm_phase phase = BEGIN_RESP;
|
||||
|
@ -297,7 +359,7 @@ void MyRouter::send_begin_response(int link, tlm_gp& trans){
|
|||
}
|
||||
}
|
||||
|
||||
void MyRouter::switching(int link, tlm_gp& trans){
|
||||
void TlmRouter::switching(int link, tlm_gp& trans){
|
||||
log_info(link, "Switching start");
|
||||
trans.set_response_status(TLM_OK_RESPONSE);
|
||||
// arbitration and send message to next router
|
||||
|
@ -333,7 +395,7 @@ void MyRouter::switching(int link, tlm_gp& trans){
|
|||
}
|
||||
|
||||
|
||||
Dir MyRouter::xyz_routing(int link, uint8_t dest[3]){
|
||||
Dir TlmRouter::xyz_routing(int link, uint8_t dest[3]){
|
||||
if (dest[0] < rout_pos[0] && valid_links[Dir::west]){
|
||||
return Dir::west;
|
||||
}
|
||||
|
@ -361,7 +423,7 @@ Dir MyRouter::xyz_routing(int link, uint8_t dest[3]){
|
|||
}
|
||||
}
|
||||
|
||||
Dir MyRouter::routing(int link, tlm_gp& trans){
|
||||
Dir TlmRouter::routing(int link, tlm_gp& trans){
|
||||
int address = trans.get_address();
|
||||
uint8_t dest_x = address % max_pos[0];
|
||||
uint8_t dest_y = address / max_pos[0];
|
||||
|
@ -372,22 +434,22 @@ Dir MyRouter::routing(int link, tlm_gp& trans){
|
|||
|
||||
|
||||
/******************* LOG FUNCTIONS ********************/
|
||||
void MyRouter::log_info(uint8_t link, string msg){
|
||||
void TlmRouter::log_info(uint8_t link, string msg){
|
||||
string str_link = DIR::toString(link);
|
||||
SC_REPORT_INFO(R_LOG, (router_name+":"+str_link+":"+msg).c_str());
|
||||
}
|
||||
|
||||
void MyRouter::log_warn(uint8_t link, string msg){
|
||||
void TlmRouter::log_warn(uint8_t link, string msg){
|
||||
string str_link = DIR::toString(link);
|
||||
SC_REPORT_WARNING(R_LOG, (router_name+":"+str_link+":"+msg).c_str());
|
||||
}
|
||||
|
||||
void MyRouter::log_error(uint8_t link, string msg){
|
||||
void TlmRouter::log_error(uint8_t link, string msg){
|
||||
string str_link = DIR::toString(link);
|
||||
SC_REPORT_ERROR(R_LOG, (router_name+":"+str_link+":"+msg).c_str());
|
||||
}
|
||||
|
||||
void MyRouter::log_fatal(uint8_t link, string msg){
|
||||
void TlmRouter::log_fatal(uint8_t link, string msg){
|
||||
string str_link = DIR::toString(link);
|
||||
SC_REPORT_FATAL(R_LOG, (router_name+":"+str_link+":"+msg).c_str());
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "tlm_utils/simple_target_socket.h"
|
||||
#include "tlm_utils/peq_with_cb_and_phase.h"
|
||||
|
||||
#include "ratatoskrUtils/model/NetworkParticipant.h"
|
||||
#include "utils/memory_manager.h"
|
||||
#include "utils/configuration.h"
|
||||
#include "utils/utils.h"
|
||||
|
@ -47,30 +46,33 @@ using namespace tlm_utils;
|
|||
#define NUM_LINKS Direction::num_dirs
|
||||
#define MAX_PRIORITY NUM_LINKS - 1
|
||||
|
||||
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<link_extension> {
|
||||
int link;
|
||||
int data_type;
|
||||
virtual tlm_extension_base* clone() const {
|
||||
return new link_extension(*this);
|
||||
}
|
||||
virtual void copy_from(const tlm_extension_base& ext) {
|
||||
link = static_cast<const link_extension&>(ext).link;
|
||||
data_type = static_cast<const link_extension&>(ext).data_type;
|
||||
}
|
||||
};
|
||||
|
||||
class MyRouter : public sc_module{
|
||||
class TlmRouter : public sc_module{
|
||||
public:
|
||||
// TLM
|
||||
typedef simple_initiator_socket_tagged<MyRouter> rout_init_socket;
|
||||
typedef simple_target_socket_tagged<MyRouter> rout_targ_socket;
|
||||
typedef simple_initiator_socket_tagged<TlmRouter> rout_init_socket;
|
||||
typedef simple_target_socket_tagged<TlmRouter> rout_targ_socket;
|
||||
|
||||
rout_init_socket* init_socket[NUM_LINKS];
|
||||
rout_targ_socket* target_socket[NUM_LINKS];
|
||||
peq_with_cb_and_phase<MyRouter> init_peq;
|
||||
peq_with_cb_and_phase<MyRouter> target_peq;
|
||||
peq_with_cb_and_phase<TlmRouter> init_peq;
|
||||
peq_with_cb_and_phase<TlmRouter> target_peq;
|
||||
tlm_gp* curr_req[NUM_LINKS];
|
||||
tlm_gp* end_req_pend[NUM_LINKS];
|
||||
tlm_gp* nxt_resp_pend[NUM_LINKS];
|
||||
tlm_gp* nxt_send_data_pend[NUM_LINKS];
|
||||
MemoryManager m_mm;
|
||||
|
@ -84,10 +86,10 @@ class MyRouter : public sc_module{
|
|||
uint8_t max_pos[3];
|
||||
bool valid_links[NUM_LINKS];
|
||||
|
||||
SC_HAS_PROCESS(MyRouter);
|
||||
MyRouter(sc_module_name name, uint8_t rout_pos[3],
|
||||
SC_HAS_PROCESS(TlmRouter);
|
||||
TlmRouter(sc_module_name name, uint8_t rout_pos[3],
|
||||
uint8_t max_pos[3]);
|
||||
~MyRouter();
|
||||
~TlmRouter();
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -95,6 +97,16 @@ class MyRouter : public sc_module{
|
|||
*/
|
||||
void initialize();
|
||||
|
||||
/**
|
||||
* Build the transaction tp send. Called by send flit
|
||||
*
|
||||
* @param trans TLM generic payload object
|
||||
* @param dest_link destination link to send the data to
|
||||
*
|
||||
* @return created transaction
|
||||
*/
|
||||
tlm_gp* build_transaction(tlm_gp& trans, int dest_link);
|
||||
|
||||
/**
|
||||
* Send data
|
||||
*
|
||||
|
@ -114,6 +126,25 @@ class MyRouter : 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
|
||||
*/
|
||||
bool send_cs_rout_conf_msg(int link, int destination, tlm_gp& trans);
|
||||
|
||||
/**
|
||||
* Callback function for non blocking transport backward
|
||||
*
|
||||
|
|
174
src/router/router_cs.cpp
Executable file
174
src/router/router_cs.cpp
Executable file
|
@ -0,0 +1,174 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2024 Juan Neyra
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
#include "router_cs.h"
|
||||
|
||||
TlmRouterCS::TlmRouterCS(sc_module_name name, uint8_t rout_pos[3],
|
||||
uint8_t max_pos[3]):
|
||||
TlmRouter(name, rout_pos, max_pos) {
|
||||
}
|
||||
|
||||
TlmRouterCS::~TlmRouterCS(){
|
||||
}
|
||||
|
||||
void TlmRouterCS::initialize(){
|
||||
for(int link=0; link<NUM_LINKS; link++){
|
||||
init_socket[link] = new rout_init_socket(("csnoc_"+router_name+
|
||||
"_"+to_string(link)+"_init").c_str());
|
||||
(*init_socket[link]).register_nb_transport_bw(this,
|
||||
&TlmRouterCS::nb_transport_bw_cb, link);
|
||||
|
||||
target_socket[link] = new rout_targ_socket(("csnoc_"+router_name+
|
||||
"_"+to_string(link)+"_targ").c_str());
|
||||
(*target_socket[link]).register_nb_transport_fw(this,
|
||||
&TlmRouterCS::nb_transport_fw_cb, link);
|
||||
|
||||
valid_links[link] = false;
|
||||
//resp_in_progress[link] = false;
|
||||
//nxt_resp_pend[link] = 0;
|
||||
end_req_pend[link] = 0;
|
||||
nxt_send_data_pend[link] = 0;
|
||||
curr_req[link] = 0;
|
||||
//send_data_in_prog_dest[link] = Direction::invalid;
|
||||
credit_counter[link] = NUM_CREDITS_CS;
|
||||
auto_rout_map[link] = Direction::invalid;
|
||||
}
|
||||
}
|
||||
|
||||
Dir TlmRouterCS::routing(int link, tlm_gp& trans){
|
||||
return auto_rout_map[link];
|
||||
}
|
||||
|
||||
void TlmRouterCS::set_auto_router_map(int link, Dir dir){
|
||||
auto_rout_map[link] = dir;
|
||||
}
|
||||
|
||||
Dir TlmRouterCS::get_auto_router_map(int link){
|
||||
return auto_rout_map[link];
|
||||
}
|
||||
|
||||
|
||||
void TlmRouter::send_begin_req(int link, tlm_gp& trans, int dest_link){
|
||||
tlm_gp* new_trans = build_transaction(trans, dest_link);
|
||||
|
||||
// send transaction in socket
|
||||
tlm_phase phase = BEGIN_REQ;
|
||||
sc_time delay = sc_time(REQ_INIT_DELAY, UNITS_DELAY);
|
||||
|
||||
tlm_sync_enum status;
|
||||
status = (*init_socket[dest_link])->nb_transport_fw(
|
||||
*new_trans, phase, delay);
|
||||
curr_req[dest_link] = new_trans;
|
||||
credit_counter[dest_link]--;
|
||||
// react to result
|
||||
if(status == TLM_COMPLETED) {
|
||||
log_error(link, "Request completed prematurely");
|
||||
curr_req[dest_link] = 0;
|
||||
check_transaction(link, *new_trans);
|
||||
credit_counter[dest_link]++;
|
||||
new_trans->release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void configure_router(tlm_gp& trans){
|
||||
// get link and destination
|
||||
int* data = trans.get_data_ptr();
|
||||
int link = data && 3;
|
||||
int destination = data >> 2;
|
||||
// set auto router map
|
||||
set_auto_router_map(link, destination);
|
||||
}
|
||||
|
||||
/******************* 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");
|
||||
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");
|
||||
switch (phase) {
|
||||
case BEGIN_REQ:
|
||||
trans.acquire();
|
||||
send_end_req(link, trans);
|
||||
break;
|
||||
default:
|
||||
if(phase == INTERNAL_PROC_PHASE){
|
||||
switching(link, trans);
|
||||
}
|
||||
else if(phase == CONF_ROUT_PHASE){
|
||||
configure_router(trans);
|
||||
}
|
||||
else{
|
||||
log_error(link,
|
||||
"Illegal transaction phase received by target");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tlm_sync_enum TlmRouterCS::send_end_req(int link, tlm_gp& trans){
|
||||
log_info(link, "Send end request start");
|
||||
// Queue the acceptance and the response with the appropriate latency
|
||||
sc_time delay = sc_time(REQ_END_DELAY, UNITS_DELAY);
|
||||
tlm_phase phase = END_REQ;
|
||||
tlm_sync_enum status = (*target_socket[link])->nb_transport_bw(
|
||||
trans, phase, delay);
|
||||
if (status == TLM_COMPLETED) {
|
||||
log_warn(link,"Request completed, no response to be send");
|
||||
trans.release();
|
||||
return status;
|
||||
}
|
||||
delay = SC_ZERO_TIME; // no processing in circuit switching routers
|
||||
// Queue internal event to mark beginning of response
|
||||
int type = get_type_from_extension(trans);
|
||||
sc_phase phase = (type == TYPE_STREAM) ? INTERNAL_PROC_PHASE :
|
||||
CONF_ROUT_PHASE;
|
||||
target_peq.notify(trans, phase, delay);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void TlmRouterCS::switching(int link, tlm_gp& trans){
|
||||
log_info(link, "Switching start");
|
||||
trans.set_response_status(TLM_OK_RESPONSE);
|
||||
// arbitration and send message to next router
|
||||
Dir destination = routing(link, trans);
|
||||
bool data_sent;
|
||||
if (destination == Dir::num_dirs) {
|
||||
data_sent = true;
|
||||
check_transaction(link, trans);
|
||||
// change to fatal?
|
||||
log_warn(link, "Routing failed. Message couldn't be delivered");
|
||||
}
|
||||
else{
|
||||
data_sent = send_data(link, destination, trans);
|
||||
}
|
||||
// validate pending data sent
|
||||
if (!data_sent) {
|
||||
log_error(link,"Attempt to have pending data in same destination");
|
||||
}
|
||||
}
|
91
src/router/router_cs.h
Executable file
91
src/router/router_cs.h
Executable file
|
@ -0,0 +1,91 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2024 Juan Neyra
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
|
||||
#define SC_INCLUDE_DYNAMIC_PROCESSES
|
||||
#endif
|
||||
|
||||
#include <systemc>
|
||||
#include <string>
|
||||
#include "tlm.h"
|
||||
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
using namespace std;
|
||||
using namespace tlm;
|
||||
using namespace tlm_utils;
|
||||
|
||||
DECLARE_EXTENDED_PHASE(CONF_ROUT_PHASE);
|
||||
|
||||
class TlmRouterCS : public sc_module, TlmRouter{
|
||||
public:
|
||||
SC_HAS_PROCESS(TlmRouterCS);
|
||||
TlmRouterCS(sc_module_name name, uint8_t rout_pos[3],
|
||||
uint8_t max_pos[3]);
|
||||
~TlmRouterCS();
|
||||
|
||||
void set_auto_router_map(int link, Dir dir);
|
||||
Dir get_auto_router_map(int link);
|
||||
|
||||
private:
|
||||
Dir auto_rout_map[NUM_LINKS] = {0};
|
||||
|
||||
/**
|
||||
* Configure sockets and set initial values of variables
|
||||
*/
|
||||
void initialize() override;
|
||||
|
||||
/**
|
||||
* Routing
|
||||
*
|
||||
* @param link active link
|
||||
* @param trans TLM generic payload object
|
||||
*/
|
||||
Dir TlmRouterCS::routing(int link, tlm_gp& trans) override;
|
||||
|
||||
|
||||
/**
|
||||
* Process arrived data: finds destination link and transmit it
|
||||
*
|
||||
* @param link active link
|
||||
* @param trans TLM generic payload object
|
||||
*/
|
||||
void switching(int link, tlm_gp& trans);
|
||||
|
||||
/**
|
||||
* Send end request
|
||||
*
|
||||
* @param link active link
|
||||
* @param trans TLM generic payload object
|
||||
*/
|
||||
tlm::tlm_sync_enum send_end_req(int link, tlm_gp& trans) override;
|
||||
|
||||
/**
|
||||
* Callback target Payload Event Queue (PEQ)
|
||||
*
|
||||
* @param trans TLM generic payload object
|
||||
* @param phase TLM current phase
|
||||
*/
|
||||
void target_peq_cb(tlm_gp& trans, const tlm_phase& phase) override;
|
||||
};
|
||||
|
|
@ -41,3 +41,10 @@ using namespace sc_dt;
|
|||
|
||||
// types
|
||||
typedef tlm::tlm_generic_payload tlm_gp;
|
||||
|
||||
// for circuit switching noc
|
||||
#define NUM_CREDITS_CS 1
|
||||
#define TYPE_PACKET 0
|
||||
#define TYPE_STREAM 1
|
||||
#define TYPE_INIT_STREAM 2
|
||||
#define TYPE_END_STREAM 3
|
||||
|
|
Loading…
Reference in a new issue