VPR-6.0
|
00001 #include <limits.h> 00002 #include "util.h" 00003 #include "vpr_types.h" 00004 #include "globals.h" 00005 #include "mst.h" 00006 00007 #define ABS_DIFF(X, Y) (((X) > (Y))? ((X) - (Y)):((Y) - (X))) 00008 00009 static int min_dist_from_mst(int node_outside, 00010 int inet, 00011 boolean * in_mst, 00012 int *node_inside); 00013 00014 /** given the net number, find and return its minimum spanning tree */ 00015 t_mst_edge * 00016 get_mst_of_net(int inet) 00017 { 00018 int i, ipin, node_dist, num_pins_on_net, num_edges, blk1, blk2; 00019 int nearest_node; 00020 t_mst_edge *min_spantree; 00021 boolean *in_mst; 00022 int *edge_weight_with_curr_mst, *nearest_node_with_curr_mst; 00023 00024 00025 num_pins_on_net = (clb_net[inet].num_sinks + 1); 00026 00027 if(num_pins_on_net > USHRT_MAX) 00028 { 00029 printf("Error: num_pins_on_net (%d) > USHRT_MAX(%u)\n", 00030 num_pins_on_net, USHRT_MAX); 00031 exit(1); 00032 } 00033 00034 /* minimum spanning tree represented by a set of edges */ 00035 min_spantree = 00036 (t_mst_edge *) my_malloc(sizeof(t_mst_edge) * (num_pins_on_net - 1)); 00037 in_mst = (boolean *) my_malloc(sizeof(boolean) * (num_pins_on_net)); 00038 edge_weight_with_curr_mst = (int *) my_malloc(sizeof(int) * (num_pins_on_net)); 00039 nearest_node_with_curr_mst = (int *) my_malloc(sizeof(int) * (num_pins_on_net)); 00040 00041 /* identifier for minimum spanning tree by nodes */ 00042 in_mst[0] = TRUE; 00043 for(ipin = 1; ipin < num_pins_on_net; ipin++) { 00044 in_mst[ipin] = FALSE; 00045 blk1 = clb_net[inet].node_block[0]; 00046 blk2 = clb_net[inet].node_block[ipin]; 00047 edge_weight_with_curr_mst[ipin] = ABS_DIFF(block[blk1].x, block[blk2].x) + 00048 ABS_DIFF(block[blk1].y, block[blk2].y); 00049 nearest_node_with_curr_mst[ipin] = 0; 00050 } 00051 00052 num_edges = 0; 00053 00054 /* need to add num_pins - 1 number of edges */ 00055 for(i = 1; i < num_pins_on_net; i++) 00056 { 00057 /* look at remaining num_pins - 1 pins, and add them to the mst one at a time */ 00058 00059 nearest_node = -1; 00060 00061 for(ipin = 1; ipin < num_pins_on_net; ipin++) 00062 { 00063 /* look at each pin not in the mst, find the nearest to the current partial mst */ 00064 if(!in_mst[ipin]) 00065 { 00066 if(nearest_node == -1 || edge_weight_with_curr_mst[ipin] <= edge_weight_with_curr_mst[nearest_node]) { 00067 nearest_node = ipin; 00068 } 00069 } 00070 } 00071 00072 /* found the nearest to the current partial mst, so add an edge to mst */ 00073 min_spantree[num_edges].from_node = nearest_node_with_curr_mst[nearest_node]; 00074 00075 min_spantree[num_edges].to_node = nearest_node; 00076 00077 num_edges++; 00078 00079 in_mst[nearest_node] = TRUE; 00080 00081 for(ipin = 1; ipin < num_pins_on_net; ipin++) 00082 { 00083 /* Update closest node to partial mst */ 00084 if(!in_mst[ipin]) 00085 { 00086 blk1 = clb_net[inet].node_block[nearest_node]; 00087 blk2 = clb_net[inet].node_block[ipin]; 00088 node_dist = ABS_DIFF(block[blk1].x, block[blk2].x) + 00089 ABS_DIFF(block[blk1].y, block[blk2].y); 00090 if(node_dist < edge_weight_with_curr_mst[ipin]) { 00091 edge_weight_with_curr_mst[ipin] = node_dist; 00092 nearest_node_with_curr_mst[ipin] = nearest_node; 00093 } 00094 } 00095 } 00096 } 00097 00098 free(in_mst); 00099 free(edge_weight_with_curr_mst); 00100 free(nearest_node_with_curr_mst); 00101 return min_spantree; 00102 }