/**
 * 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
		);
	}

}
Esempio n. 2
0
File: m2.cpp Progetto: saad34/mapper
//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);

		}
	}
}