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

📄 draw.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 3 页
字号:
       drawline (x1,y1,x2,y2); /*      x1 = x2;  */    /* Uncomment to draw a chain instead of a star. */ /*      y1 = y2;  */    } }}static void get_block_center (int bnum, float *x, float *y) {/* This routine finds the center of block bnum in the current placement, * * and returns it in *x and *y.  This is used in routine shownets.       */ int i, j, k;  i = block[bnum].x; j = block[bnum].y; if (clb[i][j].type == CLB) {    *x = x_clb_left[i] + clb_width/2.;    *y = y_clb_bottom[j] + clb_width/2.; } else {    /* IO clb.  Have to figure out which subblock it is. */    for (k=0;k<clb[i][j].occ;k++)        if (clb[i][j].u.io_blocks[k] == bnum)           break;             if (i == 0 || i == nx + 1) {   /* clb split vertically */       *x = x_clb_left[i] + clb_width/2.;       *y = y_clb_bottom[j] + (k + 0.5) * clb_width / (float) io_rat;     }    else {                         /* clb split horizontally */       *x = x_clb_left[i] + (k + 0.5) * clb_width / (float) io_rat;        *y = y_clb_bottom[j] + clb_width/2.;    } }}static void draw_congestion (void) {/* Draws all the overused routing resources (i.e. congestion) in RED.   */ int inode, itrack; setcolor (RED); setlinewidth (2); for (inode=0;inode<num_rr_nodes;inode++) {    if (rr_node[inode].occ > rr_node[inode].capacity) {            switch (rr_node[inode].type) {       case CHANX:          itrack = rr_node[inode].ptc_num;          draw_rr_chanx (inode, itrack);          break;                 case CHANY:          itrack = rr_node[inode].ptc_num;          draw_rr_chany (inode, itrack);          break;        case IPIN: case OPIN:          draw_rr_pin (inode, RED);          break;         default:          break;       }    } }}static void draw_rr (void) {/* Draws the routing resources that exist in the FPGA, if the user wants * * them drawn.                                                           */ int inode, itrack; if (draw_rr_toggle == DRAW_NO_RR) {    setlinewidth (3);    drawroute (HIGHLIGHTED);    setlinewidth (0);    return; } setlinestyle (SOLID); setlinewidth (0); for (inode=0;inode<num_rr_nodes;inode++) {      switch (rr_node[inode].type) {          case SOURCE: case SINK:        break;         /* Don't draw. */     case CHANX:       setcolor (BLACK);       itrack = rr_node[inode].ptc_num;       draw_rr_chanx (inode, itrack);       draw_rr_edges (inode);       break;     case CHANY:       setcolor (BLACK);       itrack = rr_node[inode].ptc_num;       draw_rr_chany (inode, itrack);       draw_rr_edges (inode);       break;    case IPIN:       draw_rr_pin (inode, BLUE);       break;    case OPIN:       draw_rr_pin (inode, RED);       setcolor (RED);       draw_rr_edges (inode);       break;    default:       printf("Error in draw_rr:  Unexpected rr_node type: %d.\n",               rr_node[inode].type);       exit (1);    } }  setlinewidth (3); drawroute (HIGHLIGHTED); setlinewidth (0);}static void draw_rr_chanx (int inode, int itrack) {/* Draws an x-directed channel segment.                       */ float x1, x2, y; /* Track 0 at bottom edge, closest to "owning" clb. */  x1 = x_clb_left[rr_node[inode].xlow];  x2 = x_clb_left[rr_node[inode].xhigh] + clb_width;  y = y_clb_bottom[rr_node[inode].ylow] + 1. + itrack + clb_width;  drawline (x1, y, x2, y);}static void draw_rr_chany (int inode, int itrack) { /* Draws a y-directed channel segment.                       */   float x, y1, y2;  /* Track 0 at left edge, closest to "owning" clb. */  x = x_clb_left[rr_node[inode].xlow] + 1. + itrack + clb_width;  y1 = y_clb_bottom[rr_node[inode].ylow];  y2 = y_clb_bottom[rr_node[inode].yhigh] + clb_width;  drawline (x, y1, x, y2);}static void draw_rr_edges (int inode) {/* Draws all the edges that the user wants shown between inode and what it * * connects to.  inode is assumed to be a CHANX, CHANY, or OPIN.           */ t_rr_type from_type, to_type; int iedge, to_node, from_ptc_num, to_ptc_num; short switch_type; from_type = rr_node[inode].type; if (draw_rr_toggle == DRAW_NODES_RR || (draw_rr_toggle ==               DRAW_NODES_AND_SBOX_RR && from_type == OPIN))    return;                                          /* Nothing to draw. */ from_ptc_num = rr_node[inode].ptc_num;  for (iedge=0;iedge<rr_node[inode].num_edges;iedge++) {    to_node = rr_node[inode].edges[iedge];    to_type = rr_node[to_node].type;    to_ptc_num = rr_node[to_node].ptc_num;        switch (from_type) {    case OPIN:       switch (to_type) {       case CHANX: case CHANY:          setcolor (RED);          draw_pin_to_chan_edge (inode, to_node, to_ptc_num, TRUE);          break;       default:          printf("Error in draw_rr_edges:  node %d (type: %d) connects to \n"             "node %d (type: %d).\n", inode, from_type, to_node, to_type);          exit (1);          break;       }       break;    case CHANX:            /* from_type */       switch (to_type) {              case IPIN:          if (draw_rr_toggle == DRAW_NODES_AND_SBOX_RR)             break;                    setcolor (BLUE);          draw_pin_to_chan_edge (to_node, inode, from_ptc_num, TRUE);          break;       case CHANX:          setcolor (DARKGREEN);          switch_type = rr_node[inode].switches[iedge];          draw_chanx_to_chanx_edge (inode, from_ptc_num, to_node,                     to_ptc_num, switch_type);          break;       case CHANY:          setcolor (DARKGREEN);          switch_type = rr_node[inode].switches[iedge];          draw_chanx_to_chany_edge (inode, from_ptc_num, to_node,                      to_ptc_num, FROM_X_TO_Y, switch_type);           break;       default:          printf("Error in draw_rr_edges:  node %d (type: %d) connects to \n"             "node %d (type: %d).\n", inode, from_type, to_node, to_type);          exit (1);          break;           }       break;         case CHANY:                   /* from_type */       switch (to_type) {       case IPIN:          if (draw_rr_toggle == DRAW_NODES_AND_SBOX_RR)             break;                   setcolor (BLUE);          draw_pin_to_chan_edge (to_node, inode, from_ptc_num, TRUE);          break;       case CHANX:          setcolor (DARKGREEN);          switch_type = rr_node[inode].switches[iedge];          draw_chanx_to_chany_edge (to_node, to_ptc_num, inode,                      from_ptc_num, FROM_Y_TO_X, switch_type);           break;       case CHANY:          setcolor (DARKGREEN);          switch_type = rr_node[inode].switches[iedge];          draw_chany_to_chany_edge (inode, from_ptc_num, to_node,                    to_ptc_num, switch_type);          break;       default:          printf("Error in draw_rr_edges:  node %d (type: %d) connects to \n"             "node %d (type: %d).\n", inode, from_type, to_node, to_type);          exit (1);          break;       }       break;    default:                     /* from_type */       printf("Error:  draw_rr_edges called with node %d of type %d.\n",               inode, from_type);       exit (1);       break;    } }   /* End of for each edge loop */}static void draw_pin_to_chan_edge (int pin_node, int chan_node, int itrack,             boolean mark_conn) {/* This routine draws an edge from the pin_node to the chan_node (CHANX or   * * CHANY).  The track number of the channel is passed in itrack, rather than * * taken from chan_node's ptc_num to allow this routine to draw global       * * routings (where the track number isn't in the rr_graph).  If mark_conn is * * TRUE, draw a box where the pin connects to the track (useful for drawing  * * the rr graph).                                                            */ t_rr_type chan_type; int pin_x, pin_y, pin_num, chan_xlow, chan_ylow; float x1, x2, y1, y2; pin_x = rr_node[pin_node].xlow; pin_y = rr_node[pin_node].ylow; pin_num = rr_node[pin_node].ptc_num; chan_type = rr_node[chan_node].type; switch (chan_type) { case CHANX:    chan_ylow = rr_node[chan_node].ylow;    if (pin_y == chan_ylow) {       get_rr_pin_draw_coords (pin_node, TOP, &x1, &y1);       y1 += pin_size;                        /* Don't overdraw pin number. */    }    else {       get_rr_pin_draw_coords (pin_node, BOTTOM, &x1, &y1);       y1 -= pin_size;    }         y2 = y_clb_bottom[chan_ylow] + clb_width + 1 + itrack;    x2 = x1;    break;  case CHANY:    chan_xlow = rr_node[chan_node].xlow;    if (pin_x == chan_xlow) {       get_rr_pin_draw_coords (pin_node, RIGHT, &x1, &y1);       x1 += pin_size;    }    else {       get_rr_pin_draw_coords (pin_node, LEFT, &x1, &y1);       x1 -= pin_size;    }     x2 = x_clb_left[chan_xlow] + clb_width + 1 + itrack;    y2 = y1;    break; default:    printf ("Error in draw_pin_to_chan_edge:  invalid channel node %d.\n",            chan_node);    exit (1); } drawline (x1, y1, x2, y2); if (mark_conn)    draw_x (x2, y2, 0.7 * pin_size);}static void draw_x (float x, float y, float size) {/* Draws an X centered at (x,y).  The width and height of the X are each    * * 2 * size.                                                                */ drawline (x-size, y+size, x+size, y-size); drawline (x-size, y-size, x+size, y+size);}static void draw_chanx_to_chany_edge (int chanx_node,  int chanx_track,          int chany_node, int chany_track, enum e_edge_dir edge_dir, short          switch_type) {/* Draws an edge (SBOX connection) between an x-directed channel and a    * * y-directed channel.                                                    */ float x1, y1, x2, y2; int chanx_y, chany_x, chanx_xlow, chany_ylow; chanx_y = rr_node[chanx_node].ylow; chanx_xlow = rr_node[chanx_node].xlow; chany_x = rr_node[chany_node].xlow; chany_ylow = rr_node[chany_node].ylow;/* (x1,y1): point on CHANX segment, (x2,y2): point on CHANY segment. */ y1 = y_clb_bottom[chanx_y] + clb_width + 1. + chanx_track; x2 = x_clb_left[chany_x] + clb_width + 1. + chany_track; if (chanx_xlow <= chany_x) {   /* Can draw connection going right */    x1 = x_clb_left[chany_x] + clb_width; } else {            /* Must draw connection going left. */    x1 = x_clb_left[chanx_xlow];  } if (chany_ylow <= chanx_y) {   /* Can draw connection going up. */    y2 = y_clb_bottom[chanx_y] + clb_width; } else {     /* Must draw connection going down. */    y2 = y_clb_bottom[chany_ylow]; } drawline (x1, y1, x2, y2); if (draw_rr_toggle != DRAW_ALL_RR)     return; if (edge_dir == FROM_X_TO_Y)     draw_rr_switch (x1, y1, x2, y2, switch_inf[switch_type].buffered); else    draw_rr_switch (x2, y2, x1, y1, switch_inf[switch_type].buffered);}static void draw_chanx_to_chanx_edge (int from_node, int from_track,         int to_node, int to_track, short switch_type) {/* Draws a connection between two x-channel segments.  Passing in the track * * numbers allows this routine to be used for both rr_graph and routing     * * drawing.                                                                 */ float x1, x2, y1, y2; int from_y, to_y, from_xlow, to_xlow, from_xhigh, to_xhigh; from_y = rr_node[from_node].ylow; from_xlow = rr_node[from_node].xlow; from_xhigh = rr_node[from_node].xhigh; to_y = rr_node[to_node].ylow; to_xlow = rr_node[to_node].xlow; to_xhigh = rr_node[to_node].xhigh;/* (x1, y1) point on from_node, (x2, y2) point on to_node. */ y1 = y_clb_bottom[from_y] + clb_width + 1 + from_track; y2 = y_clb_bottom[to_y] + clb_width + 1 + to_track;  if (to_xhigh < from_xlow) {   /* From right to left */    x1 = x_clb_left[from_xlow];    x2 = x_clb_left[to_xhigh] + clb_width; } else if (to_xlow > from_xhigh) { /* From left to right */    x1 = x_clb_left[from_xhigh] + clb_width;    x2 = x_clb_left[to_xlow]; }/* Segments overlap in the channel.  Figure out best way to draw.  Have to  * * make sure the drawing is symmetric in the from rr and to rr so the edges * * will be drawn on top of each other for bidirectional connections.        */ else if (to_xlow < from_xlow) {   /* Draw from left edge of one to other */    x1 = x_clb_left[from_xlow];    x2 = x_clb_left[from_xlow - 1] + clb_width; } else if (from_xlow < to_xlow) {    x1 = x_clb_left[to_xlow - 1] + clb_width;    x2 = x_clb_left[to_xlow]; } else if (to_xhigh > from_xhigh) {  /* Draw from right edge of one to other */    x1 = x_clb_left[from_xhigh] + clb_width;    x2 = x_clb_left[from_xhigh + 1]; } else if (from_xhigh > to_xhigh) {    x1 = x_clb_left[to_xhigh + 1];    x2 = x_clb_left[to_xhigh] + clb_width; } else { /* Complete overlap: start and end both align. Draw outside the sbox */    x1 = x_clb_left[from_xlow];    x2 = x_clb_left[from_xlow] + clb_width; }  drawline (x1, y1, x2, y2);  if (draw_rr_toggle == DRAW_ALL_RR)    draw_rr_switch (x1, y1, x2, y2, switch_inf[switch_type].buffered);}static void draw_chany_to_chany_edge (int from_node, int from_track,        int to_node, int to_track, short switch_type) { /* Draws a connection between two y-channel segments.  Passing in the track * * numbers allows this routine to be used for both rr_graph and routing     * * drawing.                                                                 */  float x1, x2, y1, y2; int from_x, to_x, from_ylow, to_ylow, from_yhigh, to_yhigh;  from_x = rr_node[from_node].xlow; from_ylow = rr_node[from_node].ylow; from_yhigh = rr_node[from_node].yhigh; to_x = rr_node[to_node].xlow; to_ylow = rr_node[to_node].ylow; to_yhigh = rr_node[to_node].yhigh;/* (x1, y1) point on from_node, (x2, y2) point on to_node. */  x1 = x_clb_left[from_x] + clb_width + 1 + from_track; x2 = x_clb_left[to_x] + clb_width + 1 + to_track; if (to_yhigh < from_ylow) {   /* From upper to lower */    y1 = y_clb_bottom[from_ylow];    y2 = y_clb_bottom[to_yhigh] + clb_width; } else if (to_ylow > from_yhigh) {    /* From lower to upper */    y1 = y_clb_bottom[from_yhigh] + clb_width;    y2 = y_clb_bottom[to_ylow]; }/* Segments overlap in the channel.  Figure out best way to draw.  Have to  * * make sure the drawing is symmetric in the from rr and to rr so the edges * * will be drawn on top of each other for bidirectional connections.        */  else if (to_ylow < from_ylow) {  /* Draw from bottom edge of one to other. */

⌨️ 快捷键说明

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