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