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

📄 draw.c

📁 用于学术研究的FPGA布局布线软件VPR
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <stdio.h>#include <string.h>#include <math.h>#include "util.h"#include "vpr_types.h"#include "vpr_utils.h"#include "globals.h"#include "graphics.h"#include "path_delay.h"#include "draw.h"#include <assert.h>/*************** Types local to this module *********************************/enum e_draw_rr_toggle{    DRAW_NO_RR = 0,    DRAW_ALL_RR,    DRAW_ALL_BUT_BUFFERS_RR,    DRAW_NODES_AND_SBOX_RR,    DRAW_NODES_RR,    DRAW_RR_TOGGLE_MAX};enum e_draw_net_type{ ALL_NETS, HIGHLIGHTED };enum e_edge_dir{ FROM_X_TO_Y, FROM_Y_TO_X };	/* Chanx to chany or vice versa? *//****************** Variables local to this module. *************************/static boolean show_nets = FALSE;	/* Show nets of placement or routing? *//* Controls drawing of routing resources on screen, if pic_on_screen is   * * ROUTING.                                                               *//* Can toggle to DRAW_NO_RR;*/static enum e_draw_rr_toggle draw_rr_toggle = DRAW_NO_RR;	/* UDSD by AY */static enum e_route_type draw_route_type;/* Controls if congestion is shown, when ROUTING is on screen. */static boolean show_congestion = FALSE;static boolean show_graphics;	/* Graphics enabled or not? */static char default_message[BUFSIZE];	/* Default screen message on screen */static int gr_automode;		/* Need user input after: 0: each t,   *				 * 1: each place, 2: never             */static enum pic_type pic_on_screen = NO_PICTURE;	/* What do I draw? */static float *tile_x, *tile_y;/* The left and bottom coordinates of each grid_tile in the FPGA.         * * tile_x[0..nx+1] and tile_y[0..ny+1].                         * * COORDINATE SYSTEM goes from (0,0) at the lower left corner to          * * (tile_x[nx+1]+tile_width, tile_y[ny+1]+tile_width) in the      * * upper right corner.                                                    */static float tile_width, pin_size;/* Drawn width (and height) of a grid_tile, and the half-width or half-height of * * a pin, respectiviely.  Set when init_draw_coords is called.         */static enum color_types *net_color, *block_color;/* Color in which each block and net should be drawn.      * * [0..num_nets-1] and [0..num_blocks-1], respectively.    *//********************** Subroutines local to this module ********************/static void toggle_nets(void (*drawscreen) (void));static void toggle_rr(void (*drawscreen) (void));static void toggle_congestion(void (*drawscreen) (void));static void highlight_crit_path(void (*drawscreen_ptr) (void));static void drawscreen(void);static void redraw_screen(void);static void drawplace(void);static void drawnets(void);static void drawroute(enum e_draw_net_type draw_net_type);static void draw_congestion(void);static void highlight_blocks(float x,			     float y);static void get_block_center(int bnum,			     float *x,			     float *y);static void deselect_all(void);static void draw_rr(void);static void draw_rr_edges(int from_node);static void draw_rr_pin(int inode,			enum color_types color);static void draw_rr_chanx(int inode,			  int itrack);static void draw_rr_chany(int inode,			  int itrack);static void get_rr_pin_draw_coords(int inode,				   int iside,				   int ioff,				   float *xcen,				   float *ycen);static void draw_pin_to_chan_edge(int pin_node,				  int chan_node);static void draw_x(float x,		   float y,		   float size);static void draw_chany_to_chany_edge(int from_node,				     int from_track,				     int to_node,				     int to_track,				     short switch_type);static void draw_chanx_to_chanx_edge(int from_node,				     int from_track,				     int to_node,				     int to_track,				     short switch_type);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);static int get_track_num(int inode,			 int **chanx_track,			 int **chany_track);static void draw_rr_switch(float from_x,			   float from_y,			   float to_x,			   float to_y,			   boolean buffered);static void draw_triangle_along_line(float xend,				     float yend,	/* UDSD by AY */				     float x1,				     float x2,	/* UDSD by AY */				     float y1,				     float y2);	/* UDSD by AY *//********************** Subroutine definitions ******************************/voidset_graphics_state(boolean show_graphics_val,		   int gr_automode_val,		   enum e_route_type route_type){    /* Sets the static show_graphics and gr_automode variables to the    *     * desired values.  They control if graphics are enabled and, if so, *     * how often the user is prompted for input.                         */    show_graphics = show_graphics_val;    gr_automode = gr_automode_val;    draw_route_type = route_type;}voidupdate_screen(int priority,	      char *msg,	      enum pic_type pic_on_screen_val,	      boolean crit_path_button_enabled){    /* Updates the screen if the user has requested graphics.  The priority  *     * value controls whether or not the Proceed button must be clicked to   *     * continue.  Saves the pic_on_screen_val to allow pan and zoom redraws. */    if(!show_graphics)		/* Graphics turned off */	return;    /* If it's the type of picture displayed has changed, set up the proper  *     * buttons.                                                              */    if(pic_on_screen != pic_on_screen_val)	{	    if(pic_on_screen_val == PLACEMENT && pic_on_screen == NO_PICTURE)		{		    create_button("Window", "Toggle Nets", toggle_nets);		}	    else if(pic_on_screen_val == ROUTING		    && pic_on_screen == PLACEMENT)		{		    create_button("Toggle Nets", "Toggle RR", toggle_rr);		    create_button("Toggle RR", "Congestion",				  toggle_congestion);		    if(crit_path_button_enabled)			{			    create_button("Congestion", "Crit. Path",					  highlight_crit_path);			}		}	    else if(pic_on_screen_val == PLACEMENT		    && pic_on_screen == ROUTING)		{		    destroy_button("Toggle RR");		    destroy_button("Congestion");		    if(crit_path_button_enabled)			{			    destroy_button("Crit. Path");			}		}	    else if(pic_on_screen_val == ROUTING		    && pic_on_screen == NO_PICTURE)		{		    create_button("Window", "Toggle Nets", toggle_nets);		    create_button("Toggle Nets", "Toggle RR", toggle_rr);		    create_button("Toggle RR", "Congestion",				  toggle_congestion);		    if(crit_path_button_enabled)			{			    create_button("Congestion", "Crit. Path",					  highlight_crit_path);			}		}	}    /* Save the main message. */    my_strncpy(default_message, msg, BUFSIZE);    pic_on_screen = pic_on_screen_val;    update_message(msg);    drawscreen();    if(priority >= gr_automode)	{	    event_loop(highlight_blocks, drawscreen);	}    else	{	    flushinput();	}}static voiddrawscreen(){    /* This is the screen redrawing routine that event_loop assumes exists.  *     * It erases whatever is on screen, then calls redraw_screen to redraw   *     * it.                                                                   */    clearscreen();    redraw_screen();}static voidredraw_screen(){    /* The screen redrawing routine called by drawscreen and           *     * highlight_blocks.  Call this routine instead of drawscreen if   *     * you know you don't need to erase the current graphics, and want *     * to avoid a screen "flash".                                      */    setfontsize(20);		/* UDSD Modification by WMF */    if(pic_on_screen == PLACEMENT)	{	    drawplace();	    if(show_nets)		{		    drawnets();		}	}    else	{			/* ROUTING on screen */	    drawplace();	    if(show_nets)		{		    drawroute(ALL_NETS);		}	    else		{		    draw_rr();		}	    if(show_congestion)		{		    draw_congestion();		}	}}static voidtoggle_nets(void (*drawscreen_ptr) (void)){    /* Enables/disables drawing of nets when a the user clicks on a button.    *     * Also disables drawing of routing resources.  See graphics.c for details *     * of how buttons work.                                                    */    show_nets = !show_nets;    draw_rr_toggle = DRAW_NO_RR;    show_congestion = FALSE;    update_message(default_message);    drawscreen_ptr();}static voidtoggle_rr(void (*drawscreen_ptr) (void)){    /* Cycles through the options for viewing the routing resources available   *     * in an FPGA.  If a routing isn't on screen, the routing graph hasn't been *     * built, and this routine doesn't switch the view. Otherwise, this routine *     * switches to the routing resource view.  Clicking on the toggle cycles    *     * through the options:  DRAW_NO_RR, DRAW_ALL_RR, DRAW_ALL_BUT_BUFFERS_RR,  *     * DRAW_NODES_AND_SBOX_RR, and DRAW_NODES_RR.                               */    draw_rr_toggle = (draw_rr_toggle + 1) % (DRAW_RR_TOGGLE_MAX);    show_nets = FALSE;    show_congestion = FALSE;    update_message(default_message);    drawscreen_ptr();}static voidtoggle_congestion(void (*drawscreen_ptr) (void)){    /* Turns the congestion display on and off.   */    char msg[BUFSIZE];    int inode, num_congested;    show_nets = FALSE;    draw_rr_toggle = DRAW_NO_RR;    show_congestion = !show_congestion;    if(!show_congestion)	{	    update_message(default_message);	}    else	{	    num_congested = 0;	    for(inode = 0; inode < num_rr_nodes; inode++)		{		    if(rr_node[inode].occ > rr_node[inode].capacity)			{			    num_congested++;			}		}	    sprintf(msg, "%d routing resources are overused.", num_congested);	    update_message(msg);	}    drawscreen_ptr();}static voidhighlight_crit_path(void (*drawscreen_ptr) (void)){    /* Highlights all the blocks and nets on the critical path. */    t_linked_int *critical_path_head, *critical_path_node;    int inode, iblk, inet, num_nets_seen;    static int nets_to_highlight = 1;    char msg[BUFSIZE];    if(nets_to_highlight == 0)	{			/* Clear the display of all highlighting. */	    nets_to_highlight = 1;	    deselect_all();	    update_message(default_message);	    drawscreen_ptr();	    return;	}    critical_path_head = allocate_and_load_critical_path();    critical_path_node = critical_path_head;    num_nets_seen = 0;    while(critical_path_node != NULL)	{	    inode = critical_path_node->data;	    get_tnode_block_and_output_net(inode, &iblk, &inet);	    if(num_nets_seen == nets_to_highlight)		{		/* Last block */		    block_color[iblk] = MAGENTA;		}	    else if(num_nets_seen == nets_to_highlight - 1)		{		/* 2nd last block */		    block_color[iblk] = YELLOW;		}	    else if(num_nets_seen < nets_to_highlight)		{		/* Earlier block */		    block_color[iblk] = DARKGREEN;		}	    if(inet != OPEN)		{		    num_nets_seen++;		    if(num_nets_seen < nets_to_highlight)			{	/* First nets. */			    net_color[inet] = DARKGREEN;			}		    else if(num_nets_seen == nets_to_highlight)			{			    net_color[inet] = CYAN;	/* Last (new) net. */			}		}	    critical_path_node = critical_path_node->next;	}    if(nets_to_highlight == num_nets_seen)	{	    nets_to_highlight = 0;	    sprintf(msg, "All %d nets on the critical path highlighted.",		    num_nets_seen);	}    else	{	    sprintf(msg, "First %d nets on the critical path highlighted.",		    nets_to_highlight);	    nets_to_highlight++;	}    free_int_list(&critical_path_head);    update_message(msg);    drawscreen_ptr();}voidalloc_draw_structs(void){    /* Allocate the structures needed to draw the placement and routing.  Set *     * up the default colors for blocks and nets.                             */    tile_x = (float *)my_malloc((nx + 2) * sizeof(float));    tile_y = (float *)my_malloc((ny + 2) * sizeof(float));    net_color = (enum color_types *)	my_malloc(num_nets * sizeof(enum color_types));    block_color = (enum color_types *)	my_malloc(num_blocks * sizeof(enum color_types));    deselect_all();		/* Set initial colors */}voidinit_draw_coords(float width_val){    /* Load the arrays containing the left and bottom coordinates of the clbs   *     * forming the FPGA.  tile_width_val sets the width and height of a drawn    *     * clb.                                                                     */    int i;    int j;    if(!show_graphics)	return;			/* -nodisp was selected. */    tile_width = width_val;    pin_size = 0.3;    for(i = 0; i < num_types; ++i)	{	    pin_size =		min(pin_size,		    (tile_width / (4.0 * type_descriptors[i].num_pins)));	}    j = 0;    for(i = 0; i < (nx + 1); i++)	{	    tile_x[i] = (i * tile_width) + j;	    j += chan_width_y[i] + 1;	/* N wires need N+1 units of space */	}    tile_x[nx + 1] = ((nx + 1) * tile_width) + j;    j = 0;    for(i = 0; i < (ny + 1); ++i)	{	    tile_y[i] = (i * tile_width) + j;	    j += chan_width_x[i] + 1;	}    tile_y[ny + 1] = ((ny + 1) * tile_width) + j;    init_world(0.0,	       tile_y[ny + 1] + tile_width, tile_x[nx + 1] + tile_width, 0.0);}static voiddrawplace(void){    /* Draws the blocks placed on the proper clbs.  Occupied clbs are light *     * grey, while empty ones are left white and have a dashed border.      */    float sub_tile_step;    float x1, y1, x2, y2;    int i, j, k, bnum;    int num_sub_tiles;    int height;    setlinewidth(0);    for(i = 0; i <= (nx + 1); i++)	{	    for(j = 0; j <= (ny + 1); j++)		{		    /* Only the first block of a group should control drawing */		    if(grid[i][j].offset > 0)			continue;		    /* Don't draw corners */		    if(((i < 1) || (i > nx)) && ((j < 1) || (j > ny)))			continue;

⌨️ 快捷键说明

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