⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 route_common.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 3 页
字号:
      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);}void reset_path_costs (void) {/* The routine sets the path_cost to HUGE_FLOAT for all channel segments   * * touched by previous routing phases.                                     */ struct s_linked_f_pointer *mod_ptr;#ifdef DEBUG int num_mod_ptrs;#endif/* The traversal method below is slightly painful to make it faster. */ if (rr_modified_head != NULL) {    mod_ptr = rr_modified_head;#ifdef DEBUG     num_mod_ptrs = 1;#endif    while (mod_ptr->next != NULL) {       *(mod_ptr->fptr) = HUGE_FLOAT;       mod_ptr = mod_ptr->next;#ifdef DEBUG        num_mod_ptrs++;#endif    }    *(mod_ptr->fptr) = HUGE_FLOAT;   /* Do last one. */    /* Reset the modified list and put all the elements back in the free   * * list.                                                               */    mod_ptr->next = linked_f_pointer_free_head;    linked_f_pointer_free_head = rr_modified_head;     rr_modified_head = NULL;#ifdef DEBUG     num_linked_f_pointer_allocated -= num_mod_ptrs;#endif }}float get_rr_cong_cost (int inode) {/* Returns the *congestion* cost of using this rr_node. */ short cost_index; float cost; cost_index = rr_node[inode].cost_index; cost = rr_indexed_data[cost_index].base_cost *                  rr_node_route_inf[inode].acc_cost *                 rr_node_route_inf[inode].pres_cost; return (cost);}void mark_ends (int inet) {/* Mark all the SINKs of this net as targets by setting their target flags  * * to the number of times the net must connect to each SINK.  Note that     * * this number can occassionally be greater than 1 -- think of connecting   * * the same net to two inputs of an and-gate (and-gate inputs are logically * * equivalent, so both will connect to the same SINK).                      */ int ipin, inode; for (ipin=1;ipin<net[inet].num_pins;ipin++) {    inode = net_rr_terminals[inet][ipin];    rr_node_route_inf[inode].target_flag++; }}void node_to_heap (int inode, float cost, int prev_node, int prev_edge,                   float backward_path_cost, float R_upstream) {/* Puts an rr_node on the heap, if the new cost given is lower than the     * * current path_cost to this channel segment.  The index of its predecessor * * is stored to make traceback easy.  The index of the edge used to get     * * from its predecessor to it is also stored to make timing analysis, etc.  * * easy.  The backward_path_cost and R_upstream values are used only by the * * timing-driven router -- the breadth-first router ignores them.           */ struct s_heap *hptr; if (cost >= rr_node_route_inf[inode].path_cost)     return; hptr = alloc_heap_data(); hptr->index = inode;  hptr->cost = cost; hptr->u.prev_node = prev_node; hptr->prev_edge = prev_edge; hptr->backward_path_cost = backward_path_cost; hptr->R_upstream = R_upstream; add_to_heap (hptr);}void free_traceback (int inet) {/* Puts the entire traceback (old routing) for this net on the free list * * and sets the trace_head pointers etc. for the net to NULL.            */ struct s_trace *tptr, *tempptr; tptr = trace_head[inet]; while (tptr != NULL) {    tempptr = tptr->next;     free_trace_data (tptr);    tptr = tempptr; }  trace_head[inet] = NULL;  trace_tail[inet] = NULL;}t_ivec **alloc_route_structs (t_subblock_data subblock_data) {/* Allocates the data structures needed for routing.    */ t_ivec **clb_opins_used_locally; trace_head = (struct s_trace **) my_calloc (num_nets,      sizeof(struct s_trace *)); trace_tail = (struct s_trace **) my_malloc (num_nets *     sizeof(struct s_trace *)); heap_size = nx*ny; heap = (struct s_heap **) my_malloc (heap_size *     sizeof (struct s_heap *)); heap--;   /* heap stores from [1..heap_size] */ heap_tail = 1; route_bb = (struct s_bb *) my_malloc (num_nets * sizeof (struct s_bb)); clb_opins_used_locally = alloc_and_load_clb_opins_used_locally (              subblock_data);  return (clb_opins_used_locally);}struct s_trace **alloc_saved_routing (t_ivec **clb_opins_used_locally,         t_ivec ***saved_clb_opins_used_locally_ptr) {/* Allocates data structures into which the key routing data can be saved,   * * allowing the routing to be recovered later (e.g. after a another routing  * * is attempted).                                                            */ struct s_trace **best_routing; t_ivec **saved_clb_opins_used_locally; int iblk, iclass, num_local_opins; best_routing = (struct s_trace **) my_calloc (num_nets,      sizeof (struct s_trace *)); saved_clb_opins_used_locally = (t_ivec **) alloc_matrix (0, num_blocks-1, 0,       num_class-1, sizeof (t_ivec)); for (iblk=0;iblk<num_blocks;iblk++) {    for (iclass=0;iclass<num_class;iclass++) {       num_local_opins = clb_opins_used_locally[iblk][iclass].nelem;       saved_clb_opins_used_locally[iblk][iclass].nelem = num_local_opins;       if (num_local_opins == 0) {          saved_clb_opins_used_locally[iblk][iclass].list = NULL;       }       else {          saved_clb_opins_used_locally[iblk][iclass].list = (int *)                my_malloc (num_local_opins * sizeof (int));       }    } }  *saved_clb_opins_used_locally_ptr = saved_clb_opins_used_locally; return (best_routing);}static t_ivec **alloc_and_load_clb_opins_used_locally (t_subblock_data           subblock_data) {/* Allocates and loads the data needed to make the router reserve some CLB  * * output pins for connections made locally within a CLB (if the netlist    * * specifies that this is necessary).                                       */ t_ivec **clb_opins_used_locally; int *num_subblocks_per_block; t_subblock **subblock_inf; int iblk, isub, clb_pin, iclass, num_local_opins; clb_opins_used_locally = (t_ivec **) alloc_matrix (0, num_blocks-1, 0,                     num_class-1, sizeof (t_ivec)); num_subblocks_per_block = subblock_data.num_subblocks_per_block; subblock_inf = subblock_data.subblock_inf; for (iblk=0;iblk<num_blocks;iblk++) {    if (block[iblk].type != CLB) {       for (iclass=0;iclass<num_class;iclass++) {          clb_opins_used_locally[iblk][iclass].nelem = 0;          clb_opins_used_locally[iblk][iclass].list = NULL;       }    }        else {  /* CLB */       for (iclass=0;iclass<num_class;iclass++)           clb_opins_used_locally[iblk][iclass].nelem = 0;       for (isub=0;isub<num_subblocks_per_block[iblk];isub++) {          clb_pin = subblock_inf[iblk][isub].output;     /* Subblock output used only locally, but must connect to a CLB OPIN?  */          if (clb_pin != OPEN && block[iblk].nets[clb_pin] == OPEN) {             iclass = clb_pin_class[clb_pin];             clb_opins_used_locally[iblk][iclass].nelem++;          }       }       for (iclass=0;iclass<num_class;iclass++) {          num_local_opins =                   clb_opins_used_locally[iblk][iclass].nelem;          if (num_local_opins == 0)              clb_opins_used_locally[iblk][iclass].list = NULL;          else              clb_opins_used_locally[iblk][iclass].list =                  (int *) my_malloc (num_local_opins * sizeof (int));       }    } }  return (clb_opins_used_locally);}void free_trace_structs (void) {  /*the trace lists are only freed after use by the timing-driven placer*/  /*Do not  free them after use by the router, since stats, and draw  */  /*routines use the trace values */  int i;  for (i=0; i<num_nets; i++)    free_traceback(i);  free(trace_head);  free(trace_tail);  trace_head = NULL;  trace_tail = NULL;}void free_route_structs (t_ivec **clb_opins_used_locally) {/* Frees the temporary storage needed only during the routing.  The  * * final routing result is not freed.                                */ free (heap + 1); free (route_bb); heap = NULL;         /* Defensive coding:  crash hard if I use these. */ route_bb = NULL; free_ivec_matrix (clb_opins_used_locally, 0, num_blocks-1, 0, num_class-1);/* NB:  Should use my chunk_malloc for tptr, hptr, and mod_ptr structures. * * I could free everything except the tptrs at the end then.               */}void free_saved_routing (struct s_trace **best_routing, t_ivec        **saved_clb_opins_used_locally) {/* Frees the data structures needed to save a routing.                     */ free (best_routing); free_ivec_matrix (saved_clb_opins_used_locally, 0, num_blocks-1, 0,                    num_class-1);}void alloc_and_load_rr_node_route_structs (void) {/* Allocates some extra information about each rr_node that is used only   * * during routing.                                                         */ int inode; if (rr_node_route_inf != NULL) {    printf ("Error in alloc_and_load_rr_node_route_structs:  \n"            "old rr_node_route_inf array exists.\n");    exit (1); } rr_node_route_inf = my_malloc (num_rr_nodes * sizeof (t_rr_node_route_inf)); for (inode=0;inode<num_rr_nodes;inode++) {    rr_node_route_inf[inode].prev_node = NO_PREVIOUS;    rr_node_route_inf[inode].prev_edge = NO_PREVIOUS;    rr_node_route_inf[inode].pres_cost = 1.;    rr_node_route_inf[inode].acc_cost = 1.;    rr_node_route_inf[inode].path_cost = HUGE_FLOAT;    rr_node_route_inf[inode].target_flag = 0; }}void free_rr_node_route_structs (void) {/* Frees the extra information about each rr_node that is needed only      * * during routing.                                                         */ free (rr_node_route_inf); rr_node_route_inf = NULL;   /* Mark as free */}static void load_route_bb (int bb_factor) {/* This routine loads the bounding box arrays used to limit the space  * * searched by the maze router when routing each net.  The search is   * * limited to channels contained with the net bounding box expanded    * * by bb_factor channels on each side.  For example, if bb_factor is   * * 0, the maze router must route each net within its bounding box.     * * If bb_factor = nx, the maze router will search every channel in     * * the FPGA if necessary.  The bounding boxes returned by this routine * * are different from the ones used by the placer in that they are     *  * clipped to lie within (0,0) and (nx+1,ny+1) rather than (1,1) and   * * (nx,ny).                                                            */ int k, xmax, ymax, xmin, ymin, x, y, inet; for (inet=0;inet<num_nets;inet++) {    x = block[net[inet].blocks[0]].x;    y = block[net[inet].blocks[0]].y;    xmin = x;    ymin = y;    xmax = x;    ymax = y;    for (k=1;k<net[inet].num_pins;k++) {       x = block[net[inet].blocks[k]].x;       y = block[net[inet].blocks[k]].y;       if (x < xmin) {          xmin = x;       }       else if (x > xmax) {          xmax = x;       }       if (y < ymin) {          ymin = y;       }       else if (y > ymax ) {          ymax = y;       }    }      /* Want the channels on all 4 sides to be usuable, even if bb_factor = 0. */    xmin -= 1;    ymin -= 1;   /* Expand the net bounding box by bb_factor, then clip to the physical *    * chip area.                                                          */    route_bb[inet].xmin = max (xmin - bb_factor, 0);    route_bb[inet].xmax = min (xmax + bb_factor, nx+1);    route_bb[inet].ymin = max (ymin - bb_factor, 0);    route_bb[inet].ymax = min (ymax + bb_factor, ny+1); }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -