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

📄 draw.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 3 页
字号:
    y1 = y_clb_bottom[from_ylow];    y2 = y_clb_bottom[from_ylow - 1] + clb_width; } else if (from_ylow < to_ylow) {     y1 = y_clb_bottom[to_ylow - 1] + clb_width;    y2 = y_clb_bottom[to_ylow]; } else if (to_yhigh > from_yhigh) {  /* Draw from top edge of one to other. */    y1 = y_clb_bottom[from_yhigh] + clb_width;    y2 = y_clb_bottom[from_yhigh + 1]; } else if (from_yhigh > to_yhigh) {    y1 = y_clb_bottom[to_yhigh + 1];    y2 = y_clb_bottom[to_yhigh] + clb_width; } else { /* Complete overlap: start and end both align. Draw outside the sbox */    y1 = y_clb_bottom[from_ylow];    y2 = y_clb_bottom[from_ylow] + 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_rr_switch (float from_x, float from_y, float to_x, float to_y,        boolean buffered) {/* Draws a buffer (triangle) or pass transistor (circle) on the edge        * * connecting from to to, depending on the status of buffered.  The drawing * * is closest to the from_node, since it reflects the switch type of from.  */ const float switch_rad = 0.15; float magnitude, xcen, ycen, xdelta, ydelta, xbaseline, ybaseline; float xunit, yunit; t_point poly[3];  xcen = from_x + (to_x - from_x) / 10.; ycen = from_y + (to_y - from_y) / 10.; if (!buffered) {    /* Draw a circle for a pass transistor */    drawarc (xcen, ycen, switch_rad, 0., 360.); } else {  /* Buffer */    xdelta = to_x - from_x;    ydelta = to_y - from_y;    magnitude = sqrt (xdelta * xdelta + ydelta * ydelta);    xunit = xdelta / magnitude;    yunit = ydelta / magnitude;    poly[0].x = xcen + xunit * switch_rad;    poly[0].y = ycen + yunit * switch_rad;    xbaseline = xcen - xunit * switch_rad;    ybaseline = ycen - yunit * switch_rad;/* Recall: perpendicular vector to the unit vector along the switch (xv, yv) * * is (yv, -xv).                                                             */     poly[1].x = xbaseline + yunit * switch_rad;    poly[1].y = ybaseline - xunit * switch_rad;    poly[2].x = xbaseline - yunit * switch_rad;    poly[2].y = ybaseline + xunit * switch_rad;    fillpoly (poly, 3); }}static void draw_rr_pin (int inode, enum color_types color) {/* Draws an IPIN or OPIN rr_node.  Note that the pin can appear on more    * * than one side of a clb.  Also note that this routine can change the     * * current color to BLACK.                                                 */ int ipin, i, j, iside, iclass, iblk; float xcen, ycen; char str[BUFSIZE]; i = rr_node[inode].xlow; j = rr_node[inode].ylow; ipin = rr_node[inode].ptc_num; setcolor (color); if (clb[i][j].type == CLB) {    iclass = clb_pin_class[ipin];    for (iside=0;iside<=3;iside++) {       if (pinloc[iside][ipin] == 1) {   /* Pin exists on this side. */          get_rr_pin_draw_coords (inode, iside, &xcen, &ycen);          fillrect (xcen-pin_size, ycen-pin_size, xcen+pin_size, ycen+pin_size);          sprintf (str, "%d", ipin);          setcolor (BLACK);          drawtext (xcen, ycen, str, 2*pin_size);          setcolor (color);       }    } } else {               /* IO pad. */    iblk = clb[i][j].u.io_blocks[ipin];    if (i == 0)        iside = RIGHT;    else if (j == 0)       iside = TOP;    else if (i == nx+1)       iside = LEFT;    else       iside = BOTTOM;    get_rr_pin_draw_coords (inode, iside, &xcen, &ycen);    fillrect (xcen-pin_size, ycen-pin_size, xcen+pin_size, ycen+pin_size); }}static void get_rr_pin_draw_coords (int inode, int iside, float *xcen,             float *ycen) {/* Returns the coordinates at which the center of this pin should be drawn. * * inode gives the node number, and iside gives the side of the clb or pad  * * the physical pin is on.                                                  */ int i, j, ipin, ipad; float step_size, offset, xc, yc; i = rr_node[inode].xlow; j = rr_node[inode].ylow;  xc = x_clb_left[i]; yc = y_clb_bottom[j]; if (clb[i][j].type == CLB) {    ipin = rr_node[inode].ptc_num;     step_size = clb_width / (pins_per_clb + 1.);    offset = (ipin + 1.) * step_size; } else {                                        /* IO pad. */      ipad = rr_node[inode].ptc_num;     step_size = clb_width / (float) io_rat;    offset = ipad * step_size + clb_width / (3. * io_rat);   /* Pads have both an IPIN and an OPIN.  Stagger them. */    if (rr_node[inode].type == IPIN)        offset += clb_width / (3. * io_rat); } switch (iside) { case LEFT:      yc += offset;    break;  case RIGHT:     xc += clb_width;     yc += offset;     break;    case BOTTOM:     xc += offset;     break;  case TOP:     xc += offset;     yc += clb_width;     break;  default:     printf ("Error in get_rr_pin_draw_coords:  Unexpected iside %d.\n",             iside);     exit (1);     break; } *xcen = xc; *ycen = yc;}static void drawroute (enum e_draw_net_type draw_net_type) {/* Draws the nets in the positions fixed by the router.  If draw_net_type is * * ALL_NETS, draw all the nets.  If it is HIGHLIGHTED, draw only the nets    * * that are not coloured black (useful for drawing over the rr_graph).       */ /* Next free track in each channel segment if routing is GLOBAL */ static int **chanx_track = NULL;           /* [1..nx][0..ny] */ static int **chany_track = NULL;           /* [0..nx][1..ny] */ int inet, i, j, inode, prev_node, prev_track, itrack; short switch_type; struct s_trace *tptr; t_rr_type rr_type, prev_type; if (draw_route_type == GLOBAL) {   /* Allocate some temporary storage if it's not already available. */    if (chanx_track == NULL)        chanx_track = (int **) alloc_matrix (1, nx, 0, ny, sizeof(int));    if (chany_track == NULL)        chany_track = (int **) alloc_matrix (0, nx, 1, ny, sizeof(int));    for (i=1;i<=nx;i++)       for (j=0;j<=ny;j++)          chanx_track[i][j] = -1;    for (i=0;i<=nx;i++)       for (j=1;j<=ny;j++)          chany_track[i][j] = -1; } setlinestyle (SOLID);/* Now draw each net, one by one.      */ for (inet=0;inet<num_nets;inet++) {    if (is_global[inet])           /* Don't draw global nets. */       continue;    if (trace_head[inet] == NULL)  /* No routing.  Skip.  (Allows me to draw */       continue;                   /* partially complete routes).            */    if (draw_net_type == HIGHLIGHTED && net_color[inet] == BLACK)        continue;     setcolor (net_color[inet]);    tptr = trace_head[inet];   /* SOURCE to start */    inode = tptr->index;    rr_type = rr_node[inode].type;        while (1) {       prev_node = inode;       prev_type = rr_type;       switch_type = tptr->iswitch;       tptr = tptr->next;       inode = tptr->index;       rr_type = rr_node[inode].type;       switch (rr_type) {       case OPIN:          draw_rr_pin (inode, net_color[inet]);          break;       case IPIN:          draw_rr_pin (inode, net_color[inet]);          prev_track = get_track_num (prev_node, chanx_track, chany_track);          draw_pin_to_chan_edge (inode, prev_node, prev_track, FALSE);          break;       case CHANX:          if (draw_route_type == GLOBAL)             chanx_track[rr_node[inode].xlow][rr_node[inode].ylow]++;          itrack = get_track_num (inode, chanx_track, chany_track);          draw_rr_chanx (inode, itrack);          switch (prev_type) {          case CHANX:             prev_track = get_track_num (prev_node, chanx_track, chany_track);             draw_chanx_to_chanx_edge (prev_node, prev_track, inode, itrack,                         switch_type);             break;           case CHANY:             prev_track = get_track_num (prev_node, chanx_track, chany_track);             draw_chanx_to_chany_edge (inode, itrack, prev_node, prev_track,                      FROM_Y_TO_X, switch_type);             break;          case OPIN:             draw_pin_to_chan_edge (prev_node, inode, itrack, FALSE);             break;          default:             printf ("Error in drawroute:  Unexpected connection from an \n"                "rr_node of type %d to one of type %d.\n", prev_type, rr_type);             exit (1);          }          break;       case CHANY:          if (draw_route_type == GLOBAL)              chany_track[rr_node[inode].xlow][rr_node[inode].ylow]++;          itrack = get_track_num (inode, chanx_track, chany_track);          draw_rr_chany (inode, itrack);           switch (prev_type) {           case CHANX:             prev_track = get_track_num (prev_node, chanx_track, chany_track);             draw_chanx_to_chany_edge (prev_node, prev_track, inode, itrack,                       FROM_X_TO_Y, switch_type);             break;           case CHANY:             prev_track = get_track_num (prev_node, chanx_track, chany_track);             draw_chany_to_chany_edge (prev_node, prev_track, inode, itrack,                       switch_type);             break;           case OPIN:             draw_pin_to_chan_edge (prev_node, inode, itrack, FALSE);             break;           default:             printf ("Error in drawroute:  Unexpected connection from an \n"                "rr_node of type %d to one of type %d.\n", prev_type, rr_type);             exit (1);          }           break;        default:          break;             }             if (rr_type == SINK) {   /* Skip the next segment */          tptr = tptr->next;          if (tptr == NULL)              break;          inode = tptr->index;          rr_type = rr_node[inode].type;       }           } /* End loop over traceback. */ } /* End for (each net) */}static int get_track_num (int inode, int **chanx_track, int **chany_track) {/* Returns the track number of this routing resource node.   */ int i, j; t_rr_type rr_type; if (draw_route_type == DETAILED)    return (rr_node[inode].ptc_num);/* GLOBAL route stuff below. */ rr_type = rr_node[inode].type; i = rr_node[inode].xlow;       /* NB: Global rr graphs must have only unit */ j = rr_node[inode].ylow;       /* length channel segments.                 */ switch (rr_type) { case CHANX:    return (chanx_track[i][j]); case CHANY:    return (chany_track[i][j]); default:    printf ("Error in get_track_num:  unexpected node type %d for node %d."            "\n", rr_type, inode);    exit (1); }}static void highlight_blocks (float x, float y) {/* This routine is called when the user clicks in the graphics area. * * It determines if a clb was clicked on.  If one was, it is         * * highlighted in green, it's fanin nets and clbs are highlighted in * * blue and it's fanout is highlighted in red.  If no clb was        * * clicked on (user clicked on white space) any old highlighting is  * * removed.  Note that even though global nets are not drawn, their  * * fanins and fanouts are highlighted when you click on a block      * * attached to them.                                                 */ int i, j, k, hit, bnum, ipin, netnum, fanblk; int class; float io_step; char msg[BUFSIZE]; io_step = clb_width/io_rat; deselect_all (); hit = 0; for (i=0;i<=nx+1;i++) {    if (x <= x_clb_left[i]+clb_width) {       if (x >= x_clb_left[i])           hit = 1;       break;    } } if (!hit) {    update_message (default_message);    drawscreen();    return; } hit = 0; for (j=0;j<=ny+1;j++) {    if (y <= y_clb_bottom[j]+clb_width) {       if (y >= y_clb_bottom[j])          hit = 1;       break;    } } if (!hit) {    update_message (default_message);     drawscreen();    return; }/* The user selected the clb at location (i,j). */ if (clb[i][j].type == CLB) {    if (clb[i][j].occ == 0) {       update_message (default_message);        drawscreen ();       return;    }    bnum = clb[i][j].u.block; } else {   /* IO block clb */    if (i == 0 || i == nx+1)      /* Vertical columns of IOs */       k = (int) ((y - y_clb_bottom[j]) / io_step);    else        k = (int) ((x - x_clb_left[i]) / io_step);    if (k >= clb[i][j].occ) {   /* Empty spot */       update_message (default_message);        drawscreen();       return;    }    bnum = clb[i][j].u.io_blocks[k]; }/* Highlight fanin and fanout. */ if (block[bnum].type == OUTPAD) {    netnum = block[bnum].nets[0];    /* Only net. */    net_color[netnum] = BLUE;        /* Outpad drives nothing */    fanblk = net[netnum].blocks[0];    /* Net driver */    block_color[fanblk] = BLUE; } else if (block[bnum].type == INPAD) {    netnum = block[bnum].nets[0];    /* Only net. */    net_color[netnum] = RED;         /* Driven by INPAD *//* Highlight fanout blocks in RED */    for (ipin=1;ipin<net[netnum].num_pins;ipin++) {        fanblk = net[netnum].blocks[ipin];       block_color[fanblk] = RED;    } } else {       /* CLB block. */    for (k=0;k<pins_per_clb;k++) {     /* Each pin on a CLB */       netnum = block[bnum].nets[k];       if (netnum == OPEN)          continue;       class = clb_pin_class[k];       if (class_inf[class].type == DRIVER) {  /* Fanout */          net_color[netnum] = RED;          for (ipin=1;ipin<net[netnum].num_pins;ipin++) {              fanblk = net[netnum].blocks[ipin];             block_color[fanblk] = RED;          }       }       else {         /* This net is fanin to the block. */          net_color[netnum] = BLUE;          fanblk = net[netnum].blocks[0];          block_color[fanblk] = BLUE;       }    } } block_color[bnum] = GREEN;   /* Selected block. */ sprintf (msg, "Block %d (%s) at (%d, %d) selected.", bnum, block[bnum].name,               i, j); update_message (msg); drawscreen ();      /* Need to erase screen. */}static void deselect_all (void) {/* Sets the color of all clbs and nets to the default.  */ int i; for (i=0;i<num_blocks;i++)     block_color[i] = LIGHTGREY; for (i=0;i<num_nets;i++)    net_color[i] = BLACK;} 

⌨️ 快捷键说明

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