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

📄 rr_graph2.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Returns the segment number (coordinate along the channel) at which this * * segment ends.  For a segment spanning clbs from 1 to 4, seg_end is 4.   * * max_end is the maximum dimension of the FPGA in this direction --       * * either nx or ny.                                                        */ int seg_end, length, norm_start; length = seg_details[itrack].length; if (seg_start != 1) {    seg_end = min (seg_start + length - 1, max_end); } else if (seg_details[itrack].longline) {    seg_end = max_end; } else {        /* Short segment, at the left edge of array. */    norm_start = seg_details[itrack].start;    seg_end = length - (length + 1 + chan_num - norm_start) % length; }  return (seg_end);}int get_xtrack_to_clb_ipin_edges (int tr_istart, int tr_iend, int tr_j,       int itrack, int iside, t_linked_edge **edge_list_ptr, struct s_ivec        **tracks_to_clb_ipin, int nodes_per_chan, int **rr_node_indices,        t_seg_details *seg_details_x, int wire_to_ipin_switch) {/* This routine counts how many connections should be made from this segment * * to the clbs above (TOP) or below (BOTTOM) it.   It also adds them to the  * * edge linked list and updates edge_list_ptr.                               */ int clb_j, iconn, num_conn, max_conn, i, ipin, to_node; t_linked_edge *edge_list_head;/* Side is from the *track's* perspective */ if (iside == BOTTOM) {    clb_j = tr_j; } else if (iside == TOP) {    clb_j = tr_j + 1; } else {      printf ("Error in get_xtrack_to_clb_ipin_edges:  Unknown iside: %d.\n",            iside);    exit (1); } edge_list_head = *edge_list_ptr; num_conn = 0; max_conn = tracks_to_clb_ipin[itrack][iside].nelem; for (i=tr_istart;i<=tr_iend;i++) {    if (is_cbox (i, tr_j, itrack, seg_details_x)) {       for (iconn=0;iconn<max_conn;iconn++) {          ipin = tracks_to_clb_ipin[itrack][iside].list[iconn];          to_node = get_rr_node_index (i, clb_j, IPIN, ipin, nodes_per_chan,                    rr_node_indices);          edge_list_head = insert_in_edge_list (edge_list_head, to_node,                    wire_to_ipin_switch, &free_edge_list_head);       }       num_conn += max_conn;    } } *edge_list_ptr = edge_list_head; return (num_conn);}int get_ytrack_to_clb_ipin_edges (int tr_jstart, int tr_jend, int tr_i,       int itrack, int iside, t_linked_edge **edge_list_ptr, struct s_ivec       **tracks_to_clb_ipin, int nodes_per_chan, int **rr_node_indices,       t_seg_details *seg_details_y, int wire_to_ipin_switch) {/* This routine counts how many connections should be made from this segment * * to the clbs to the LEFT or RIGHT of it.  It also adds them to the edge    * * linked list and updates edge_list_ptr.                                    */ int clb_i, iconn, num_conn, max_conn, j, ipin, to_node; t_linked_edge *edge_list_head;/* Side is from the *track's* perspective */ if (iside == LEFT) {      clb_i = tr_i; } else if (iside == RIGHT) {    clb_i = tr_i + 1;    } else {      printf ("Error in get_ytrack_to_clb_ipin_edges:  Unknown iside: %d.\n",            iside);    exit (1); }  edge_list_head = *edge_list_ptr; num_conn = 0;    max_conn = tracks_to_clb_ipin[itrack][iside].nelem;  for (j=tr_jstart;j<=tr_jend;j++) {    if (is_cbox (j, tr_i, itrack, seg_details_y)) {       for (iconn=0;iconn<max_conn;iconn++) {          ipin = tracks_to_clb_ipin[itrack][iside].list[iconn];          to_node = get_rr_node_index (clb_i, j, IPIN, ipin, nodes_per_chan,                    rr_node_indices);          edge_list_head = insert_in_edge_list (edge_list_head, to_node,                         wire_to_ipin_switch, &free_edge_list_head);       }       num_conn += max_conn;    }    }  *edge_list_ptr = edge_list_head; return (num_conn); }int get_xtrack_to_pad_edges (int tr_istart, int tr_iend, int tr_j, int pad_j,        int itrack, t_linked_edge **edge_list_ptr, struct s_ivec         *tracks_to_pads, int nodes_per_chan, int **rr_node_indices,         t_seg_details *seg_details_x, int wire_to_ipin_switch) {/* This routine counts how many connections should be made from this segment * * to the row of pads above or below it.  It also adds these edges to the    * * edge list and updates edge_list_ptr to point to the new list head.        */ int iconn, ipad, to_node, num_conn, max_conn, i; t_linked_edge *edge_list_head; edge_list_head = *edge_list_ptr; num_conn = 0; max_conn = tracks_to_pads[itrack].nelem; for (i=tr_istart;i<=tr_iend;i++) {    if (is_cbox (i, tr_j, itrack, seg_details_x)) {       for (iconn=0;iconn<max_conn;iconn++) {          ipad = tracks_to_pads[itrack].list[iconn];          to_node = get_rr_node_index (i, pad_j, IPIN, ipad, nodes_per_chan,                         rr_node_indices);          edge_list_head = insert_in_edge_list (edge_list_head, to_node,                           wire_to_ipin_switch, &free_edge_list_head);       }       num_conn += max_conn;     } }  *edge_list_ptr = edge_list_head; return (num_conn);}int get_ytrack_to_pad_edges (int tr_jstart, int tr_jend, int tr_i, int pad_i,         int itrack, t_linked_edge **edge_list_ptr, struct s_ivec         *tracks_to_pads, int nodes_per_chan, int **rr_node_indices,         t_seg_details *seg_details_y, int wire_to_ipin_switch) {/* This routine counts how many connections should be made from this segment * * to the row of pads to the left or right of it.  Additionally, if rr_edges * * isn't NULL, it will also load the edges array.  Make sure rr_edges points * * at the next free spot to put an edge in this case.                        */ int iconn, ipad, to_node, num_conn, max_conn, j; t_linked_edge *edge_list_head; edge_list_head = *edge_list_ptr; num_conn = 0; max_conn = tracks_to_pads[itrack].nelem; for (j=tr_jstart;j<=tr_jend;j++) {    if (is_cbox (j, tr_i, itrack, seg_details_y)) {       for (iconn=0;iconn<tracks_to_pads[itrack].nelem;iconn++) {          ipad = tracks_to_pads[itrack].list[iconn];          to_node = get_rr_node_index (pad_i, j, IPIN, ipad, nodes_per_chan,                         rr_node_indices);          edge_list_head = insert_in_edge_list (edge_list_head, to_node,                           wire_to_ipin_switch, &free_edge_list_head);       }        num_conn += max_conn;    }   }  *edge_list_ptr = edge_list_head;  return (num_conn);}int get_xtrack_to_ytracks (int from_istart, int from_iend, int from_j, int        from_track, int to_j, t_linked_edge **edge_list_ptr, int nodes_per_chan,       int **rr_node_indices, t_seg_details *seg_details_x, t_seg_details        *seg_details_y, enum e_switch_block_type switch_block_type) {/* Counts how many connections should be made from this segment to the y-   * * segments in the adjacent channels at to_j.  It returns the number of     * * connections, and updates edge_list_ptr to point at the head of the       * * (extended) linked list giving the nodes to which this segment connects   * * and the switch type used to connect to each.                             * *                                                                          * * An edge is added from this segment to a y-segment if:                    * * (1) this segment should have a switch box at that location, or           * * (2) the y-segment to which it would connect has a switch box, and the    * *     switch type of that y-segment is unbuffered (bidirectional pass      * *     transistor).                                                         * *                                                                          * * If the switch in each direction is a pass transistor (unbuffered), both  * * switches are marked as being of the types of the larger (lower R) pass   * * transistor.  Note that this code implicitly assumes the routing is       * * bidirectional (a switch in each direction).                              */ int num_conn, to_node, i, to_track, iconn; int from_node_switch, to_node_switch; short switch_types[2]; boolean is_x_sbox, is_y_sbox, yconn_to_above; t_linked_edge *edge_list_head; struct s_ivec conn_tracks; num_conn = 0; edge_list_head = *edge_list_ptr; if (to_j <= from_j)     yconn_to_above = TRUE;  /* The connection goes up from ychan to xchan. */ else    yconn_to_above = FALSE;/* Recall:  this is the type of switch to use on switches that go *to* this * * node (i.e. the output side is on the from_node).                         */ from_node_switch = seg_details_x[from_track].wire_switch;/* For each unit-length piece of wire in the segment, I add the things it    * * would connect to diagonally to the right and diagonally to the left of    * * it.  This is important -- for some switch boxes, the connection from      * * (i,j) to (i,j+1) and the connection from (i+1,j) to (i,j+1), for example, * * would lead to connections to different tracks in the (i,j+1) channel.  In * * this case, the code below will connect to ALL the tracks that two unit    * * length segments at (i,j) and (i+1,j) would have connected to in (i,j+1).  */ for (i=from_istart;i<=from_iend;i++) {     /* Diagonal connection to left (from xchan to ychan) */    is_x_sbox = is_sbox (i, from_j, from_track, seg_details_x, FALSE);    conn_tracks = get_switch_box_tracks (i, from_j, from_track, CHANX, i-1,               to_j, CHANY, switch_block_type, nodes_per_chan);    /* For all the tracks we connect to in that channel ... */    for (iconn=0;iconn<conn_tracks.nelem;iconn++) {       to_track = conn_tracks.list[iconn];       is_y_sbox = is_sbox (to_j, i-1, to_track, seg_details_y, yconn_to_above);       to_node_switch = seg_details_y[to_track].wire_switch;              get_switch_type (is_x_sbox, is_y_sbox, from_node_switch, to_node_switch,                         switch_types);       if (switch_types[0] != OPEN) {          to_node = get_rr_node_index (i-1, to_j, CHANY, to_track,                   nodes_per_chan, rr_node_indices);          if (!rr_edge_done[to_node]) {   /* Not a repeat edge. */             num_conn++;             rr_edge_done[to_node] = TRUE;             edge_list_head = insert_in_edge_list (edge_list_head, to_node,                            switch_types[0], &free_edge_list_head);             if (switch_types[1] != OPEN) {   /* A second edge. */                edge_list_head = insert_in_edge_list (edge_list_head, to_node,                            switch_types[1], &free_edge_list_head);                num_conn++;             }          }       }    }    /* Diagonal connection to right (from xchan to ychan) */    is_x_sbox = is_sbox (i, from_j, from_track, seg_details_x, TRUE);    conn_tracks = get_switch_box_tracks (i, from_j, from_track, CHANX, i,               to_j, CHANY, switch_block_type, nodes_per_chan);       /* For all the tracks we connect to in that channel ... */    for (iconn=0;iconn<conn_tracks.nelem;iconn++) {       to_track = conn_tracks.list[iconn];       is_y_sbox = is_sbox (to_j, i, to_track, seg_details_y, yconn_to_above);       to_node_switch = seg_details_y[to_track].wire_switch;              get_switch_type (is_x_sbox, is_y_sbox, from_node_switch, to_node_switch,                        switch_types);       if (switch_types[0] != OPEN) {          to_node = get_rr_node_index (i, to_j, CHANY, to_track,                   nodes_per_chan, rr_node_indices);          if (!rr_edge_done[to_node]) {   /* Not a repeat edge. */             num_conn++;             rr_edge_done[to_node] = TRUE;             edge_list_head = insert_in_edge_list (edge_list_head, to_node,                             switch_types[0], &free_edge_list_head);             if (switch_types[1] != OPEN) {    /* A second edge */                edge_list_head = insert_in_edge_list (edge_list_head, to_node,                             switch_types[1], &free_edge_list_head);                num_conn++;             }          }       }    } }  /* End for length of segment. */  *edge_list_ptr = edge_list_head; return (num_conn);}int get_ytrack_to_xtracks (int from_jstart, int from_jend, int from_i, int        from_track, int to_i, t_linked_edge **edge_list_ptr, int nodes_per_chan,        int **rr_node_indices, t_seg_details *seg_details_x, t_seg_details        *seg_details_y, enum e_switch_block_type switch_block_type) { /* Counts how many connections should be made from this segment to the x-   * * segments in the adjacent channels at to_i.  It returns the number of     * * connections, and updates edge_list_ptr to point at the head of the       * * (extended) linked list giving the nodes to which this segment connects   * * and the switch type used to connect to each.                             * *                                                                          * * An edge is added from this segment to an x-segment if:                   * * (1) this segment should have a switch box at that location, or           * * (2) the x-segment to which it would connect has a switch box, and the    * *     switch type of that x-segment is unbuffered (bidirectional pass      * *     transistor).                                                         * *                                                                          * * If the switch in each direction is a pass transistor (unbuffered), both  * * switches are marked as being of the types of the larger (lower R) pass   * * transistor.  Note that this code implicitly assumes the routing is       * * bidirectional (a switch in each direction).                              */  int num_conn, to_node, j, to_track, iconn; int from_node_switch, to_node_switch; short switch_types[2]; boolean is_x_sbox, is_y_sbox, xconn_to_right; t_linked_edge *edge_list_head; struct s_ivec conn_tracks; num_conn = 0; edge_list_head = *edge_list_ptr; if (to_i <= from_i) 

⌨️ 快捷键说明

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