From 26f1a5d9ec98d300b9ddbd54a6269d6d0755aa1e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Mon, 21 Sep 2020 22:22:03 -0600 Subject: [PATCH] [OpenFPGA Tool] Bug fix for repacking no local routing architecture --- openfpga/src/repack/repack.cpp | 92 ++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/openfpga/src/repack/repack.cpp b/openfpga/src/repack/repack.cpp index c3ab88f1c..83956dfc9 100644 --- a/openfpga/src/repack/repack.cpp +++ b/openfpga/src/repack/repack.cpp @@ -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& sink_pb_pins) { + + std::vector 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 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& pb_pin_mapped_nets, t_pb_graph_pin** pb_graph_pin_lookup_from_index) { std::vector 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 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 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 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 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 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 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());