t_rg_node * depth_first_search(t_rg_node * parent_nd, t_trace * parent_tr, t_trace * &tr_tail, bool original_root_status, bool flip_switch){
    //printf("Call dfs %d\n",parent_nd->inode);
    if(flip_switch) parent_nd->visited = ! parent_nd->visited;
    
    if(parent_nd->child_list == NULL){
        //Return parent_nd for backtracing purpose
        
        int num_edges = rr_node[parent_tr->index].get_num_edges();
#ifdef DEBUG
        if(num_edges!=1) vpr_printf_info(__FILE__,__LINE__,"Expected only one edge here. This could have consequences further on.");
#endif
        int to_node = rr_node[parent_tr->index].edges[0];
        int iswitch = rr_node[parent_tr->index].switches[0];
        
        parent_tr->iswitch = iswitch;
        t_trace * ptr = alloc_trace_data();
        ptr->index = to_node;
        parent_tr->next = ptr;
        ptr->next = NULL;
        ptr->iswitch = -1;
        tr_tail = ptr;
        //printf("return parent_tr %d, num_edges %d\n",parent_tr->index,num_edges);
        return parent_nd;
    }
    
    //find a child that is not been visited before
    t_linked_rg_edge_ref * child_ref = parent_nd->child_list;
    while((child_ref != NULL)
          && (child_ref->edge->child->visited != original_root_status)){
        child_ref = child_ref->next;
    }
    if(child_ref == NULL){
        vpr_printf_error(__FILE__, __LINE__,"Depth_first_search: Did not find a child that was not visited before.\n");
    }
    
    parent_tr->iswitch = child_ref->edge->iswitch;
    t_trace * ptr = alloc_trace_data();
    ptr->index = child_ref->edge->child->inode;
    parent_tr->next = ptr;
    ptr->next = NULL;
    
    //printf("%d -> %d\n", parent_nd->inode, child_ref->edge->child->inode);
    return depth_first_search(child_ref->edge->child, ptr, tr_tail, original_root_status, true);
    
    
    
}
t_trace * trace_from_timing_rg_dbg(t_rg_node * root, int net){
    
    
    //initialization of the source trace element
    t_trace * head = alloc_trace_data();
    head->index = root->inode;
    head->next = NULL;
    // head->iswitch will be assigned by the depth_first_search
    //printf("Root %d, parent_list %d \n", root->inode, root->u.parent_list);
    
    bool flip_switch_hook = true;
    
    t_rg_node * hook_nd = root;
    t_trace *  hook_tr = head;
    t_trace * tail = NULL;
    bool original_root_status = root->visited;
    while(hook_nd != NULL){
        //printf("Initiating DFS\n");
            t_rg_node * sink = depth_first_search(hook_nd,hook_tr,tail,original_root_status,flip_switch_hook);
        //printf("Backtrace\n");
        if(net==40){
            hook_nd = backtrace(sink,original_root_status,true);
        }else{
            hook_nd = backtrace(sink,original_root_status,false);
        }
       
        if(hook_nd != NULL){
            hook_tr = alloc_trace_data();
            hook_tr->index = hook_nd->inode;
            hook_tr->next = NULL;
            tail->next = hook_tr;
            flip_switch_hook = false;
        }else{
            tail->next = NULL;
        }
    }
    
    return head;
    
}
Example #3
0
struct s_trace *update_traceback (struct s_heap *hptr, int inet) {

/* This routine adds the most recently finished wire segment to the         *
 * traceback linked list.  The first connection starts with the net SOURCE  *
 * and begins at the structure pointed to by trace_head[inet]. Each         *
 * connection ends with a SINK.  After each SINK, the next connection       *
 * begins (if the net has more than 2 pins).  The first element after the   *
 * SINK gives the routing node on a previous piece of the routing, which is *
 * the link from the existing net to this new piece of the net.             *
 * In each traceback I start at the end of a path and trace back through    *
 * its predecessors to the beginning.  I have stored information on the     *
 * predecesser of each node to make traceback easy -- this sacrificies some *
 * memory for easier code maintenance.  This routine returns a pointer to   *
 * the first "new" node in the traceback (node not previously in trace).    */ 

 struct s_trace *tptr, *prevptr, *temptail, *ret_ptr;
 int inode;
 short iedge;
#ifdef DEBUG
 t_rr_type rr_type;
#endif

 inode = hptr->index;

#ifdef DEBUG
   rr_type = rr_node[inode].type;
   if (rr_type != SINK) {
      printf("Error in update_traceback.  Expected type = SINK (%d).\n",
         SINK);
      printf("Got type = %d while tracing back net %d.\n", rr_type, inet);
      exit(1);
   }
#endif
 
 tptr = alloc_trace_data ();   /* SINK on the end of the connection */ 
 tptr->index = inode;
 tptr->iswitch = OPEN;
 tptr->next = NULL;
 temptail = tptr;              /* This will become the new tail at the end */
                               /* of the routine.                          */

/* Now do it's predecessor. */

 inode = hptr->u.prev_node;
 iedge = hptr->prev_edge;

 while (inode != NO_PREVIOUS) {
    prevptr = alloc_trace_data();
    prevptr->index = inode;
    prevptr->iswitch = rr_node[inode].switches[iedge];
    prevptr->next = tptr;
    tptr = prevptr;

    iedge = rr_node_route_inf[inode].prev_edge;
    inode = rr_node_route_inf[inode].prev_node;
 }

 if (trace_tail[inet] != NULL) {
    trace_tail[inet]->next = tptr;     /* Traceback ends with tptr */
    ret_ptr = tptr->next;              /* First new segment.       */
 }
 else {                /* This was the first "chunk" of the net's routing */
    trace_head[inet] = tptr;
    ret_ptr = tptr;                    /* Whole traceback is new. */
 }

 trace_tail[inet] = temptail;
 return (ret_ptr);
}