blob: 0cc07886da7f9f0787aef5b5267fdb7506cea288 [file] [log] [blame]
/* Author: Long Yu Wang
* Date: August 2013
*
* Author: Matthew J.P. Walker
* Date: May,June 2014
*/
#ifndef INTRA_LOGIC_BLOCK_H
#define INTRA_LOGIC_BLOCK_H
#ifndef NO_GRAPHICS
# include "vpr_types.h"
# include "draw_types.h"
# include "atom_netlist_fwd.h"
# include "route_tree_timing.h"
# include <unordered_set>
# include "ezgl/point.hpp"
# ifndef NO_GRAPHICS
# include "ezgl/graphics.hpp"
# include "ezgl/application.hpp"
# endif /* NO_GRAPHICS */
struct t_selected_sub_block_info {
struct clb_pin_tuple {
ClusterBlockId clb_index;
const t_pb_graph_node* pb_gnode;
clb_pin_tuple(ClusterBlockId clb_index, const t_pb_graph_node* pb_gnode);
clb_pin_tuple(const AtomPinId atom_pin);
bool operator==(const clb_pin_tuple&) const;
};
struct gnode_clb_pair {
const t_pb_graph_node* pb_gnode = nullptr;
const ClusterBlockId clb_index;
gnode_clb_pair() = default;
gnode_clb_pair(const t_pb_graph_node* pb_gnode, const ClusterBlockId clb_index);
bool operator==(const gnode_clb_pair&) const;
};
struct sel_subblk_hasher {
inline std::size_t operator()(const gnode_clb_pair& v) const {
std::hash<const void*> ptr_hasher;
return ptr_hasher((const void*)v.pb_gnode) ^ ptr_hasher((const void*)&v.clb_index);
}
inline std::size_t operator()(const std::pair<clb_pin_tuple, clb_pin_tuple>& v) const {
return (*this)(v.first) ^ (*this)(v.second);
}
inline std::size_t operator()(const clb_pin_tuple& v) const {
std::hash<int> int_hasher;
std::hash<const void*> ptr_hasher;
return int_hasher(size_t(v.clb_index))
^ ptr_hasher((const void*)v.pb_gnode);
}
};
private:
t_pb* selected_pb;
ClusterBlockId containing_block_index;
t_pb_graph_node* selected_pb_gnode;
std::unordered_set<gnode_clb_pair, sel_subblk_hasher> sinks;
std::unordered_set<gnode_clb_pair, sel_subblk_hasher> sources;
std::unordered_set<gnode_clb_pair, sel_subblk_hasher> in_selected_subtree;
public:
t_selected_sub_block_info();
void set(t_pb* new_selected_sub_block, const ClusterBlockId containing_block_index);
t_pb_graph_node* get_selected_pb_gnode() const;
ClusterBlockId get_containing_block() const;
/*
* gets the t_pb that is currently selected. Please don't use this if
* you think you can get away with using is_selected(...) or get_selected_pb_gnode() and
* get_containing_block(). May disappear in future.
*/
t_pb* get_selected_pb() const;
bool has_selection() const;
void clear();
// pb related selection test functions
bool is_selected(const t_pb_graph_node* test, const ClusterBlockId clb_index) const;
bool is_sink_of_selected(const t_pb_graph_node* test, const ClusterBlockId clb_index) const;
bool is_source_of_selected(const t_pb_graph_node* test, const ClusterBlockId clb_index) const;
bool is_in_selected_subtree(const t_pb_graph_node* test, const ClusterBlockId clb_index) const;
};
/* Enable/disable clb internals drawing. Internals drawing is enabled with a click of the
* "Blk Internal" button. With each consecutive click of the button, a lower level in the
* pb_graph will be shown for every clb. When the number of clicks on the button exceeds
* the maximum level of sub-blocks that exists in the pb_graph, internals drawing
* will be disabled.
*/
# ifndef NO_GRAPHICS
void toggle_blk_internal(GtkWidget* /*widget*/, gint /*response_id*/, gpointer data);
# endif /* NO_GRAPHICS */
/* This function pre-allocates space to store bounding boxes for all sub-blocks. Each
* sub-block is identified by its descriptor_type and a unique pin ID in the type.
*/
void draw_internal_alloc_blk();
/* This function initializes bounding box values for all sub-blocks. It calls helper functions
* to traverse through the pb_graph for each descriptor_type and compute bounding box values.
*/
void draw_internal_init_blk();
/* Top-level drawing routine for internal sub-blocks. The function traverses through all
* grid tiles and calls helper function to draw inside each block.
*/
# ifndef NO_GRAPHICS
void draw_internal_draw_subblk(ezgl::renderer* g);
# endif /* NO_GRAPHICS */
/* Determines which part of a block to highlight, and stores it,
* so that the other subblock drawing functions will obey it.
* If the user missed all sub-parts, will return 1, else 0.
*/
int highlight_sub_block(const ezgl::point2d& point_in_clb, const ClusterBlockId clb_index, t_pb* pb);
/*
* returns the struct with information about the sub-block selection
*/
t_selected_sub_block_info& get_selected_sub_block_info();
/*
* Draws lines from the proper logical sources, to the proper logical sinks.
* If the draw state says to show all logical connections, it will,
* and if there is a selected sub-block, it will highlight it's conections
*/
void draw_logical_connections(ezgl::renderer* g);
void find_pin_index_at_model_scope(const AtomPinId the_pin, const AtomBlockId lblk, int* pin_index, int* total_pins);
#endif /* NO_GRAPHICS */
#endif /* INTRA_LOGIC_BLOCK_H */