start encapsulate the whole lb router in an object

This commit is contained in:
tangxifan 2020-02-18 16:50:56 -07:00
parent ed25ccc70f
commit d58d14df8e
6 changed files with 301 additions and 1516 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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