/** * Draws ONE logical connection from src_pin in src_lblk to sink_pin in sink_lblk. * The *_abs_bbox parameters are for mild optmization, as the absolute bbox can be calculated * more effeciently elsewhere. */ void draw_one_logical_connection( const t_net_pin& src_pin, const t_logical_block& src_lblk, const t_bound_box& src_abs_bbox, const t_net_pin& sink_pin, const t_logical_block& sink_lblk, const t_bound_box& sink_abs_bbox) { const float FRACTION_USABLE_WIDTH = 0.3; float src_width = src_abs_bbox.get_width(); float sink_width = sink_abs_bbox.get_width(); float src_usable_width = src_width * FRACTION_USABLE_WIDTH; float sink_usable_width = sink_width * FRACTION_USABLE_WIDTH; float src_x_offset = src_abs_bbox.left() + src_width * (1 - FRACTION_USABLE_WIDTH)/2; float sink_x_offset = sink_abs_bbox.left() + sink_width * (1 - FRACTION_USABLE_WIDTH)/2; int src_pin_index, sink_pin_index, src_pin_total, sink_pin_total; find_pin_index_at_model_scope(src_pin, src_lblk, false, &src_pin_index, &src_pin_total ); find_pin_index_at_model_scope(sink_pin, sink_lblk, true, &sink_pin_index, &sink_pin_total); const t_point src_point = { src_x_offset + src_usable_width * src_pin_index / ((float)src_pin_total), src_abs_bbox.get_ycenter() }; const t_point sink_point = { sink_x_offset + sink_usable_width * sink_pin_index / ((float)sink_pin_total), sink_abs_bbox.get_ycenter() }; // draw a link connecting the pins. drawline(src_point.x, src_point.y, sink_point.x, sink_point.y); if (src_lblk.clb_index == sink_lblk.clb_index) { // if they are in the same clb, put one arrow in the center float center_x = (src_point.x + sink_point.x) / 2; float center_y = (src_point.y + sink_point.y) / 2; draw_triangle_along_line( center_x, center_y, src_point.x, sink_point.x, src_point.y, sink_point.y ); } else { // if they are not, put 2 near each end draw_triangle_along_line( 3, src_point.x, sink_point.x, src_point.y, sink_point.y ); draw_triangle_along_line( -3, src_point.x, sink_point.x, src_point.y, sink_point.y ); } }
//see if other regions need to be checked to find a closer intersection bool checkDistanceToBoundaries (double& distance, t_bound_box region, t_point coords, t_point& location, unsigned& intersectionID) { bool surroundingRegionEmpty = true; //for regions on the: left side, right side, top, and bottom double rightDistance = abs(coords.x - region.right()); double leftDistance = abs(coords.x - region.left()); double topDistance = abs(coords.y - region.top()); double bottomDistance = abs(coords.y - region.bottom()); //for regions at corners (e.g. up + left, down + right) double topRightDistance = sqrt(pow(abs(coords.x - region.right()), 2) + pow(abs(coords.y - region.top()), 2)); double topLeftDistance = sqrt(pow(abs(coords.x - region.left()), 2) + pow(abs(coords.y - region.top()), 2)); double bottomRightDistance = sqrt(pow(abs(coords.x - region.right()), 2) + pow(abs(coords.y - region.bottom()), 2)); double bottomLeftDistance = sqrt(pow(abs(coords.x - region.left()), 2) + pow(abs(coords.y - region.bottom()), 2)); LatLon NE = MapData::getNE(); t_point NEPoint = latLonToCoordinates(NE); /*we always need to make sure we are not along an edge of a side we are trying to check, otherwise results will be incorrect*/ //first check the 4 adjacent regions if((rightDistance < distance) && (region.right() < NEPoint.x)) { //we want the region to the right (i.e. region + 1) vector<unsigned> newRegion = MapData::getNewIntersectionRegion(region, 1); if(newRegion != MapData::getREGIONVector(region)) { for (auto iter = newRegion.begin(); iter != newRegion.end(); iter++) { LatLon position = getIntersectionPosition(*iter); t_point comparisonPoint = latLonToCoordinates(position); double comparisonDistance = sqrt(pow(abs(coords.x - comparisonPoint.x), 2) + pow(abs(coords.y - comparisonPoint.y), 2)); if (comparisonDistance < distance) { surroundingRegionEmpty = false; distance = comparisonDistance; location = comparisonPoint; intersectionID = *iter; } } } } if((leftDistance < distance) && (region.left() > 0)) { //we want the region to the left (i.e. region - 1) vector<unsigned> newRegion = MapData::getNewIntersectionRegion(region, -1); if(newRegion != MapData::getREGIONVector(region)) { for (auto iter = newRegion.begin(); iter != newRegion.end(); iter++) { LatLon position = getIntersectionPosition(*iter); t_point comparisonPoint = latLonToCoordinates(position); double comparisonDistance = sqrt(pow(abs(coords.x - comparisonPoint.x), 2) + pow(abs(coords.y - comparisonPoint.y), 2)); if (comparisonDistance < distance) { surroundingRegionEmpty = false; distance = comparisonDistance; location = comparisonPoint; intersectionID = *iter; } } } } if((topDistance < distance) && (region.top() < NEPoint.y)) { //we want the region above (i.e. region - 5) (rows of 5 regions) vector<unsigned> newRegion = MapData::getNewIntersectionRegion(region, -5); if(newRegion != MapData::getREGIONVector(region)) { for (auto iter = newRegion.begin(); iter != newRegion.end(); iter++) { LatLon position = getIntersectionPosition(*iter); t_point comparisonPoint = latLonToCoordinates(position); double comparisonDistance = sqrt(pow(abs(coords.x - comparisonPoint.x), 2) + pow(abs(coords.y - comparisonPoint.y), 2)); if (comparisonDistance < distance) { surroundingRegionEmpty = false; distance = comparisonDistance; location = comparisonPoint; intersectionID = *iter; } } } } if(bottomDistance < distance && (region.bottom() > 0)) { //we want the region below (i.e. region + 5) (rows of 5 regions) vector<unsigned> newRegion = MapData::getNewIntersectionRegion(region, 5); if(newRegion != MapData::getREGIONVector(region)) { for (auto iter = newRegion.begin(); iter != newRegion.end(); iter++) { LatLon position = getIntersectionPosition(*iter); t_point comparisonPoint = latLonToCoordinates(position); double comparisonDistance = sqrt(pow(abs(coords.x - comparisonPoint.x), 2) + pow(abs(coords.y - comparisonPoint.y), 2)); if (comparisonDistance < distance) { surroundingRegionEmpty = false; distance = comparisonDistance; location = comparisonPoint; intersectionID = *iter; } } } } //now check the 4 corner regions if((topRightDistance < distance) && (region.right() < NEPoint.x) && (region.top() < NEPoint.y)) { //we want the region to the top right (i.e. region - 4) vector<unsigned> newRegion = MapData::getNewIntersectionRegion(region, -4); if(newRegion != MapData::getREGIONVector(region)) { for (auto iter = newRegion.begin(); iter != newRegion.end(); iter++) { LatLon position = getIntersectionPosition(*iter); t_point comparisonPoint = latLonToCoordinates(position); double comparisonDistance = sqrt(pow(abs(coords.x - comparisonPoint.x), 2) + pow(abs(coords.y - comparisonPoint.y), 2)); if (comparisonDistance < distance) { surroundingRegionEmpty = false; distance = comparisonDistance; location = comparisonPoint; intersectionID = *iter; } } } } if((topLeftDistance < distance) && (region.left() > 0) && (region.top() < NEPoint.y)) { //we want the region to the top left (i.e. region - 6) vector<unsigned> newRegion = MapData::getNewIntersectionRegion(region, -6); if(newRegion != MapData::getREGIONVector(region)) { for (auto iter = newRegion.begin(); iter != newRegion.end(); iter++) { LatLon position = getIntersectionPosition(*iter); t_point comparisonPoint = latLonToCoordinates(position); double comparisonDistance = sqrt(pow(abs(coords.x - comparisonPoint.x), 2) + pow(abs(coords.y - comparisonPoint.y), 2)); if (comparisonDistance < distance) { surroundingRegionEmpty = false; distance = comparisonDistance; location = comparisonPoint; intersectionID = *iter; } } } } if((bottomRightDistance < distance) && (region.right() < NEPoint.x) && (region.bottom() > 0)) { //we want the region to the bottom right (i.e. region + 6) vector<unsigned> newRegion = MapData::getNewIntersectionRegion(region, 6); if(newRegion != MapData::getREGIONVector(region)) { for (auto iter = newRegion.begin(); iter != newRegion.end(); iter++) { LatLon position = getIntersectionPosition(*iter); t_point comparisonPoint = latLonToCoordinates(position); double comparisonDistance = sqrt(pow(abs(coords.x - comparisonPoint.x), 2) + pow(abs(coords.y - comparisonPoint.y), 2)); if (comparisonDistance < distance) { surroundingRegionEmpty = false; distance = comparisonDistance; location = comparisonPoint; intersectionID = *iter; } } } } if((bottomLeftDistance < distance) && (region.left() > 0) && (region.bottom() > 0)) { //we want the region to the bottom left (i.e. region + 4) vector<unsigned> newRegion = MapData::getNewIntersectionRegion(region, 4); if(newRegion != MapData::getREGIONVector(region)) { for (auto iter = newRegion.begin(); iter != newRegion.end(); iter++) { LatLon position = getIntersectionPosition(*iter); t_point comparisonPoint = latLonToCoordinates(position); double comparisonDistance = sqrt(pow(abs(coords.x - comparisonPoint.x), 2) + pow(abs(coords.y - comparisonPoint.y), 2)); if (comparisonDistance < distance) { surroundingRegionEmpty = false; distance = comparisonDistance; location = comparisonPoint; intersectionID = *iter; } } } } return surroundingRegionEmpty; }
/* Helper subroutine to draw all sub-blocks. This function traverses through the pb_graph * which a netlist block can map to, and draws each sub-block inside its parent block. With * each click on the "Blk Internal" button, a new level is shown. */ static void draw_internal_pb(const t_block* const clb, t_pb* pb, const t_bound_box& parent_bbox) { t_draw_coords* draw_coords = get_draw_coords_vars(); t_draw_state* draw_state = get_draw_state_vars(); t_selected_sub_block_info& sel_sub_info = get_selected_sub_block_info(); t_pb_type* pb_type = pb->pb_graph_node->pb_type; t_bound_box abs_bbox = draw_coords->get_pb_bbox(*clb, *pb->pb_graph_node) + parent_bbox.bottom_left(); // if we've gone too far, don't draw anything if (pb_type->depth > draw_state->show_blk_internal) { return; } /// first draw box /// if (pb_type->depth == 0) { if (!is_top_lvl_block_highlighted(*clb)) { // if this is a top level pb, and only if it isn't selected (ie. a funny colour), // overwrite it. (but stil draw the text) setcolor(WHITE); fillrect(abs_bbox); setcolor(BLACK); setlinestyle(SOLID); drawrect(abs_bbox); } } else { if (pb->name != NULL) { // If block is used, draw it in colour with solid border. setlinestyle(SOLID); // type_index indicates what type of block. const int type_index = clb->type->index; // determine default background color if (sel_sub_info.is_selected(pb->pb_graph_node, clb)) { setcolor(SELECTED_COLOR); } else if (sel_sub_info.is_head_of_critical_path(pb->pb_graph_node, clb)) { setcolor(crit_path_colors::blk::HEAD); } else if (sel_sub_info.is_driver_of_head_of_critical_path(pb->pb_graph_node, clb)) { setcolor(crit_path_colors::blk::HEAD_DRIVER); } else if (sel_sub_info.is_on_critical_path(pb->pb_graph_node, clb)) { setcolor(crit_path_colors::blk::TAIL); } else if (sel_sub_info.is_sink_of_selected(pb->pb_graph_node, clb)) { setcolor(DRIVES_IT_COLOR); } else if (sel_sub_info.is_source_of_selected(pb->pb_graph_node, clb)) { setcolor(DRIVEN_BY_IT_COLOR); } else if (pb_type->depth != draw_state->show_blk_internal && pb->child_pbs != NULL) { setcolor(WHITE); // draw anthing else that will have a child as white } else if (type_index < 3) { setcolor(LIGHTGREY); } else if (type_index < 3 + MAX_BLOCK_COLOURS) { setcolor(BISQUE + MAX_BLOCK_COLOURS + type_index - 3); } else { setcolor(BISQUE + 2 * MAX_BLOCK_COLOURS - 1); } } else { // If block is not used, draw as empty block (ie. white // background with dashed border). setlinestyle(DASHED); setcolor(WHITE); } fillrect(abs_bbox); setcolor(BLACK); drawrect(abs_bbox); } /// then draw text /// if (pb->name != NULL) { setfontsize(16); // note: calc_text_xbound(...) assumes this is 16 if (pb_type->depth == draw_state->show_blk_internal || pb->child_pbs == NULL) { // If this pb is at the lowest displayed level, or has no more children, then // label it in the center with its type and name int type_len = strlen(pb_type->name); int name_len = strlen(pb->name); int tot_len = type_len + name_len; char* blk_tag = (char *)my_malloc((tot_len + 8) * sizeof(char)); sprintf (blk_tag, "%s(%s)", pb_type->name, pb->name); drawtext( t_point(abs_bbox.get_xcenter(), abs_bbox.get_ycenter()), blk_tag, abs_bbox ); free(blk_tag); } else { // else (ie. has chilren, and isn't at the lowest displayed level) // just label its type, and put it up at the top so we can see it drawtext( t_point( abs_bbox.get_xcenter(), abs_bbox.top() - (abs_bbox.get_height()) / 15.0 ), pb_type->name, abs_bbox ); } } else { // If child block is not used, label it only by its type drawtext( t_point(abs_bbox.get_xcenter(), abs_bbox.get_ycenter()), pb_type->name, abs_bbox ); } /// now recurse on the child pbs. /// // return if no children, or this is an unusused pb, // or if going down will be too far down (this one is redundant, but for optimazition) if(pb->child_pbs == NULL || pb->name == NULL || pb_type->depth == draw_state->show_blk_internal) { return; } int num_child_types = pb->get_num_child_types(); for (int i = 0; i < num_child_types; ++i) { if (pb->child_pbs[i] == NULL) { continue; } int num_pb = pb->get_num_children_of_type(i); for (int j = 0; j < num_pb; ++j) { t_pb* child_pb = &pb->child_pbs[i][j]; // don't go farther if null if (child_pb == NULL) { continue; } t_pb_type* pb_child_type = child_pb->pb_graph_node->pb_type; // don't go farther if 0 modes if (pb_child_type == NULL && pb_child_type->num_modes == 0) { continue; } // now recurse draw_internal_pb(clb, child_pb, abs_bbox); } } }