Skip to content

Commit 681c32f

Browse files
committed
vpr: fix regression test issues related to heterogeneous tiles
There still are two regression tests which are not passing Signed-off-by: Alessandro Comodi <[email protected]>
1 parent 25125ff commit 681c32f

File tree

7 files changed

+108
-33
lines changed

7 files changed

+108
-33
lines changed

libs/libarchfpga/src/physical_types.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ struct t_equivalent_site;
5959
struct t_physical_tile_type;
6060
typedef const t_physical_tile_type* t_physical_tile_type_ptr;
6161
struct t_sub_tile;
62-
struct t_capacity_range;
6362
struct t_logical_block_type;
6463
typedef const t_logical_block_type* t_logical_block_type_ptr;
6564
struct t_logical_pin;
@@ -447,6 +446,12 @@ struct t_class {
447446
std::vector<int> pinlist; /* [0..num_pins - 1] */
448447
};
449448

449+
/* Struct to hold the class ranges for specific sub tiles */
450+
struct t_class_range {
451+
int low = 0;
452+
int high = 0;
453+
};
454+
450455
enum e_power_wire_type {
451456
POWER_WIRE_TYPE_UNDEFINED = 0,
452457
POWER_WIRE_TYPE_IGNORED,
@@ -636,11 +641,9 @@ struct t_physical_tile_type {
636641
* Totale TILE_X capacity is 17
637642
*/
638643
struct t_capacity_range {
639-
private:
640644
int low = 0;
641645
int high = 0;
642646

643-
public:
644647
void set(int low_cap, int high_cap) {
645648
low = low_cap;
646649
high = high_cap;
@@ -670,6 +673,7 @@ struct t_sub_tile {
670673
std::vector<t_logical_block_type_ptr> equivalent_sites;
671674

672675
t_capacity_range capacity;
676+
t_class_range class_range;
673677

674678
int num_phy_pins = 0;
675679

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -480,9 +480,13 @@ static void SetupPinClasses(t_physical_tile_type* PhysicalTileType) {
480480

481481
pin_count = 0;
482482

483+
t_class_range class_range;
484+
483485
/* Equivalent pins share the same class, non-equivalent pins belong to different pin classes */
484486
for (auto& sub_tile : PhysicalTileType->sub_tiles) {
485487
int capacity = sub_tile.capacity.total();
488+
class_range.low = PhysicalTileType->class_inf.size();
489+
class_range.high = class_range.low - 1;
486490
for (i = 0; i < capacity; ++i) {
487491
for (const auto& port : sub_tile.ports) {
488492
if (port.equivalent != PortEquivalence::NONE) {
@@ -511,12 +515,14 @@ static void SetupPinClasses(t_physical_tile_type* PhysicalTileType) {
511515
}
512516

513517
PhysicalTileType->class_inf.push_back(class_inf);
518+
class_range.high++;
514519
} else if (port.equivalent == PortEquivalence::NONE) {
515520
for (k = 0; k < port.num_pins; ++k) {
516521
t_class class_inf;
517522
num_class = (int)PhysicalTileType->class_inf.size();
518523
class_inf.num_pins = 1;
519524
class_inf.pinlist.push_back(pin_count);
525+
class_inf.equivalence = port.equivalent;
520526

521527
if (port.type == IN_PORT) {
522528
class_inf.type = RECEIVER;
@@ -535,10 +541,15 @@ static void SetupPinClasses(t_physical_tile_type* PhysicalTileType) {
535541
pin_count++;
536542

537543
PhysicalTileType->class_inf.push_back(class_inf);
544+
class_range.high++;
538545
}
539546
}
540547
}
541548
}
549+
550+
PhysicalTileType->sub_tiles[sub_tile.index].class_range = class_range;
551+
552+
VTR_LOG("PHYSICAL TILE: %s\n\tCAPACITY: %d\n\tCLASS RANGE: LOW %d, HIGH %d\n\n", PhysicalTileType->name, PhysicalTileType->capacity, PhysicalTileType->sub_tiles[sub_tile.index].class_range.low, PhysicalTileType->sub_tiles[sub_tile.index].class_range.high);
542553
}
543554

544555
VTR_ASSERT(pin_count == PhysicalTileType->num_pins);
@@ -1933,12 +1944,11 @@ static void Process_Fc(pugi::xml_node Node,
19331944

19341945
/* Go through all the port/segment combinations and create the (potentially
19351946
* overriden) pin/seg Fc specifications */
1936-
int pins_per_capacity_instance = pin_counts.total() / SubTile->capacity.total();
19371947
for (size_t iseg = 0; iseg < segments.size(); ++iseg) {
19381948
for (int icapacity = 0; icapacity < SubTile->capacity.total(); ++icapacity) {
19391949
//If capacity > 0, we need t offset the block index by the number of pins per instance
19401950
//this ensures that all pins have an Fc specification
1941-
int iblk_pin = icapacity * pins_per_capacity_instance;
1951+
int iblk_pin = icapacity * pin_counts.total();
19421952

19431953
for (const auto& port : SubTile->ports) {
19441954
t_fc_specification fc_spec;
@@ -2004,6 +2014,7 @@ static void Process_Fc(pugi::xml_node Node,
20042014
//XXX: this assumes that iterating through the tile ports
20052015
// in order yields the block pin order
20062016
int true_physical_blk_pin = SubTile->sub_tile_to_tile_pin_indices[iblk_pin];
2017+
VTR_LOG("PHYSICAL PIN: %d\n", true_physical_blk_pin);
20072018
fc_spec.pins.push_back(true_physical_blk_pin);
20082019
++iblk_pin;
20092020
}
@@ -3001,7 +3012,7 @@ static t_pin_counts ProcessSubTilePorts(pugi::xml_node Parent,
30013012
if (port.type == IN_PORT && port.is_clock == false) {
30023013
pin_counts.input += port.num_pins;
30033014
} else if (port.type == OUT_PORT) {
3004-
pin_counts.output = port.num_pins;
3015+
pin_counts.output += port.num_pins;
30053016
} else {
30063017
VTR_ASSERT(port.is_clock && port.type == IN_PORT);
30073018
pin_counts.clock += port.num_pins;
@@ -3440,7 +3451,7 @@ static void ProcessSubTiles(pugi::xml_node Node,
34403451
SubTile.name = name;
34413452

34423453
/* Load properties */
3443-
unsigned int capacity = get_attribute(CurSubTile, "capacity", loc_data, ReqOpt::OPTIONAL).as_uint(1);
3454+
int capacity = get_attribute(CurSubTile, "capacity", loc_data, ReqOpt::OPTIONAL).as_int(1);
34443455
SubTile.capacity.set(PhysicalTileType->capacity, capacity - 1);
34453456
PhysicalTileType->capacity += capacity;
34463457

@@ -3450,16 +3461,16 @@ static void ProcessSubTiles(pugi::xml_node Node,
34503461
/* Map Sub Tile physical pins with the Physical Tile Type physical pins.
34513462
* This takes into account the capacity of each sub tiles to add the correct offset.
34523463
*/
3453-
for (int ipin = 0; ipin < (int)capacity * pin_counts.total(); ipin++) {
3464+
for (int ipin = 0; ipin < capacity * pin_counts.total(); ipin++) {
34543465
SubTile.sub_tile_to_tile_pin_indices.push_back(PhysicalTileType->num_pins + ipin);
34553466
}
34563467

34573468
SubTile.num_phy_pins = pin_counts.total() * capacity;
34583469

34593470
/* Assign pin counts to the Physical Tile Type */
3460-
PhysicalTileType->num_input_pins += capacity * pin_counts.input;
3461-
PhysicalTileType->num_output_pins += capacity * pin_counts.output;
3462-
PhysicalTileType->num_clock_pins += capacity * pin_counts.clock;
3471+
PhysicalTileType->num_input_pins += pin_counts.input;
3472+
PhysicalTileType->num_output_pins += pin_counts.output;
3473+
PhysicalTileType->num_clock_pins += pin_counts.clock;
34633474
PhysicalTileType->num_pins += capacity * pin_counts.total();
34643475
PhysicalTileType->num_inst_pins += pin_counts.total();
34653476

vpr/src/base/read_place.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ void read_user_pad_loc(const char* pad_loc_file) {
250250

251251
auto physical_tile = device_ctx.grid[i][j].type;
252252
auto logical_block = cluster_ctx.clb_nlist.block_type(bnum);
253-
if (!is_tile_compatible(physical_tile, logical_block)) {
253+
if (!is_tile_compatible(physical_tile, logical_block, place_ctx.block_locs[bnum].loc)) {
254254
VPR_THROW(VPR_ERROR_PLACE_F, pad_loc_file, 0,
255255
"Attempt to place block %s at illegal location (%d, %d).\n", bname, i, j);
256256
}

vpr/src/place/move_utils.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,10 +436,13 @@ bool is_legal_swap_to_location(ClusterBlockId blk, t_pl_loc to) {
436436
auto& cluster_ctx = g_vpr_ctx.clustering();
437437
auto& place_ctx = g_vpr_ctx.placement();
438438

439+
auto physical_tile = device_ctx.grid[to.x][to.y].type;
440+
auto logical_block = cluster_ctx.clb_nlist.block_type(blk);
441+
439442
if (to.x < 0 || to.x >= int(device_ctx.grid.width())
440443
|| to.y < 0 || to.y >= int(device_ctx.grid.height())
441-
|| to.z < 0 || to.z >= device_ctx.grid[to.x][to.y].type->capacity
442-
|| !is_tile_compatible(device_ctx.grid[to.x][to.y].type, cluster_ctx.clb_nlist.block_type(blk))) {
444+
|| to.z < 0 || to.z >= physical_tile->capacity
445+
|| !is_tile_compatible(physical_tile, logical_block, to)) {
443446
return false;
444447
}
445448

vpr/src/route/route_common.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -838,16 +838,19 @@ static t_clb_opins_used alloc_and_load_clb_opins_used_locally() {
838838
* specifies that this is necessary). */
839839

840840
t_clb_opins_used clb_opins_used_locally;
841-
int clb_pin, iclass, class_low, class_high;
841+
int clb_pin, iclass;
842842

843843
auto& cluster_ctx = g_vpr_ctx.clustering();
844844

845845
clb_opins_used_locally.resize(cluster_ctx.clb_nlist.blocks().size());
846846

847847
for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
848848
auto type = physical_tile_type(blk_id);
849+
auto sub_tile = type->sub_tiles[get_sub_tile_index(blk_id)];
849850

851+
int class_low, class_high;
850852
get_class_range_for_block(blk_id, &class_low, &class_high);
853+
851854
clb_opins_used_locally[blk_id].resize((int)type->class_inf.size());
852855

853856
if (is_io_type(type)) continue;
@@ -1016,7 +1019,6 @@ static vtr::vector<ClusterBlockId, std::vector<int>> load_rr_clb_sources(const t
10161019
vtr::vector<ClusterBlockId, std::vector<int>> rr_blk_source;
10171020

10181021
int i, j, iclass, inode;
1019-
int class_low, class_high;
10201022
t_rr_type rr_type;
10211023

10221024
auto& cluster_ctx = g_vpr_ctx.clustering();
@@ -1026,7 +1028,11 @@ static vtr::vector<ClusterBlockId, std::vector<int>> load_rr_clb_sources(const t
10261028

10271029
for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
10281030
auto type = physical_tile_type(blk_id);
1031+
auto sub_tile = type->sub_tiles[get_sub_tile_index(blk_id)];
1032+
1033+
int class_low, class_high;
10291034
get_class_range_for_block(blk_id, &class_low, &class_high);
1035+
10301036
rr_blk_source[blk_id].resize((int)type->class_inf.size());
10311037
for (iclass = 0; iclass < (int)type->class_inf.size(); iclass++) {
10321038
if (iclass >= class_low && iclass <= class_high) {

vpr/src/util/vpr_utils.cpp

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ static t_pin_inst_port block_type_pin_index_to_pin_inst(t_physical_tile_type_ptr
225225
std::tie<int, int, int>(pin_index, inst_num, sub_tile_index) = get_pin_index_for_inst(type, pin_index);
226226

227227
t_pin_inst_port pin_inst_port;
228+
pin_inst_port.sub_tile_index = sub_tile_index;
228229
pin_inst_port.capacity_instance = inst_num;
229230
pin_inst_port.port_index = OPEN;
230231
pin_inst_port.pin_index_in_port = OPEN;
@@ -732,9 +733,16 @@ void get_class_range_for_block(const ClusterBlockId blk_id,
732733
auto& place_ctx = g_vpr_ctx.placement();
733734

734735
auto type = physical_tile_type(blk_id);
735-
VTR_ASSERT((int)type->class_inf.size() % type->capacity == 0);
736-
*class_low = place_ctx.block_locs[blk_id].loc.z * ((int)type->class_inf.size() / type->capacity);
737-
*class_high = (place_ctx.block_locs[blk_id].loc.z + 1) * ((int)type->class_inf.size() / type->capacity) - 1;
736+
auto sub_tile = type->sub_tiles[get_sub_tile_index(blk_id)];
737+
int sub_tile_capacity = sub_tile.capacity.total();
738+
auto class_range = sub_tile.class_range;
739+
int class_range_total = class_range.high - class_range.low + 1;
740+
741+
VTR_ASSERT((class_range_total) % sub_tile_capacity == 0);
742+
int rel_capacity = place_ctx.block_locs[blk_id].loc.z - sub_tile.capacity.low;
743+
744+
*class_low = rel_capacity * (class_range_total / sub_tile_capacity) + class_range.low;
745+
*class_high = (rel_capacity + 1) * (class_range_total / sub_tile_capacity) - 1 + class_range.low;
738746
}
739747

740748
void get_pin_range_for_block(const ClusterBlockId blk_id,
@@ -744,9 +752,16 @@ void get_pin_range_for_block(const ClusterBlockId blk_id,
744752
auto& place_ctx = g_vpr_ctx.placement();
745753

746754
auto type = physical_tile_type(blk_id);
747-
VTR_ASSERT(type->num_pins % type->capacity == 0);
748-
*pin_low = place_ctx.block_locs[blk_id].loc.z * (type->num_pins / type->capacity);
749-
*pin_high = (place_ctx.block_locs[blk_id].loc.z + 1) * (type->num_pins / type->capacity) - 1;
755+
auto sub_tile = type->sub_tiles[get_sub_tile_index(blk_id)];
756+
int sub_tile_capacity = sub_tile.capacity.total();
757+
758+
VTR_ASSERT(sub_tile.num_phy_pins % sub_tile_capacity == 0);
759+
int rel_capacity = place_ctx.block_locs[blk_id].loc.z - sub_tile.capacity.low;
760+
int rel_pin_low = rel_capacity * (sub_tile.num_phy_pins / sub_tile_capacity);
761+
int rel_pin_high = (rel_capacity + 1) * (sub_tile.num_phy_pins / sub_tile_capacity) - 1;
762+
763+
*pin_low = sub_tile.sub_tile_to_tile_pin_indices[rel_pin_low];
764+
*pin_high = sub_tile.sub_tile_to_tile_pin_indices[rel_pin_high];
750765
}
751766

752767
t_physical_tile_type_ptr find_tile_type_by_name(std::string name, const std::vector<t_physical_tile_type>& types) {
@@ -857,7 +872,7 @@ InstPort parse_inst_port(std::string str) {
857872
VPR_FATAL_ERROR(VPR_ERROR_ARCH, "Failed to find block type named %s", inst_port.instance_name().c_str());
858873
}
859874

860-
int num_pins = find_tile_port_by_name(blk_type, inst_port.instance_name().c_str()).num_pins;
875+
int num_pins = find_tile_port_by_name(blk_type, inst_port.port_name().c_str()).num_pins;
861876

862877
if (num_pins == OPEN) {
863878
VPR_FATAL_ERROR(VPR_ERROR_ARCH, "Failed to find port %s on block type %s", inst_port.port_name().c_str(), inst_port.instance_name().c_str());
@@ -1621,18 +1636,21 @@ static void alloc_and_load_blk_pin_from_port_pin() {
16211636

16221637
/* Resize and initialize the values to OPEN (-1). */
16231638
int num_types = types.size();
1624-
f_blk_pin_from_port_pin.resize(device_ctx.physical_tile_types.size());
1639+
f_blk_pin_from_port_pin.resize(num_types);
16251640
for (int itype = 1; itype < num_types; itype++) {
16261641
int blk_pin_count = 0;
16271642
auto& type = types[itype];
16281643
int num_sub_tiles = type.sub_tiles.size();
16291644
f_blk_pin_from_port_pin[itype].resize(num_sub_tiles);
1630-
for (int isub_tile; isub_tile < num_sub_tiles; isub_tile++) {
1645+
for (int isub_tile = 0; isub_tile < num_sub_tiles; isub_tile++) {
16311646
int num_ports = type.sub_tiles[isub_tile].ports.size();
16321647
f_blk_pin_from_port_pin[itype][isub_tile].resize(num_ports);
16331648
for (int iport = 0; iport < num_ports; iport++) {
1634-
f_blk_pin_from_port_pin[itype][isub_tile][iport].push_back(blk_pin_count);
1635-
blk_pin_count++;
1649+
int num_pins = type.sub_tiles[isub_tile].ports[iport].num_pins;
1650+
for (int ipin = 0; ipin < num_pins; ipin++) {
1651+
f_blk_pin_from_port_pin[itype][isub_tile][iport].push_back(blk_pin_count);
1652+
blk_pin_count++;
1653+
}
16361654
}
16371655
}
16381656
}
@@ -2067,7 +2085,6 @@ void print_switch_usage() {
20672085
* }
20682086
*/
20692087

2070-
// TODO FIX THIS!
20712088
void place_sync_external_block_connections(ClusterBlockId iblk) {
20722089
auto& cluster_ctx = g_vpr_ctx.clustering();
20732090
auto& clb_nlist = cluster_ctx.clb_nlist;
@@ -2076,15 +2093,20 @@ void place_sync_external_block_connections(ClusterBlockId iblk) {
20762093
auto physical_tile = physical_tile_type(iblk);
20772094
auto logical_block = clb_nlist.block_type(iblk);
20782095

2079-
VTR_ASSERT(physical_tile->num_pins % physical_tile->capacity == 0);
2080-
int max_num_block_pins = physical_tile->num_pins / physical_tile->capacity;
2096+
int sub_tile_index = get_sub_tile_index(iblk);
2097+
auto sub_tile = physical_tile->sub_tiles[sub_tile_index];
2098+
2099+
VTR_ASSERT(sub_tile.num_phy_pins % sub_tile.capacity.total() == 0);
2100+
2101+
int max_num_block_pins = sub_tile.num_phy_pins / sub_tile.capacity.total();
2102+
int physical_pin_offset = get_physical_pin_offset(&sub_tile, physical_tile);
20812103
/* Logical location and physical location is offset by z * max_num_block_pins */
20822104

20832105
for (auto pin : clb_nlist.block_pins(iblk)) {
20842106
int logical_pin_index = clb_nlist.pin_logical_index(pin);
2085-
int physical_pin_index = get_physical_pin(physical_tile, logical_block, logical_pin_index);
2107+
int physical_pin_index = get_physical_pin(sub_tile_index, physical_tile, logical_block, logical_pin_index);
20862108

2087-
int new_physical_pin_index = physical_pin_index + place_ctx.block_locs[iblk].loc.z * max_num_block_pins;
2109+
int new_physical_pin_index = physical_pin_offset + physical_pin_index + place_ctx.block_locs[iblk].loc.z * max_num_block_pins;
20882110

20892111
auto result = place_ctx.physical_pins.find(pin);
20902112
if (result != place_ctx.physical_pins.end()) {
@@ -2121,6 +2143,18 @@ bool is_tile_compatible(t_physical_tile_type_ptr physical_tile, t_logical_block_
21212143
return std::find(equivalent_tiles.begin(), equivalent_tiles.end(), physical_tile) != equivalent_tiles.end();
21222144
}
21232145

2146+
bool is_tile_compatible(t_physical_tile_type_ptr physical_tile, t_logical_block_type_ptr logical_block, t_pl_loc loc) {
2147+
bool capacity_compatible = false;
2148+
for (auto& sub_tile : physical_tile->sub_tiles) {
2149+
if (sub_tile.capacity.is_in_range(loc.z)) {
2150+
capacity_compatible = true;
2151+
break;
2152+
}
2153+
}
2154+
2155+
return capacity_compatible && is_tile_compatible(physical_tile, logical_block);
2156+
}
2157+
21242158
/**
21252159
* This function returns the most common physical tile type given a logical block
21262160
*/
@@ -2215,6 +2249,17 @@ int get_physical_pin(t_physical_tile_type_ptr physical_tile,
22152249
return result->second.pin;
22162250
}
22172251

2252+
int get_physical_pin_offset(t_sub_tile* sub_tile,
2253+
t_physical_tile_type_ptr physical_tile) {
2254+
int offset = 0;
2255+
2256+
for (int isub_tile = 0; isub_tile < sub_tile->index; isub_tile++) {
2257+
offset += physical_tile->sub_tiles[isub_tile].num_phy_pins;
2258+
}
2259+
2260+
return offset;
2261+
}
2262+
22182263
int net_pin_to_tile_pin_index(const ClusterNetId net_id, int net_pin_index) {
22192264
auto& cluster_ctx = g_vpr_ctx.clustering();
22202265

vpr/src/util/vpr_utils.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ int get_sub_tile_index(ClusterBlockId blk);
3535

3636
int get_unique_pb_graph_node_id(const t_pb_graph_node* pb_graph_node);
3737

38-
void get_class_range_for_block(const ClusterBlockId blk_id, int* class_low, int* class_high);
38+
void get_class_range_for_block(const ClusterBlockId blk_id,
39+
int* class_low,
40+
int* class_high);
3941

4042
void get_pin_range_for_block(const ClusterBlockId blk_id,
4143
int* pin_low,
@@ -146,6 +148,8 @@ int get_max_num_pins(t_logical_block_type_ptr logical_block);
146148

147149
bool is_tile_compatible(t_physical_tile_type_ptr physical_tile, t_logical_block_type_ptr logical_block);
148150

151+
bool is_tile_compatible(t_physical_tile_type_ptr physical_tile, t_logical_block_type_ptr logical_block, t_pl_loc loc);
152+
149153
//Returns the physical tile type which 'best' matches logical_block
150154
t_physical_tile_type_ptr pick_best_physical_type(t_logical_block_type_ptr logical_block);
151155

@@ -166,6 +170,8 @@ int get_physical_pin(int sub_tile_index,
166170
t_physical_tile_type_ptr physical_tile,
167171
t_logical_block_type_ptr logical_block,
168172
int pin);
173+
int get_physical_pin_offset(t_sub_tile* sub_tile,
174+
t_physical_tile_type_ptr physical_tile);
169175

170176
//Returns the physical pin of the tile, related to the given ClusterNedId, and the net pin index
171177
int net_pin_to_tile_pin_index(const ClusterNetId net_id, int net_pin_index);

0 commit comments

Comments
 (0)