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

📄 check_route.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 2 页
字号:
  for (iconn=0;iconn<rr_node[from_node].num_edges;iconn++) {    if (rr_node[from_node].edges[iconn] == to_node) {       reached = TRUE;       break;    } }  if (!reached)    return (FALSE); /* Now we know the rr graph says these two nodes are adjacent.  Double  * * check that this makes sense, to verify the rr graph.                 */  num_adj = 0;  from_type = rr_node[from_node].type; from_xlow = rr_node[from_node].xlow; from_ylow = rr_node[from_node].ylow; from_ptc = rr_node[from_node].ptc_num; to_type = rr_node[to_node].type; to_xlow = rr_node[to_node].xlow; to_ylow = rr_node[to_node].ylow; to_ptc = rr_node[to_node].ptc_num;  switch (from_type) {  case SOURCE:    if (to_type == OPIN) {       if (from_xlow == to_xlow && from_ylow == to_ylow) {          if (clb[to_xlow][to_ylow].type == CLB) {             iclass = clb_pin_class[to_ptc];             if (iclass == from_ptc)                num_adj++;          }          else {   /* IO block */             if (to_ptc == from_ptc)                num_adj++;          }       }     }    break;  case SINK:    if (to_type == SOURCE) {   /* Feedthrough.  Not in code as yet. */       if (from_xlow == to_xlow && from_ylow == to_ylow &&               clb[to_xlow][to_ylow].type == CLB)          num_adj++;    }    break;  case OPIN:    if (to_type == CHANX || to_type == CHANY)       num_adj += pin_and_chan_adjacent (from_node, to_node);     break;  case IPIN:    if (to_type == SINK && from_xlow == to_xlow && from_ylow == to_ylow) {       if (clb[from_xlow][from_ylow].type == CLB) {          iclass = clb_pin_class[from_ptc];          if (iclass == to_ptc)             num_adj++;       }        else {    /* OUTPAD */          if (from_ptc == to_ptc)             num_adj++;       }     }    break;  case CHANX:    if (to_type == IPIN) {       num_adj += pin_and_chan_adjacent (to_node, from_node);    }    else if (to_type == CHANX) {       from_xhigh = rr_node[from_node].xhigh;       to_xhigh = rr_node[to_node].xhigh;       if (from_ylow == to_ylow) {          if (to_xhigh == from_xlow-1 || from_xhigh == to_xlow-1)             num_adj++;       }     }    else if (to_type == CHANY) {       num_adj += chanx_chany_adjacent (from_node, to_node);    }    break;  case CHANY:    if (to_type == IPIN) {       num_adj += pin_and_chan_adjacent (to_node, from_node);    }    else if (to_type == CHANY) {       from_yhigh = rr_node[from_node].yhigh;       to_yhigh = rr_node[to_node].yhigh;       if (from_xlow == to_xlow) {          if (to_yhigh == from_ylow-1 || from_yhigh == to_ylow-1)             num_adj++;       }     }    else if (to_type == CHANX) {       num_adj += chanx_chany_adjacent (to_node, from_node);    }    break;  default:    break;  }  if (num_adj == 1)    return (TRUE); else if (num_adj == 0)    return (FALSE);  printf ("Error in check_adjacent: num_adj = %d. Expected 0 or 1.\n", num_adj); exit (1);}  static int chanx_chany_adjacent (int chanx_node, int chany_node) { /* Returns 1 if the specified CHANX and CHANY nodes are adjacent, 0         * * otherwise.                                                               */  int chanx_y, chanx_xlow, chanx_xhigh; int chany_x, chany_ylow, chany_yhigh;  chanx_y = rr_node[chanx_node].ylow; chanx_xlow = rr_node[chanx_node].xlow; chanx_xhigh = rr_node[chanx_node].xhigh; chany_x = rr_node[chany_node].xlow;  chany_ylow = rr_node[chany_node].ylow;  chany_yhigh = rr_node[chany_node].yhigh;  if (chany_ylow > chanx_y+1 || chany_yhigh < chanx_y)    return (0);  if (chanx_xlow > chany_x+1 || chanx_xhigh < chany_x)    return (0);  return (1);}  static int pin_and_chan_adjacent (int pin_node, int chan_node) { /* Checks if pin_node is adjacent to chan_node.  It returns 1 if the two   * * nodes are adjacent and 0 if they are not (any other value means there's * * a bug in this routine).                                                 */  int num_adj, pin_x, pin_y, chan_xlow, chan_ylow, chan_xhigh, chan_yhigh; int pin_ptc; t_rr_type chan_type;  num_adj = 0; pin_x = rr_node[pin_node].xlow; pin_y = rr_node[pin_node].ylow; pin_ptc = rr_node[pin_node].ptc_num; chan_type = rr_node[chan_node].type; chan_xlow = rr_node[chan_node].xlow; chan_ylow = rr_node[chan_node].ylow; chan_xhigh = rr_node[chan_node].xhigh; chan_yhigh = rr_node[chan_node].yhigh;  if (clb[pin_x][pin_y].type == CLB) {    if (chan_type == CHANX) {       if (chan_ylow == pin_y) {   /* CHANX above CLB */          if (pinloc[TOP][pin_ptc] == 1 && pin_x <= chan_xhigh &&                pin_x >= chan_xlow)             num_adj++;       }        else if (chan_ylow == pin_y-1) {   /* CHANX below CLB */          if (pinloc[BOTTOM][pin_ptc] == 1 && pin_x <= chan_xhigh &&                pin_x >= chan_xlow)             num_adj++;       }     }    else if (chan_type == CHANY) {       if (chan_xlow == pin_x) {   /* CHANY to right of CLB */          if (pinloc[RIGHT][pin_ptc] == 1 && pin_y <= chan_yhigh &&                pin_y >= chan_ylow)             num_adj++;       }        else if (chan_xlow == pin_x-1) {   /* CHANY to left of CLB */          if (pinloc[LEFT][pin_ptc] == 1 && pin_y <= chan_yhigh &&                pin_y >= chan_ylow)             num_adj++;       }     } }  else {            /* IO pad */    if (pin_y == 0) {    /* Bottom row of pads. */       if (chan_type == CHANX && chan_ylow == 0 && pin_x <= chan_xhigh &&              pin_x >= chan_xlow)          num_adj++;    }    else if (pin_y == ny+1) {   /* Top row of pads. */       if (chan_type == CHANX && chan_ylow == ny && pin_x <= chan_xhigh &&              pin_x >= chan_xlow)          num_adj++;    }    else if (pin_x == 0) {     /* Left column of pads */       if (chan_type == CHANY && chan_xlow == 0 && pin_y <= chan_yhigh &&              pin_y >= chan_ylow)          num_adj++;    }    else if (pin_x == nx+1) {  /* Right row of pads */       if (chan_type == CHANY && chan_xlow == nx && pin_y <= chan_yhigh &&              pin_y >= chan_ylow)          num_adj++;    } }  return (num_adj);}static void recompute_occupancy_from_scratch (t_ivec **clb_opins_used_locally)           {/* This routine updates the occ field in the rr_node structure according to * * the resource usage of the current routing.  It does a brute force        * * recompute from scratch that is useful for sanity checking.               */ int inode, inet, iblk, iclass, ipin, num_local_opins; struct s_trace *tptr;/* First set the occupancy of everything to zero. */ for (inode=0;inode<num_rr_nodes;inode++)    rr_node[inode].occ = 0;/* Now go through each net and count the tracks and pins used everywhere */ for (inet=0;inet<num_nets;inet++) {       if (is_global[inet])            /* Skip global nets. */       continue;    tptr = trace_head[inet];    if (tptr == NULL)       continue;    while (1) {       inode = tptr->index;       rr_node[inode].occ++;       if (rr_node[inode].type == SINK) {          tptr = tptr->next;                /* Skip next segment. */          if (tptr == NULL)             break;       }        tptr = tptr->next;    } }/* Now update the occupancy of each of the "locally used" OPINs on each CLB * * (CLB outputs used up by being directly wired to subblocks used only      * * locally).                                                                */ for (iblk=0;iblk<num_blocks;iblk++) {    for (iclass=0;iclass<num_class;iclass++) {       num_local_opins = clb_opins_used_locally[iblk][iclass].nelem;            /* Will always be 0 for pads or SINK classes. */       for (ipin=0;ipin<num_local_opins;ipin++) {          inode = clb_opins_used_locally[iblk][iclass].list[ipin];          rr_node[inode].occ++;       }    } }}static void check_locally_used_clb_opins (t_ivec **clb_opins_used_locally,         enum e_route_type route_type) {/* Checks that enough OPINs on CLBs have been set aside (used up) to make a * * legal routing if subblocks connect to OPINs directly.                    */ int iclass, iblk, num_local_opins, inode, ipin; t_rr_type rr_type;  for (iblk=0;iblk<num_blocks;iblk++) {    for (iclass=0;iclass<num_class;iclass++) {       num_local_opins = clb_opins_used_locally[iblk][iclass].nelem;        /* Always 0 for pads and for SINK classes */       for (ipin=0;ipin<num_local_opins;ipin++) {          inode = clb_opins_used_locally[iblk][iclass].list[ipin];          check_node_and_range (inode, route_type);  /* Node makes sense? */         /* Now check that node is an OPIN of the right type. */          rr_type = rr_node[inode].type;          if (rr_type != OPIN) {             printf ("Error in check_locally_used_opins:  Block #%d (%s)\n"                    "\tclass %d locally used OPIN is of the wrong rr_type --\n"                    "\tit is rr_node #%d of type %d.\n", iblk,                     block[iblk].name, iclass, inode, rr_type);             exit (1);          }          ipin = rr_node[inode].ptc_num;          if (clb_pin_class[ipin] != iclass) {             printf ("Error in check_locally_used_opins:  Block #%d (%s):\n"                    "\tExpected class %d locally used OPIN, got class %d."                    "\trr_node #: %d.\n", iblk, block[iblk].name, iclass,                     clb_pin_class[ipin], inode);             exit (1);          }       }    } }}static void check_node_and_range (int inode, enum e_route_type route_type) {/* Checks that inode is within the legal range, then calls check_node to    * * check that everything else about the node is OK.                         */ if (inode < 0 || inode >= num_rr_nodes) {    printf ("Error in check_node_and_range:  rr_node #%d is out of legal "            "\trange (0 to %d).\n", inode, num_rr_nodes-1);    exit (1); } check_node (inode, route_type);}

⌨️ 快捷键说明

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