23
23
#include " rr_graph.h"
24
24
#include " vtr_assert.h"
25
25
#include " vtr_util.h"
26
+ #include " vtr_time.h"
26
27
#include " tatum/echo_writer.hpp"
27
28
#include " vtr_log.h"
28
29
#include " check_route.h"
40
41
#include " echo_files.h"
41
42
#include " route_common.h"
42
43
#include " read_route.h"
44
+ #include " rr_graph2.h"
43
45
44
46
/* ************Functions local to this module*************/
45
- static void process_route (std::ifstream& fp, const char * filename, int & lineno);
46
- static void process_nodes (std::ifstream& fp, ClusterNetId inet, const char * filename, int & lineno);
47
- static void process_nets (std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char * filename, int & lineno);
47
+ static void process_route (std::ifstream& fp, const char * filename, int & lineno, const std::unordered_map< int , ClusterBlockId>& node_to_block );
48
+ static void process_nodes (std::ifstream& fp, ClusterNetId inet, const char * filename, int & lineno, const std::unordered_map< int , ClusterBlockId>& node_to_block );
49
+ static void process_nets (std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char * filename, int & lineno, const std::unordered_map< int , ClusterBlockId>& node_to_block );
48
50
static void process_global_blocks (std::ifstream& fp, ClusterNetId inet, const char * filename, int & lineno);
49
51
static void format_coordinates (int & x, int & y, std::string coord, ClusterNetId net, const char * filename, const int lineno);
50
52
static void format_pin_info (std::string& pb_name, std::string& port_name, int & pb_pin_num, std::string input);
53
+ static void build_cluster_block_map (std::unordered_map<int , ClusterBlockId>* node_to_block);
51
54
static std::string format_name (std::string name);
52
55
53
56
/* ************Global Functions****************************/
54
57
bool read_route (const char * route_file, const t_router_opts& router_opts, bool verify_file_digests) {
55
58
/* Reads in the routing file to fill in the trace.head and t_clb_opins_used data structure.
56
59
* Perform a series of verification tests to ensure the netlist, placement, and routing
57
60
* files match */
58
- auto & device_ctx = g_vpr_ctx.mutable_device ();
61
+ auto & device_ctx = g_vpr_ctx.device ();
59
62
auto & place_ctx = g_vpr_ctx.placement ();
60
63
/* Begin parsing the file */
61
64
VTR_LOG (" Begin loading FPGA routing file.\n " );
@@ -103,8 +106,12 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v
103
106
header[2 ].c_str (), header[4 ].c_str (), device_ctx.grid .width (), device_ctx.grid .height ());
104
107
}
105
108
109
+ // Build lookup from SOURCE/SINK node to ClusterBlockId.
110
+ std::unordered_map<int , ClusterBlockId> node_to_block;
111
+ build_cluster_block_map (&node_to_block);
112
+
106
113
/* Read in every net */
107
- process_route (fp, route_file, lineno);
114
+ process_route (fp, route_file, lineno, node_to_block );
108
115
109
116
fp.close ();
110
117
@@ -130,7 +137,7 @@ bool read_route(const char* route_file, const t_router_opts& router_opts, bool v
130
137
return is_feasible;
131
138
}
132
139
133
- static void process_route (std::ifstream& fp, const char * filename, int & lineno) {
140
+ static void process_route (std::ifstream& fp, const char * filename, int & lineno, const std::unordered_map< int , ClusterBlockId>& node_to_block ) {
134
141
/* Walks through every net and add the routing appropriately*/
135
142
std::string input;
136
143
std::vector<std::string> tokens;
@@ -144,16 +151,56 @@ static void process_route(std::ifstream& fp, const char* filename, int& lineno)
144
151
continue ; // Skip commented lines
145
152
} else if (tokens[0 ] == " Net" ) {
146
153
ClusterNetId inet (atoi (tokens[1 ].c_str ()));
147
- process_nets (fp, inet, tokens[2 ], tokens, filename, lineno);
154
+ process_nets (fp, inet, tokens[2 ], tokens, filename, lineno, node_to_block );
148
155
}
149
156
}
150
157
151
158
tokens.clear ();
152
159
}
153
160
154
- static void process_nets (std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char * filename, int & lineno) {
161
+ static void build_cluster_block_map (std::unordered_map<int , ClusterBlockId>* node_to_block) {
162
+ auto & cluster_ctx = g_vpr_ctx.clustering ();
163
+ auto & place_ctx = g_vpr_ctx.placement ();
164
+ auto & device_ctx = g_vpr_ctx.device ();
165
+
166
+ vtr::ScopedStartFinishTimer timer (" Building ClusterBlockId lookup" );
167
+
168
+ for (auto net_id : cluster_ctx.clb_nlist .nets ()) {
169
+ int pin_count = 0 ;
170
+ for (auto pin_id : cluster_ctx.clb_nlist .net_pins (net_id)) {
171
+ auto block_id = cluster_ctx.clb_nlist .pin_block (pin_id);
172
+
173
+ const auto * logical_tile = cluster_ctx.clb_nlist .block_type (block_id);
174
+ const auto * physical_tile = physical_tile_type (block_id);
175
+ VTR_ASSERT (block_id);
176
+ int i = place_ctx.block_locs [block_id].loc .x ;
177
+ int j = place_ctx.block_locs [block_id].loc .y ;
178
+
179
+ int logical_pin_index = cluster_ctx.clb_nlist .pin_logical_index (pin_id);
180
+ int physical_pin_index = get_physical_pin (
181
+ physical_tile, place_ctx.block_locs [block_id].loc .z ,
182
+ logical_tile, logical_pin_index);
183
+ int physical_pin_class = physical_tile->pin_class [physical_pin_index];
184
+ int class_inode = get_rr_node_index (device_ctx.rr_node_indices ,
185
+ i, j, (pin_count == 0 ? SOURCE : SINK), /* First pin is driver */
186
+ physical_pin_class);
187
+
188
+ auto result = node_to_block->insert (std::make_pair (class_inode, block_id));
189
+ if (!result.second && result.first ->second != block_id) {
190
+ VPR_FATAL_ERROR (VPR_ERROR_ROUTE,
191
+ " Clustered netlist has inconsistent rr node mapping, class rr node %d has two block ids %zu and %zu?" ,
192
+ class_inode, (size_t )block_id, result.first ->second );
193
+ }
194
+ pin_count++;
195
+ }
196
+ }
197
+
198
+ VTR_LOG (" ClusterBlockId lookup has %zu entries\n " , node_to_block->size ());
199
+ }
200
+
201
+ static void process_nets (std::ifstream& fp, ClusterNetId inet, std::string name, std::vector<std::string> input_tokens, const char * filename, int & lineno, const std::unordered_map<int , ClusterBlockId>& node_to_block) {
155
202
/* Check if the net is global or not, and process appropriately */
156
- auto & cluster_ctx = g_vpr_ctx.mutable_clustering ();
203
+ auto & cluster_ctx = g_vpr_ctx.clustering ();
157
204
158
205
if (input_tokens.size () > 3 && input_tokens[3 ] == " global"
159
206
&& input_tokens[4 ] == " net" && input_tokens[5 ] == " connecting:" ) {
@@ -187,19 +234,18 @@ static void process_nets(std::ifstream& fp, ClusterNetId inet, std::string name,
187
234
name.c_str (), size_t (inet), cluster_ctx.clb_nlist .net_name (inet).c_str ());
188
235
}
189
236
190
- process_nodes (fp, inet, filename, lineno);
237
+ process_nodes (fp, inet, filename, lineno, node_to_block );
191
238
}
192
239
input_tokens.clear ();
193
240
return ;
194
241
}
195
242
196
- static void process_nodes (std::ifstream& fp, ClusterNetId inet, const char * filename, int & lineno) {
243
+ static void process_nodes (std::ifstream& fp, ClusterNetId inet, const char * filename, int & lineno, const std::unordered_map< int , ClusterBlockId>& node_to_block ) {
197
244
/* Not a global net. Goes through every node and add it into trace.head*/
198
245
199
- auto & cluster_ctx = g_vpr_ctx.mutable_clustering ();
200
- auto & device_ctx = g_vpr_ctx.mutable_device ();
246
+ auto & cluster_ctx = g_vpr_ctx.clustering ();
247
+ auto & device_ctx = g_vpr_ctx.device ();
201
248
auto & route_ctx = g_vpr_ctx.mutable_routing ();
202
- auto & place_ctx = g_vpr_ctx.placement ();
203
249
204
250
t_trace* tptr = route_ctx.trace [inet].head ;
205
251
@@ -289,9 +335,22 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
289
335
if (tokens[6 + offset] != " Switch:" ) {
290
336
/* This is an opin or ipin, process its pin nums*/
291
337
if (!is_io_type (device_ctx.grid [x][y].type ) && (tokens[2 ] == " IPIN" || tokens[2 ] == " OPIN" )) {
338
+ // Convert this IPIN/OPIN back to class.
339
+ auto rr_type = device_ctx.rr_nodes [inode].type ();
340
+ VTR_ASSERT (rr_type == IPIN || rr_type == OPIN);
292
341
int pin_num = device_ctx.rr_nodes [inode].ptc_num ();
293
- int height_offset = device_ctx.grid [x][y].height_offset ;
294
- ClusterBlockId iblock = place_ctx.grid_blocks [x][y - height_offset].blocks [0 ];
342
+ int iclass = device_ctx.grid [x][y].type ->pin_class [pin_num];
343
+ int class_inode = get_rr_node_index (device_ctx.rr_node_indices ,
344
+ x, y, (rr_type == OPIN ? SOURCE : SINK), iclass);
345
+
346
+ auto itr = node_to_block.find (class_inode);
347
+ if (itr == node_to_block.end ()) {
348
+ vpr_throw (VPR_ERROR_ROUTE, filename, lineno,
349
+ " Class RR node %d does not have an associated ClusterBlockId?" , class_inode);
350
+ }
351
+
352
+ ClusterBlockId iblock = itr->second ;
353
+ VTR_ASSERT (iblock);
295
354
t_pb_graph_pin* pb_pin = get_pb_graph_node_pin_from_block_pin (iblock, pin_num);
296
355
t_pb_type* pb_type = pb_pin->parent_node ->pb_type ;
297
356
@@ -338,7 +397,7 @@ static void process_nodes(std::ifstream& fp, ClusterNetId inet, const char* file
338
397
/* This function goes through all the blocks in a global net and verify it with the
339
398
* clustered netlist and the placement */
340
399
static void process_global_blocks (std::ifstream& fp, ClusterNetId inet, const char * filename, int & lineno) {
341
- auto & cluster_ctx = g_vpr_ctx.mutable_clustering ();
400
+ auto & cluster_ctx = g_vpr_ctx.clustering ();
342
401
auto & place_ctx = g_vpr_ctx.placement ();
343
402
344
403
std::string block, bnum_str;
0 commit comments