@@ -73,25 +73,26 @@ struct t_fc_override {
73
73
};
74
74
75
75
struct t_pin_counts {
76
- int total = 0 ;
77
76
int input = 0 ;
78
77
int output = 0 ;
79
78
int clock = 0 ;
80
79
81
- void sum () {
82
- total = input + output + clock ;
80
+ int total () {
81
+ return input + output + clock ;
83
82
}
84
83
};
85
84
86
- struct t_pin_loc {
85
+ struct t_pin_locs {
87
86
private:
87
+ // Distribution must be set once for each physical tile type
88
+ // and must be equal for each sub tile within a physical tile.
88
89
bool distribution_set = false ;
89
90
90
91
public:
91
92
enum e_pin_location_distr distribution = E_SPREAD_PIN_DISTR;
92
93
93
94
/* [0..num_sub_tiles-1][0..width-1][0..height-1][0..3][0..num_tokens-1] */
94
- std::vector <std::vector<std::vector<std::vector<std::vector<std:: string>>>> > assignments;
95
+ vtr::NdMatrix <std::vector<std::string>, 4 > assignments;
95
96
96
97
bool is_distribution_set () {
97
98
return distribution_set;
@@ -113,7 +114,7 @@ static void SetupPinClasses(t_physical_tile_type* PhysicalTileType);
113
114
114
115
static void LoadPinLoc (pugi::xml_node Locations,
115
116
t_physical_tile_type* type,
116
- t_pin_loc* pin_loc ,
117
+ t_pin_locs* pin_locs ,
117
118
const pugiutil::loc_data& loc_data);
118
119
template <typename T>
119
120
static std::pair<int , int > ProcessPinString (pugi::xml_node Locations,
@@ -160,7 +161,7 @@ static void ProcessEquivalentSiteCustomConnection(pugi::xml_node Parent,
160
161
static void ProcessPinLocations (pugi::xml_node Locations,
161
162
t_physical_tile_type* PhysicalTileType,
162
163
t_sub_tile* SubTile,
163
- t_pin_loc* pin_loc ,
164
+ t_pin_locs* pin_locs ,
164
165
const pugiutil::loc_data& loc_data);
165
166
static void ProcessSubTiles (pugi::xml_node Node,
166
167
t_physical_tile_type* PhysicalTileType,
@@ -480,8 +481,9 @@ static void SetupPinClasses(t_physical_tile_type* PhysicalTileType) {
480
481
pin_count = 0 ;
481
482
482
483
/* Equivalent pins share the same class, non-equivalent pins belong to different pin classes */
483
- for (const auto & sub_tile : PhysicalTileType->sub_tiles ) {
484
- for (i = 0 ; i < sub_tile.capacity ; ++i) {
484
+ for (auto & sub_tile : PhysicalTileType->sub_tiles ) {
485
+ int capacity = sub_tile.capacity .total ();
486
+ for (i = 0 ; i < capacity; ++i) {
485
487
for (const auto & port : sub_tile.ports ) {
486
488
if (port.equivalent != PortEquivalence::NONE) {
487
489
t_class class_inf;
@@ -544,13 +546,13 @@ static void SetupPinClasses(t_physical_tile_type* PhysicalTileType) {
544
546
545
547
static void LoadPinLoc (pugi::xml_node Locations,
546
548
t_physical_tile_type* type,
547
- t_pin_loc* pin_loc ,
549
+ t_pin_locs* pin_locs ,
548
550
const pugiutil::loc_data& loc_data) {
549
551
type->pin_width_offset .resize (type->num_pins , 0 );
550
552
type->pin_height_offset .resize (type->num_pins , 0 );
551
553
552
554
std::vector<int > physical_pin_counts (type->num_pins , 0 );
553
- if (pin_loc ->distribution == E_SPREAD_PIN_DISTR) {
555
+ if (pin_locs ->distribution == E_SPREAD_PIN_DISTR) {
554
556
/* evenly distribute pins starting at bottom left corner */
555
557
556
558
int num_sides = 4 * (type->width * type->height );
@@ -575,7 +577,7 @@ static void LoadPinLoc(pugi::xml_node Locations,
575
577
}
576
578
VTR_ASSERT (side_index == num_sides);
577
579
VTR_ASSERT (count == type->num_pins );
578
- } else if (pin_loc ->distribution == E_PERIMETER_PIN_DISTR) {
580
+ } else if (pin_locs ->distribution == E_PERIMETER_PIN_DISTR) {
579
581
// Add one pin at-a-time to perimeter sides in round-robin order
580
582
int ipin = 0 ;
581
583
while (ipin < type->num_pins ) {
@@ -601,7 +603,7 @@ static void LoadPinLoc(pugi::xml_node Locations,
601
603
}
602
604
VTR_ASSERT (ipin == type->num_pins );
603
605
604
- } else if (pin_loc ->distribution == E_SPREAD_INPUTS_PERIMETER_OUTPUTS_PIN_DISTR) {
606
+ } else if (pin_locs ->distribution == E_SPREAD_INPUTS_PERIMETER_OUTPUTS_PIN_DISTR) {
605
607
// Collect the sets of block input/output pins
606
608
std::vector<int > input_pins;
607
609
std::vector<int > output_pins;
@@ -668,23 +670,24 @@ static void LoadPinLoc(pugi::xml_node Locations,
668
670
VTR_ASSERT (ipin == output_pins.size ());
669
671
670
672
} else {
671
- VTR_ASSERT (pin_loc ->distribution == E_CUSTOM_PIN_DISTR);
673
+ VTR_ASSERT (pin_locs ->distribution == E_CUSTOM_PIN_DISTR);
672
674
for (auto & sub_tile : type->sub_tiles ) {
673
675
int sub_tile_index = sub_tile.index ;
676
+ int sub_tile_capacity = sub_tile.capacity .total ();
674
677
675
678
for (int width = 0 ; width < type->width ; ++width) {
676
679
for (int height = 0 ; height < type->height ; ++height) {
677
680
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
678
- for (auto token : pin_loc ->assignments [sub_tile_index][width][height][side]) {
681
+ for (auto token : pin_locs ->assignments [sub_tile_index][width][height][side]) {
679
682
auto pin_range = ProcessPinString<t_sub_tile*>(Locations,
680
683
&sub_tile,
681
684
token.c_str (),
682
685
loc_data);
683
686
684
687
for (int pin_num = pin_range.first ; pin_num < pin_range.second ; ++pin_num) {
685
- VTR_ASSERT (pin_num < (int )sub_tile.sub_tile_to_tile_pin_indices .size () / sub_tile. capacity );
686
- for (int capacity = 0 ; capacity < sub_tile. capacity ; ++capacity) {
687
- int sub_tile_pin_index = pin_num + capacity * type->num_pins / sub_tile. capacity ;
688
+ VTR_ASSERT (pin_num < (int )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 ;
688
691
int physical_pin_index = sub_tile.sub_tile_to_tile_pin_indices [sub_tile_pin_index];
689
692
type->pinloc [width][height][side][physical_pin_index] = true ;
690
693
type->pin_width_offset [physical_pin_index] += width;
@@ -1930,9 +1933,9 @@ static void Process_Fc(pugi::xml_node Node,
1930
1933
1931
1934
/* Go through all the port/segment combinations and create the (potentially
1932
1935
* overriden) pin/seg Fc specifications */
1933
- int pins_per_capacity_instance = pin_counts.total / SubTile->capacity ;
1936
+ int pins_per_capacity_instance = pin_counts.total () / SubTile->capacity . total () ;
1934
1937
for (size_t iseg = 0 ; iseg < segments.size (); ++iseg) {
1935
- for (int icapacity = 0 ; icapacity < SubTile->capacity ; ++icapacity) {
1938
+ for (int icapacity = 0 ; icapacity < SubTile->capacity . total () ; ++icapacity) {
1936
1939
// If capacity > 0, we need t offset the block index by the number of pins per instance
1937
1940
// this ensures that all pins have an Fc specification
1938
1941
int iblk_pin = icapacity * pins_per_capacity_instance;
@@ -3003,8 +3006,6 @@ static t_pin_counts ProcessSubTilePorts(pugi::xml_node Parent,
3003
3006
}
3004
3007
}
3005
3008
3006
- pin_counts.sum ();
3007
-
3008
3009
return pin_counts;
3009
3010
}
3010
3011
@@ -3124,7 +3125,7 @@ static void ProcessEquivalentSiteDirectConnection(pugi::xml_node Parent,
3124
3125
t_physical_tile_type* PhysicalTileType,
3125
3126
t_logical_block_type* LogicalBlockType,
3126
3127
const pugiutil::loc_data& loc_data) {
3127
- int num_pins = (int )SubTile->sub_tile_to_tile_pin_indices .size () / SubTile->capacity ;
3128
+ int num_pins = (int )SubTile->sub_tile_to_tile_pin_indices .size () / SubTile->capacity . total () ;
3128
3129
3129
3130
if (num_pins != LogicalBlockType->pb_type ->num_pins ) {
3130
3131
archfpga_throw (loc_data.filename_c_str (), loc_data.line (Parent),
@@ -3207,7 +3208,7 @@ static void ProcessEquivalentSiteCustomConnection(pugi::xml_node Parent,
3207
3208
static void ProcessPinLocations (pugi::xml_node Locations,
3208
3209
t_physical_tile_type* PhysicalTileType,
3209
3210
t_sub_tile* SubTile,
3210
- t_pin_loc* pin_loc ,
3211
+ t_pin_locs* pin_locs ,
3211
3212
const pugiutil::loc_data& loc_data) {
3212
3213
pugi::xml_node Cur;
3213
3214
const char * Prop;
@@ -3233,16 +3234,16 @@ static void ProcessPinLocations(pugi::xml_node Locations,
3233
3234
distribution = E_SPREAD_PIN_DISTR;
3234
3235
}
3235
3236
3236
- if (pin_loc ->is_distribution_set ()) {
3237
- if (pin_loc ->distribution != distribution) {
3237
+ if (pin_locs ->is_distribution_set ()) {
3238
+ if (pin_locs ->distribution != distribution) {
3238
3239
archfpga_throw (loc_data.filename_c_str (), loc_data.line (Locations),
3239
3240
" Sub Tile %s has a different pin location pattern (%s) with respect "
3240
3241
" to the sibling sub tiles" ,
3241
3242
SubTile->name , Prop);
3242
3243
}
3243
3244
} else {
3244
- pin_loc ->distribution = distribution;
3245
- pin_loc ->set_distribution ();
3245
+ pin_locs ->distribution = distribution;
3246
+ pin_locs ->set_distribution ();
3246
3247
}
3247
3248
3248
3249
int sub_tile_index = SubTile->index ;
@@ -3303,7 +3304,7 @@ static void ProcessPinLocations(pugi::xml_node Locations,
3303
3304
if (Count > 0 ) {
3304
3305
for (int pin = 0 ; pin < Count; ++pin) {
3305
3306
/* Store location assignment */
3306
- pin_loc ->assignments [sub_tile_index][x_offset][y_offset][side].push_back (std::string (Tokens[pin].c_str ()));
3307
+ pin_locs ->assignments [sub_tile_index][x_offset][y_offset][side].push_back (std::string (Tokens[pin].c_str ()));
3307
3308
3308
3309
/* Advance through list of pins in this location */
3309
3310
}
@@ -3318,7 +3319,7 @@ static void ProcessPinLocations(pugi::xml_node Locations,
3318
3319
for (int w = 0 ; w < PhysicalTileType->width ; ++w) {
3319
3320
for (int h = 0 ; h < PhysicalTileType->height ; ++h) {
3320
3321
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
3321
- for (auto token : pin_loc ->assignments [sub_tile_index][w][h][side]) {
3322
+ for (auto token : pin_locs ->assignments [sub_tile_index][w][h][side]) {
3322
3323
InstPort inst_port (token.c_str ());
3323
3324
3324
3325
// A pin specification should contain only the block name, and not any instace count information
@@ -3398,24 +3399,15 @@ static void ProcessSubTiles(pugi::xml_node Node,
3398
3399
pugi::xml_node Cur;
3399
3400
int index = 0 ;
3400
3401
3401
- int num_sub_tiles = count_children (Node, " sub_tile" , loc_data);
3402
- int width = PhysicalTileType->width ;
3403
- int height = PhysicalTileType->height ;
3404
- int num_sides = 4 ;
3402
+ unsigned long int num_sub_tiles = count_children (Node, " sub_tile" , loc_data);
3403
+ unsigned long int width = PhysicalTileType->width ;
3404
+ unsigned long int height = PhysicalTileType->height ;
3405
+ unsigned long int num_sides = 4 ;
3405
3406
3406
3407
std::map<std::string, int > sub_tile_names;
3407
3408
3408
- t_pin_loc pin_loc;
3409
- pin_loc.assignments .resize (num_sub_tiles);
3410
- for (int isub_tile = 0 ; isub_tile < num_sub_tiles; isub_tile++) {
3411
- pin_loc.assignments [isub_tile].resize (width);
3412
- for (int iwidth = 0 ; iwidth < width; iwidth++) {
3413
- pin_loc.assignments [isub_tile][iwidth].resize (height);
3414
- for (int iheight = 0 ; iheight < height; iheight++) {
3415
- pin_loc.assignments [isub_tile][iwidth][iheight].resize (num_sides);
3416
- }
3417
- }
3418
- }
3409
+ t_pin_locs pin_locs;
3410
+ pin_locs.assignments .resize ({num_sub_tiles, width, height, num_sides});
3419
3411
3420
3412
if (num_sub_tiles == 0 ) {
3421
3413
archfpga_throw (loc_data.filename_c_str (), loc_data.line (Node),
@@ -3448,7 +3440,7 @@ static void ProcessSubTiles(pugi::xml_node Node,
3448
3440
3449
3441
/* Load properties */
3450
3442
unsigned int capacity = get_attribute (CurSubTile, " capacity" , loc_data, ReqOpt::OPTIONAL).as_uint (1 );
3451
- SubTile.capacity = capacity;
3443
+ SubTile.capacity . set (PhysicalTileType-> capacity , capacity - 1 ) ;
3452
3444
PhysicalTileType->capacity += capacity;
3453
3445
3454
3446
/* Process sub tile port definitions */
@@ -3457,22 +3449,24 @@ static void ProcessSubTiles(pugi::xml_node Node,
3457
3449
/* Map Sub Tile physical pins with the Physical Tile Type physical pins.
3458
3450
* This takes into account the capacity of each sub tiles to add the correct offset.
3459
3451
*/
3460
- for (int ipin = 0 ; ipin < (int )capacity * pin_counts.total ; ipin++) {
3452
+ for (int ipin = 0 ; ipin < (int )capacity * pin_counts.total () ; ipin++) {
3461
3453
SubTile.sub_tile_to_tile_pin_indices .push_back (PhysicalTileType->num_pins + ipin);
3462
3454
}
3463
3455
3456
+ SubTile.num_phy_pins = pin_counts.total () * capacity;
3457
+
3464
3458
/* Assign pin counts to the Physical Tile Type */
3465
3459
PhysicalTileType->num_input_pins += capacity * pin_counts.input ;
3466
3460
PhysicalTileType->num_output_pins += capacity * pin_counts.output ;
3467
3461
PhysicalTileType->num_clock_pins += capacity * pin_counts.clock ;
3468
- PhysicalTileType->num_pins += capacity * pin_counts.total ;
3462
+ PhysicalTileType->num_pins += capacity * pin_counts.total () ;
3469
3463
3470
3464
/* Assign drivers and receivers count to Physical Tile Type */
3471
3465
PhysicalTileType->num_receivers += capacity * pin_counts.input ;
3472
3466
PhysicalTileType->num_drivers += capacity * pin_counts.output ;
3473
3467
3474
3468
Cur = get_single_child (CurSubTile, " pinlocations" , loc_data, ReqOpt::OPTIONAL);
3475
- ProcessPinLocations (Cur, PhysicalTileType, &SubTile, &pin_loc , loc_data);
3469
+ ProcessPinLocations (Cur, PhysicalTileType, &SubTile, &pin_locs , loc_data);
3476
3470
3477
3471
/* Load Fc */
3478
3472
Cur = get_single_child (CurSubTile, " fc" , loc_data, ReqOpt::OPTIONAL);
@@ -3491,19 +3485,10 @@ static void ProcessSubTiles(pugi::xml_node Node,
3491
3485
3492
3486
// Initialize pinloc data structure.
3493
3487
int num_pins = PhysicalTileType->num_pins ;
3494
- PhysicalTileType->pinloc .resize (width);
3495
- for (int iwidth = 0 ; iwidth < width; iwidth++) {
3496
- PhysicalTileType->pinloc [iwidth].resize (height);
3497
- for (int iheight = 0 ; iheight < height; iheight++) {
3498
- PhysicalTileType->pinloc [iwidth][iheight].resize (num_sides);
3499
- for (int iside = 0 ; iside < num_sides; iside++) {
3500
- PhysicalTileType->pinloc [iwidth][iheight][iside].resize (num_pins);
3501
- }
3502
- }
3503
- }
3488
+ PhysicalTileType->pinloc .resize ({width, height, num_sides}, std::vector<bool >(num_pins, false ));
3504
3489
3505
3490
SetupPinClasses (PhysicalTileType);
3506
- LoadPinLoc (Cur, PhysicalTileType, &pin_loc , loc_data);
3491
+ LoadPinLoc (Cur, PhysicalTileType, &pin_locs , loc_data);
3507
3492
}
3508
3493
3509
3494
/* Takes in node pointing to <typelist> and loads all the
@@ -4969,6 +4954,7 @@ e_side string_to_side(std::string side_str) {
4969
4954
return side;
4970
4955
}
4971
4956
4957
+ // TODO: Correctly link the sub tiles with the correct logic tiles.
4972
4958
static void link_physical_logical_types (std::vector<t_physical_tile_type>& PhysicalTileTypes,
4973
4959
std::vector<t_logical_block_type>& LogicalBlockTypes) {
4974
4960
for (auto & physical_tile : PhysicalTileTypes) {
0 commit comments