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

📄 draw.c

📁 用于学术研究的FPGA布局布线软件VPR
💻 C
📖 第 1 页 / 共 4 页
字号:
			    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 voiddraw_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);}/* UDSD Modifications by WMF: Thank God Andy fixed this. */static voiddraw_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 = tile_y[chanx_y] + tile_width + 1. + chanx_track;    x2 = tile_x[chany_x] + tile_width + 1. + chany_track;    if(chanx_xlow <= chany_x)	{			/* Can draw connection going right */	    x1 = tile_x[chany_x] + tile_width;	    /* UDSD by AY Start */	    if(rr_node[chanx_node].direction != BI_DIRECTION)		{		    if(edge_dir == FROM_X_TO_Y)			{			    if((chanx_track % 2) == 1)				{	/* UDSD Modifications by WMF: If dec wire, then going left */				    x1 = tile_x[chany_x + 1];				}			}		}	    /* UDSD by AY End */	}    else	{			/* Must draw connection going left. */	    x1 = tile_x[chanx_xlow];	}    if(chany_ylow <= chanx_y)	{			/* Can draw connection going up. */	    y2 = tile_y[chanx_y] + tile_width;	    /* UDSD by AY Start */	    if(rr_node[chany_node].direction != BI_DIRECTION)		{		    if(edge_dir == FROM_Y_TO_X)			{			    if((chany_track % 2) == 1)				{	/* UDSD Modifications by WMF: If dec wire, then going down */				    y2 = tile_y[chanx_y + 1];				}			}		}	    /* UDSD by AY End */	}    else	{			/* Must draw connection going down. */	    y2 = tile_y[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 voiddraw_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 = tile_y[from_y] + tile_width + 1 + from_track;    y2 = tile_y[to_y] + tile_width + 1 + to_track;    if(to_xhigh < from_xlow)	{			/* From right to left */	    /* UDSD Note by WMF: could never happen for INC wires, unless U-turn. For DEC 	     * wires this handles well */	    x1 = tile_x[from_xlow];	    x2 = tile_x[to_xhigh] + tile_width;	}    else if(to_xlow > from_xhigh)	{			/* From left to right */	    /* UDSD Note by WMF: could never happen for DEC wires, unless U-turn. For INC 	     * wires this handles well */	    x1 = tile_x[from_xhigh] + tile_width;	    x2 = tile_x[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.        */    /* UDSD Modification by WMF Begin */    else	{	    if(rr_node[to_node].direction != BI_DIRECTION)		{		    /* must connect to to_node's wire beginning at x2 */		    if(to_track % 2 == 0)			{	/* INC wire starts at leftmost edge */			    assert(from_xlow < to_xlow);			    x2 = tile_x[to_xlow];			    /* since no U-turns from_track must be INC as well */			    x1 = tile_x[to_xlow - 1] + tile_width;			}		    else			{	/* DEC wire starts at rightmost edge */			    assert(from_xhigh > to_xhigh);			    x2 = tile_x[to_xhigh] + tile_width;			    x1 = tile_x[to_xhigh + 1];			}		}	    else		{		    if(to_xlow < from_xlow)			{	/* Draw from left edge of one to other */			    x1 = tile_x[from_xlow];			    x2 = tile_x[from_xlow - 1] + tile_width;			}		    else if(from_xlow < to_xlow)			{			    x1 = tile_x[to_xlow - 1] + tile_width;			    x2 = tile_x[to_xlow];			}	/* The following then is executed when from_xlow == to_xlow */		    else if(to_xhigh > from_xhigh)			{	/* Draw from right edge of one to other */			    x1 = tile_x[from_xhigh] + tile_width;			    x2 = tile_x[from_xhigh + 1];			}		    else if(from_xhigh > to_xhigh)			{			    x1 = tile_x[to_xhigh + 1];			    x2 = tile_x[to_xhigh] + tile_width;			}		    else			{	/* Complete overlap: start and end both align. Draw outside the sbox */			    x1 = tile_x[from_xlow];			    x2 = tile_x[from_xlow] + tile_width;			}		}	}    /* UDSD Modification by WMF End */    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 voiddraw_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 = tile_x[from_x] + tile_width + 1 + from_track;    x2 = tile_x[to_x] + tile_width + 1 + to_track;    if(to_yhigh < from_ylow)	{			/* From upper to lower */	    y1 = tile_y[from_ylow];	    y2 = tile_y[to_yhigh] + tile_width;	}    else if(to_ylow > from_yhigh)	{			/* From lower to upper */	    y1 = tile_y[from_yhigh] + tile_width;	    y2 = tile_y[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.        */    /* UDSD Modification by WMF Begin */    else	{	    if(rr_node[to_node].direction != BI_DIRECTION)		{		    if(to_track % 2 == 0)			{	/* INC wire starts at bottom edge */			    assert(from_ylow < to_ylow);			    y2 = tile_y[to_ylow];			    /* since no U-turns from_track must be INC as well */			    y1 = tile_y[to_ylow - 1] + tile_width;			}		    else			{	/* DEC wire starts at top edge */			    if(!(from_yhigh > to_yhigh))				{				    printf					("from_yhigh (%d) !> to_yhigh (%d).\n",					 from_yhigh, to_yhigh);				    printf					("from is (%d, %d) to (%d, %d) track %d.\n",					 rr_node[from_node].xhigh,					 rr_node[from_node].yhigh,					 rr_node[from_node].xlow,					 rr_node[from_node].ylow,					 rr_node[from_node].ptc_num);				    printf					("to is (%d, %d) to (%d, %d) track %d.\n",					 rr_node[to_node].xhigh,					 rr_node[to_node].yhigh,					 rr_node[to_node].xlow,					 rr_node[to_node].ylow,					 rr_node[to_node].ptc_num);				    exit(1);				}			    y2 = tile_y[to_yhigh] + tile_width;			    y1 = tile_y[to_yhigh + 1];			}		}	    else		{		    if(to_ylow < from_ylow)			{	/* Draw from bottom edge of one to other. */			    y1 = tile_y[from_ylow];			    y2 = tile_y[from_ylow - 1] + tile_width;			}		    else if(from_ylow < to_ylow)			{			    y1 = tile_y[to_ylow - 1] + tile_width;			    y2 = tile_y[to_ylow];			}		    else if(to_yhigh > from_yhigh)			{	/* Draw from top edge of one to other. */			    y1 = tile_y[from_yhigh] + tile_width;			    y2 = tile_y[from_yhigh + 1];			}		    else if(from_yhigh > to_yhigh)			{			    y1 = tile_y[to_yhigh + 1];			    y2 = tile_y[to_yhigh] + tile_width;			}		    else			{	/* Complete overlap: start and end both align. Draw outside the sbox */			    y1 = tile_y[from_ylow];			    y2 = tile_y[from_ylow] + tile_width;			}		}	}    /* UDSD Modification by WMF End */    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 voiddraw_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 voiddraw_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, ioff;    float xcen, ycen;    char str[BUFSIZE];    t_type_ptr type;    i = rr_node[inode].xlow;    j = rr_node[inode].ylow;    ipin = rr_node[inode].ptc_num;    type = grid[i][j].type;    ioff = grid[i][j].offset;    setcolor(color);    iclass = type->pin_class[ipin];    /* TODO: This is where we can hide fringe physical pins and also identify globals (hide, color, show) */    for(iside = 0; iside < 4; iside++)	{	    if(type->pinloc[grid[i][j].offset][iside][ipin])		{		/* Pin exists on this side. */		    get_rr_pin_draw_coords(inode, iside, ioff, &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);		}	}}static voidget_rr_pin_draw_coords(int inode,		       int iside,		       int ioff,		       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, k, ipin, pins_per_sub_tile;    float offset, xc, yc, step;    t_type_ptr type;    i = rr_node[inode].xlow;    j = rr_node[inode].ylow + ioff;	/* Need correct tile of block */    xc = tile_x[i];    yc = tile_y[j];    ipin = rr_node[inode].ptc_num;    type = grid[i][j].type;    pins_per_sub_tile = grid[i][j].type->num_pins / grid[i][j].type->capacity;    k = ipin / pins_per_sub_tile;    /* Since pins numbers go across all sub_tiles in a block in order     * we can treat as a block box for this step */    /* For each sub_tile we need and extra padding space */    step = (float)(tile_width) / (float)(type->num_pins + type->capacity);    offset = (ipin + k + 1) * step;    switch (iside)	{	case LEFT:	    yc += offset;	    break;	case RIGHT:	    xc += tile_width;	    yc += offset;	    break;	case BOTTOM:	    xc += offset;	    break;	case TOP:	    xc += offset;	    yc += tile_width;	    break;	default:	    printf("Error in get_rr_pin_draw_coords:  Unexpected iside %d.\n",		   iside);	    exit(1);	    break;	}    *xcen = xc;    *ycen = yc;}static voiddrawroute(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(net[inet].is_global)	/* 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]);

⌨️ 快捷键说明

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