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

📄 rr_graph2.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 4 页
字号:
    xconn_to_right = TRUE;  /* The connection goes RIGHT from xchan to ychan */ else    xconn_to_right = 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_y[from_track].wire_switch;/* For each unit-length piece of wire in the segment, I add the things it    * * would connect to diagonally above and diagonally below it.  This is       * * important -- for some switch boxes, the connection from (i,j) to (i+1,j)  * * and the connection from (i,j+1) to (i+1,j), for example, would lead to    * * connections to different tracks in the (i+1,j) channel.  In this case,    * * the code below will connect to ALL the tracks that two unit length        * * segments at (i,j) and (i,j+1) would have connected to in (i+1,j).         */  for (j=from_jstart;j<=from_jend;j++) {       /* Diagonal connection to below (from ychan to xchan) */    is_y_sbox = is_sbox (j, from_i, from_track, seg_details_y, FALSE);    conn_tracks = get_switch_box_tracks (from_i, j, from_track, CHANY, to_i,               j-1, CHANX, 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_x_sbox = is_sbox (to_i, j-1, to_track, seg_details_x, xconn_to_right);       to_node_switch = seg_details_x[to_track].wire_switch;            get_switch_type (is_y_sbox, is_x_sbox, from_node_switch, to_node_switch,                        switch_types);       if (switch_types[0] != OPEN) {           to_node = get_rr_node_index (to_i, j-1, CHANX, 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 above (from ychan to xchan) */    is_y_sbox = is_sbox (j, from_i, from_track, seg_details_y, TRUE);    conn_tracks = get_switch_box_tracks (from_i, j, from_track, CHANY, to_i,               j, CHANX, 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_x_sbox = is_sbox (to_i, j, to_track, seg_details_x, xconn_to_right);       to_node_switch = seg_details_x[to_track].wire_switch;       get_switch_type (is_y_sbox, is_x_sbox, from_node_switch, to_node_switch,                        switch_types);       if (switch_types[0] != OPEN) {           to_node = get_rr_node_index (to_i, j, CHANX, 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_xtrack_to_xtrack (int from_i, int j, 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, enum        e_switch_block_type switch_block_type) {/* Returns the number of edges between the specified channel segments.      * * Also updates edge_list_ptr to point at the new (extended) linked list    * * of edges and switch types.                                               */  boolean is_from_sbox, is_to_sbox, from_goes_right, to_goes_right; int to_track, to_node, iconn, num_conn; int from_node_switch, to_node_switch; short switch_types[2]; struct s_ivec conn_tracks; if (from_i < to_i) {    from_goes_right = TRUE;    to_goes_right = FALSE; } else {    from_goes_right = FALSE;    to_goes_right = TRUE; } num_conn = 0; from_node_switch = seg_details_x[from_track].wire_switch; is_from_sbox = is_sbox (from_i, j, from_track, seg_details_x, from_goes_right); conn_tracks = get_switch_box_tracks (from_i, j, from_track, CHANX, to_i,            j, CHANX, 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_to_sbox = is_sbox (to_i, j, to_track, seg_details_x, to_goes_right);    to_node_switch = seg_details_x[to_track].wire_switch;      get_switch_type (is_from_sbox, is_to_sbox, from_node_switch,                     to_node_switch, switch_types);     if (switch_types[0] != OPEN) {       to_node = get_rr_node_index (to_i, j, CHANX, to_track, nodes_per_chan,               rr_node_indices);       /* No need to check for repeats with the current switch boxes. */       *edge_list_ptr = insert_in_edge_list (*edge_list_ptr, to_node,                         switch_types[0], &free_edge_list_head);       num_conn++;       if (switch_types[1] != OPEN) {          *edge_list_ptr = insert_in_edge_list (*edge_list_ptr, to_node,                            switch_types[1], &free_edge_list_head);          num_conn++;       }    } }         return (num_conn);}int get_ytrack_to_ytrack (int i, 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_y, enum        e_switch_block_type switch_block_type) { /* Returns the number of edges between the specified channel segments.      * * Also updates edge_list_ptr to point at the new (extended) linked list    * * of edges and switch types.                                               */  boolean is_from_sbox, is_to_sbox, from_goes_up, to_goes_up;  int to_track, to_node, iconn, num_conn; int from_node_switch, to_node_switch; short switch_types[2]; struct s_ivec conn_tracks;if (from_j < to_j) {     from_goes_up = TRUE;     to_goes_up = FALSE;  }  else {    from_goes_up = FALSE;     to_goes_up = TRUE;  }  num_conn = 0; from_node_switch = seg_details_y[from_track].wire_switch;  is_from_sbox = is_sbox (from_j, i, from_track, seg_details_y, from_goes_up);  conn_tracks = get_switch_box_tracks (i, from_j, from_track, CHANY, 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_to_sbox = is_sbox (to_j, i, to_track, seg_details_y, to_goes_up);     to_node_switch = seg_details_y[to_track].wire_switch;     get_switch_type (is_from_sbox, is_to_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);        /* No need to check for repeats with the current switch boxes. */       *edge_list_ptr = insert_in_edge_list (*edge_list_ptr, to_node,                        switch_types[0], &free_edge_list_head);       num_conn++;       if (switch_types[1] != OPEN) {          *edge_list_ptr = insert_in_edge_list (*edge_list_ptr, to_node,                           switch_types[1], &free_edge_list_head);          num_conn++;       }    } }  return (num_conn);}boolean is_sbox (int seg_num, int chan_num, int itrack, t_seg_details           *seg_details, boolean above_or_right) {/* Returns TRUE if the specified segment has a switch box at the specified  * * location, FALSE otherwise.  The switch box is from the specified segment * * to the left (for chanx) or below (for chany) unless above_or_right is    * * TRUE.                                                                    */ int seg_offset, start, length; boolean longline;  length = seg_details[itrack].length; start = seg_details[itrack].start; longline = seg_details[itrack].longline;/* NB: Periodicity is length for normal segments, length + 1 for long lines. */  if (!longline) {    seg_offset = (seg_num + chan_num - start + length) % length;    seg_offset += above_or_right;    /* Add one if conn. is above or to right */ } else {    /* Is a longline */    seg_offset = (seg_num + chan_num - start + above_or_right) % (length + 1); } return (seg_details[itrack].sb[seg_offset]);}static void get_switch_type (boolean is_from_sbox, boolean is_to_sbox,            short from_node_switch, short to_node_switch, short switch_types[2])           {/* This routine looks at whether the from_node and to_node want a switch,  * * and what type of switch is used to connect *to* each type of node       * * (from_node_switch and to_node_switch).  It decides what type of switch, * * if any, should be used to go from from_node to to_node.  If no switch   * * should be inserted (i.e. no connection), it returns OPEN.  Its returned * * values are in the switch_types array.  It needs to return an array      * * because one topology (a buffer in the forward direction and a pass      * * transistor in the backward direction) results in *two* switches.        */ switch_types[0] = OPEN;  /* No switch */ switch_types[1] = OPEN; if (!is_from_sbox && !is_to_sbox) {  /* No connection wanted in either dir */    switch_types[0] = OPEN; } else if (is_from_sbox && !is_to_sbox) {  /* Only forward connection wanted */    switch_types[0] = to_node_switch;  /* Type of switch to go *to* to_node */ }  else if (!is_from_sbox && is_to_sbox) {/* Only backward connection desired.  We're deciding whether or not to put * * in the forward connection.  Put it in if the backward connection uses   * * a bidirectional (pass transistor) switch.  Remember that the backward   * * connection uses a from_node_switch type of switch.                      */    if (switch_inf[from_node_switch].buffered == FALSE) {       switch_types[0] = from_node_switch;    } } else {/* Both a forward and a backward connection desired.  If the switch types   * * desired for the two connection are different, we have to reconcile them. */    if (from_node_switch == to_node_switch) {       switch_types[0] = to_node_switch;    }    else {    /* Different switch types.  Reconcile. */       if (switch_inf[to_node_switch].buffered) {          switch_types[0] = to_node_switch;          if (switch_inf[from_node_switch].buffered == FALSE) {         /* Buffer in forward direction, pass transistor in backward.  Put *          * in *two* edges.                                                */                           switch_types[1] = from_node_switch;          }       }       else {   /* Forward connection is a pass transistor. */          if (switch_inf[from_node_switch].buffered) {             switch_types[0] = to_node_switch;          }          else {            /* Both forward and backward connections use pass transistors. *           * use whichever one is larger, since you'll only physically   *           * build one switch.                                           */                  if (switch_inf[to_node_switch].R <                             switch_inf[from_node_switch].R) {                switch_types[0] = to_node_switch;             }             else if (switch_inf[from_node_switch].R <                             switch_inf[to_node_switch].R) {                switch_types[0] = from_node_switch;             }             else {             /* Two pass transistors have the same R, but are have different *              * switch indices.  Use the one with lower index (arbitrarily), *              * to ensure both switches are of the same type (since you can  *              * only physically build one).  I'm being pretty dogmatic here. */                if (to_node_switch < from_node_switch) {                   switch_types[0] = to_node_switch;                }                else {                   switch_types[0] = from_node_switch;                }             }          }       }    }     /* End switch types are different */ }   /* End both forward and backward connection desired. */}

⌨️ 快捷键说明

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