|
5 | 5 | #include <fstream>
|
6 | 6 | #include <cstdlib>
|
7 | 7 | #include <sstream>
|
| 8 | +#include <limits> |
| 9 | +#include <queue> |
8 | 10 |
|
9 | 11 | #include "vtr_assert.h"
|
10 | 12 | #include "vtr_log.h"
|
@@ -60,6 +62,104 @@ static std::vector<AtomBlockId> find_noc_router_atoms() {
|
60 | 62 | return noc_router_atoms;
|
61 | 63 | }
|
62 | 64 |
|
| 65 | +static void update_noc_reachability_partitions(const std::vector<AtomBlockId>& noc_atoms) { |
| 66 | + const auto& atom_ctx = g_vpr_ctx.atom(); |
| 67 | + auto& constraints = g_vpr_ctx.mutable_floorplanning().constraints; |
| 68 | + const auto& high_fanout_thresholds = g_vpr_ctx.cl_helper().high_fanout_thresholds; |
| 69 | + |
| 70 | + const size_t high_fanout_threshold = high_fanout_thresholds.get_threshold(""); |
| 71 | + |
| 72 | + // get the total number of atoms |
| 73 | + const size_t n_atoms = atom_ctx.nlist.blocks().size(); |
| 74 | + |
| 75 | + vtr::vector<AtomBlockId, bool> atom_visited(n_atoms, false); |
| 76 | + |
| 77 | + int exclusivity_cnt = 0; |
| 78 | + |
| 79 | + RegionRectCoord unconstrained_rect{std::numeric_limits<int>::min(), |
| 80 | + std::numeric_limits<int>::min(), |
| 81 | + std::numeric_limits<int>::max(), |
| 82 | + std::numeric_limits<int>::max(), |
| 83 | + -1}; |
| 84 | + Region unconstrained_region; |
| 85 | + unconstrained_region.set_region_rect(unconstrained_rect); |
| 86 | + |
| 87 | + for (auto noc_atom_id : noc_atoms) { |
| 88 | + // check if this NoC router has already been visited |
| 89 | + if (atom_visited[noc_atom_id]) { |
| 90 | + continue; |
| 91 | + } |
| 92 | + |
| 93 | + exclusivity_cnt++; |
| 94 | + |
| 95 | + PartitionRegion associated_noc_partition_region; |
| 96 | + associated_noc_partition_region.set_exclusivity_index(exclusivity_cnt); |
| 97 | + associated_noc_partition_region.add_to_part_region(unconstrained_region); |
| 98 | + |
| 99 | + Partition associated_noc_partition; |
| 100 | + associated_noc_partition.set_name(atom_ctx.nlist.block_name(noc_atom_id)); |
| 101 | + associated_noc_partition.set_part_region(associated_noc_partition_region); |
| 102 | + auto associated_noc_partition_id = (PartitionId)constraints.get_num_partitions(); |
| 103 | + constraints.add_partition(associated_noc_partition); |
| 104 | + |
| 105 | + const PartitionId noc_partition_id = constraints.get_atom_partition(noc_atom_id); |
| 106 | + |
| 107 | + if (noc_partition_id == PartitionId::INVALID()) { |
| 108 | + constraints.add_constrained_atom(noc_atom_id, associated_noc_partition_id); |
| 109 | + } else { // noc atom is already in a partition |
| 110 | + auto& noc_partition = constraints.get_mutable_partition(noc_partition_id); |
| 111 | + auto& noc_partition_region = noc_partition.get_mutable_part_region(); |
| 112 | + VTR_ASSERT(noc_partition_region.get_exclusivity_index() < 0); |
| 113 | + noc_partition_region.set_exclusivity_index(exclusivity_cnt); |
| 114 | + } |
| 115 | + |
| 116 | + std::queue<AtomBlockId> q; |
| 117 | + q.push(noc_atom_id); |
| 118 | + atom_visited[noc_atom_id] = true; |
| 119 | + |
| 120 | + while (!q.empty()) { |
| 121 | + AtomBlockId current_atom = q.front(); |
| 122 | + q.pop(); |
| 123 | + |
| 124 | + PartitionId atom_partition_id = constraints.get_atom_partition(noc_atom_id); |
| 125 | + if (atom_partition_id == PartitionId::INVALID()) { |
| 126 | + constraints.add_constrained_atom(current_atom, associated_noc_partition_id); |
| 127 | + } else { |
| 128 | + auto& atom_partition = constraints.get_mutable_partition(atom_partition_id); |
| 129 | + auto& atom_partition_region = atom_partition.get_mutable_part_region(); |
| 130 | + VTR_ASSERT(atom_partition_region.get_exclusivity_index() < 0); |
| 131 | + atom_partition_region.set_exclusivity_index(exclusivity_cnt); |
| 132 | + } |
| 133 | + |
| 134 | + for(auto pin : atom_ctx.nlist.block_pins(current_atom)) { |
| 135 | + AtomNetId net_id = atom_ctx.nlist.pin_net(pin); |
| 136 | + size_t net_fanout = atom_ctx.nlist.net_sinks(net_id).size(); |
| 137 | + |
| 138 | + if (net_fanout >= high_fanout_threshold) { |
| 139 | + continue; |
| 140 | + } |
| 141 | + |
| 142 | + AtomBlockId driver_atom_id = atom_ctx.nlist.net_driver_block(net_id); |
| 143 | + if (!atom_visited[driver_atom_id]) { |
| 144 | + q.push(driver_atom_id); |
| 145 | + atom_visited[driver_atom_id] = true; |
| 146 | + } |
| 147 | + |
| 148 | + for (auto sink_pin : atom_ctx.nlist.net_sinks(net_id)) { |
| 149 | + AtomBlockId sink_atom_id = atom_ctx.nlist.pin_block(sink_pin); |
| 150 | + if (!atom_visited[sink_atom_id]) { |
| 151 | + q.push(sink_atom_id); |
| 152 | + atom_visited[sink_atom_id] = true; |
| 153 | + } |
| 154 | + } |
| 155 | + |
| 156 | + } |
| 157 | + } |
| 158 | + |
| 159 | + } |
| 160 | +} |
| 161 | + |
| 162 | + |
63 | 163 | bool try_pack(t_packer_opts* packer_opts,
|
64 | 164 | const t_analysis_opts* analysis_opts,
|
65 | 165 | const t_arch* arch,
|
@@ -151,10 +251,9 @@ bool try_pack(t_packer_opts* packer_opts,
|
151 | 251 | int pack_iteration = 1;
|
152 | 252 | bool floorplan_regions_overfull = false;
|
153 | 253 |
|
| 254 | + // find all NoC router atoms |
154 | 255 | auto noc_atoms = find_noc_router_atoms();
|
155 |
| - for (auto noc_atom : noc_atoms) { |
156 |
| - std::cout << "NoC Atom: " << atom_ctx.nlist.block_name(noc_atom) << std::endl; |
157 |
| - } |
| 256 | + update_noc_reachability_partitions(noc_atoms); |
158 | 257 |
|
159 | 258 | while (true) {
|
160 | 259 | free_clustering_data(*packer_opts, clustering_data);
|
|
0 commit comments