7
7
#include " fasm_utils.h"
8
8
#include " arch_util.h"
9
9
#include " rr_graph_writer.h"
10
+ #include " post_routing_pb_pin_fixup.h"
10
11
#include < sstream>
11
12
#include < fstream>
12
13
#include < regex>
@@ -168,6 +169,54 @@ TEST_CASE("match_lut_init", "[fasm]") {
168
169
CHECK (match_lut_init (" 16'b0000000011111111" , " 16'b0000111100001111" ));
169
170
}
170
171
172
+ std::string get_pin_feature (size_t inode) {
173
+ auto & device_ctx = g_vpr_ctx.device ();
174
+
175
+ // Get tile physical tile and the pin number
176
+ int ilow = device_ctx.rr_nodes [inode].xlow ();
177
+ int jlow = device_ctx.rr_nodes [inode].ylow ();
178
+ auto physical_tile = device_ctx.grid [ilow][jlow].type ;
179
+ int pin_num = device_ctx.rr_nodes [inode].ptc_num ();
180
+
181
+ // Get the sub tile (type, not instance)
182
+ const t_sub_tile* sub_tile_type = nullptr ;
183
+ int sub_tile_pin = -1 ;
184
+
185
+ for (auto & sub_tile : physical_tile->sub_tiles ) {
186
+ auto max_inst_pins = sub_tile.num_phy_pins / sub_tile.capacity .total ();
187
+ for (int pin = 0 ; pin < sub_tile.num_phy_pins ; pin++) {
188
+ if (sub_tile.sub_tile_to_tile_pin_indices [pin] == pin_num) {
189
+ sub_tile_type = &sub_tile;
190
+ sub_tile_pin = pin % max_inst_pins;
191
+ break ;
192
+ }
193
+ }
194
+
195
+ if (sub_tile_type != nullptr ) {
196
+ break ;
197
+ }
198
+ }
199
+
200
+ REQUIRE (sub_tile_type != nullptr );
201
+ REQUIRE (sub_tile_pin != -1 );
202
+
203
+ // Find the sub tile port and pin index
204
+ for (const auto & port : sub_tile_type->ports ) {
205
+ int pin_lo = port.absolute_first_pin_index ;
206
+ int pin_hi = pin_lo + port.num_pins ;
207
+
208
+ if (sub_tile_pin >= pin_lo && sub_tile_pin < pin_hi) {
209
+ int port_pin = sub_tile_pin - pin_lo;
210
+ fprintf (stderr, " %zu %s %d\n " , inode, port.name , port_pin);
211
+ return vtr::string_fmt (" PIN_%d_%d_%s_%s_%d" , ilow, jlow, sub_tile_type->name , port.name , port_pin);
212
+ }
213
+ }
214
+
215
+ // Pin not found
216
+ REQUIRE (false );
217
+ return std::string ();
218
+ }
219
+
171
220
TEST_CASE (" fasm_integration_test" , " [fasm]" ) {
172
221
{
173
222
t_vpr_setup vpr_setup;
@@ -193,6 +242,15 @@ TEST_CASE("fasm_integration_test", "[fasm]") {
193
242
auto switch_id = device_ctx.rr_nodes [inode].edge_switch (iedge);
194
243
auto value = vtr::string_fmt (" %d_%d_%zu" ,
195
244
inode, sink_inode, switch_id);
245
+
246
+ // Add additional features to edges that go to CLB.I[11:0] pins
247
+ // to correlate them with features of CLB input mux later.
248
+ auto sink_type = device_ctx.rr_nodes [sink_inode].type ();
249
+ if (sink_type == IPIN) {
250
+ auto pin_feature = get_pin_feature (sink_inode);
251
+ value = value + " \n " + pin_feature;
252
+ }
253
+
196
254
vpr::add_rr_edge_metadata (inode, sink_inode, switch_id,
197
255
vtr::string_view (" fasm_features" ), vtr::string_view (value.data (), value.size ()));
198
256
}
@@ -227,6 +285,17 @@ TEST_CASE("fasm_integration_test", "[fasm]") {
227
285
bool flow_succeeded = vpr_flow (vpr_setup, arch);
228
286
REQUIRE (flow_succeeded == true );
229
287
288
+ /* Sync netlist to the actual routing (necessary if there are block
289
+ ports with equivalent pins) */
290
+ if (flow_succeeded) {
291
+ sync_netlists_to_routing (g_vpr_ctx.device (),
292
+ g_vpr_ctx.mutable_atom (),
293
+ g_vpr_ctx.mutable_clustering (),
294
+ g_vpr_ctx.placement (),
295
+ g_vpr_ctx.routing (),
296
+ vpr_setup.PackerOpts .pack_verbosity > 2 );
297
+ }
298
+
230
299
std::stringstream fasm_string;
231
300
fasm::FasmWriterVisitor visitor (&arch.strings , fasm_string);
232
301
NetlistWalker nl_walker (visitor);
@@ -272,6 +341,8 @@ TEST_CASE("fasm_integration_test", "[fasm]") {
272
341
fasm_string.clear ();
273
342
fasm_string.seekg (0 );
274
343
344
+ std::set<std::string> xbar_features;
345
+ std::set<std::tuple<int , int , std::string, std::string, int >> routed_pins; // x, y, tile, port, pin
275
346
std::set<std::tuple<int , int , short >> routing_edges;
276
347
std::set<std::tuple<int , int >> occupied_locs;
277
348
bool found_lut5 = false ;
@@ -313,7 +384,21 @@ TEST_CASE("fasm_integration_test", "[fasm]") {
313
384
}
314
385
}
315
386
316
- if (line.find (" FLE" ) != std::string::npos) {
387
+ // A feature representing block pin used by the router
388
+ if (line.find (" PIN_" ) != std::string::npos) {
389
+ auto parts = vtr::split (line, " _" );
390
+ REQUIRE (parts.size () == 6 );
391
+
392
+ auto x = vtr::atoi (parts[1 ]);
393
+ auto y = vtr::atoi (parts[2 ]);
394
+ auto tile = parts[3 ];
395
+ auto port = parts[4 ];
396
+ auto pin = vtr::atoi (parts[5 ]);
397
+
398
+ routed_pins.insert (std::make_tuple (x, y, tile, port, pin));
399
+ }
400
+
401
+ else if (line.find (" FLE" ) != std::string::npos) {
317
402
318
403
// Check correlation with top-level prefixes with X coordinates
319
404
// as defined in the architecture
@@ -335,6 +420,11 @@ TEST_CASE("fasm_integration_test", "[fasm]") {
335
420
// Check presence of LOC prefix substitutions
336
421
CHECK_THAT (line, MatchesRegex (" .*X\\ d+Y\\ d+.*" ));
337
422
423
+ // Add to xbar features
424
+ if (line.find (" _XBAR_" ) != std::string::npos) {
425
+ xbar_features.insert (line);
426
+ }
427
+
338
428
// Extract loc from tag
339
429
std::smatch locMatch;
340
430
REQUIRE (std::regex_match (line, locMatch, std::regex (" .*X(\\ d+)Y(\\ d+).*" )));
@@ -472,6 +562,28 @@ TEST_CASE("fasm_integration_test", "[fasm]") {
472
562
}
473
563
}
474
564
565
+ // Verify CLB crossbar mux features against routed pin features.
566
+ for (const auto & xbar_feature : xbar_features) {
567
+
568
+ // Decompose the xbar feature - extract only the necessary information
569
+ // such as block location and pin index.
570
+ std::smatch m;
571
+ fprintf (stderr, " %s\n " , xbar_feature.c_str ());
572
+ auto res = std::regex_match (xbar_feature, m, std::regex (
573
+ " .*_X([0-9]+)Y([0-9]+)\\ .IN([0-9])_XBAR_I([0-9]+)$" ));
574
+ REQUIRE (res == true );
575
+
576
+ int x = vtr::atoi (m.str (1 ));
577
+ int y = vtr::atoi (m.str (2 ));
578
+ std::string mux = m.str (3 );
579
+ int pin = vtr::atoi (m.str (4 ));
580
+
581
+ // Check if there is a corresponding routed pin feature
582
+ auto pin_feature = std::make_tuple (x, y, std::string (" clb" ), std::string (" I" ), pin);
583
+ size_t count = routed_pins.count (pin_feature);
584
+ REQUIRE (count == 1 );
585
+ }
586
+
475
587
// Verify that all LUTs defined in the BLIF file ended up in fasm
476
588
CHECK (lut_defs.size () == 0 );
477
589
0 commit comments