[OpenFPGA Tool] Bug fix for repacking no local routing architecture

This commit is contained in:
tangxifan 2020-09-21 22:22:03 -06:00
parent a8a269aa82
commit 26f1a5d9ec
1 changed files with 89 additions and 3 deletions

View File

@ -20,6 +20,73 @@
/* begin namespace openfpga */
namespace openfpga {
/***************************************************************************************
* Try to find sink pb graph pins through walking through the fan-out edges from
* the source pb graph pin
* Only the sink meeting the following requirements can be considered:
* - All the fan-out edges between the source and sink are from direct interconnection
* - sink is an input of a primitive pb_type
*
* Note:
* - If there is a fan-out of the current source pb graph pin is not a direct interconnection
* the direct search should stop.
* - This function is designed for pb graph without local routing
* For example: direct connection between root pb graph node to the LUT pb graph node
*
* root pb_graph_node
* +-----------------------------------------
* | Intermediate pb_graph_node
* | +----------------------------------
* | | primitive pb_graph_node
* | | +-------------------------
* I[0] ---->+------>+------->|I[0] LUT
*
* - This function is designed for passing wires inside pb graph
*
* root pb_graph_node
* +------------------------------+
* | Intermediate pb_graph_node |
* | +-------------+ |
* | | | |
* | | | |
* I[0]----->+------>+--- ... ---->+------->+------>O[0]
*
***************************************************************************************/
static
bool rec_direct_search_sink_pb_graph_pins(const t_pb_graph_pin* source_pb_pin,
std::vector<t_pb_graph_pin*>& sink_pb_pins) {
std::vector<t_pb_graph_pin*> sink_pb_pins_to_search;
for (int iedge = 0; iedge < source_pb_pin->num_output_edges; ++iedge) {
if (DIRECT_INTERC != source_pb_pin->output_edges[iedge]->interconnect->type) {
return false;
}
for (int ipin = 0; ipin < source_pb_pin->output_edges[iedge]->num_output_pins; ++ipin) {
t_pb_graph_pin* cand_sink_pb_pin = source_pb_pin->output_edges[iedge]->output_pins[ipin];
if ( (true == is_primitive_pb_type(cand_sink_pb_pin->parent_node->pb_type))
&& (IN_PORT == cand_sink_pb_pin->port->type)) {
sink_pb_pins.push_back(cand_sink_pb_pin);
} else if ( (true == cand_sink_pb_pin->parent_node->is_root())
&& (OUT_PORT == cand_sink_pb_pin->port->type)) {
sink_pb_pins.push_back(cand_sink_pb_pin);
} else {
sink_pb_pins_to_search.push_back(cand_sink_pb_pin);
}
}
}
for (t_pb_graph_pin* sink_pb_pin : sink_pb_pins_to_search) {
bool direct_search_status = rec_direct_search_sink_pb_graph_pins(sink_pb_pin, sink_pb_pins);
if (false == direct_search_status) {
return false;
}
}
/* Reach here, we succeed. */
return true;
}
/***************************************************************************************
* 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
@ -133,13 +200,32 @@ void rec_find_routed_sink_pb_graph_pins(const t_pb* pb,
static
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 t_pb_graph_pin* packing_source_pb_pin,
const AtomNetId& atom_net_id,
const VprDeviceAnnotation& device_annotation,
const std::map<const t_pb_graph_pin*, AtomNetId>& pb_pin_mapped_nets,
t_pb_graph_pin** pb_graph_pin_lookup_from_index) {
std::vector<t_pb_graph_pin*> sink_pb_pins;
rec_find_routed_sink_pb_graph_pins(pb, source_pb_pin, atom_net_id, device_annotation, pb_pin_mapped_nets, pb_graph_pin_lookup_from_index, sink_pb_pins);
/* Try to directly search for sink pb_pins from the source_pb_pin,
* which is the actual source pin to be routed from
* Note that the packing source_pb_pin is the source pin considered by
* VPR packer, but may not be the actual source!!!
*/
if (true == source_pb_pin->parent_node->is_root()) {
bool direct_search_status = rec_direct_search_sink_pb_graph_pins(source_pb_pin, sink_pb_pins);
if (true == direct_search_status) {
VTR_ASSERT(!sink_pb_pins.empty());
/* We have find through direct searching, return now */
return sink_pb_pins;
}
/* Cannot find through direct searching, reset results */
VTR_ASSERT_SAFE(false == direct_search_status);
sink_pb_pins.clear();
}
rec_find_routed_sink_pb_graph_pins(pb, packing_source_pb_pin, atom_net_id, device_annotation, pb_pin_mapped_nets, pb_graph_pin_lookup_from_index, sink_pb_pins);
return sink_pb_pins;
}
@ -339,7 +425,7 @@ void add_lb_router_nets(LbRouter& lb_router,
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 */
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, device_annotation, pb_pin_mapped_nets, 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, packing_source_pb_pin, atom_net_id, device_annotation, pb_pin_mapped_nets, 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);
VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size());
@ -404,7 +490,7 @@ void add_lb_router_nets(LbRouter& lb_router,
VTR_ASSERT(AtomNetId::INVALID() != atom_net_id);
/* 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, source_pb_pin, atom_net_id, device_annotation, pb_pin_mapped_nets, pb_graph_pin_lookup_from_index);
std::vector<t_pb_graph_pin*> sink_pb_graph_pins = find_routed_pb_graph_pins_atom_net(pb, physical_source_pb_pin, source_pb_pin, atom_net_id, device_annotation, pb_pin_mapped_nets, 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);
VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size());