|
14 | 14 | #include "side_manager.h" |
15 | 15 |
|
16 | 16 | #include "vpr_utils.h" |
| 17 | +#include "physical_types_util.h" |
17 | 18 | #include "rr_graph_view_util.h" |
18 | 19 | #include "tileable_rr_graph_utils.h" |
19 | 20 | #include "rr_graph_builder_utils.h" |
@@ -1723,49 +1724,67 @@ void build_direct_connections_for_one_gsb(const RRGraphView& rr_graph, |
1723 | 1724 | /* get every opin in the range */ |
1724 | 1725 | for (int opin = min_index; opin <= max_index; ++opin) { |
1725 | 1726 | int offset = opin - min_index; |
| 1727 | + //Capacity location determined by pin number relative to pins per capacity instance |
| 1728 | + auto [z, relative_opin] = get_capacity_location_from_physical_pin(grid_type, opin); |
| 1729 | + VTR_ASSERT(z >= 0 && z < grid_type->capacity); |
1726 | 1730 |
|
1727 | 1731 | if ((to_grid_coordinate.x() < grids.width() - 1) |
1728 | 1732 | && (to_grid_coordinate.y() < grids.height() - 1)) { |
1729 | | - int ipin = UNDEFINED; |
| 1733 | + int relative_ipin = UNDEFINED; |
1730 | 1734 | if (clb_to_clb_directs[i].to_clb_pin_start_index |
1731 | 1735 | > clb_to_clb_directs[i].to_clb_pin_end_index) { |
1732 | 1736 | if (true == swap) { |
1733 | | - ipin = clb_to_clb_directs[i].to_clb_pin_end_index + offset; |
| 1737 | + relative_ipin = clb_to_clb_directs[i].to_clb_pin_end_index + offset; |
1734 | 1738 | } else { |
1735 | | - ipin = clb_to_clb_directs[i].to_clb_pin_start_index - offset; |
| 1739 | + relative_ipin = clb_to_clb_directs[i].to_clb_pin_start_index - offset; |
1736 | 1740 | } |
1737 | 1741 | } else { |
1738 | 1742 | if (true == swap) { |
1739 | | - ipin = clb_to_clb_directs[i].to_clb_pin_end_index - offset; |
| 1743 | + relative_ipin = clb_to_clb_directs[i].to_clb_pin_end_index - offset; |
1740 | 1744 | } else { |
1741 | | - ipin = clb_to_clb_directs[i].to_clb_pin_start_index + offset; |
| 1745 | + relative_ipin = clb_to_clb_directs[i].to_clb_pin_start_index + offset; |
1742 | 1746 | } |
1743 | 1747 | } |
1744 | 1748 |
|
1745 | 1749 | /* Get the pin index in the rr_graph */ |
1746 | 1750 | t_physical_tile_loc from_tile_loc(from_grid_coordinate.x(), from_grid_coordinate.y(), layer); |
1747 | | - int from_grid_width_ofs = grids.get_width_offset(from_tile_loc); |
1748 | | - int from_grid_height_ofs = grids.get_height_offset(from_tile_loc); |
1749 | 1751 | t_physical_tile_loc to_tile_loc(to_grid_coordinate.x(), to_grid_coordinate.y(), layer); |
1750 | | - int to_grid_width_ofs = grids.get_width_offset(to_tile_loc); |
1751 | | - int to_grid_height_ofs = grids.get_height_offset(to_tile_loc); |
1752 | 1752 |
|
1753 | 1753 | /* Find the side of grid pins, the pin location should be unique! |
1754 | 1754 | * Pin location is required by searching a node in rr_graph |
1755 | 1755 | */ |
1756 | | - std::vector<e_side> opin_grid_side = find_grid_pin_sides(grids, layer, from_grid_coordinate.x(), from_grid_coordinate.y(), opin); |
1757 | | - VTR_ASSERT(1 == opin_grid_side.size()); |
1758 | | - |
1759 | | - std::vector<e_side> ipin_grid_side = find_grid_pin_sides(grids, layer, to_grid_coordinate.x(), to_grid_coordinate.y(), ipin); |
1760 | | - VTR_ASSERT(1 == ipin_grid_side.size()); |
| 1756 | + std::vector<e_side> opin_grid_side = find_grid_pin_sides(grids, layer, from_grid_coordinate.x() + grid_type->pin_width_offset[opin], from_grid_coordinate.y() + grid_type->pin_height_offset[opin], opin); |
| 1757 | + if (1 != opin_grid_side.size()) { |
| 1758 | + VPR_FATAL_ERROR(VPR_ERROR_ARCH, "[Arch LINE %d] From pin (index=%d) of direct connection '%s' does not exist on any side of the programmable block '%s'.\n", directs[i].line, opin, directs[i].from_pin.c_str()); |
| 1759 | + } |
| 1760 | + |
| 1761 | + /* directs[i].sub_tile_offset is added to from_capacity(z) to get the target_capacity */ |
| 1762 | + int to_subtile_cap = z + directs[i].sub_tile_offset; |
| 1763 | + /* Iterate over all sub_tiles to get the sub_tile which the target_cap belongs to. */ |
| 1764 | + const t_sub_tile* to_sub_tile = nullptr; |
| 1765 | + for (const t_sub_tile& sub_tile : to_grid_type->sub_tiles) { |
| 1766 | + if (sub_tile.capacity.is_in_range(to_subtile_cap)) { |
| 1767 | + to_sub_tile = &sub_tile; |
| 1768 | + break; |
| 1769 | + } |
| 1770 | + } |
| 1771 | + VTR_ASSERT(to_sub_tile != nullptr); |
| 1772 | + if (relative_ipin >= to_sub_tile->num_phy_pins) continue; |
| 1773 | + // If this block has capacity > 1 then the pins of z position > 0 are offset |
| 1774 | + // by the number of pins per capacity instance |
| 1775 | + int ipin = get_physical_pin_from_capacity_location(to_grid_type, relative_ipin, to_subtile_cap); |
| 1776 | + std::vector<e_side> ipin_grid_side = find_grid_pin_sides(grids, layer, to_grid_coordinate.x() + to_grid_type->pin_width_offset[ipin], to_grid_coordinate.y() + to_grid_type->pin_height_offset[ipin], ipin); |
| 1777 | + if (1 != ipin_grid_side.size()) { |
| 1778 | + VPR_FATAL_ERROR(VPR_ERROR_ARCH, "[Arch LINE %d] To pin (index=%d) of direct connection '%s' does not exist on any side of the programmable block '%s'.\n", directs[i].line, relative_ipin, directs[i].to_pin.c_str()); |
| 1779 | + } |
1761 | 1780 |
|
1762 | 1781 | RRNodeId opin_node_id = rr_graph.node_lookup().find_node(layer, |
1763 | | - from_grid_coordinate.x() - from_grid_width_ofs, |
1764 | | - from_grid_coordinate.y() - from_grid_height_ofs, |
| 1782 | + from_grid_coordinate.x() + grid_type->pin_width_offset[opin], |
| 1783 | + from_grid_coordinate.y() + grid_type->pin_height_offset[opin], |
1765 | 1784 | e_rr_type::OPIN, opin, opin_grid_side[0]); |
1766 | 1785 | RRNodeId ipin_node_id = rr_graph.node_lookup().find_node(layer, |
1767 | | - to_grid_coordinate.x() - to_grid_width_ofs, |
1768 | | - to_grid_coordinate.y() - to_grid_height_ofs, |
| 1786 | + to_grid_coordinate.x() + to_grid_type->pin_width_offset[ipin], |
| 1787 | + to_grid_coordinate.y() + to_grid_type->pin_height_offset[ipin], |
1769 | 1788 | e_rr_type::IPIN, ipin, ipin_grid_side[0]); |
1770 | 1789 |
|
1771 | 1790 | /* add edges to the opin_node */ |
|
0 commit comments