@@ -83,24 +83,21 @@ struct t_pin_counts {
83
83
}
84
84
};
85
85
86
- struct t_pin_loc_assignments {
87
- private bool pin_distribution_set = false ;
86
+ struct t_pin_loc {
87
+ private bool distribution_set = false ;
88
88
89
- enum e_pin_location_distr pin_location_distribution = E_SPREAD_PIN_DISTR;
89
+ enum e_pin_location_distr distribution = E_SPREAD_PIN_DISTR;
90
90
91
- /* [0..width-1][0..height-1][0..3] */
92
- std::vector<std::vector<std::vector<int >>> num_assignments ;
91
+ /* [0..num_sub_tiles-1][0.. width-1][0..height-1][0..3][0..num_tokens-1 ] */
92
+ std::vector<std::vector<std::vector<std::vector<std::vector<std::string >>>>> assignments ;
93
93
94
- /* [0..width-1][0..height-1][0..3][0..num_tokens-1][string_name] */
95
- std::vector<std::vector<std::vector<std::vector<std::string>>>> assignments;
96
-
97
- bool is_pin_distribution_set () {
98
- return pin_distribution_set;
94
+ bool is_distribution_set () {
95
+ return distribution_set;
99
96
}
100
97
101
- void set_pin_distribution () {
102
- VTR_ASSERT (pin_distribution_set == false );
103
- pin_distribution = true ;
98
+ void set_distribution () {
99
+ VTR_ASSERT (distribution_set == false );
100
+ distribution = true ;
104
101
}
105
102
106
103
};
@@ -111,12 +108,13 @@ static const char* arch_file_name = nullptr;
111
108
112
109
/* Function prototypes */
113
110
/* Populate data */
114
- static void SetupPinLocationsAndPinClasses (pugi::xml_node Locations,
115
- t_physical_tile_type* PhysicalTileType,
116
- const pugiutil::loc_data& loc_data);
111
+ static void SetupPinClasses (pugi::xml_node Locations,
112
+ t_physical_tile_type* PhysicalTileType,
113
+ const pugiutil::loc_data& loc_data);
117
114
118
115
static void LoadPinLoc (pugi::xml_node Locations,
119
116
t_physical_tile_type* type,
117
+ t_pin_loc* pin_loc,
120
118
const pugiutil::loc_data& loc_data);
121
119
template <typename T>
122
120
static std::pair<int , int > ProcessPinString (pugi::xml_node Locations,
@@ -160,7 +158,7 @@ static void ProcessEquivalentSiteCustomConnection(pugi::xml_node Parent,
160
158
static void ProcessPinLocations (pugi::xml_node Locations,
161
159
t_physical_tile_type* PhysicalTileType,
162
160
t_sub_tile* SubTile,
163
- t_pin_loc_assignments* pin_loc_assignments ,
161
+ t_pin_loc* pin_loc ,
164
162
const pugiutil::loc_data& loc_data);
165
163
static void ProcessSubTiles (pugi::xml_node Node,
166
164
t_physical_tile_type* PhysicalTileType
@@ -463,16 +461,14 @@ void XmlReadArch(const char* ArchFile,
463
461
*
464
462
*/
465
463
466
- /* Sets up the pinloc map and pin classes for the type.
467
- * Pins and pin classes must already be setup by SetupPinClasses */
468
- static void SetupPinLocationsAndPinClasses (pugi::xml_node Locations,
469
- t_physical_tile_type* PhysicalTileType,
470
- const pugiutil::loc_data& loc_data) {
464
+ /* Sets up the pin classes for the type. */
465
+ static void SetupPinClasses (pugi::xml_node Locations,
466
+ t_physical_tile_type* PhysicalTileType,
467
+ const pugiutil::loc_data& loc_data) {
471
468
int i, k, Count;
472
469
int capacity
473
470
int pin_count;
474
471
int num_class;
475
- const char * Prop;
476
472
477
473
pugi::xml_node Cur;
478
474
@@ -551,12 +547,13 @@ static void SetupPinLocationsAndPinClasses(pugi::xml_node Locations,
551
547
552
548
static void LoadPinLoc (pugi::xml_node Locations,
553
549
t_physical_tile_type* type,
550
+ t_pin_loc* pin_loc;
554
551
const pugiutil::loc_data& loc_data) {
555
552
type->pin_width_offset .resize (type->num_pins , 0 );
556
553
type->pin_height_offset .resize (type->num_pins , 0 );
557
554
558
555
std::vector<int > physical_pin_counts (type->num_pins , 0 );
559
- if (type-> pin_location_distribution == E_SPREAD_PIN_DISTR) {
556
+ if (pin_loc-> distribution == E_SPREAD_PIN_DISTR) {
560
557
/* evenly distribute pins starting at bottom left corner */
561
558
562
559
int num_sides = 4 * (type->width * type->height );
@@ -581,7 +578,7 @@ static void LoadPinLoc(pugi::xml_node Locations,
581
578
}
582
579
VTR_ASSERT (side_index == num_sides);
583
580
VTR_ASSERT (count == type->num_pins );
584
- } else if (type-> pin_location_distribution == E_PERIMETER_PIN_DISTR) {
581
+ } else if (pin_loc-> distribution == E_PERIMETER_PIN_DISTR) {
585
582
// Add one pin at-a-time to perimeter sides in round-robin order
586
583
int ipin = 0 ;
587
584
while (ipin < type->num_pins ) {
@@ -607,7 +604,7 @@ static void LoadPinLoc(pugi::xml_node Locations,
607
604
}
608
605
VTR_ASSERT (ipin == type->num_pins );
609
606
610
- } else if (type-> pin_location_distribution == E_SPREAD_INPUTS_PERIMETER_OUTPUTS_PIN_DISTR) {
607
+ } else if (pin_loc-> distribution == E_SPREAD_INPUTS_PERIMETER_OUTPUTS_PIN_DISTR) {
611
608
// Collect the sets of block input/output pins
612
609
std::vector<int > input_pins;
613
610
std::vector<int > output_pins;
@@ -675,22 +672,28 @@ static void LoadPinLoc(pugi::xml_node Locations,
675
672
676
673
} else {
677
674
VTR_ASSERT (type->pin_location_distribution == E_CUSTOM_PIN_DISTR);
678
- for (int width = 0 ; width < type->width ; ++width) {
679
- for (int height = 0 ; height < type->height ; ++height) {
680
- for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
681
- for (int pin = 0 ; pin < type->num_pin_loc_assignments [width][height][side]; ++pin) {
682
- auto pin_range = ProcessPinString<t_physical_tile_type_ptr>(Locations,
683
- type,
684
- type->pin_loc_assignments [width][height][side][pin],
685
- loc_data);
686
-
687
- for (int pin_num = pin_range.first ; pin_num < pin_range.second ; ++pin_num) {
688
- VTR_ASSERT (pin_num < type->num_pins / type->capacity );
689
- for (int capacity = 0 ; capacity < type->capacity ; ++capacity) {
690
- type->pinloc [width][height][side][pin_num + capacity * type->num_pins / type->capacity ] = true ;
691
- type->pin_width_offset [pin_num + capacity * type->num_pins / type->capacity ] += width;
692
- type->pin_height_offset [pin_num + capacity * type->num_pins / type->capacity ] += height;
693
- physical_pin_counts[pin_num + capacity * type->num_pins / type->capacity ] += 1 ;
675
+ for (const auto & sub_tile : PhysicalTileType->sub_tiles ) {
676
+ int sub_tile_index = sub_tile->index ;
677
+
678
+ for (int width = 0 ; width < type->width ; ++width) {
679
+ for (int height = 0 ; height < type->height ; ++height) {
680
+ for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
681
+ for (auto token : pin_loc->assignments [sub_tile_index][width][height][side]) {
682
+ auto pin_range = ProcessPinString<t_sub_tile>(Locations,
683
+ sub_tile,
684
+ token.c_str (),
685
+ loc_data);
686
+
687
+ for (int pin_num = pin_range.first ; pin_num < pin_range.second ; ++pin_num) {
688
+ VTR_ASSERT (pin_num < sub_tile->sub_tile_to_tile_pin_indices .size () / sub_tile->capacity );
689
+ for (int capacity = 0 ; capacity < sub_tile->capacity ; ++capacity) {
690
+ int sub_tile_pin_index = pin_num + capacity * type->num_pins / sub_tile->capacity ;
691
+ int physical_pin_index = sub_tile->sub_tile_to_tile_pin_indices [sub_tile_pin_index];
692
+ type->pinloc [width][height][side][physical_pin_index] = true ;
693
+ type->pin_width_offset [physical_pin_index] += width;
694
+ type->pin_height_offset [physical_pin_index] += height;
695
+ physical_pin_counts[physical_pin_index] += 1 ;
696
+ }
694
697
}
695
698
}
696
699
}
@@ -3203,31 +3206,47 @@ static void ProcessEquivalentSiteCustomConnection(pugi::xml_node Parent,
3203
3206
static void ProcessPinLocations (pugi::xml_node Locations,
3204
3207
t_physical_tile_type* PhysicalTileType,
3205
3208
t_sub_tile* SubTile,
3206
- t_pin_loc_assignments* pin_loc_assignments ,
3209
+ t_pin_loc* pin_loc ,
3207
3210
const pugiutil::loc_data& loc_data) {
3208
-
3209
3211
pugi::xml_node Cur;
3212
+ char * Prop;
3213
+ enum e_pin_location_distr distribution;
3210
3214
3211
3215
if (Locations) {
3212
3216
expect_only_attributes (Locations, {" pattern" }, loc_data);
3213
3217
3214
3218
Prop = get_attribute (Locations, " pattern" , loc_data).value ();
3215
3219
if (strcmp (Prop, " spread" ) == 0 ) {
3216
- PhysicalTileType-> pin_location_distribution = E_SPREAD_PIN_DISTR;
3220
+ distribution = E_SPREAD_PIN_DISTR;
3217
3221
} else if (strcmp (Prop, " perimeter" ) == 0 ) {
3218
- PhysicalTileType-> pin_location_distribution = E_PERIMETER_PIN_DISTR;
3222
+ distribution = E_PERIMETER_PIN_DISTR;
3219
3223
} else if (strcmp (Prop, " spread_inputs_perimeter_outputs" ) == 0 ) {
3220
- PhysicalTileType-> pin_location_distribution = E_SPREAD_INPUTS_PERIMETER_OUTPUTS_PIN_DISTR;
3224
+ distribution = E_SPREAD_INPUTS_PERIMETER_OUTPUTS_PIN_DISTR;
3221
3225
} else if (strcmp (Prop, " custom" ) == 0 ) {
3222
- PhysicalTileType-> pin_location_distribution = E_CUSTOM_PIN_DISTR;
3226
+ distribution = E_CUSTOM_PIN_DISTR;
3223
3227
} else {
3224
3228
archfpga_throw (loc_data.filename_c_str (), loc_data.line (Locations),
3225
3229
" %s is an invalid pin location pattern.\n " , Prop);
3226
3230
}
3231
+ } else {
3232
+ distribution = E_SPREAD_PIN_DISTR;
3233
+ }
3234
+
3235
+ if (pin_loc->is_pin_distribution_set ()) {
3236
+ if (pin_loc->distribution != distribution) {
3237
+ archfpga_throw (loc_data.filename_c_str (), loc_data.line (Locations),
3238
+ " Sub Tile %s has a different pin location pattern (%s) with respect "
3239
+ " to the sibling sub tiles" , SubTile->name , Prop);
3240
+ }
3241
+ } else {
3242
+ pin_loc->distribution = distribution;
3243
+ pin_loc->set_pin_distribution ();
3227
3244
}
3228
3245
3246
+ int sub_tile_index = SubTile->index ;
3247
+
3229
3248
/* Load the pin locations */
3230
- if (pin_location_distribution == E_CUSTOM_PIN_DISTR) {
3249
+ if (distribution == E_CUSTOM_PIN_DISTR) {
3231
3250
expect_only_children (Locations, {" loc" }, loc_data);
3232
3251
Cur = Locations.first_child ();
3233
3252
std::set<std::tuple<e_side, int , int >> seen_sides;
@@ -3279,12 +3298,10 @@ static void ProcessPinLocations(pugi::xml_node Locations,
3279
3298
/* Go through lists of pins */
3280
3299
const std::vector<std::string> Tokens = vtr::split (Cur.child_value ());
3281
3300
Count = Tokens.size ();
3282
- PhysicalTileType->num_pin_loc_assignments [x_offset][y_offset][side] = Count;
3283
3301
if (Count > 0 ) {
3284
- PhysicalTileType->pin_loc_assignments [x_offset][y_offset][side] = (char **)vtr::calloc (Count, sizeof (char *));
3285
3302
for (int pin = 0 ; pin < Count; ++pin) {
3286
3303
/* Store location assignment */
3287
- PhysicalTileType-> pin_loc_assignments [ x_offset][y_offset][side][pin] = vtr::strdup (Tokens[pin]. c_str ( ));
3304
+ pin_loc-> assignments [sub_tile_index][ x_offset][y_offset][side]. push_back ( vtr::strdup (Tokens[pin]));
3288
3305
3289
3306
/* Advance through list of pins in this location */
3290
3307
}
@@ -3299,9 +3316,8 @@ static void ProcessPinLocations(pugi::xml_node Locations,
3299
3316
for (int w = 0 ; w < PhysicalTileType->width ; ++w) {
3300
3317
for (int h = 0 ; h < PhysicalTileType->height ; ++h) {
3301
3318
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
3302
- for (int itoken = 0 ; itoken < PhysicalTileType->num_pin_loc_assignments [w][h][side]; ++itoken) {
3303
- const char * pin_spec = PhysicalTileType->pin_loc_assignments [w][h][side][itoken];
3304
- InstPort inst_port (PhysicalTileType->pin_loc_assignments [w][h][side][itoken]);
3319
+ for (auto token : pin_loc->assignments [sub_tile_index][w][h][side]) {
3320
+ InstPort inst_port (token.c_str ());
3305
3321
3306
3322
// A pin specification should contain only the block name, and not any instace count information
3307
3323
if (inst_port.instance_low_index () != InstPort::UNSPECIFIED || inst_port.instance_high_index () != InstPort::UNSPECIFIED) {
@@ -3325,7 +3341,7 @@ static void ProcessPinLocations(pugi::xml_node Locations,
3325
3341
3326
3342
// Find the matching pb type to get the total number of pins
3327
3343
const t_physical_tile_port* port = nullptr ;
3328
- for (const auto & tmp_port : PhysicalTileType ->ports ) {
3344
+ for (const auto & tmp_port : SubTile ->ports ) {
3329
3345
if (tmp_port.name == inst_port.port_name ()) {
3330
3346
port = &tmp_port;
3331
3347
break ;
@@ -3338,7 +3354,7 @@ static void ProcessPinLocations(pugi::xml_node Locations,
3338
3354
} else {
3339
3355
archfpga_throw (loc_data.filename_c_str (), loc_data.line (Locations),
3340
3356
" Failed to find port named '%s' on block '%s'" ,
3341
- inst_port.port_name ().c_str (), PhysicalTileType ->name );
3357
+ inst_port.port_name ().c_str (), SubTile ->name );
3342
3358
}
3343
3359
}
3344
3360
VTR_ASSERT (pin_low_idx >= 0 );
@@ -3354,21 +3370,20 @@ static void ProcessPinLocations(pugi::xml_node Locations,
3354
3370
}
3355
3371
3356
3372
// Check for any pins missing location specs
3357
- for (const auto & port : PhysicalTileType ->ports ) {
3373
+ for (const auto & port : SubTile ->ports ) {
3358
3374
for (int ipin = 0 ; ipin < port.num_pins ; ++ipin) {
3359
3375
if (!port_pins_with_specified_locations[port.name ].count (ipin)) {
3360
3376
// Missing
3361
3377
archfpga_throw (loc_data.filename_c_str (), loc_data.line (Locations),
3362
3378
" Pin '%s.%s[%d]' has no pin location specificed (a location is required for pattern=\" custom\" )" ,
3363
- PhysicalTileType ->name , port.name , ipin);
3379
+ SubTile ->name , port.name , ipin);
3364
3380
}
3365
3381
}
3366
3382
}
3367
3383
} else if (Locations) {
3368
3384
// Non-custom pin locations. There should be no child tags
3369
3385
expect_child_node_count (Locations, 0 , loc_data);
3370
3386
}
3371
-
3372
3387
}
3373
3388
3374
3389
static void ProcessSubTiles (pugi::xml_node Node,
@@ -3379,30 +3394,32 @@ static void ProcessSubTiles(pugi::xml_node Node,
3379
3394
const pugiutil::loc_data& loc_data) {
3380
3395
pugi::xml_node CurSubTile;
3381
3396
pugi::xml_node Cur;
3397
+ int index = 0 ;
3382
3398
3383
3399
int width = PhysicalTileType->width ;
3384
3400
int height = PhysicalTileType->height ;
3385
3401
int num_sides = 4 ;
3402
+ int num_sub_tiles = count_children (Node, " sub_tile" , loc_data);
3386
3403
3387
3404
std::map<std::string, int > sub_tile_names;
3388
3405
3389
- t_pin_loc_assignments pin_loc_assignments;
3390
-
3391
- pin_loc_assignments.num_assignments = std::vector (width, std::vector (height, std::vector (num_sides, 0 )))
3392
- pin_loc_assignments.assignments = std::vector (width, std::vector (height, std::vector (num_sides, 0 )))
3406
+ t_pin_loc pin_loc;
3407
+ pin_loc.assignments = std::vector (num_sub_tiles, std::vector (width, std::vector (height, std::vector (num_sides, 0 ))))
3393
3408
3394
- CurSubTile = get_single_child (Node, " sub_tile" , loc_data);
3395
-
3396
- if (!CurSubTile) {
3409
+ if (num_sub_tiles == 0 ) {
3397
3410
archfpga_throw (loc_data.filename_c_str (), loc_data.line (Node),
3398
3411
" No sub tile found for the Physical Tile %s.\n "
3399
3412
" At least one sub tile is needed to correctly describe the Physical Tile.\n " ,
3400
3413
PhysicalTileType->name )
3401
3414
}
3402
3415
3416
+ CurSubTile = get_single_child (Node, " sub_tile" , loc_data);
3417
+
3403
3418
while (CurSubTile) {
3404
3419
t_sub_tile SubTile;
3405
3420
3421
+ SubTile.index = index;
3422
+
3406
3423
expect_only_attributes (CurSubTile, {" name" , " capacity" }, loc_data);
3407
3424
3408
3425
/* Load type name */
@@ -3444,7 +3461,7 @@ static void ProcessSubTiles(pugi::xml_node Node,
3444
3461
PhysicalTileType->num_drivers += capacity * pin_counts.output ;
3445
3462
3446
3463
Cur = get_single_child (CurTileType, " pinlocations" , loc_data, ReqOpt::OPTIONAL);
3447
- ProcessPinLocations (Cur, PhysicalTileType, &SubTile, &pin_loc_assignments , loc_data);
3464
+ ProcessPinLocations (Cur, PhysicalTileType, &SubTile, &pin_loc , loc_data);
3448
3465
3449
3466
/* Load Fc */
3450
3467
Cur = get_single_child (CurTileType, " fc" , loc_data, ReqOpt::OPTIONAL);
@@ -3456,22 +3473,17 @@ static void ProcessSubTiles(pugi::xml_node Node,
3456
3473
3457
3474
PhysicalTileType->sub_tiles .push_back (SubTile);
3458
3475
3476
+ index++;
3477
+
3459
3478
CurSubTile = CurSubTile.next_sibling (CurSubTile.name ());
3460
3479
}
3461
3480
3462
3481
// Initialize pinloc data structure.
3463
3482
int num_pins = PhysicalTileType->num_pins ;
3464
3483
PhysicalTileType->pinloc = std::vector (width, std::vector (height, std::vector (num_sides, std::vector (num_pins, false ))));
3465
3484
3466
- SetupPinLocationsAndPinClasses (Cur, PhysicalTileType, loc_data);
3467
-
3468
- CurSubTile = get_single_child (Node, " sub_tile" , loc_data);
3469
-
3470
- while (CurSubTile) {
3471
- /* Load pin names and classes and locations */
3472
- Cur = get_single_child (CurTileType, " pinlocations" , loc_data, ReqOpt::OPTIONAL);
3473
- LoadPinLoc (Cur, PhysicalTileType, loc_data);
3474
- }
3485
+ SetupPinClasses (Cur, PhysicalTileType, loc_data);
3486
+ LoadPinLoc (Cur, PhysicalTileType, &pin_loc, loc_data);
3475
3487
}
3476
3488
3477
3489
/* Takes in node pointing to <typelist> and loads all the
0 commit comments