📄 rr_graph2.c
字号:
t_rr_type chan_type; boolean cbox_exists; t_linked_edge *edge_list_head; t_seg_details *seg_details;/* Find location of adjacent channel. */ if (j == 0) { /* Bottom row of pads. */ chan_i = i; chan_j = j; chan_type = CHANX; seg_details = seg_details_x; } else if (j == ny+1) { chan_i = i; chan_j = j-1; chan_type = CHANX; seg_details = seg_details_x; } else if (i == 0) { chan_i = i; chan_j = j; chan_type = CHANY; seg_details = seg_details_y; } else if (i == nx+1) { chan_i = i-1; chan_j = j; chan_type = CHANY; seg_details = seg_details_y; } else { printf ("Error in get_pad_opin_connections: requested IO block at " "(%d,%d) does not exist.\n", i, j); exit (1); } edge_list_head = *edge_list_ptr; num_conn = 0; for (iconn=0;iconn<Fc_pad;iconn++) { itrack = pads_to_tracks[ipad][iconn]; if (chan_type == CHANX) cbox_exists = is_cbox (chan_i, chan_j, itrack, seg_details); else cbox_exists = is_cbox (chan_j, chan_i, itrack, seg_details); if (cbox_exists) { to_node = get_rr_node_index (chan_i, chan_j, chan_type, itrack, nodes_per_chan, rr_node_indices); edge_list_head = insert_in_edge_list (edge_list_head, to_node, seg_details[itrack].opin_switch, &free_edge_list_head); num_conn++; } } if (num_conn == 0) { printf ("Error: INPAD %d at (%d,%d) does not connect to any " "tracks.\n", ipad, i, j); exit (1); } *edge_list_ptr = edge_list_head; return (num_conn);}boolean is_cbox (int seg_num, int chan_num, int itrack, t_seg_details *seg_details) {/* Returns 1 (TRUE) if the track segment at this segment and channel * * location with track number itrack contains a connection box, 0 otherwise. */ int seg_offset, start, length; length = seg_details[itrack].length; start = seg_details[itrack].start; seg_offset = (seg_num + chan_num - start + length) % length; return (seg_details[itrack].cb[seg_offset]);}int **alloc_and_load_rr_node_indices (int nodes_per_clb, int nodes_per_pad, int nodes_per_chan, t_seg_details *seg_details_x, t_seg_details *seg_details_y) {/* Allocates and loads all the structures needed for fast lookups of the * * index of an rr_node. rr_node_indices is a matrix containing the index * * of the *first* rr_node at a given (i,j) location. The chanx_rr_indices * * and chany_rr_indices data structures give the rr_node index for each * * track in each (i,j) channel segment. */ int index, i, j; int **rr_node_indices; rr_node_indices = (int **) alloc_matrix (0, nx+1, 0, ny+1, sizeof(int)); chanx_rr_indices = (int ***) alloc_matrix3 (1, nx, 0, ny, 0, nodes_per_chan - 1, sizeof (int)); chany_rr_indices = (int ***) alloc_matrix3 (0, nx, 1, ny, 0, nodes_per_chan - 1, sizeof (int)); index = 0; for (i=0;i<=nx+1;i++) { for (j=0;j<=ny+1;j++) { rr_node_indices[i][j] = index; if (clb[i][j].type == CLB) { index += nodes_per_clb; index = load_chanx_rr_indices (seg_details_x, nodes_per_chan, index, i, j); index = load_chany_rr_indices (seg_details_y, nodes_per_chan, index, i, j); } else if (clb[i][j].type == IO) { index += nodes_per_pad; if (j == 0) /* Bottom row */ index = load_chanx_rr_indices (seg_details_x, nodes_per_chan, index, i, j); if (i == 0) /* Leftmost column */ index = load_chany_rr_indices (seg_details_y, nodes_per_chan, index, i, j); } else if (clb[i][j].type != ILLEGAL) { printf("Error in alloc_and_load_rr_node_indices. Unexpected clb" " type.\n"); exit (1); } } } return (rr_node_indices);}void free_rr_node_indices (int **rr_node_indices) {/* Frees all the rr_node_indices structures allocated for fast index * * computations. */ free_matrix (rr_node_indices, 0, nx+1, 0, sizeof(int)); free_matrix3 (chanx_rr_indices, 1, nx, 0, ny, 0, sizeof (int)); free_matrix3 (chany_rr_indices, 0, nx, 1, ny, 0, sizeof (int));}static int load_chanx_rr_indices (t_seg_details *seg_details_x, int nodes_per_chan, int start_index, int i, int j) {/* Loads the chanx_rr_indices array for all track segments starting at * * (i,j), assuming the first segment found has index start_index. It also * * returns the next free index (i.e. the index for the next rr_node). */ int rr_index, istart, iend, iseg, itrack; rr_index = start_index; for (itrack=0;itrack<nodes_per_chan;itrack++) { istart = get_closest_seg_start (seg_details_x, itrack, i, j); /* Don't do anything if this isn't the start of the segment. */ if (istart != i) continue; iend = get_seg_end (seg_details_x, itrack, istart, j, nx); for (iseg=istart;iseg<=iend;iseg++) chanx_rr_indices[iseg][j][itrack] = rr_index; rr_index++; } return (rr_index);}static int load_chany_rr_indices (t_seg_details *seg_details_y, int nodes_per_chan, int start_index, int i, int j) { /* Loads the chany_rr_indices array for all track segments starting at * * (i,j), assuming the first segment found has index start_index. It also * * returns the next free index (i.e. the index for the next rr_node). */ int rr_index, jstart, jend, jseg, itrack; rr_index = start_index; for (itrack=0;itrack<nodes_per_chan;itrack++) { jstart = get_closest_seg_start (seg_details_y, itrack, j, i); /* Don't do anything if this isn't the start of the segment. */ if (jstart != j) continue; jend = get_seg_end (seg_details_y, itrack, jstart, i, ny); for (jseg=jstart;jseg<=jend;jseg++) chany_rr_indices[i][jseg][itrack] = rr_index; rr_index++; } return (rr_index); } int get_rr_node_index (int i, int j, t_rr_type rr_type, int ioff, int nodes_per_chan, int **rr_node_indices) {/* Returns the index of the specified routing resource node. (i,j) are * * the location within the FPGA, rr_type specifies the type of resource, * * and ioff gives the number of this resource. ioff is the class number, * * pin number or track number, depending on what type of resource this * * is. All ioffs start at 0 and go up to pins_per_clb-1 or the equivalent. * * The order within a clb is: SOURCEs + SINKs (num_class of them); IPINs, * * and OPINs (pins_per_clb of them); CHANX; and CHANY (nodes_per_chan of * * each). For (i,j) locations that point at pads the order is: io_rat * * occurances of SOURCE, SINK, OPIN, IPIN (one for each pad), then one * * associated channel (if there is a channel at (i,j)). All IO pads are * * bidirectional, so while each will be used only as an INPAD or as an * * OUTPAD, all the switches necessary to do both must be in each pad. * * * * Note that for segments (CHANX and CHANY) of length > 1, the segment is * * given an rr_index based on the (i,j) location at which it starts (i.e. * * lowest (i,j) location at which this segment exists). * * This routine also performs error checking to make sure the node in * * question exists. */ int index, iclass; assert (ioff >= 0); assert (i >= 0 && i < nx + 2); assert (j >= 0 && j < ny + 2); index = rr_node_indices[i][j]; /* Start of that block */ switch (clb[i][j].type) { case CLB: switch (rr_type) { case SOURCE: assert (ioff < num_class); assert (class_inf[ioff].type == DRIVER); index += ioff; return (index); case SINK: assert (ioff < num_class); assert (class_inf[ioff].type == RECEIVER); index += ioff; return (index); case OPIN: assert (ioff < pins_per_clb); iclass = clb_pin_class[ioff]; assert (class_inf[iclass].type == DRIVER); index += num_class + ioff; return (index); case IPIN: assert (ioff < pins_per_clb); iclass = clb_pin_class[ioff]; assert (class_inf[iclass].type == RECEIVER); index += num_class + ioff; return (index); case CHANX: assert (ioff < nodes_per_chan); index = chanx_rr_indices[i][j][ioff]; return (index); case CHANY: assert (ioff < nodes_per_chan); index = chany_rr_indices[i][j][ioff]; return (index); default: printf ("Error: Bad rr_node passed to get_rr_node_index.\n" "Request for type %d number %d at (%d, %d).\n", rr_type, ioff, i, j); exit (1); } break; case IO: switch (rr_type) { case SOURCE: assert (ioff < io_rat); index += 4 * ioff; return (index); case SINK: assert (ioff < io_rat); index += 4 * ioff + 1; return (index); case OPIN: assert (ioff < io_rat); index += 4 * ioff + 2; return (index); case IPIN: assert (ioff < io_rat); index += 4 * ioff + 3; return (index); case CHANX: assert (ioff < nodes_per_chan); assert (j == 0); /* Only one with a channel. */ index = chanx_rr_indices[i][j][ioff]; return (index); case CHANY: assert (ioff < nodes_per_chan); assert (i == 0); /* Only one with a channel. */ index = chany_rr_indices[i][j][ioff]; return (index); default: printf ("Error: Bad rr_node passed to get_rr_node_index.\n" "Request for type %d number %d at (%d, %d).\n", rr_type, ioff, i, j); exit (1); } break; default: printf("Error in get_rr_node_index: unexpected block type (%d) at " "(%d, %d).\nrr_type: %d.\n", clb[i][j].type, i, j, rr_type); exit (1); }}int get_seg_end (t_seg_details *seg_details, int itrack, int seg_start, int chan_num, int max_end) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -