@@ -427,6 +427,77 @@ static void SetupPinLocationsAndPinClasses(pugi::xml_node Locations,
427
427
}
428
428
Cur = Cur.next_sibling (Cur.name ());
429
429
}
430
+
431
+ // Verify that all top-level pins have had thier locations specified
432
+
433
+ // Count up all the specified pins
434
+ std::map<std::string,std::set<int >> port_pins_with_specified_locations;
435
+ for (int w = 0 ; w < Type->width ; ++w) {
436
+ for (int h = 0 ; h < Type->height ; ++h) {
437
+ for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
438
+ for (int itoken = 0 ; itoken < Type->num_pin_loc_assignments [w][h][side]; ++itoken) {
439
+ const char * pin_spec = Type->pin_loc_assignments [w][h][side][itoken];
440
+ InstPort inst_port (Type->pin_loc_assignments [w][h][side][itoken]);
441
+
442
+ // A pin specification should contain only the block name, and not any instace count information
443
+ if (inst_port.instance_low_index () != InstPort::UNSPECIFIED || inst_port.instance_high_index () != InstPort::UNSPECIFIED) {
444
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (Locations),
445
+ " Pin location specification '%s' should not contain an instance range (should only be the block name)" ,
446
+ pin_spec);
447
+ }
448
+
449
+ // Check that the block name matches
450
+ if (inst_port.instance_name () != Type->name ) {
451
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (Locations),
452
+ " Mismatched block name in pin location specification (expected '%s' was '%s')" ,
453
+ Type->name , inst_port.instance_name ().c_str ());
454
+ }
455
+
456
+ int pin_low_idx = inst_port.port_low_index ();
457
+ int pin_high_idx = inst_port.port_high_index ();
458
+
459
+ if (pin_low_idx == InstPort::UNSPECIFIED && pin_high_idx == InstPort::UNSPECIFIED) {
460
+ // Empty range, so full port
461
+
462
+ // Find the matching pb type to get the total number of pins
463
+ const t_port* port = nullptr ;
464
+ for (int iport = 0 ; iport < Type->pb_type ->num_ports ; ++iport) {
465
+ const t_port* tmp_port = &Type->pb_type ->ports [iport];
466
+ if (tmp_port->name == inst_port.port_name ()) {
467
+ port = tmp_port;
468
+ break ;
469
+ }
470
+ }
471
+ VTR_ASSERT (port);
472
+
473
+ pin_low_idx = 0 ;
474
+ pin_high_idx = port->num_pins - 1 ;
475
+ }
476
+ VTR_ASSERT (pin_low_idx >= 0 );
477
+ VTR_ASSERT (pin_high_idx >= 0 );
478
+
479
+ for (int ipin = pin_low_idx; ipin <= pin_high_idx; ++ipin) {
480
+ // Record that the pin has it's location specified
481
+ port_pins_with_specified_locations[inst_port.port_name ()].insert (ipin);
482
+ }
483
+ }
484
+ }
485
+ }
486
+ }
487
+
488
+ // Check for any pins missing location specs
489
+ for (int iport = 0 ; iport < Type->pb_type ->num_ports ; ++iport) {
490
+ const t_port* port = &Type->pb_type ->ports [iport];
491
+
492
+ for (int ipin = 0 ; ipin < port->num_pins ; ++ipin) {
493
+ if (!port_pins_with_specified_locations[port->name ].count (ipin)) {
494
+ // Missing
495
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (Locations),
496
+ " Pin '%s.%s[%d]' has no pin location specificed with pin location pattern=\" custom\" " ,
497
+ Type->name , port->name , ipin);
498
+ }
499
+ }
500
+ }
430
501
}
431
502
432
503
/* Setup pin classes */
0 commit comments