critical bug fixed for find proper pb_route traceback
This commit is contained in:
parent
81e5af464e
commit
808853db0b
|
@ -244,17 +244,6 @@ bool LbRouter::try_route_net(const LbRRGraph& lb_rr_graph,
|
||||||
/* Route each sink of net */
|
/* Route each sink of net */
|
||||||
for (size_t isink = 0; isink < lb_net_sinks_[net_idx].size(); ++isink) {
|
for (size_t isink = 0; isink < lb_net_sinks_[net_idx].size(); ++isink) {
|
||||||
|
|
||||||
/* Do not route the sink if it share the same pb_type as source
|
|
||||||
* This is actually forbidden! This will definitely create a combinational loop
|
|
||||||
*/
|
|
||||||
if ( (nullptr != lb_rr_graph.node_pb_graph_pin(lb_net_sinks_[net_idx][isink]))
|
|
||||||
&& (nullptr != lb_rr_graph.node_pb_graph_pin(lb_net_sources_[net_idx][isrc])) ) {
|
|
||||||
if (lb_rr_graph.node_pb_graph_pin(lb_net_sinks_[net_idx][isink])->parent_node
|
|
||||||
== lb_rr_graph.node_pb_graph_pin(lb_net_sources_[net_idx][isrc])->parent_node) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip routed nets */
|
/* Skip routed nets */
|
||||||
if (true == sink_routed[isink]) {
|
if (true == sink_routed[isink]) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -585,11 +574,6 @@ void LbRouter::commit_remove_rt(const LbRRGraph& lb_rr_graph,
|
||||||
explored_node_tb_[inode].inet = NetId::INVALID();
|
explored_node_tb_[inode].inet = NetId::INVALID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == RT_COMMIT) {
|
|
||||||
VTR_LOGV(lb_rr_graph.node_pb_graph_pin(inode),
|
|
||||||
"Commit node '%s' to routing tree\n",
|
|
||||||
lb_rr_graph.node_pb_graph_pin(inode)->to_string().c_str());
|
|
||||||
}
|
|
||||||
routing_status_[inode].occ += incr;
|
routing_status_[inode].occ += incr;
|
||||||
VTR_ASSERT(routing_status_[inode].occ >= 0);
|
VTR_ASSERT(routing_status_[inode].occ >= 0);
|
||||||
|
|
||||||
|
|
|
@ -21,15 +21,100 @@
|
||||||
namespace openfpga {
|
namespace openfpga {
|
||||||
|
|
||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
* Try find the pin id which is mapped to a given atom net id in the context of pb route
|
* Try find all the sink pins which is mapped to a routing trace in the context of pb route
|
||||||
|
* This function uses a recursive walk-through over the pb_route
|
||||||
|
* We will always start from the pb_route of the source pin
|
||||||
|
* For each sink,
|
||||||
|
* - if it is the end point of a routing tree, we add it to the sink list
|
||||||
|
* - An output of top-level pb_graph_node
|
||||||
|
* - An input of a primitive pb_graph_node
|
||||||
|
* - if it is not the end point of a routing tree, we visit the pb_route
|
||||||
|
* corresponds to the sink pin
|
||||||
|
*
|
||||||
|
* Note: when you call this function at the top-level, please provide an empty vector
|
||||||
|
* of sink_pb_pins!!!
|
||||||
|
***************************************************************************************/
|
||||||
|
static
|
||||||
|
void rec_find_routed_sink_pb_graph_pins(const t_pb* pb,
|
||||||
|
const t_pb_graph_pin* source_pb_pin,
|
||||||
|
const AtomNetId& atom_net_id,
|
||||||
|
t_pb_graph_pin** pb_graph_pin_lookup_from_index,
|
||||||
|
std::vector<t_pb_graph_pin*>& sink_pb_pins) {
|
||||||
|
|
||||||
|
/* Bypass unused pins */
|
||||||
|
if (0 == pb->pb_route.count(source_pb_pin->pin_count_in_cluster)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the driver pb pin id, it must be valid */
|
||||||
|
if (atom_net_id != pb->pb_route[source_pb_pin->pin_count_in_cluster].atom_net_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check each sink nodes, if pin belongs to an input of a primitive pb_graph_node, it is what we want */
|
||||||
|
std::vector<t_pb_graph_pin*> sink_pb_pins_to_search;
|
||||||
|
for (const int& sink_pb_pin_id : pb->pb_route[source_pb_pin->pin_count_in_cluster].sink_pb_pin_ids) {
|
||||||
|
t_pb_graph_pin* sink_pb_pin = pb_graph_pin_lookup_from_index[sink_pb_pin_id];
|
||||||
|
VTR_ASSERT(nullptr != sink_pb_pin);
|
||||||
|
|
||||||
|
/* We will update sink node list only
|
||||||
|
* - input pins of primitive nodes
|
||||||
|
* - output pins of top node
|
||||||
|
*/
|
||||||
|
if ( (true == is_primitive_pb_type(sink_pb_pin->parent_node->pb_type))
|
||||||
|
&& (IN_PORT == sink_pb_pin->port->type)) {
|
||||||
|
sink_pb_pins.push_back(sink_pb_pin);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (true == sink_pb_pin->parent_node->is_root())
|
||||||
|
&& (OUT_PORT == sink_pb_pin->port->type)) {
|
||||||
|
sink_pb_pins.push_back(sink_pb_pin);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We should find the pb_route recursively */
|
||||||
|
sink_pb_pins_to_search.push_back(sink_pb_pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (t_pb_graph_pin* sink_pb_pin : sink_pb_pins_to_search) {
|
||||||
|
rec_find_routed_sink_pb_graph_pins(pb, sink_pb_pin, atom_net_id, pb_graph_pin_lookup_from_index, sink_pb_pins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
* A wrapper for the recursive function rec_find_route_sink_pb_graph_pins(),
|
||||||
|
* we ensure that we provide a clear sink node lists
|
||||||
***************************************************************************************/
|
***************************************************************************************/
|
||||||
static
|
static
|
||||||
std::vector<t_pb_graph_pin*> find_routed_pb_graph_pins_atom_net(const t_pb* pb,
|
std::vector<t_pb_graph_pin*> find_routed_pb_graph_pins_atom_net(const t_pb* pb,
|
||||||
|
const t_pb_graph_pin* source_pb_pin,
|
||||||
const AtomNetId& atom_net_id,
|
const AtomNetId& atom_net_id,
|
||||||
t_pb_graph_pin** pb_graph_pin_lookup_from_index) {
|
t_pb_graph_pin** pb_graph_pin_lookup_from_index) {
|
||||||
std::vector<t_pb_graph_pin*> sink_pb_pins;
|
std::vector<t_pb_graph_pin*> sink_pb_pins;
|
||||||
|
|
||||||
/* Find the sink nodes from top-level node */
|
rec_find_routed_sink_pb_graph_pins(pb, source_pb_pin, atom_net_id, pb_graph_pin_lookup_from_index, sink_pb_pins);
|
||||||
|
|
||||||
|
return sink_pb_pins;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
* This function will find the actual source_pb_pin that is mapped by packed in the pb route
|
||||||
|
* As the inputs of clustered block may be renamed during routing,
|
||||||
|
* our pb_route results may lose consistency.
|
||||||
|
* It is possible that the source pb_pin may not be mapped during packing but
|
||||||
|
* be mapped during routing
|
||||||
|
*
|
||||||
|
* Note: this is ONLY applicable to the pb_pin of top-level pb_graph_node
|
||||||
|
***************************************************************************************/
|
||||||
|
static
|
||||||
|
int find_pb_route_remapped_source_pb_pin(const t_pb* pb,
|
||||||
|
const t_pb_graph_pin* source_pb_pin,
|
||||||
|
const AtomNetId& atom_net_id) {
|
||||||
|
VTR_ASSERT(true == source_pb_pin->parent_node->is_root());
|
||||||
|
|
||||||
|
std::vector<int> pb_route_indices;
|
||||||
|
|
||||||
for (int pin = 0; pin < pb->pb_graph_node->total_pb_pins; ++pin) {
|
for (int pin = 0; pin < pb->pb_graph_node->total_pb_pins; ++pin) {
|
||||||
/* Bypass unused pins */
|
/* Bypass unused pins */
|
||||||
if ((0 == pb->pb_route.count(pin)) || (AtomNetId::INVALID() == pb->pb_route[pin].atom_net_id)) {
|
if ((0 == pb->pb_route.count(pin)) || (AtomNetId::INVALID() == pb->pb_route[pin].atom_net_id)) {
|
||||||
|
@ -39,27 +124,15 @@ std::vector<t_pb_graph_pin*> find_routed_pb_graph_pins_atom_net(const t_pb* pb,
|
||||||
if (atom_net_id != pb->pb_route[pin].atom_net_id) {
|
if (atom_net_id != pb->pb_route[pin].atom_net_id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Check each sink nodes, if pin belongs to an input of a primitive pb_graph_node, it is what we want */
|
/* Only care the pin that shares the same parent_node as source_pb_pin */
|
||||||
for (const int& sink_pb_pin_id : pb->pb_route[pin].sink_pb_pin_ids) {
|
if (source_pb_pin->parent_node == pb->pb_route[pin].pb_graph_pin->parent_node) {
|
||||||
t_pb_graph_pin* sink_pb_pin = pb_graph_pin_lookup_from_index[sink_pb_pin_id];
|
pb_route_indices.push_back(pin);
|
||||||
VTR_ASSERT(nullptr != sink_pb_pin);
|
}
|
||||||
/* We care only
|
|
||||||
* - input pins of primitive nodes
|
|
||||||
* - output pins of top node
|
|
||||||
*/
|
|
||||||
if ( (true == is_primitive_pb_type(sink_pb_pin->parent_node->pb_type))
|
|
||||||
&& (IN_PORT == sink_pb_pin->port->type)) {
|
|
||||||
sink_pb_pins.push_back(sink_pb_pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (true == sink_pb_pin->parent_node->is_root())
|
|
||||||
&& (OUT_PORT == sink_pb_pin->port->type)) {
|
|
||||||
sink_pb_pins.push_back(sink_pb_pin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sink_pb_pins;
|
VTR_ASSERT(1 == pb_route_indices.size());
|
||||||
|
|
||||||
|
return pb_route_indices[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
|
@ -154,6 +227,9 @@ void add_lb_router_nets(LbRouter& lb_router,
|
||||||
*/
|
*/
|
||||||
std::map<AtomNetId, std::array<std::vector<LbRRNodeId>, 2>> net_terminals;
|
std::map<AtomNetId, std::array<std::vector<LbRRNodeId>, 2>> net_terminals;
|
||||||
|
|
||||||
|
/* A list showing that some sinks should be touched by some sources in a multi-source net */
|
||||||
|
std::map<AtomNetId, std::map<LbRRNodeId, std::vector<LbRRNodeId>>> invisible_sinks;
|
||||||
|
|
||||||
/* Find the source nodes for the nets mapped to inputs of a clustered block */
|
/* Find the source nodes for the nets mapped to inputs of a clustered block */
|
||||||
for (int j = 0; j < lb_type->pb_type->num_pins; j++) {
|
for (int j = 0; j < lb_type->pb_type->num_pins; j++) {
|
||||||
/* Find the net mapped to this pin in clustering results*/
|
/* Find the net mapped to this pin in clustering results*/
|
||||||
|
@ -185,31 +261,36 @@ void add_lb_router_nets(LbRouter& lb_router,
|
||||||
AtomNetId atom_net_id = atom_ctx.lookup.atom_net(cluster_net_id);
|
AtomNetId atom_net_id = atom_ctx.lookup.atom_net(cluster_net_id);
|
||||||
VTR_ASSERT(AtomNetId::INVALID() != atom_net_id);
|
VTR_ASSERT(AtomNetId::INVALID() != atom_net_id);
|
||||||
|
|
||||||
|
|
||||||
|
int pb_route_index = find_pb_route_remapped_source_pb_pin(pb, source_pb_pin, atom_net_id);
|
||||||
|
t_pb_graph_pin* packing_source_pb_pin = get_pb_graph_node_pin_from_block_pin(block_id, pb_route_index);
|
||||||
|
VTR_ASSERT(nullptr != packing_source_pb_pin);
|
||||||
|
|
||||||
/* Find all the sink pins in the pb_route, we walk through the input pins and find the pin */
|
/* Find all the sink pins in the pb_route, we walk through the input pins and find the pin */
|
||||||
std::vector<t_pb_graph_pin*> sink_pb_graph_pins = find_routed_pb_graph_pins_atom_net(pb, atom_net_id, pb_graph_pin_lookup_from_index);
|
std::vector<t_pb_graph_pin*> sink_pb_graph_pins = find_routed_pb_graph_pins_atom_net(pb, packing_source_pb_pin, atom_net_id, pb_graph_pin_lookup_from_index);
|
||||||
std::vector<LbRRNodeId> sink_lb_rr_nodes = find_lb_net_physical_sink_lb_rr_nodes(lb_rr_graph, sink_pb_graph_pins, device_annotation);
|
std::vector<LbRRNodeId> sink_lb_rr_nodes = find_lb_net_physical_sink_lb_rr_nodes(lb_rr_graph, sink_pb_graph_pins, device_annotation);
|
||||||
VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size());
|
VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size());
|
||||||
|
|
||||||
/* Cache the net */
|
/* Printf for debugging only, may be enabled if verbose is enabled
|
||||||
if (0 < net_terminals.count(atom_net_id)) {
|
VTR_LOG("Pb route for Net %s:\n",
|
||||||
if (net_terminals[atom_net_id][0].end() == std::find(net_terminals[atom_net_id][0].begin(),
|
atom_ctx.nlist.net_name(atom_net_id).c_str());
|
||||||
net_terminals[atom_net_id][0].end(),
|
VTR_LOG("Source node:\n\t%s -> %s\n",
|
||||||
source_lb_rr_node)) {
|
source_pb_pin->to_string().c_str(),
|
||||||
net_terminals[atom_net_id][0].push_back(source_lb_rr_node);
|
source_pb_pin->to_string().c_str());
|
||||||
}
|
VTR_LOG("Sink nodes:\n");
|
||||||
|
for (t_pb_graph_pin* sink_pb_pin : sink_pb_graph_pins) {
|
||||||
for (const LbRRNodeId& sink_lb_rr_node : sink_lb_rr_nodes) {
|
VTR_LOG("\t%s\n",
|
||||||
if (net_terminals[atom_net_id][1].end() == std::find(net_terminals[atom_net_id][1].begin(),
|
sink_pb_pin->to_string().c_str());
|
||||||
net_terminals[atom_net_id][1].end(),
|
|
||||||
sink_lb_rr_node)) {
|
|
||||||
net_terminals[atom_net_id][1].push_back(sink_lb_rr_node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
net_terminals[atom_net_id][0].push_back(source_lb_rr_node);
|
|
||||||
net_terminals[atom_net_id][1] = sink_lb_rr_nodes;
|
|
||||||
net_counter++;
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Add the net */
|
||||||
|
add_lb_router_net_to_route(lb_router, lb_rr_graph,
|
||||||
|
std::vector<LbRRNodeId>(1, source_lb_rr_node),
|
||||||
|
sink_lb_rr_nodes,
|
||||||
|
atom_ctx, atom_net_id);
|
||||||
|
|
||||||
|
net_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the source nodes for the nets mapped to outputs of primitive pb_graph_node */
|
/* Find the source nodes for the nets mapped to outputs of primitive pb_graph_node */
|
||||||
|
@ -248,58 +329,35 @@ void add_lb_router_nets(LbRouter& lb_router,
|
||||||
VTR_ASSERT(AtomNetId::INVALID() != atom_net_id);
|
VTR_ASSERT(AtomNetId::INVALID() != atom_net_id);
|
||||||
|
|
||||||
/* Find all the sink pins in the pb_route */
|
/* Find all the sink pins in the pb_route */
|
||||||
std::vector<t_pb_graph_pin*> sink_pb_graph_pins = find_routed_pb_graph_pins_atom_net(pb, atom_net_id, pb_graph_pin_lookup_from_index);
|
std::vector<t_pb_graph_pin*> sink_pb_graph_pins = find_routed_pb_graph_pins_atom_net(pb, source_pb_pin, atom_net_id, pb_graph_pin_lookup_from_index);
|
||||||
|
|
||||||
std::vector<LbRRNodeId> sink_lb_rr_nodes = find_lb_net_physical_sink_lb_rr_nodes(lb_rr_graph, sink_pb_graph_pins, device_annotation);
|
std::vector<LbRRNodeId> sink_lb_rr_nodes = find_lb_net_physical_sink_lb_rr_nodes(lb_rr_graph, sink_pb_graph_pins, device_annotation);
|
||||||
VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size());
|
VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size());
|
||||||
|
|
||||||
/* Cache the net */
|
/* Printf for debugging only, may be enabled if verbose is enabled
|
||||||
if (0 < net_terminals.count(atom_net_id)) {
|
VTR_LOG("Pb route for Net %s:\n",
|
||||||
if (net_terminals[atom_net_id][0].end() == std::find(net_terminals[atom_net_id][0].begin(),
|
atom_ctx.nlist.net_name(atom_net_id).c_str());
|
||||||
net_terminals[atom_net_id][0].end(),
|
VTR_LOG("Source node:\n\t%s -> %s\n",
|
||||||
source_lb_rr_node)) {
|
source_pb_pin->to_string().c_str(),
|
||||||
net_terminals[atom_net_id][0].push_back(source_lb_rr_node);
|
physical_source_pb_pin->to_string().c_str());
|
||||||
}
|
VTR_LOG("Sink nodes:\n");
|
||||||
|
for (t_pb_graph_pin* sink_pb_pin : sink_pb_graph_pins) {
|
||||||
for (const LbRRNodeId& sink_lb_rr_node : sink_lb_rr_nodes) {
|
VTR_LOG("\t%s\n",
|
||||||
if (net_terminals[atom_net_id][1].end() == std::find(net_terminals[atom_net_id][1].begin(),
|
sink_pb_pin->to_string().c_str());
|
||||||
net_terminals[atom_net_id][1].end(),
|
|
||||||
sink_lb_rr_node)) {
|
|
||||||
net_terminals[atom_net_id][1].push_back(sink_lb_rr_node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
net_terminals[atom_net_id][0].push_back(source_lb_rr_node);
|
|
||||||
net_terminals[atom_net_id][1] = sink_lb_rr_nodes;
|
|
||||||
net_counter++;
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Add the net */
|
||||||
|
add_lb_router_net_to_route(lb_router, lb_rr_graph,
|
||||||
|
std::vector<LbRRNodeId>(1, source_lb_rr_node),
|
||||||
|
sink_lb_rr_nodes,
|
||||||
|
atom_ctx, atom_net_id);
|
||||||
|
net_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free */
|
/* Free */
|
||||||
free_pb_graph_pin_lookup_from_index(pb_graph_pin_lookup_from_index);
|
free_pb_graph_pin_lookup_from_index(pb_graph_pin_lookup_from_index);
|
||||||
|
|
||||||
/* Add all the nets */
|
|
||||||
for (std::pair<AtomNetId, std::array<std::vector<LbRRNodeId>, 2>> net_terminal_pair : net_terminals) {
|
|
||||||
const AtomNetId& atom_net_id = net_terminal_pair.first;
|
|
||||||
|
|
||||||
/* MUST have >1 source nodes and >1 sinks nodes */
|
|
||||||
if (0 == net_terminal_pair.second[0].size()) {
|
|
||||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
|
||||||
"Net '%s' has 0 source nodes!",
|
|
||||||
atom_ctx.nlist.net_name(atom_net_id).c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 == net_terminal_pair.second[1].size()) {
|
|
||||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
|
||||||
"Net '%s' has 0 sink nodes!",
|
|
||||||
atom_ctx.nlist.net_name(atom_net_id).c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the net */
|
|
||||||
add_lb_router_net_to_route(lb_router, lb_rr_graph,
|
|
||||||
net_terminal_pair.second[0], net_terminal_pair.second[1],
|
|
||||||
atom_ctx, atom_net_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
VTR_LOGV(verbose,
|
VTR_LOGV(verbose,
|
||||||
"Added %lu nets to be routed.\n",
|
"Added %lu nets to be routed.\n",
|
||||||
net_counter);
|
net_counter);
|
||||||
|
|
Loading…
Reference in New Issue