📄 draw.c
字号:
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 + -