static void update_subtree(t_rg_node * rg_node){ float r_upstream_max; t_linked_rg_edge_ref *child_link = rg_node->child_list; t_rg_node * child = NULL; t_linked_rg_edge_ref *parent_link = NULL; t_rg_node * parent = NULL; while(child_link!=NULL){ child = child_link->edge->child; if(!g_rr_switch_inf[child_link->edge->iswitch].buffered){ r_upstream_max = 0.0; parent_link = child->u.parent_list; while(parent_link!=NULL){ parent = parent_link->edge->u.parent; if(parent->inode!=rg_node->inode && !g_rr_switch_inf[parent_link->edge->iswitch].buffered && parent->R_upstream > r_upstream_max){ r_upstream_max = parent->R_upstream; } parent_link = parent_link->next; } if(rg_node->R_upstream>r_upstream_max){ child->R_upstream = rg_node->R_upstream + g_rr_switch_inf[child_link->edge->iswitch].R + rr_node[child->inode].R; update_subtree(child); } } child_link = child_link->next; } }
/*--------------------------------------------------------------- Routine : database_modified_callback Purpose: To perform all the actions required to the tree whenever the database changes. This change may be as a result to the event data, a change of database or an asscciation change. ---------------------------------------------------------------*/ void database_modified_callback( void *client_data ) { TREE_PIC_FOREST *tree_pic_forest = (TREE_PIC_FOREST *)client_data; update_subtree( tree_pic_forest->tree_pic->tree->top_item, tree_pic_forest->tree_pic->tree->database ); } /* database_modified_callback */
void remove_connection_from_route_timing_graph(int icon, t_rg_node *root, t_rg_node *sink_rg_node) { /* Adds the most recently finished wire segment to the routing tree, and * * updates the Tdel, etc. numbers for the rest of the routing tree. hptr * * is the heap pointer of the SINK that was reached. This routine returns * * a pointer to the rt_node of the SINK that it adds to the routing. */ t_rg_node *rg_node, *parent_rg_node; t_linked_rg_edge_ref *parent_link, *it, *prev, *sel; t_rg_edge *edge; struct s_trace *btptr; float R_upstream_max; bool found; if (root->child_list == NULL || sink_rg_node == NULL) return; it = NULL; prev = NULL; rg_node = sink_rg_node; btptr = back_trace_head_con[icon]->next->next; parent_link = rg_node->u.parent_list; #ifdef DEBUG if (parent_link == NULL) { printf("Error: parent of IPIN is NULL, should be a wire node.\n"); exit(5); } #endif while (parent_link != NULL) { edge = parent_link->edge; parent_rg_node = edge->u.parent; if (edge->usage == 1) { //printf("inode %d, type %d, parent %d\n", rg_node->inode, rr_node[rg_node->inode].type,parent_rg_node->inode); rg_node->no_parents--; /* Select and remove parent link */ //printf("Select and remove parent link\n"); R_upstream_max = 0.0; sel = NULL; prev = NULL; found = false; it = rg_node->u.parent_list; while (it != NULL) { //printf("it->edge->u.parent->inode %d, parent_rg_node->inode %d\n",it->edge->u.parent->inode,parent_rg_node->inode); if (!found && it->edge->u.parent->inode == parent_rg_node->inode) { sel = it; found = true; } else if ((it->edge->u.parent->R_upstream > R_upstream_max)) { R_upstream_max = it->edge->u.parent->R_upstream; } if (!found) prev = it; it = it->next; } if (sel->edge->u.parent->R_upstream > R_upstream_max) { rg_node->R_upstream = R_upstream_max; update_subtree(rg_node); } if (prev == NULL) { rg_node->u.parent_list = sel->next; } else { prev->next = sel->next; } free_rg_link(sel); /* Select and remove child link of parent */ //printf("Select and remove child link of parent\n"); prev = NULL; it = parent_rg_node->child_list; //printf("it->edge->child->inode %d, rg_node->inode %d\n",it->edge->child->inode,rg_node->inode); while (it->edge->child->inode != rg_node->inode) { prev = it; it = it->next; //printf("it->edge->child->inode %d, rg_node->inode %d\n",it->edge->child->inode,rg_node->inode); } if (prev == NULL) { parent_rg_node->child_list = it->next; } else { prev->next = it->next; } free_rg_link(it); if (rr_node_route_inf[rg_node->inode].usage == 0) { free_rg_node(rg_node); } free_rg_edge(edge); } else { edge->usage--; } rg_node = parent_rg_node; btptr = btptr->next; parent_link = rg_node->u.parent_list; // printf("rg_node->inode %d\n",rg_node->inode); // if(btptr!=NULL) printf("btptr->index %d, parent_link %d\n",btptr->index,parent_link); // else printf("btptr NULL, parent_link %d\n",parent_link); while (parent_link != NULL && parent_link->edge->u.parent->inode != btptr->index) { //printf("parent_link %d, parent_link->edge->u.parent->inode %d\n",parent_link,parent_link->edge->u.parent->inode); parent_link = parent_link->next; } // if(parent_link==NULL){ // printf("parent_link null\n"); // }else{ // printf("parent_link->edge->u.parent->inode %d, btptr->index %d\n",parent_link->edge->u.parent->inode, btptr->index); // } // printf("a\n"); } // printf("return rg node inode %d, type %d child list %d, no_parents %d\n", rg_node->inode, rr_node[rg_node->inode].type,rg_node->child_list,rg_node->no_parents); // printf("Update C downstream.\n"); //update_C_downstream(root,icon); }
static t_rg_node * add_con_path_to_route_graph_and_update_R_upstream(int icon, t_rg_node *root, t_rr_to_rg_node_hash_map* node_map) { /* Adds the most recent wire segment, ending at the SINK indicated by hptr, * * to the routing tree. It returns the first (most upstream) new rt_node, * * and (via a pointer) the rt_node of the new SINK. */ struct s_trace *tptr; struct s_trace *prev_tptr; float R_upstream; float R_upstream_max; t_linked_rg_edge_ref *link; t_linked_rg_edge_ref *prev_link; t_linked_rg_edge_ref *parent_link; t_rg_edge *edge; t_rr_to_rg_node_entry *node_entry; bool sink_found = false; t_rg_node * rg_node = root; t_rg_node * prev_rg_node = NULL; tptr = trace_head_con[icon]; prev_tptr = tptr; tptr = tptr->next; link = root->child_list; prev_link = NULL; while(!sink_found){ /* Find branch point, explore the routing time graph until branch point is found. */ //printf("Find branch point\n"); while(link!=NULL){ //printf("link: %d\n",link->edge->child->inode); if(link->edge->child->inode == tptr->index){ link->edge->usage++; prev_rg_node = rg_node; rg_node = link->edge->child; prev_tptr = tptr; tptr = tptr->next; prev_link = link; link = rg_node->child_list; }else{ prev_link = link; link = link->next; } } //printf("tptr->index %d, tptr-next->index %d\n",tptr->index,tptr->next->index); //printf("get_rr_to_rg_node_entry(node_map,tptr->index)->usage %d, get_rr_to_rg_node_entry(node_map,tptr->next->index)->usage %d\n",get_rr_to_rg_node_entry(node_map,tptr->index)->usage,get_rr_to_rg_node_entry(node_map,tptr->next->index)->usage); if(get_rr_to_rg_node_entry(node_map,tptr->index)->usage>1){ //printf("Switch between branches.\n"); //printf("rg_node %d, prev_rg_node %d\n",rg_node->inode,prev_rg_node->inode); /* Switch between branches */ link = alloc_linked_rg_edge_ref(); edge = alloc_rg_edge(); link->edge = edge; #ifdef DEBUG if (prev_link == NULL) { printf("Error in add_connection_path_to_route_graph. prev_edge is NULL, while switching between branches.\n"); exit(1); } #endif prev_link->next = link; edge->iswitch = prev_tptr->iswitch; R_upstream = rg_node->R_upstream; //printf("before prev_rg_node->inode %d\n",prev_rg_node->inode); //printf("before rg_node->inode %d\n",rg_node->inode); prev_rg_node = rg_node; rg_node = get_rr_to_rg_node_entry(node_map, tptr->index)->rg_node; //printf("after prev_rg_node->inode %d\n",prev_rg_node->inode); //printf("rg_node %d\n",rg_node); //printf("after rg_node->inode %d\n",rg_node->inode); edge->child = rg_node; edge->u.parent = prev_rg_node; edge->usage=1; if(g_rr_switch_inf[link->edge->iswitch].buffered){ R_upstream = g_rr_switch_inf[edge->iswitch].R + rr_node[rg_node->inode].R; }else{ R_upstream = R_upstream + g_rr_switch_inf[edge->iswitch].R + rr_node[rg_node->inode].R; } if(R_upstream>rg_node->R_upstream) { rg_node->R_upstream = R_upstream; } parent_link = alloc_linked_rg_edge_ref(); parent_link->edge = edge; parent_link->next = rg_node->u.parent_list; rg_node->u.parent_list = parent_link; rg_node->no_parents++; prev_tptr = tptr; tptr = tptr->next; link = rg_node->child_list; }else{ //printf("A new part has to be added.\n"); /* A new part has to be added to the routing time graph */ /* Add new part of the path to the routing time graph */ /* First, add a child edge to the branch point*/ R_upstream = rg_node->R_upstream; prev_rg_node = rg_node; rg_node = alloc_rg_node(); rg_node->inode = tptr->index; //printf("assigning rg_node to entry %d \n", tptr->index); get_rr_to_rg_node_entry(node_map, tptr->index)->rg_node = rg_node; if(prev_rg_node!=NULL) rg_node->visited = prev_rg_node->visited; edge = alloc_rg_edge(); //printf("prev_tptr->index %d\n",prev_tptr->index); edge->iswitch = prev_tptr->iswitch; edge->child = rg_node; edge->u.parent = prev_rg_node; edge->usage = 1; if(g_rr_switch_inf[edge->iswitch].buffered) rg_node->R_upstream = g_rr_switch_inf[edge->iswitch].R + rr_node[rg_node->inode].R; else rg_node->R_upstream = R_upstream + g_rr_switch_inf[edge->iswitch].R + rr_node[rg_node->inode].R; /* Child link */ link = alloc_linked_rg_edge_ref(); link->edge = edge; link->next = prev_rg_node->child_list; prev_rg_node->child_list = link; parent_link = alloc_linked_rg_edge_ref(); parent_link->next = NULL; parent_link->edge = edge; rg_node->u.parent_list = parent_link; rg_node->no_parents = 1; node_entry = get_rr_to_rg_node_entry(node_map, tptr->next->index); while(node_entry->rg_node==NULL && rr_node[tptr->next->index].type!=1){ prev_tptr = tptr; tptr = tptr->next; prev_rg_node = rg_node; rg_node = alloc_rg_node(); rg_node->inode = tptr->index; //printf("assigning rg_node to entry %d \n", tptr->index); node_entry->rg_node = rg_node; //printf("Add %d\n",rg_node->inode); if(g_rr_switch_inf[prev_tptr->iswitch].buffered) rg_node->R_upstream = g_rr_switch_inf[prev_tptr->iswitch].R + rr_node[rg_node->inode].R; else rg_node->R_upstream = prev_rg_node->R_upstream + g_rr_switch_inf[prev_tptr->iswitch].R + rr_node[rg_node->inode].R; /* Edge */ edge = alloc_rg_edge(); edge->child = rg_node; edge->u.parent = prev_rg_node; edge->usage = 1; edge->iswitch = prev_tptr->iswitch; /* Child link*/ link = alloc_linked_rg_edge_ref(); link->edge = edge; link->next = NULL; prev_rg_node->child_list = link; /* Parent link */ parent_link = alloc_linked_rg_edge_ref(); parent_link->edge = edge; parent_link->next = NULL; rg_node->u.parent_list = parent_link; rg_node->no_parents=1; node_entry = get_rr_to_rg_node_entry(node_map, tptr->next->index); //printf("node %d, type %d\n",tptr->index, rr_node[tptr->next->index].type); } if(rr_node[tptr->next->index].type==1){ rg_node->child_list=NULL; //printf("sink inode %d, u.child_list %d, type node %d, prev_rg_node(%d)->child_list %d\n",rg_node->inode, rg_node->child_list, rr_node[rg_node->inode].type, prev_rg_node->inode, prev_rg_node->child_list); return rg_node; }else{ /* The trace reconnects with the routing graph*/ // printf("The trace reconnects with the routing graph\n"); // printf("before prev_rg_node->inode %d\n",prev_rg_node->inode); // printf("before rg_node->inode %d\n",rg_node->inode); prev_tptr = tptr; tptr = tptr->next; prev_rg_node = rg_node; rg_node = get_rr_to_rg_node_entry(node_map, tptr->index)->rg_node; // printf("after prev_rg_node->inode %d\n",prev_rg_node->inode); // printf("after rg_node->inode %d\n",rg_node->inode); // printf("after prev_tptr %d\n",prev_tptr->index); // printf("after tptr %d\n",tptr->index); /* Edge */ edge = alloc_rg_edge(); edge->child = rg_node; edge->u.parent = prev_rg_node; edge->usage = 1; edge->iswitch = prev_tptr->iswitch; /* Child link*/ link = alloc_linked_rg_edge_ref(); link->edge = edge; link->next = NULL; prev_rg_node->child_list = link; /* Parent link */ parent_link = alloc_linked_rg_edge_ref(); parent_link->edge = edge; parent_link->next = rg_node->u.parent_list; rg_node->u.parent_list = parent_link; rg_node->no_parents++; if(!g_rr_switch_inf[tptr->iswitch].buffered){ link = parent_link; R_upstream_max = 0.0; while(link->next!=NULL){ if(!g_rr_switch_inf[link->edge->iswitch].buffered && (link->edge->child->R_upstream > R_upstream_max)) R_upstream_max = link->edge->child->R_upstream; link = link->next; } /* Update R_upstream */ if((prev_rg_node->R_upstream - R_upstream_max)>0.0001){ rg_node->R_upstream = prev_rg_node->R_upstream + g_rr_switch_inf[prev_tptr->iswitch].R + rr_node[rg_node->inode].R; update_subtree(rg_node); } } // printf("tptr %d\n",tptr->index); prev_tptr = tptr; tptr = tptr->next; link = rg_node->child_list; } } } }