@@ -42,23 +42,6 @@ static void fixup_atom_pb_graph_pin_mapping(void);
42
42
43
43
/* Function definitions */
44
44
45
- /* * Is the clock net found in the routing results?
46
- * (If not, clock_modeling is probably ideal and we should preserve clock routing while rebuilding.) */
47
- inline bool is_clock_net_routed (void ) {
48
- auto & atom_ctx = g_vpr_ctx.atom ();
49
- auto & route_ctx = g_vpr_ctx.routing ();
50
-
51
- for (auto net_id : atom_ctx.netlist ().nets ()) {
52
- auto & tree = route_ctx.route_trees [net_id];
53
- if (!tree)
54
- continue ;
55
- if (route_ctx.is_clock_net [net_id]) /* Clock net has routing */
56
- return true ;
57
- }
58
-
59
- return false ;
60
- }
61
-
62
45
/* * Get the ClusterBlockId for a given RRNodeId. */
63
46
inline ClusterBlockId get_cluster_block_from_rr_node (RRNodeId inode) {
64
47
auto & device_ctx = g_vpr_ctx.device ();
@@ -185,18 +168,22 @@ static void sync_pb_routes_to_routing(void) {
185
168
auto & route_ctx = g_vpr_ctx.routing ();
186
169
auto & rr_graph = device_ctx.rr_graph ;
187
170
188
- /* Was the clock net routed? */
189
- bool clock_net_is_routed = is_clock_net_routed ();
190
-
191
171
/* Clear out existing pb_routes: they were made by the intra cluster router and are invalid now */
192
172
for (ClusterBlockId clb_blk_id : cluster_ctx.clb_nlist .blocks ()) {
193
- /* If we don't have routing for the clock net, don't erase entries associated with a clock net.
194
- * Otherwise we won't have data to rebuild them */
173
+ /* Don't erase entries for nets without routing in place (clocks, globals...) */
195
174
std::vector<int > pins_to_erase;
196
- auto & pb_routes = cluster_ctx.clb_nlist .block_pb (clb_blk_id)->pb_route ;
175
+ t_pb_routes & pb_routes = cluster_ctx.clb_nlist .block_pb (clb_blk_id)->pb_route ;
197
176
for (auto & [pin, pb_route] : pb_routes) {
198
- if (clock_net_is_routed || !route_ctx.is_clock_net [pb_route.atom_net_id ])
199
- pins_to_erase.push_back (pin);
177
+ /*
178
+ * Given that this function is called when flat routing is enabled,
179
+ * we can safely assume that the net IDs to index into route_ctx.route_trees
180
+ * correspond to the atom net IDs.
181
+ */
182
+ if (!route_ctx.route_trees [pb_route.atom_net_id ]) {
183
+ /* No route tree: no routing in place, it is global or clock */
184
+ continue ;
185
+ }
186
+ pins_to_erase.push_back (pin);
200
187
}
201
188
202
189
for (int pin : pins_to_erase) {
@@ -276,37 +263,37 @@ static void sync_clustered_netlist_to_routing(void) {
276
263
auto & atom_ctx = g_vpr_ctx.mutable_atom ();
277
264
auto & atom_lookup = atom_ctx.lookup ();
278
265
279
- bool clock_net_is_routed = is_clock_net_routed ();
280
-
281
266
/* 1. Remove all nets, pins and ports from the clustered netlist.
282
- * If the clock net is not routed, don't remove entries for the clock net
283
- * otherwise we won 't have data to rebuild them . */
267
+ * Do not remove entries for nets without an existing route tree,
268
+ * since we don 't have the information to rebuild those parts . */
284
269
std::vector<ClusterNetId> nets_to_remove;
285
270
std::vector<ClusterPinId> pins_to_remove;
286
271
std::vector<ClusterPortId> ports_to_remove;
287
272
288
273
for (auto net_id : clb_netlist.nets ()) {
289
274
auto atom_net_id = atom_lookup.atom_net (net_id);
290
- if (!clock_net_is_routed && route_ctx.is_clock_net [atom_net_id])
275
+ if (!route_ctx.route_trees [atom_net_id])
291
276
continue ;
292
277
293
278
nets_to_remove.push_back (net_id);
294
279
}
295
- for (auto pin_id : clb_netlist.pins ()) {
296
- ClusterNetId clb_net_id = clb_netlist.pin_net (pin_id);
297
- auto atom_net_id = atom_lookup.atom_net (clb_net_id);
298
- if (!clock_net_is_routed && atom_net_id && route_ctx.is_clock_net [atom_net_id])
299
- continue ;
300
-
301
- pins_to_remove.push_back (pin_id);
302
- }
280
+ /* Mark ports and pins for removal. Don't remove a port if
281
+ * it has at least one pin remaining */
303
282
for (auto port_id : clb_netlist.ports ()) {
304
- ClusterNetId clb_net_id = clb_netlist.port_net (port_id, 0 );
305
- auto atom_net_id = atom_lookup.atom_net (clb_net_id);
306
- if (!clock_net_is_routed && atom_net_id && route_ctx.is_clock_net [atom_net_id])
307
- continue ;
283
+ size_t skipped_pins = 0 ;
284
+
285
+ for (auto pin_id : clb_netlist.port_pins (port_id)) {
286
+ ClusterNetId clb_net_id = clb_netlist.pin_net (pin_id);
287
+ auto atom_net_id = atom_lookup.atom_net (clb_net_id);
288
+ if (atom_net_id && !route_ctx.route_trees [atom_net_id]) {
289
+ skipped_pins++;
290
+ } else {
291
+ pins_to_remove.push_back (pin_id);
292
+ }
293
+ }
308
294
309
- ports_to_remove.push_back (port_id);
295
+ if (!skipped_pins) // All pins have been removed, remove port
296
+ ports_to_remove.push_back (port_id);
310
297
}
311
298
312
299
/* ClusteredNetlist's iterators rely on internal lookups, so we mark for removal
@@ -363,6 +350,7 @@ static void sync_clustered_netlist_to_routing(void) {
363
350
364
351
t_pb_graph_pin* pb_graph_pin = get_pb_graph_node_pin_from_block_pin (clb, pin_index);
365
352
353
+ /* Get or create port */
366
354
ClusterPortId port_id = clb_netlist.find_port (clb, pb_graph_pin->port ->name );
367
355
if (!port_id) {
368
356
PortType port_type;
@@ -378,6 +366,15 @@ static void sync_clustered_netlist_to_routing(void) {
378
366
}
379
367
PinType pin_type = node_type == e_rr_type::OPIN ? PinType::DRIVER : PinType::SINK;
380
368
369
+ /* Pin already exists. This means a global net that was not routed (i.e. 'ideal' mode). */
370
+ if (clb_netlist.port_pin (port_id, pb_graph_pin->pin_number )) {
371
+ VTR_LOG_WARN (" Pin %s of block %s has a global or clock net"
372
+ " connected and it has a routing clash with the flat router."
373
+ " This may cause inconsistent results.\n " ,
374
+ pb_graph_pin->to_string ().c_str (),
375
+ clb_netlist.block_name (clb).c_str ());
376
+ continue ;
377
+ }
381
378
ClusterPinId new_pin = clb_netlist.create_pin (port_id, pb_graph_pin->pin_number , clb_net_id, pin_type, pb_graph_pin->pin_count_in_cluster );
382
379
clb_netlist.set_pin_net (new_pin, pin_type, clb_net_id);
383
380
}
@@ -419,6 +416,12 @@ static void fixup_atom_pb_graph_pin_mapping(void) {
419
416
420
417
/* Find atom port from pbg pin's model port */
421
418
AtomPortId atom_port = atom_ctx.netlist ().find_atom_port (atb, atom_pbg_pin->port ->model_port );
419
+
420
+ /* Not an equivalent port, so no need to do fixup */
421
+ if (atom_pbg_pin->port ->equivalent != PortEquivalence::FULL) {
422
+ continue ;
423
+ }
424
+
422
425
for (AtomPinId atom_pin : atom_ctx.netlist ().port_pins (atom_port)) {
423
426
/* Match net IDs from pb_route and atom netlist and connect in lookup */
424
427
if (pb_route.atom_net_id == atom_ctx.netlist ().pin_net (atom_pin)) {
0 commit comments