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; }
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); }