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

📄 draw.c

📁 用于学术研究的FPGA布局布线软件VPR
💻 C
📖 第 1 页 / 共 4 页
字号:
		    num_sub_tiles = grid[i][j].type->capacity;		    sub_tile_step = tile_width / num_sub_tiles;		    height = grid[i][j].type->height;		    if(num_sub_tiles < 1)			{			    setcolor(BLACK);			    setlinestyle(DASHED);			    drawrect(tile_x[i], tile_y[j],				     tile_x[i] + tile_width,				     tile_y[j] + tile_width);			    draw_x(tile_x[i] + (tile_width / 2),				   tile_y[j] + (tile_width / 2),				   (tile_width / 2));			}		    for(k = 0; k < num_sub_tiles; ++k)			{			    /* Graphics will look unusual for multiple height and capacity */			    assert(height == 1 || num_sub_tiles == 1);			    /* Get coords of current sub_tile */			    if((i < 1) || (i > nx))				{	/* left and right fringes */				    x1 = tile_x[i];				    y1 = tile_y[j] + (k * sub_tile_step);				    x2 = x1 + tile_width;				    y2 = y1 + sub_tile_step;				}			    else if((j < 1) || (j > ny))				{	/* top and bottom fringes */				    x1 = tile_x[i] + (k * sub_tile_step);				    y1 = tile_y[j];				    x2 = x1 + sub_tile_step;				    y2 = y1 + tile_width;				}			    else				{				    assert(num_sub_tiles <= 1);	/* Need to change draw code to support */				    x1 = tile_x[i];				    y1 = tile_y[j];				    x2 = x1 + tile_width;				    y2 = tile_y[j + height - 1] + tile_width;				}			    /* Look at the tile at start of large block */			    bnum = grid[i][j].blocks[k];			    /* Draw background */			    if(bnum != EMPTY)				{				    setcolor(block_color[bnum]);				    fillrect(x1, y1, x2, y2);				}			    setcolor(BLACK);			    setlinestyle((EMPTY == bnum) ? DASHED : SOLID);			    drawrect(x1, y1, x2, y2);			    /* Draw text if the space has parts of the netlist */			    if(bnum != EMPTY)				{				    drawtext((x1 + x2) / 2.0, (y1 + y2) / 2.0,					     block[bnum].name, tile_width);				}				/* Draw text for block type so that user knows what block */				if(grid[i][j].offset == 0) {					if(i > 0 && i <= nx && j > 0 && j <= ny) {						drawtext((x1 + x2) / 2.0, y1 + (tile_width / 4.0),							grid[i][j].type->name, tile_width);					}				}			}		}	}}static voiddrawnets(void){    /* This routine draws the nets on the placement.  The nets have not *     * yet been routed, so we just draw a chain showing a possible path *     * for each net.  This gives some idea of future congestion.        */    int inet, ipin, b1, b2;    float x1, y1, x2, y2;    setlinestyle(SOLID);    setlinewidth(0);    /* Draw the net as a star from the source to each sink. Draw from centers of *     * blocks (or sub blocks in the case of IOs).                                */    for(inet = 0; inet < num_nets; inet++)	{	    if(net[inet].is_global)		continue;	/* Don't draw global nets. */	    setcolor(net_color[inet]);	    b1 = net[inet].node_block[0];	/* The DRIVER */	    get_block_center(b1, &x1, &y1);	    for(ipin = 1; ipin < (net[inet].num_sinks + 1); ipin++)		{		    b2 = net[inet].node_block[ipin];		    get_block_center(b2, &x2, &y2);		    drawline(x1, y1, x2, y2);		    /* Uncomment to draw a chain instead of a star. */		    /*      x1 = x2;  */		    /*      y1 = y2;  */		}	}}static voidget_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;    float sub_tile_step;    i = block[bnum].x;    j = block[bnum].y;    k = block[bnum].z;    sub_tile_step = tile_width / block[bnum].type->capacity;    if((i < 1) || (i > nx))	{			/* Left and right fringe */	    *x = tile_x[i] + (sub_tile_step * (k + 0.5));	}    else	{	    *x = tile_x[i] + (tile_width / 2.0);	}    if((j < 1) || (j > ny))	{			/* Top and bottom fringe */	    *y = tile_y[j] + (sub_tile_step * (k + 0.5));	}    else	{	    *y = tile_y[j] + (tile_width / 2.0);	}}static voiddraw_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;			}		}	}}voiddraw_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 voiddraw_rr_chanx(int inode,	      int itrack){    /* Draws an x-directed channel segment.                       */    enum    { BUFFSIZE = 80 };    float x1, x2, y;    float y1, y2;		/* UDSD by AY */    int k;			/* UDSD by AY */    char str[BUFFSIZE];    /* Track 0 at bottom edge, closest to "owning" clb. */    x1 = tile_x[rr_node[inode].xlow];    x2 = tile_y[rr_node[inode].xhigh] + tile_width;    y = tile_y[rr_node[inode].ylow] + tile_width + 1.0 + itrack;    drawline(x1, y, x2, y);    /* UDSD by AY Start */    y1 = y - 0.25;    y2 = y + 0.25;    if(rr_node[inode].direction == INC_DIRECTION)	{	    setlinewidth(2);	    setcolor(YELLOW);	    drawline(x1, y1, x1, y2);	/* Draw a line at start of wire to indicate mux */	    /* Mux balence numbers */	    setcolor(BLACK);	    sprintf(str, "%d", rr_node[inode].fan_in);	    drawtext(x1, y, str, 5);	    setcolor(BLACK);	    setlinewidth(0);	    draw_triangle_along_line(x2 - 0.15, y, x1, x2, y, y);	    setcolor(LIGHTGREY);	    /* TODO: this looks odd, why does it ignore final block? does this mean nothing appears with L=1 ? */	    for(k = rr_node[inode].xlow; k < rr_node[inode].xhigh; k++)		{		    x2 = tile_x[k] + tile_width;		    draw_triangle_along_line(x2 - 0.15, y, x1, x2, y, y);		    x2 = tile_x[k + 1];		    draw_triangle_along_line(x2 + 0.15, y, x1, x2, y, y);		}	    setcolor(BLACK);	}    else if(rr_node[inode].direction == DEC_DIRECTION)	{	    setlinewidth(2);	    setcolor(YELLOW);	    drawline(x2, y1, x2, y2);	    /* Mux balance numbers */	    setcolor(BLACK);	    sprintf(str, "%d", rr_node[inode].fan_in);	    drawtext(x2, y, str, 5);	    setlinewidth(0);	    draw_triangle_along_line(x1 + 0.15, y, x2, x1, y, y);	    setcolor(LIGHTGREY);	    for(k = rr_node[inode].xhigh; k > rr_node[inode].xlow; k--)		{		    x1 = tile_x[k];		    draw_triangle_along_line(x1 + 0.15, y, x2, x1, y, y);		    x1 = tile_x[k - 1] + tile_width;		    draw_triangle_along_line(x1 - 0.15, y, x2, x1, y, y);		}	    setcolor(BLACK);	}    /* UDSD by AY End */}static voiddraw_rr_chany(int inode,	      int itrack){    /* Draws a y-directed channel segment.                       */    enum    { BUFFSIZE = 80 };    float x, y1, y2;    float x1, x2;		/* UDSD by AY */    int k;			/* UDSD by AY */    char str[BUFFSIZE];    /* Track 0 at left edge, closest to "owning" clb. */    x = tile_x[rr_node[inode].xlow] + tile_width + 1. + itrack;    y1 = tile_y[rr_node[inode].ylow];    y2 = tile_y[rr_node[inode].yhigh] + tile_width;    drawline(x, y1, x, y2);    /* UDSD by AY Start */    x1 = x - 0.25;    x2 = x + 0.25;    if(rr_node[inode].direction == INC_DIRECTION)	{	    setlinewidth(2);	    setcolor(YELLOW);	    drawline(x1, y1, x2, y1);	    /* UDSD Modifications by WMF Begin */	    setcolor(BLACK);	    sprintf(str, "%d", rr_node[inode].fan_in);	    drawtext(x, y1, str, 5);	    setcolor(BLACK);	    /* UDSD Modifications by WMF End */	    setlinewidth(0);	    draw_triangle_along_line(x, y2 - 0.15, x, x, y1, y2);	    setcolor(LIGHTGREY);	    for(k = rr_node[inode].ylow; k < rr_node[inode].yhigh; k++)		{		    y2 = tile_y[k] + tile_width;		    draw_triangle_along_line(x, y2 - 0.15, x, x, y1, y2);		    y2 = tile_y[k + 1];		    draw_triangle_along_line(x, y2 + 0.15, x, x, y1, y2);		}	    setcolor(BLACK);	}    else if(rr_node[inode].direction == DEC_DIRECTION)	{	    setlinewidth(2);	    setcolor(YELLOW);	    drawline(x1, y2, x2, y2);	    /* UDSD Modifications by WMF Begin */	    setcolor(BLACK);	    sprintf(str, "%d", rr_node[inode].fan_in);	    drawtext(x, y2, str, 5);	    setcolor(BLACK);	    /* UDSD Modifications by WMF End */	    setlinewidth(0);	    draw_triangle_along_line(x, y1 + 0.15, x, x, y2, y1);	    setcolor(LIGHTGREY);	    for(k = rr_node[inode].yhigh; k > rr_node[inode].ylow; k--)		{		    y1 = tile_y[k];		    draw_triangle_along_line(x, y1 + 0.15, x, x, y2, y1);		    y1 = tile_y[k - 1] + tile_width;		    draw_triangle_along_line(x, y1 - 0.15, x, x, y2, y1);		}	    setcolor(BLACK);	}    /* UDSD by AY End */}static voiddraw_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);			    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);			    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);			    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);

⌨️ 快捷键说明

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