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;
    }
    
}
Example #2
0
/*---------------------------------------------------------------
 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;
            }
        }


    }

}