blob: a3a6c10cc1a292a9f5402931c7b756a68ec4e819 [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
#include "vpr_types.h"
#include "draw_types.h"
#include "netlist.h"
#include "route_tree_timing.h"
#include <unordered_set>
struct t_selected_sub_block_info {
struct clb_pin_tuple {
int clb_index;
//const t_pb_graph_pin* pb_gpin;
const t_pb_graph_node* pb_gnode;
// clb_pin_tuple(int clb_index, const t_pb_graph_pin* pb_gpin);
clb_pin_tuple(int clb_index, const t_pb_graph_node* pb_gnode);
clb_pin_tuple(const t_net_pin& atom_pin, bool is_input_pin, bool is_in_global_net);
bool operator==(const clb_pin_tuple&) const;
};
struct gnode_clb_pair {
const t_pb_graph_node* pb_gnode;
const t_block* clb;
gnode_clb_pair(const t_pb_graph_node* pb_gnode, const t_block* clb);
gnode_clb_pair();
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);
}
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(v.clb_index)
// ^ ptr_hasher((const void*)v.pb_gpin);
^ ptr_hasher((const void*)v.pb_gnode);
}
};
private:
t_pb* selected_pb;
t_block* containing_block;
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< std::pair<clb_pin_tuple, clb_pin_tuple>, sel_subblk_hasher> nets_on_critical_path;
std::unordered_set< gnode_clb_pair, sel_subblk_hasher > in_selected_subtree;
std::unordered_set< gnode_clb_pair, sel_subblk_hasher > blocks_on_critical_path;
gnode_clb_pair head_of_critical_path;
// clb_pin_tuple head_of_critical_path;
gnode_clb_pair driver_of_head_of_critical_path;
// clb_pin_tuple driver_of_head_of_critical_path;
public:
t_selected_sub_block_info();
void set(t_pb* new_selected_sub_block, t_block* containing_block);
void add_to_critical_path(const t_tnode& src_tnode, const t_tnode& sink_tnode);
t_pb_graph_node* get_selected_pb_gnode() const;
t_block* 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();
void clear_critical_path();
// pb related selection test functions
bool is_selected(const t_pb_graph_node* test, const t_block* test_block) const;
bool is_sink_of_selected(const t_pb_graph_node* test, const t_block* test_block) const;
bool is_source_of_selected(const t_pb_graph_node* test, const t_block* test_block) const;
bool is_in_selected_subtree(const t_pb_graph_node* test, const t_block* test_block) const;
bool is_on_critical_path(const t_pb_graph_node* test, const t_block* test_block) const;
bool is_head_of_critical_path(const t_pb_graph_node* test, const t_block* test_block) const;
bool is_driver_of_head_of_critical_path(const t_pb_graph_node* test, const t_block* test_block) const;
// net related selection test functions
bool is_head_net_of_critical_path(const t_net_pin& test_src, const t_net_pin& test_sink) const;
bool is_on_critical_path(const t_net_pin& test_src, const t_net_pin& test_sink) 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.
*/
void toggle_blk_internal(void (*drawscreen_ptr)(void));
/* 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.
*/
void draw_internal_draw_subblk();
/* 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 t_point& point_in_clb, t_block& clb);
/*
* 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();
#endif /* INTRA_LOGIC_BLOCK_H */