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

📄 draw.c

📁 用于学术研究的FPGA布局布线软件VPR
💻 C
📖 第 1 页 / 共 4 页
字号:
	    tptr = trace_head[inet];	/* SOURCE to start */	    inode = tptr->index;	    rr_type = rr_node[inode].type;	    for(;;)		{		    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);			    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);				    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);				    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 intget_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 voidhighlight_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 iclass;    float io_step;    t_type_ptr type;    char msg[BUFSIZE];    deselect_all();    hit = 0;    for(i = 0; i <= (nx + 1); i++)	{	    if(x <= tile_x[i] + tile_width)		{		    if(x >= tile_x[i])			hit = 1;		    break;		}	}    if(!hit)	{	    update_message(default_message);	    drawscreen();	    return;	}    hit = 0;    for(j = 0; j <= (ny + 1); j++)	{	    if(y <= tile_y[j] + tile_width)		{		    if(y >= tile_y[j])			hit = 1;		    break;		}	}    if(!hit)	{	    update_message(default_message);	    drawscreen();	    return;	}    type = grid[i][j].type;    if(EMPTY_TYPE == type)	{	    update_message(default_message);	    drawscreen();	    return;	}    /* The user selected the clb at location (i,j). */    io_step = tile_width / type->capacity;    if((i < 1) || (i > nx))	/* Vertical columns of IOs */	k = (int)((y - tile_y[j]) / io_step);    else	k = (int)((x - tile_x[i]) / io_step);    assert(k < type->capacity);    if(grid[i][j].blocks[k] == EMPTY)	{	    update_message(default_message);	    drawscreen();	    return;	}    bnum = grid[i][j].blocks[k];    /* Highlight fanin and fanout. */    for(k = 0; k < type->num_pins; k++)	{			/* Each pin on a FB */	    netnum = block[bnum].nets[k];	    if(netnum == OPEN)		continue;	    iclass = type->pin_class[k];	    if(type->class_inf[iclass].type == DRIVER)		{		/* Fanout */		    net_color[netnum] = RED;		    for(ipin = 1; ipin <= net[netnum].num_sinks; ipin++)			{			    fanblk = net[netnum].node_block[ipin];			    block_color[fanblk] = RED;			}		}	    else		{		/* This net is fanin to the block. */		    net_color[netnum] = BLUE;		    fanblk = net[netnum].node_block[0];	/* DRIVER to net */		    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 voiddeselect_all(void){    /* Sets the color of all clbs and nets to the default.  */    int i;    /* TODO: make blocks diff colors */    for(i = 0; i < num_blocks; i++)	block_color[i] = LIGHTGREY;    for(i = 0; i < num_nets; i++)	net_color[i] = BLACK;}/* UDSD by AY Start */static voiddraw_triangle_along_line(float xend,			 float yend,			 float x1,			 float x2,			 float y1,			 float y2){    float switch_rad = 0.15;    float xdelta, ydelta;    float magnitude;    float xunit, yunit;    float xbaseline, ybaseline;    t_point poly[3];    xdelta = x2 - x1;    ydelta = y2 - y1;    magnitude = sqrt(xdelta * xdelta + ydelta * ydelta);    xunit = xdelta / magnitude;    yunit = ydelta / magnitude;    poly[0].x = xend + xunit * switch_rad;    poly[0].y = yend + yunit * switch_rad;    xbaseline = xend - xunit * switch_rad;    ybaseline = yend - yunit * switch_rad;    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_pin_to_chan_edge(int pin_node,		      int chan_node){/* This routine draws an edge from the pin_node to the chan_node (CHANX or   * * CHANY).  The connection is made to the nearest end of the track instead   * * of perpundicular to the track to symbolize a single-drive connection.     * * If mark_conn is TRUE, draw a box where the pin connects to the track      * * (useful for drawing  the rr graph)                                        *//* TODO: Fix this for global routing, currently for detailed only */    t_rr_type chan_type;    int grid_x, grid_y, pin_num, chan_xlow, chan_ylow, ioff, height;    float x1, x2, y1, y2;    int start, end, i;    int itrack;    float xend, yend;    float draw_pin_off;    enum e_direction direction;    enum e_side iside;    t_type_ptr type;    direction = rr_node[chan_node].direction;    grid_x = rr_node[pin_node].xlow;    grid_y = rr_node[pin_node].ylow;    pin_num = rr_node[pin_node].ptc_num;    chan_type = rr_node[chan_node].type;    itrack = rr_node[chan_node].ptc_num;    type = grid[grid_x][grid_y].type;    ioff = grid[grid_x][grid_y].offset;    /* large block begins at primary tile (offset == 0) */    grid_y = grid_y - ioff;    height = grid[grid_x][grid_y].type->height;    chan_ylow = rr_node[chan_node].ylow;    chan_xlow = rr_node[chan_node].xlow;    start = -1;    end = -1;    switch (chan_type)	{	case CHANX:	    start = rr_node[chan_node].xlow;	    end = rr_node[chan_node].xhigh;	    if(is_opin(pin_num, type))		{		    if(direction == INC_DIRECTION)			{			    end = rr_node[chan_node].xlow;			}		    else if(direction == DEC_DIRECTION)			{			    start = rr_node[chan_node].xhigh;			}		}	    start = max(start, grid_x);	    end = min(end, grid_x);	/* Width is 1 always */	    assert(end >= start);	/* Make sure we are nearby */	    if((grid_y + height - 1) == chan_ylow)		{		    iside = TOP;		    ioff = height - 1;		    draw_pin_off = pin_size;		}	    else		{		    assert((grid_y - 1) == chan_ylow);		    iside = BOTTOM;		    ioff = 0;		    draw_pin_off = -pin_size;		}	    assert(grid[grid_x][grid_y].type->pinloc[ioff][iside][pin_num]);	    get_rr_pin_draw_coords(pin_node, iside, ioff, &x1, &y1);	    y1 += draw_pin_off;	    y2 = tile_y[rr_node[chan_node].ylow] + tile_width + 1. + itrack;	    x2 = x1;	    if(is_opin(pin_num, type))		{		    if(direction == INC_DIRECTION)			{			    x2 = tile_x[rr_node[chan_node].xlow];			}		    else if(direction == DEC_DIRECTION)			{			    x2 = tile_x[rr_node[chan_node].xhigh] +				tile_width;			}		}	    break;	case CHANY:	    start = rr_node[chan_node].ylow;	    end = rr_node[chan_node].yhigh;	    if(is_opin(pin_num, type))		{		    if(direction == INC_DIRECTION)			{			    end = rr_node[chan_node].ylow;			}		    else if(direction == DEC_DIRECTION)			{			    start = rr_node[chan_node].yhigh;			}		}	    start = max(start, grid_y);	    end = min(end, (grid_y + height - 1));	/* Width is 1 always */	    assert(end >= start);	/* Make sure we are nearby */	    if((grid_x) == chan_xlow)		{		    iside = RIGHT;		    draw_pin_off = pin_size;		}	    else		{		    assert((grid_x - 1) == chan_xlow);		    iside = LEFT;		    draw_pin_off = -pin_size;		}	    for(i = start; i <= end; i++)		{		    ioff = i - grid_y;		    assert(ioff >= 0 && ioff < type->height);		    /* Once we find the location, break out, this will leave ioff pointing		     * to the correct offset.  If an offset is not found, the assertion after		     * this will fail.  With the correct routing graph, the assertion will not		     * be triggered.  This also takes care of connecting a wire once to multiple		     * physical pins on the same side. */		    if(grid[grid_x][grid_y].type->		       pinloc[ioff][iside][pin_num])			{			    break;			}		}	    assert(grid[grid_x][grid_y].type->pinloc[ioff][iside][pin_num]);	    get_rr_pin_draw_coords(pin_node, iside, ioff, &x1, &y1);	    x1 += draw_pin_off;	    x2 = tile_x[chan_xlow] + tile_width + 1 + itrack;	    y2 = y1;	    if(is_opin(pin_num, type))		{		    if(direction == INC_DIRECTION)			{			    y2 = tile_y[rr_node[chan_node].ylow];			}		    else if(direction == DEC_DIRECTION)			{			    y2 = tile_y[rr_node[chan_node].yhigh] +				tile_width;			}		}	    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(direction == BI_DIRECTION || !is_opin(pin_num, type))	{	    draw_x(x2, y2, 0.7 * pin_size);	}    else	{	    xend = x2 + (x1 - x2) / 10.;	    yend = y2 + (y1 - y2) / 10.;	    draw_triangle_along_line(xend, yend, x1, x2, y1, y2);	}}/* UDSD by AY End */

⌨️ 快捷键说明

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