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

📄 draw.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <stdio.h> #include <string.h>#include <math.h>#include "util.h"#include "vpr_types.h"#include "globals.h"#include "graphics.h"#include "path_delay.h"#include "draw.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};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.                                                               */static enum e_draw_rr_toggle draw_rr_toggle = DRAW_NO_RR;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 *x_clb_left, *y_clb_bottom;/* The left and bottom coordinates of each clb in the FPGA.               * * x_clb_left[0..nx+1] and y_clb_bottom[0..ny+1].                         * * COORDINATE SYSTEM goes from (0,0) at the lower left corner to          * * (x_clb_left[nx+1]+clb_width, y_clb_bottom[ny+1]+clb_width) in the      * * upper right corner.                                                    */static float clb_width, pin_size;/* Drawn width (and height) of a clb, and the half-width or half-height of * * a clb 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, float *xcen,             float *ycen); static void draw_pin_to_chan_edge (int pin_node, int chan_node, int itrack,            boolean mark_conn); 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); /********************** Subroutine definitions ******************************/void set_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;}void update_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");    } }/* Save the main message. */ 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 void drawscreen (void) {/* 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 void redraw_screen (void) {/* 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".                                      */ 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 void toggle_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 void toggle_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_NODES_RR + 1); show_nets = FALSE; show_congestion = FALSE; update_message (default_message); drawscreen_ptr ();}static void toggle_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 void highlight_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 ();}void alloc_draw_structs (void) {/* Allocate the structures needed to draw the placement and routing.  Set * * up the default colors for blocks and nets.                             */ x_clb_left = (float *) my_malloc ((nx+2)*sizeof(float)); y_clb_bottom = (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 */}void init_draw_coords (float clb_width_val) {/* Load the arrays containing the left and bottom coordinates of the clbs   * * forming the FPGA.  clb_width_val sets the width and height of a drawn    * * clb.                                                                     */ int i; if (!show_graphics) return;   /* -nodisp was selected. */ clb_width = clb_width_val; pin_size = clb_width / (4. * pins_per_clb); pin_size = min (pin_size, clb_width / (4. * io_rat)); pin_size = min (pin_size, 0.3);  x_clb_left[0] = 0.; for (i=1;i<=nx+1;i++)    x_clb_left[i] = x_clb_left[i-1] + clb_width + chan_width_y[i-1] + 1.; y_clb_bottom[0] = 0.; for (i=1;i<=ny+1;i++)    y_clb_bottom[i] = y_clb_bottom[i-1] + clb_width +         chan_width_x[i-1] + 1.; init_world (0., y_clb_bottom[ny+1] + clb_width,    x_clb_left[nx+1]+ clb_width, 0.);}static void drawplace (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 io_step = clb_width/io_rat; float x1, y1, x2, y2; int i, j, k, bnum; /* Draw the IO Pads first. Want each subblock to border on core. */ setlinewidth (0); for (i=1;i<=nx;i++) {     for (j=0;j<=ny+1;j+=ny+1) {  /* top and bottom */       y1 = y_clb_bottom[j];       y2 = y1 + clb_width;       setlinestyle (SOLID);       for (k=0;k<clb[i][j].occ;k++) {          bnum = clb[i][j].u.io_blocks[k];          setcolor (block_color[bnum]);          x1 = x_clb_left[i] + k * io_step;          x2 = x1 + io_step;          fillrect (x1,y1,x2,y2);          setcolor (BLACK);          drawrect (x1,y1,x2,y2);/* Vertically offset text so these closely spaced names don't overlap. */          drawtext ((x1 + x2)/2., y1 + io_step * (k + 0.5),              block[clb[i][j].u.io_blocks[k]].name, clb_width);       }       setlinestyle (DASHED);       setcolor (BLACK);       for (k=clb[i][j].occ;k<io_rat;k++) {          x1 = x_clb_left[i] + k * io_step;          x2 = x1 + io_step;          drawrect (x1,y1,x2,y2);       }    } }         for (j=1;j<=ny;j++) {    for (i=0;i<=nx+1;i+=nx+1) {  /* IOs on left and right */       x1 = x_clb_left[i];       x2 = x1 + clb_width;       setlinestyle (SOLID);       for (k=0;k<clb[i][j].occ;k++) {          bnum = clb[i][j].u.io_blocks[k];          setcolor (block_color[bnum]);          y1 = y_clb_bottom[j] + k * io_step;          y2 = y1 + io_step;          fillrect (x1,y1,x2,y2);           setcolor (BLACK);          drawrect (x1,y1,x2,y2);          drawtext ((x1 + x2)/2., (y1 + y2)/2.,             block[clb[i][j].u.io_blocks[k]].name, clb_width);       }                 setlinestyle (DASHED);       setcolor (BLACK);       for (k=clb[i][j].occ;k<io_rat;k++) {          y1 = y_clb_bottom[j] + k * io_step;          y2 = y1 + io_step;          drawrect (x1,y1,x2,y2);       }    }      }     /* Now do the CLBs in the middle. */ for (i=1;i<=nx;i++) {    x1 = x_clb_left[i];    x2 = x1 + clb_width;    for (j=1;j<=ny;j++) {       y1 = y_clb_bottom[j];       y2 = y1 + clb_width;       if (clb[i][j].occ != 0) {          setlinestyle (SOLID);          bnum = clb[i][j].u.block;          setcolor (block_color[bnum]);          fillrect (x1,y1,x2,y2);          setcolor (BLACK);          drawrect (x1,y1,x2,y2);          drawtext ((x1 + x2)/2., (y1 + y2)/2., block[clb[i][j].u.block].name,              clb_width);       }       else {          setlinestyle (DASHED);          setcolor (BLACK);          drawrect (x1,y1,x2,y2);       }    }    /* end j */ }    /* end i */}static void drawnets (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 (is_global[inet])               /* Don't draw global nets. */       continue;    setcolor (net_color[inet]);    b1 = net[inet].blocks[0];    get_block_center (b1, &x1, &y1);           for (ipin=1;ipin<net[inet].num_pins;ipin++) {       b2 = net[inet].blocks[ipin];       get_block_center (b2, &x2, &y2);

⌨️ 快捷键说明

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