1
- /* *******************************************************************
2
- * This file includes functions to fix up the pb pin mapping results
3
- * after routing optimization
4
- *******************************************************************/
5
- /* Headers from vtrutil library */
1
+ /* *
2
+ * @file sync_netlists_to_routing_flat.cpp
3
+ *
4
+ * @brief Implementation for \see sync_netlists_to_routing_flat().
5
+ */
6
+
6
7
#include " clustered_netlist_fwd.h"
7
8
#include " clustered_netlist_utils.h"
8
9
#include " logic_types.h"
20
21
21
22
#include " sync_netlists_to_routing_flat.h"
22
23
24
+ /* Static function decls (file-scope) */
25
+
26
+ /* * Get intra-cluster connections from a given RouteTree. Output <source, sink> pairs to \p out_connections . */
23
27
static void get_intra_cluster_connections (const RouteTree& tree, std::vector<std::pair<RRNodeId, RRNodeId>>& out_connections);
28
+
29
+ /* * Rudimentary intra-cluster router between two pb_graph pins.
30
+ * This is needed because the flat router compresses the RRG reducing singular paths into nodes.
31
+ * We need to unpack it to get valid packing results, which is the purpose of this simple BFS router.
32
+ * Outputs the path to the pb_routes field of \p out_pb . */
24
33
static void route_intra_cluster_conn (const t_pb_graph_pin* source_pin, const t_pb_graph_pin* sink_pin, AtomNetId net_id, t_pb* out_pb);
34
+
35
+ /* * Rebuild the pb.pb_routes struct for each cluster block from flat routing results.
36
+ * The pb_routes struct holds all intra-cluster routing. */
25
37
static void sync_pb_routes_to_routing (void );
38
+
39
+ /* * Rebuild ClusteredNetlist from flat routing results, since some nets can move in/out of a block after routing. */
26
40
static void sync_clustered_netlist_to_routing (void );
41
+
42
+ /* * Rebuild atom_lookup.atom_pin_pb_graph_pin and pb.atom_pin_bit_index from flat routing results.
43
+ * These contain mappings between the AtomNetlist and the physical pins, which are invalidated after flat routing due to changed pin rotations.
44
+ * (i.e. the primitive has equivalent input pins and flat routing used a different pin) */
27
45
static void fixup_atom_pb_graph_pin_mapping (void );
28
46
47
+
48
+ /* Function definitions */
49
+
50
+ /* * Is the clock net found in the routing results?
51
+ * (If not, clock_modeling is probably ideal and we should preserve clock routing while rebuilding.) */
52
+ inline bool is_clock_net_routed (void ){
53
+ auto & atom_ctx = g_vpr_ctx.atom ();
54
+ auto & route_ctx = g_vpr_ctx.routing ();
55
+
56
+ for (auto net_id: atom_ctx.nlist .nets ()){
57
+ auto & tree = route_ctx.route_trees [net_id];
58
+ if (!tree)
59
+ continue ;
60
+ if (route_ctx.is_clock_net [net_id]) /* Clock net has routing */
61
+ return true ;
62
+ }
63
+
64
+ return false ;
65
+ }
66
+
67
+ /* * Get the ClusterBlockId for a given RRNodeId. */
29
68
inline ClusterBlockId get_cluster_block_from_rr_node (RRNodeId inode){
30
69
auto & device_ctx = g_vpr_ctx.device ();
31
70
auto & place_ctx = g_vpr_ctx.placement ();
@@ -51,7 +90,6 @@ inline ClusterBlockId get_cluster_block_from_rr_node(RRNodeId inode){
51
90
return clb;
52
91
}
53
92
54
- /* Output all intra-cluster connections for a RouteTreeNode */
55
93
static void get_intra_cluster_connections (const RouteTree& tree, std::vector<std::pair<RRNodeId, RRNodeId>>& out_connections){
56
94
auto & rr_graph = g_vpr_ctx.device ().rr_graph ;
57
95
@@ -73,10 +111,6 @@ static void get_intra_cluster_connections(const RouteTree& tree, std::vector<std
73
111
}
74
112
}
75
113
76
- /* * Rudimentary intra-cluster router between two pb_graph pins.
77
- * Easier to use than the packer's router, but it assumes that there is only one path between the provided pins.
78
- * (which should be the case due to the flat router's RR graph compression)
79
- * Outputs the path to the given pb. */
80
114
static void route_intra_cluster_conn (const t_pb_graph_pin* source_pin, const t_pb_graph_pin* sink_pin, AtomNetId net_id, t_pb* out_pb){
81
115
std::unordered_set<const t_pb_graph_pin*> visited;
82
116
std::deque<const t_pb_graph_pin*> queue;
@@ -117,7 +151,7 @@ static void route_intra_cluster_conn(const t_pb_graph_pin* source_pin, const t_p
117
151
}
118
152
path.push_back (source_pin);
119
153
120
- /* Output the path into out_pb_routes (start from source) */
154
+ /* Output the path into out_pb, starting from source. This is where the pb_route is updated */
121
155
int prev_pin_id = -1 ;
122
156
for (auto it = path.rbegin (); it != path.rend (); ++it){
123
157
cur_pin = *it;
@@ -155,14 +189,17 @@ static void sync_pb_routes_to_routing(void){
155
189
auto & route_ctx = g_vpr_ctx.routing ();
156
190
auto & rr_graph = device_ctx.rr_graph ;
157
191
192
+ /* Was the clock net routed? */
193
+ bool clock_net_is_routed = is_clock_net_routed ();
194
+
158
195
/* Clear out existing pb_routes: they were made by the intra cluster router and are invalid now */
159
196
for (ClusterBlockId clb_blk_id : cluster_ctx.clb_nlist .blocks ()) {
160
- /* Only erase entries which are not associated with a clock net: the router doesn 't touch the clock nets
161
- * XXX: Assumes --clock_modeling ideal */
197
+ /* If we don't have routing for the clock net, don 't erase entries associated with a clock net.
198
+ * Otherwise we won't have data to rebuild them */
162
199
std::vector<int > pins_to_erase;
163
200
auto & pb_routes = cluster_ctx.clb_nlist .block_pb (clb_blk_id)->pb_route ;
164
201
for (auto & [pin, pb_route]: pb_routes){
165
- if (!route_ctx.is_clock_net [pb_route.atom_net_id ])
202
+ if (clock_net_is_routed || !route_ctx.is_clock_net [pb_route.atom_net_id ])
166
203
pins_to_erase.push_back (pin);
167
204
}
168
205
@@ -221,8 +258,9 @@ static void sync_pb_routes_to_routing(void){
221
258
}
222
259
}
223
260
224
- /* * Rebuild the ClusterNetId <-> AtomNetId lookup after compressing the ClusterNetlist
225
- * Needs the "most recent" ClusterNetIds in atom_ctx.lookup: won't work after invalidating the ClusterNetIds twice */
261
+ /* * Rebuild the ClusterNetId <-> AtomNetId lookup after compressing the ClusterNetlist.
262
+ * Needs the old ClusterNetIds in atom_ctx.lookup. Won't work after calling compress() twice,
263
+ * since we won't have access to the old IDs in the IdRemapper anywhere. */
226
264
inline void rebuild_atom_nets_lookup (ClusteredNetlist::IdRemapper& remapped){
227
265
auto & atom_ctx = g_vpr_ctx.mutable_atom ();
228
266
auto & atom_lookup = atom_ctx.lookup ;
@@ -248,10 +286,14 @@ static void sync_clustered_netlist_to_routing(void){
248
286
auto & atom_ctx = g_vpr_ctx.mutable_atom ();
249
287
auto & atom_lookup = atom_ctx.lookup ;
250
288
251
- /* 1. Remove all nets, pins and ports from the clustered netlist (except clocks) */
289
+ bool clock_net_is_routed = is_clock_net_routed ();
290
+
291
+ /* 1. Remove all nets, pins and ports from the clustered netlist.
292
+ * If the clock net is not routed, don't remove entries for the clock net
293
+ * otherwise we won't have data to rebuild them. */
252
294
for (auto net_id: clb_netlist.nets ()){
253
295
auto atom_net_id = atom_lookup.atom_net (net_id);
254
- if (route_ctx.is_clock_net [atom_net_id])
296
+ if (!clock_net_is_routed && route_ctx.is_clock_net [atom_net_id])
255
297
continue ;
256
298
257
299
clb_netlist.remove_net (net_id);
@@ -260,14 +302,14 @@ static void sync_clustered_netlist_to_routing(void){
260
302
for (auto pin_id: clb_netlist.pins ()){
261
303
ClusterNetId clb_net_id = clb_netlist.pin_net (pin_id);
262
304
auto atom_net_id = atom_lookup.atom_net (clb_net_id);
263
- if (atom_net_id && route_ctx.is_clock_net [atom_net_id])
305
+ if (!clock_net_is_routed && atom_net_id && route_ctx.is_clock_net [atom_net_id])
264
306
continue ;
265
307
clb_netlist.remove_pin (pin_id);
266
308
}
267
309
for (auto port_id: clb_netlist.ports ()){
268
310
ClusterNetId clb_net_id = clb_netlist.port_net (port_id, 0 );
269
311
auto atom_net_id = atom_lookup.atom_net (clb_net_id);
270
- if (atom_net_id && route_ctx.is_clock_net [atom_net_id])
312
+ if (!clock_net_is_routed && atom_net_id && route_ctx.is_clock_net [atom_net_id])
271
313
continue ;
272
314
clb_netlist.remove_port (port_id);
273
315
}
@@ -346,7 +388,6 @@ static void sync_clustered_netlist_to_routing(void){
346
388
}
347
389
}
348
390
349
- /* * Fix up pin rotation maps and the atom pin -> pb graph pin lookup for every block */
350
391
static void fixup_atom_pb_graph_pin_mapping (void ){
351
392
auto & cluster_ctx = g_vpr_ctx.clustering ();
352
393
auto & atom_ctx = g_vpr_ctx.mutable_atom ();
0 commit comments