start encapsulate the whole lb router in an object
This commit is contained in:
parent
ed25ccc70f
commit
d58d14df8e
File diff suppressed because it is too large
Load Diff
|
@ -1,16 +1,20 @@
|
|||
/********************************************************************
|
||||
* Intra-logic block router determines if a candidate packing solution (or intermediate solution) can route.
|
||||
* Adapted from original VPR cluster router to the use of LbRRGraph object
|
||||
*******************************************************************/
|
||||
#ifndef LB_ROUTER_H
|
||||
#define LB_ROUTER_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "vtr_vector.h"
|
||||
|
||||
#include "arch_types.h"
|
||||
#include "vpr_types.h"
|
||||
#include "atom_netlist_fwd.h"
|
||||
#include "pack_types.h"
|
||||
|
||||
#include "lb_rr_graph.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
|
@ -19,21 +23,160 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/* Constructors/Destructors */
|
||||
t_lb_router_data* alloc_and_load_router_data(std::vector<t_lb_type_rr_node>* lb_type_graph, t_logical_block_type_ptr type);
|
||||
void free_router_data(t_lb_router_data* router_data);
|
||||
void free_intra_lb_nets(std::vector<t_intra_lb_net>* intra_lb_nets);
|
||||
class LbRouter {
|
||||
public: /* Intra-Logic Block Routing Data Structures (by instance) */
|
||||
/**************************************************************************
|
||||
* A routing traceback data structure, provides a logic cluster_ctx.blocks
|
||||
* instance specific trace lookup directly from the t_lb_type_rr_node array index
|
||||
* After packing, routing info for each CLB will have an array of t_lb_traceback
|
||||
* to store routing info within the CLB
|
||||
***************************************************************************/
|
||||
struct t_traceback {
|
||||
int net; /* net of flat, technology-mapped, netlist using this node */
|
||||
LbRRNodeId prev_lb_rr_node; /* index of previous node that drives current node */
|
||||
LbRREdgeId prev_edge; /* index of previous edge that drives current node */
|
||||
};
|
||||
|
||||
/* Routing Functions */
|
||||
void add_atom_as_target(t_lb_router_data* router_data, const AtomBlockId blk_id);
|
||||
void remove_atom_from_target(t_lb_router_data* router_data, const AtomBlockId blk_id);
|
||||
void set_reset_pb_modes(t_lb_router_data* router_data, const t_pb* pb, const bool set);
|
||||
bool try_intra_lb_route(t_lb_router_data* router_data, int verbosity, t_mode_selection_status* mode_status);
|
||||
void reset_intra_lb_route(t_lb_router_data* router_data);
|
||||
/**************************************************************************
|
||||
* Describes the status of a logic cluster_ctx.blocks routing resource node
|
||||
* for a given logic cluster_ctx.blocks instance
|
||||
***************************************************************************/
|
||||
struct t_routing_stats {
|
||||
int occ; /* Number of nets currently using this lb_rr_node */
|
||||
t_mode* mode; /* Mode that this rr_node is set to */
|
||||
|
||||
int historical_usage; /* Historical usage of using this node */
|
||||
|
||||
t_lb_rr_graph_stats() {
|
||||
occ = 0;
|
||||
mode = nullptr;
|
||||
historical_usage = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/* Accessor Functions */
|
||||
t_pb_routes alloc_and_load_pb_route(const std::vector<t_intra_lb_net>* intra_lb_nets, t_pb_graph_node* pb_graph_head);
|
||||
void free_pb_route(t_pb_route* free_pb_route);
|
||||
/**************************************************************************
|
||||
* Data structure forming the route tree of a net within one logic cluster_ctx.blocks.
|
||||
* A net is implemented using routing resource nodes.
|
||||
* The t_lb_trace data structure records one of the nodes used by the net and the connections
|
||||
* to other nodes
|
||||
***************************************************************************/
|
||||
struct t_trace {
|
||||
LbRRNodeId current_node; /* current t_lb_type_rr_node used by net */
|
||||
std::vector<t_lb_trace> next_nodes; /* index of previous edge that drives current node */
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
* Represents a net used inside a logic cluster_ctx.blocks and the
|
||||
* physical nodes used by the net
|
||||
***************************************************************************/
|
||||
struct t_net {
|
||||
AtomNetId atom_net_id; /* index of atom net this intra_lb_net represents */
|
||||
std::vector<LbRRNodeId> terminals; /* endpoints of the intra_lb_net, 0th position is the source, all others are sinks */
|
||||
std::vector<AtomPinId> atom_pins; /* AtomPin's associated with each terminal */
|
||||
std::vector<bool> fixed_terminals; /* Marks a terminal as having a fixed target (i.e. a pin not a sink) */
|
||||
t_lb_trace* rt_tree; /* Route tree head */
|
||||
|
||||
t_lb_rr_net() {
|
||||
atom_net_id = AtomNetId::INVALID();
|
||||
rt_tree = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
* Stores tuning parameters used by intra-logic cluster_ctx.blocks router
|
||||
***************************************************************************/
|
||||
struct t_option {
|
||||
int max_iterations;
|
||||
float pres_fac;
|
||||
float pres_fac_mult;
|
||||
float hist_fac;
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
* Node expanded by router
|
||||
***************************************************************************/
|
||||
struct t_expansion_node {
|
||||
LbRRNodeId node_index; /* Index of logic cluster_ctx.blocks rr node this expansion node represents */
|
||||
LbRRNodeId prev_index; /* Index of logic cluster_ctx.blocks rr node that drives this expansion node */
|
||||
float cost;
|
||||
|
||||
t_expansion_node() {
|
||||
node_index = LbRRNodeId::INVALID();
|
||||
prev_index = LbRRNodeId::INVALID();
|
||||
cost = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class compare_expansion_node {
|
||||
public:
|
||||
/* Returns true if t1 is earlier than t2 */
|
||||
bool operator()(t_expansion_node& e1, t_expansion_node& e2) {
|
||||
if (e1.cost > e2.cost) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
* Stores explored nodes by router
|
||||
***************************************************************************/
|
||||
struct t_explored_node_stats {
|
||||
LbRRNodeId prev_index; /* Prevous node that drives this one */
|
||||
int explored_id; /* ID used to determine if this node has been explored */
|
||||
int inet; /* net index of route tree */
|
||||
int enqueue_id; /* ID used ot determine if this node has been pushed on exploration priority queue */
|
||||
float enqueue_cost; /* cost of node pused on exploration priority queue */
|
||||
|
||||
t_explored_node_stats() {
|
||||
prev_index = LbRRNodeId::INVALID();
|
||||
explored_id = OPEN;
|
||||
enqueue_id = OPEN;
|
||||
inet = OPEN;
|
||||
enqueue_cost = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
* Stores status of mode selection during clustering
|
||||
***************************************************************************/
|
||||
struct t_mode_selection_status {
|
||||
bool is_mode_conflict = false;
|
||||
bool try_expand_all_modes = false;
|
||||
bool expand_all_modes = false;
|
||||
|
||||
bool is_mode_issue() {
|
||||
return is_mode_conflict || try_expand_all_modes;
|
||||
}
|
||||
};
|
||||
|
||||
private : /* Stores all data needed by intra-logic cluster_ctx.blocks router */
|
||||
/* Logical Netlist Info */
|
||||
std::vector<t_net> intra_lb_nets_; /* Pointer to vector of intra logic cluster_ctx.blocks nets and their connections */
|
||||
|
||||
/* Saved nets */
|
||||
std::vector<t_net> saved_lb_nets_; /* Save vector of intra logic cluster_ctx.blocks nets and their connections */
|
||||
|
||||
std::map<AtomBlockId, bool> atoms_added_; /* map that records which atoms are added to cluster router */
|
||||
|
||||
/* Logical-to-physical mapping info */
|
||||
vtr::vector<LbRRNodeId, t_routing_stats> lb_rr_node_stats_; /* [0..lb_type_graph->size()-1] Stats for each logic cluster_ctx.blocks rr node instance */
|
||||
|
||||
/* Stores state info during Pathfinder iterative routing */
|
||||
vtr::vector<LbRRNodeId, t_explored_node_stats> explored_node_tb_; /* [0..lb_type_graph->size()-1] Stores mode exploration and traceback info for nodes */
|
||||
int explore_id_index_; /* used in conjunction with node_traceback to determine whether or not a location has been explored. By using a unique identifier every route, I don't have to clear the previous route exploration */
|
||||
|
||||
/* Current type */
|
||||
t_logical_block_type_ptr lb_type_;
|
||||
|
||||
/* Parameters used by router */
|
||||
t_option options_;
|
||||
|
||||
bool is_routed_; /* Stores whether or not the current logical-to-physical mapping has a routed solution */
|
||||
|
||||
/* current congestion factor */
|
||||
float pres_con_fac_;
|
||||
};
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
|
@ -9,6 +9,14 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/**************************************************
|
||||
* Public Constructors
|
||||
*************************************************/
|
||||
LbRRGraph::LbRRGraph() {
|
||||
ext_source_node_ = LbRRNodeId::INVALID();
|
||||
ext_sink_node_ = LbRRNodeId::INVALID();
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Public Accessors: Aggregates
|
||||
*************************************************/
|
||||
|
@ -43,6 +51,11 @@ float LbRRGraph::node_intrinsic_cost(const LbRRNodeId& node) const {
|
|||
return node_intrinsic_costs_[node];
|
||||
}
|
||||
|
||||
std::vector<LbRREdgeId> LbRRGraph::node_in_edges(const LbRRNodeId& node) const {
|
||||
VTR_ASSERT(true == valid_node_id(node));
|
||||
return node_in_edges_[node];
|
||||
}
|
||||
|
||||
std::vector<LbRREdgeId> LbRRGraph::node_in_edges(const LbRRNodeId& node, t_mode* mode) const {
|
||||
std::vector<LbRREdgeId> in_edges;
|
||||
|
||||
|
@ -81,6 +94,24 @@ LbRRNodeId LbRRGraph::find_node(const e_lb_rr_type& type, t_pb_graph_pin* pb_gra
|
|||
return node_lookup_[size_t(type)].at(pb_graph_pin);
|
||||
}
|
||||
|
||||
LbRRNodeId ext_source_node() const {
|
||||
return ext_source_node_;
|
||||
}
|
||||
|
||||
LbRRNodeId ext_sink_node() const {
|
||||
return ext_sink_node_;
|
||||
}
|
||||
|
||||
std::vector<LbRREdgeId> find_edge(const LbRRNodeId& src_node, const LbRRNodeId& sink_node) const {
|
||||
std::vector<LbRREdgeId> edges;
|
||||
for (const LbRREdgeId& edge : node_out_edges_[src_node]) {
|
||||
if (sink_node == edge_sink_node(edge)) {
|
||||
edges.push_back(edge);
|
||||
}
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
|
||||
LbRRNodeId LbRRGraph::edge_src_node(const LbRREdgeId& edge) const {
|
||||
VTR_ASSERT(true == valid_edge_id(edge));
|
||||
return edge_src_nodes_[edge];
|
||||
|
@ -141,6 +172,16 @@ LbRRNodeId LbRRGraph::create_node(const e_lb_rr_type& type) {
|
|||
return node;
|
||||
}
|
||||
|
||||
LbRRNodeId LbRRGraph::create_ext_source_node(const e_lb_rr_type& type) {
|
||||
LbRRNodeId ext_source_node = create_node(type);
|
||||
ext_source_node_ = ext_source_node;
|
||||
}
|
||||
|
||||
LbRRNodeId LbRRGraph::create_ext_sink_node(const e_lb_rr_type& type) {
|
||||
LbRRNodeId ext_sink_node = create_node(type);
|
||||
ext_sink_node_ = ext_sink_node;
|
||||
}
|
||||
|
||||
void LbRRGraph::set_node_type(const LbRRNodeId& node, const e_lb_rr_type& type) {
|
||||
VTR_ASSERT(true == valid_node_id(node));
|
||||
node_types_[node] = type;
|
||||
|
|
|
@ -168,6 +168,9 @@ class LbRRGraph {
|
|||
typedef vtr::Range<node_iterator> node_range;
|
||||
typedef vtr::Range<edge_iterator> edge_range;
|
||||
|
||||
public: /* Constructors */
|
||||
LbRRGraph();
|
||||
|
||||
public: /* Accessors */
|
||||
/* Aggregates: create range-based loops for nodes/edges/switches/segments
|
||||
* To iterate over the nodes/edges/switches/segments in a RRGraph,
|
||||
|
@ -195,13 +198,20 @@ class LbRRGraph {
|
|||
float node_intrinsic_cost(const LbRRNodeId& node) const;
|
||||
|
||||
/* Get a list of edge ids, which are incoming edges to a node */
|
||||
std::vector<LbRREdgeId> node_in_edges(const LbRRNodeId& node) const;
|
||||
std::vector<LbRREdgeId> node_in_edges(const LbRRNodeId& node, t_mode* mode) const;
|
||||
|
||||
/* Get a list of edge ids, which are outgoing edges from a node */
|
||||
std::vector<LbRREdgeId> node_out_edges(const LbRRNodeId& node, t_mode* mode) const;
|
||||
|
||||
/* General method to look up a node with type and only pb_graph_pin information */
|
||||
LbRRNodeId find_node(const e_lb_rr_type& type, t_pb_graph_pin* pb_graph_pin) const;
|
||||
/* Method to find special node */
|
||||
LbRRNodeId ext_source_node() const;
|
||||
LbRRNodeId ext_sink_node() const;
|
||||
|
||||
/* General method to look up a edge with source and sink nodes */
|
||||
std::vector<LbRREdgeId> find_edge(const LbRRNodeId& src_node, const LbRRNodeId& sink_node) const;
|
||||
/* Get the source node which drives a edge */
|
||||
LbRRNodeId edge_src_node(const LbRREdgeId& edge) const;
|
||||
/* Get the sink node which a edge ends to */
|
||||
|
@ -234,6 +244,10 @@ class LbRRGraph {
|
|||
* set_node_xlow(node, 0);
|
||||
*/
|
||||
LbRRNodeId create_node(const e_lb_rr_type& type);
|
||||
|
||||
/* Create special nodes */
|
||||
LbRRNodeId create_ext_source_node(const e_lb_rr_type& type);
|
||||
LbRRNodeId create_ext_sink_node(const e_lb_rr_type& type);
|
||||
|
||||
/* Set node-level information */
|
||||
void set_node_type(const LbRRNodeId& node, const e_lb_rr_type& type);
|
||||
|
@ -289,6 +303,10 @@ class LbRRGraph {
|
|||
*/
|
||||
typedef std::vector<std::map<t_pb_graph_pin*, LbRRNodeId>> NodeLookup;
|
||||
mutable NodeLookup node_lookup_;
|
||||
|
||||
/* Special node look-up */
|
||||
LbRRNodeId ext_source_node_;
|
||||
LbRRNodeId ext_sink_node_;
|
||||
};
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/***************************************************************************************
|
||||
* This file includes most utilized functions for LbRRGraph object
|
||||
***************************************************************************************/
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_assert.h"
|
||||
|
||||
#include "lb_rr_graph_utils.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/***************************************************************************************
|
||||
* Generate a string to describe a node in a logical tile rr_graph
|
||||
* in the context of logical tile
|
||||
***************************************************************************************/
|
||||
std::string describe_lb_rr_node(const LbRRGraph& lb_rr_graph,
|
||||
const LbRRNodeId& inode) {
|
||||
std::string description;
|
||||
|
||||
const t_pb_graph_pin* pb_graph_pin = lb_rr_graph.node_pb_graph_pin(inode);
|
||||
|
||||
if (pb_graph_pin) {
|
||||
description += "'" + pb_graph_pin->to_string(false) + "'";
|
||||
} else if (inode == lb_rr_graph.ext_source_node()) {
|
||||
VTR_ASSERT(LB_SOURCE == lb_rr_graph.node_type(inode));
|
||||
description = "cluster-external source (LB_SOURCE)";
|
||||
} else if (inode == lb_rr_graph.ext_sink_index()) {
|
||||
VTR_ASSERT(LB_SINK == lb_rr_graph.node_type(inode));
|
||||
description = "cluster-external sink (LB_SINK)";
|
||||
} else if (LB_SINK == lb_rr_graph.node_type(inode)) {
|
||||
description = "cluster-internal sink (LB_SINK accessible via architecture pins: ";
|
||||
|
||||
//To account for equivalent pins multiple pins may route to a single sink.
|
||||
//As a result we need to fin all the nodes which connect to this sink in order
|
||||
//to give user-friendly pin names
|
||||
std::vector<std::string> pin_descriptions;
|
||||
for (const LbRREdgeId edge : lb_rr_graph.node_in_edges(inode)) {
|
||||
const LbRRNodeId pin_rr_idx = lb_rr_graph.edge_src_node(edge);
|
||||
const t_pb_graph_pin* pin_pb_gpin = lb_rr_graph.node_pb_graph_pin(pin_rr_idx);
|
||||
pin_descriptions.push_back(pin_pb_gpin->to_string());
|
||||
}
|
||||
|
||||
description += vtr::join(pin_descriptions, ", ");
|
||||
description += ")";
|
||||
|
||||
} else if (LB_SOURCE == lb_rr_graph.node_type(inode)) {
|
||||
description = "cluster-internal source (LB_SOURCE)";
|
||||
} else if (LB_INTERMEDIATE == lb_rr_graph.node_type(inode)) {
|
||||
description = "cluster-internal intermediate?";
|
||||
} else {
|
||||
description = "<unknown lb_type_rr_node>";
|
||||
}
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef LB_RR_GRAPH_UTILS_H
|
||||
#define LB_RR_GRAPH_UTILS_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <string>
|
||||
#include "lb_rr_graph.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
std::string describe_lb_rr_node(const LbRRGraph& lb_rr_graph,
|
||||
const LbRRNodeId& inode);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue