/* Updating the entries in the routing table based on the routes existing in configuration file*/ void net_routing_table_route_update(struct net_routing_table_t *routing_table, struct net_node_t *src_node, struct net_node_t *dst_node, struct net_node_t *next_node, int vc_num) { int k; int route_check = 0 ; struct net_buffer_t *buffer; struct net_link_t *link; struct net_routing_table_entry_t *entry; entry = net_routing_table_lookup(routing_table, src_node, dst_node); entry->next_node = next_node; entry->output_buffer = NULL ; /* Look for output buffer */ buffer = NULL; assert(list_count(src_node->output_buffer_list)); for (k = 0; (k < list_count(src_node->output_buffer_list) && route_check != 1); k++) { buffer = list_get(src_node->output_buffer_list, k); link = buffer->link; assert(link); if ((link->dst_node == next_node)) { if (vc_num == 0) { entry->output_buffer = buffer; route_check = 1; } else { if (link->virtual_channel <= vc_num) fatal("Network %s: %s.to.%s: wrong virtual channel number is used in route \n %s", routing_table->net->name, src_node->name, dst_node->name, err_net_config); struct net_buffer_t *vc_buffer; vc_buffer = list_get(src_node->output_buffer_list, (buffer->index)+vc_num); assert(vc_buffer->link == buffer->link); entry->output_buffer = vc_buffer; route_check = 1; } } } /*If there is not a route between the source node and next node , error */ if (route_check == 0) fatal("Network %s : route %s.to.%s = %s : Missing Link \n%s ", routing_table->net->name, src_node->name, dst_node->name, next_node->name, err_net_routing); /* Find cycle in routing table */ net_routing_table_cycle_detection(routing_table); }
/* Calculate shortest paths Floyd-Warshall algorithm.*/ void net_routing_table_floyd_warshall(struct net_routing_table_t *routing_table) { int i, j, k ; struct net_t *net = routing_table->net; struct net_node_t *next_node; struct net_buffer_t *buffer; struct net_link_t *link; struct net_routing_table_entry_t *entry; /* The 'routing_table_entry->next_node' values do * not necessarily point to the immediate next hop after this. */ for (k = 0; k < net->node_count; k++) { for (i = 0; i < net->node_count; i++) { for (j = 0; j < net->node_count; j++) { struct net_node_t *node_i; struct net_node_t *node_j; struct net_node_t *node_k; struct net_routing_table_entry_t *entry_i_k; struct net_routing_table_entry_t *entry_k_j; struct net_routing_table_entry_t *entry_i_j; node_i = list_get(net->node_list, i); node_j = list_get(net->node_list, j); node_k = list_get(net->node_list, k); entry_i_k = net_routing_table_lookup(routing_table, node_i, node_k); entry_k_j = net_routing_table_lookup(routing_table, node_k, node_j); entry_i_j = net_routing_table_lookup(routing_table, node_i, node_j); if (entry_i_k->cost + entry_k_j->cost < entry_i_j->cost) { entry_i_j->cost = entry_i_k->cost + entry_k_j->cost; entry_i_j->next_node = node_k; } } } } /* Calculate output buffers */ for (i = 0; i < net->node_count; i++) { for (j = 0; j < net->node_count; j++) { struct net_node_t *node_i; struct net_node_t *node_j; struct net_routing_table_entry_t *entry_i_j; node_i = list_get(net->node_list, i); node_j = list_get(net->node_list, j); entry_i_j = net_routing_table_lookup(routing_table, node_i, node_j); next_node = entry_i_j->next_node; /* No route to node */ if (!next_node) { entry_i_j->output_buffer = NULL; continue; } /* Follow path */ for (;;) { entry = net_routing_table_lookup(routing_table, node_i, next_node); if (entry->cost <= 1) break; next_node = entry->next_node; } /* Look for output buffer */ buffer = NULL; assert(list_count(node_i->output_buffer_list)); for (k = 0; k < list_count(node_i->output_buffer_list); k++) { buffer = list_get(node_i->output_buffer_list, k); link = buffer->link; assert(link); if (link->dst_node == next_node) break; } assert(k < list_count(node_i->output_buffer_list)); entry_i_j->output_buffer = buffer; } } /* Update routing table entries to point to the next hop */ for (i = 0; i < net->node_count; i++) { for (j = 0; j < net->node_count; j++) { struct net_node_t *node_i; struct net_node_t *node_j; struct net_routing_table_entry_t *entry_i_j; node_i = list_get(net->node_list, i); node_j = list_get(net->node_list, j); entry_i_j = net_routing_table_lookup(routing_table, node_i, node_j); buffer = entry_i_j->output_buffer; if (buffer) { link = buffer->link; assert(link); entry_i_j->next_node = link->dst_node; } } } /* Find cycle in routing table */ net_routing_table_cycle_detection(routing_table); }
/* Updating the entries in the routing table based on the routes existing in * configuration file */ void net_routing_table_route_update(struct net_routing_table_t *routing_table, struct net_node_t *src_node, struct net_node_t *dst_node, struct net_node_t *next_node, int vc_num) { int route_check = 0; int k; struct net_buffer_t *buffer; struct net_link_t *link; struct net_bus_t *bus; struct net_routing_table_entry_t *entry; entry = net_routing_table_lookup(routing_table, src_node, dst_node); entry->next_node = next_node; entry->output_buffer = NULL; /* Look for output buffer */ buffer = NULL; assert(list_count(src_node->output_buffer_list)); for (k = 0; (k < list_count(src_node->output_buffer_list) && route_check != 1); k++) { buffer = list_get(src_node->output_buffer_list, k); if (buffer->kind == net_buffer_link) { link = buffer->link; assert(link); assert(!buffer->bus); if ((link->dst_node == next_node)) { if (vc_num == 0) { entry->output_buffer = buffer; route_check = 1; } else { if (link->virtual_channel <= vc_num) fatal("Network %s: %s.to.%s: wrong virtual channel " "number is used in route \n %s", routing_table->net->name, src_node->name, dst_node->name, net_err_config); struct net_buffer_t *vc_buffer; vc_buffer = list_get(src_node->output_buffer_list, (buffer->index)+vc_num); assert(vc_buffer->link == buffer->link); entry->output_buffer = vc_buffer; route_check = 1; } } } else if (buffer->kind == net_buffer_bus || buffer->kind == net_buffer_photonic) { assert(!buffer->link); bus = buffer->bus; assert(bus); struct net_node_t * bus_node; bus_node = bus->node; for (int i = 0; i < list_count(bus_node->dst_buffer_list); i++) { struct net_buffer_t *dst_buffer; dst_buffer = list_get(bus_node->dst_buffer_list, i); if (dst_buffer->node == next_node) { entry->output_buffer = buffer; route_check = 1; break; } } if (vc_num != 0) fatal("Network %s: %s.to.%s: BUS does not contain virtual channel \n %s", routing_table->net->name, src_node->name, dst_node->name, net_err_config); } } /*If there is not a route between the source node and next node , error */ if (route_check == 0) fatal("Network %s : route %s.to.%s = %s : Missing connection \n%s ", routing_table->net->name, src_node->name, dst_node->name, next_node->name, net_err_route_step); /* Find cycle in routing table */ net_routing_table_cycle_detection(routing_table); }