diff --git a/libs/libclkarchopenfpga/src/base/clock_network.cpp b/libs/libclkarchopenfpga/src/base/clock_network.cpp index 6abb021d8..488deab6e 100644 --- a/libs/libclkarchopenfpga/src/base/clock_network.cpp +++ b/libs/libclkarchopenfpga/src/base/clock_network.cpp @@ -401,12 +401,68 @@ size_t ClockNetwork::tap_step_y(const ClockTapId& tap_id) const { return tap_bb_steps_[tap_id].y(); } +bool ClockNetwork::valid_tap_coord_in_bb(const ClockTapId& tap_id, const vtr::Point& tap_coord) const { + VTR_ASSERT(valid_tap_id(tap_id)); + if (tap_type(tap_id) == ClockNetwork::e_tap_type::ALL) { + return true; + } + if (tap_type(tap_id) == ClockNetwork::e_tap_type::SINGLE && tap_bbs_[tap_id].strictly_contains(tap_coord)) { + return true; + } + if (tap_type(tap_id) == ClockNetwork::e_tap_type::REGION && tap_bbs_[tap_id].strictly_contains(tap_coord)) { + /* Check if steps are considered, coords still matches */ + bool x_in_bb = false; + for (size_t ix = tap_bbs_[tap_id].xmin(); ix < tap_bbs_[tap_id].xmax(); ix = ix + tap_bb_steps_[tap_id].x()) { + if (tap_coord.x() == ix) { + x_in_bb = true; + break; + } + } + /* Early exit */ + if (!x_in_bb) { + return false; + } + bool y_in_bb = false; + for (size_t iy = tap_bbs_[tap_id].ymin(); iy < tap_bbs_[tap_id].ymax(); iy = iy + tap_bb_steps_[tap_id].y()) { + if (tap_coord.y() == iy) { + y_in_bb = true; + break; + } + } + if (y_in_bb && x_in_bb) { + return true; + } + } + return false; +} + std::vector ClockNetwork::tree_flatten_tap_to_ports( - const ClockTreeId& tree_id, const ClockTreePinId& clk_pin_id) const { + const ClockTreeId& tree_id, const ClockTreePinId& clk_pin_id, const vtr::Point& tap_coord) const { VTR_ASSERT(valid_tree_id(tree_id)); std::vector flatten_taps; for (ClockTapId tap_id : tree_taps_[tree_id]) { VTR_ASSERT(valid_tap_id(tap_id)); + /* Filter out unmatched from ports. Expect [clk_pin_id:clk_pin_id] */ + std::string tap_from_port_name = tap_from_ports_[tap_id]; + PortParser from_port_parser(tap_from_port_name); + BasicPort from_port = from_port_parser.port(); + if (!from_port.is_valid()) { + VTR_LOG_ERROR("Invalid from port name '%s' whose index is not valid\n", + tap_from_port_name.c_str()); + exit(1); + } + if (from_port.get_width() != 1) { + VTR_LOG_ERROR("Invalid from port name '%s' whose width is not 1\n", + tap_from_port_name.c_str()); + exit(1); + } + if (from_port.get_lsb() != size_t(clk_pin_id)) { + continue; + } + /* Filter out unmatched coordinates */ + if (!valid_tap_coord_in_bb(tap_id, tap_coord)) { + continue; + } std::string tap_name = tap_to_ports_[tap_id]; StringToken tokenizer(tap_name); std::vector pin_tokens = tokenizer.split("."); diff --git a/libs/libclkarchopenfpga/src/base/clock_network.h b/libs/libclkarchopenfpga/src/base/clock_network.h index e5236ab10..57ed39cb9 100644 --- a/libs/libclkarchopenfpga/src/base/clock_network.h +++ b/libs/libclkarchopenfpga/src/base/clock_network.h @@ -164,7 +164,7 @@ class ClockNetwork { * resource graph Note that the clk_pin_id limits only 1 clock to be accessed */ std::vector tree_flatten_tap_to_ports( - const ClockTreeId& tree_id, const ClockTreePinId& clk_pin_id) const; + const ClockTreeId& tree_id, const ClockTreePinId& clk_pin_id, const vtr::Point& tap_coord) const; /* Find a spine with a given name, if not found, return an valid id, otherwise * return an invalid one */ ClockSpineId find_spine(const std::string& name) const; @@ -264,6 +264,8 @@ class ClockNetwork { const ClockInternalDriverId& int_driver_id) const; /* Show if the tap id is a valid for data queries */ bool valid_tap_id(const ClockTapId& tap_id) const; + /* Check if a given coordinate matches the requirements for a tap point */ + bool valid_tap_coord_in_bb(const ClockTapId& tap_id, const vtr::Point& tap_coord) const; private: /* Private mutators */ /* Build internal links between spines under a given tree */ diff --git a/openfpga/src/annotation/append_clock_rr_graph.cpp b/openfpga/src/annotation/append_clock_rr_graph.cpp index 53cad0453..d5f325ca6 100644 --- a/openfpga/src/annotation/append_clock_rr_graph.cpp +++ b/openfpga/src/annotation/append_clock_rr_graph.cpp @@ -400,7 +400,7 @@ static void try_find_and_add_clock_track2ipin_node( t_physical_tile_type_ptr grid_type = grids.get_physical_type( t_physical_tile_loc(grid_coord.x(), grid_coord.y(), layer)); for (std::string tap_pin_name : - clk_ntwk.tree_flatten_taps(clk_tree, clk_pin)) { + clk_ntwk.tree_flatten_tap_to_ports(clk_tree, clk_pin, grid_coord)) { /* tap pin name could be 'io[5:5].a2f[0]' */ int grid_pin_idx = find_physical_tile_pin_index(grid_type, tap_pin_name); if (grid_pin_idx == grid_type->num_pins) {