Skip to content

Commit 827170f

Browse files
authored
Merge pull request #1741 from verilog-to-routing/floorplan_constraints_tuning
Floorplan constraints tuning
2 parents 606b079 + 8c6dc01 commit 827170f

8 files changed

+62
-31
lines changed

vpr/src/base/gen/vpr_constraints_uxsdcxx.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@
2525
#include "pugixml.hpp"
2626

2727
#include "vpr_constraints_uxsdcxx_interface.h"
28-
29-
//sentinel value for indicating that a subtile has not been specified
30-
constexpr int NO_SUBTILE = -1;
28+
#include "region.h"
3129

3230
/* All uxsdcxx functions and structs live in this namespace. */
3331
namespace uxsd {

vpr/src/base/partition_region.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ std::vector<Region> PartitionRegion::get_partition_region() {
99
return partition_region;
1010
}
1111

12+
void PartitionRegion::set_partition_region(std::vector<Region> pr) {
13+
partition_region = pr;
14+
}
15+
1216
bool PartitionRegion::empty() {
1317
return partition_region.size() == 0;
1418
}
@@ -26,20 +30,18 @@ bool PartitionRegion::is_loc_in_part_reg(t_pl_loc loc) {
2630
return is_in_pr;
2731
}
2832

29-
PartitionRegion intersection(PartitionRegion& pr1, PartitionRegion& pr2) {
33+
PartitionRegion intersection(const PartitionRegion& cluster_pr, const PartitionRegion& new_pr) {
3034
/**for N regions in part_region and M in the calling object you can get anywhere from
3135
* 0 to M*N regions in the resulting vector. Only intersection regions with non-zero area rectangles and
3236
* equivalent subtiles are put in the resulting vector
3337
* Rectangles are not merged even if it would be possible
3438
*/
3539
PartitionRegion pr;
3640
Region intersect_region;
37-
bool regions_intersect;
38-
for (unsigned int i = 0; i < pr1.partition_region.size(); i++) {
39-
for (unsigned int j = 0; j < pr2.partition_region.size(); j++) {
40-
regions_intersect = do_regions_intersect(pr1.partition_region[i], pr2.partition_region[j]);
41-
if (regions_intersect) {
42-
intersect_region = intersection(pr1.partition_region[i], pr2.partition_region[j]);
41+
for (unsigned int i = 0; i < cluster_pr.partition_region.size(); i++) {
42+
for (unsigned int j = 0; j < new_pr.partition_region.size(); j++) {
43+
intersect_region = intersection(cluster_pr.partition_region[i], new_pr.partition_region[j]);
44+
if (!intersect_region.empty()) {
4345
pr.partition_region.push_back(intersect_region);
4446
}
4547
}
@@ -48,6 +50,20 @@ PartitionRegion intersection(PartitionRegion& pr1, PartitionRegion& pr2) {
4850
return pr;
4951
}
5052

53+
void update_cluster_part_reg(PartitionRegion& cluster_pr, const PartitionRegion& new_pr) {
54+
Region intersect_region;
55+
std::vector<Region> int_regions;
56+
for (unsigned int i = 0; i < cluster_pr.partition_region.size(); i++) {
57+
for (unsigned int j = 0; j < new_pr.partition_region.size(); j++) {
58+
intersect_region = intersection(cluster_pr.partition_region[i], new_pr.partition_region[j]);
59+
if (!intersect_region.empty()) {
60+
int_regions.push_back(intersect_region);
61+
}
62+
}
63+
}
64+
cluster_pr.set_partition_region(int_regions);
65+
}
66+
5167
void print_partition_region(FILE* fp, PartitionRegion pr) {
5268
std::vector<Region> part_region = pr.get_partition_region();
5369

vpr/src/base/partition_region.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ class PartitionRegion {
2727
*/
2828
std::vector<Region> get_partition_region();
2929

30+
/**
31+
* @brief Set the union of regions
32+
*/
33+
void set_partition_region(std::vector<Region> pr);
34+
3035
/**
3136
* @brief Check if the PartitionRegion is empty (meaning there is no constraint on the object the PartitionRegion belongs to)
3237
*/
@@ -43,10 +48,19 @@ class PartitionRegion {
4348
/**
4449
* @brief Global friend function that returns the intersection of two PartitionRegions
4550
*
46-
* @param pr1 One of the PartitionRegions to be intersected
47-
* @param pr2 One of the PartitionRegions to be intersected
51+
* @param cluster_pr One of the PartitionRegions to be intersected
52+
* @param new_pr One of the PartitionRegions to be intersected
53+
*/
54+
friend PartitionRegion intersection(const PartitionRegion& cluster_pr, const PartitionRegion& new_pr);
55+
56+
/**
57+
* @brief Global friend function that updates the PartitionRegion of a cluster with the intersection
58+
* of the cluster PartitionRegion and a new PartitionRegion
59+
*
60+
* @param cluster_pr The cluster PartitionRegion that is to be updated
61+
* @param new_pr The new PartitionRegion that the cluster PartitionRegion will be intersected with
4862
*/
49-
friend PartitionRegion intersection(PartitionRegion& pr1, PartitionRegion& pr2);
63+
friend void update_cluster_part_reg(PartitionRegion& cluster_pr, const PartitionRegion& new_pr);
5064

5165
private:
5266
std::vector<Region> partition_region; ///< union of rectangular regions that a partition can be placed in

vpr/src/base/region.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
#include "region.h"
22

3-
/// @brief sentinel value for indicating that a subtile has not been specified
4-
constexpr int NO_SUBTILE = -1;
5-
63
Region::Region() {
74
sub_tile = NO_SUBTILE;
85

@@ -14,7 +11,7 @@ Region::Region() {
1411
region_bounds.set_ymax(-1);
1512
}
1613

17-
vtr::Rect<int> Region::get_region_rect() {
14+
vtr::Rect<int> Region::get_region_rect() const {
1815
return region_bounds;
1916
}
2017

@@ -25,7 +22,7 @@ void Region::set_region_rect(int _xmin, int _ymin, int _xmax, int _ymax) {
2522
region_bounds.set_ymax(_ymax);
2623
}
2724

28-
int Region::get_sub_tile() {
25+
int Region::get_sub_tile() const {
2926
return sub_tile;
3027
}
3128

@@ -82,7 +79,7 @@ bool do_regions_intersect(Region r1, Region r2) {
8279
return intersect;
8380
}
8481

85-
Region intersection(Region r1, Region r2) {
82+
Region intersection(const Region& r1, const Region& r2) {
8683
Region intersect;
8784

8885
/**

vpr/src/base/region.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
*
1414
*/
1515

16+
/// @brief sentinel value for indicating that a subtile has not been specified
17+
constexpr int NO_SUBTILE = -1;
18+
1619
class Region {
1720
public:
1821
/**
@@ -23,7 +26,7 @@ class Region {
2326
/**
2427
* @brief Accessor for the region's rectangle
2528
*/
26-
vtr::Rect<int> get_region_rect();
29+
vtr::Rect<int> get_region_rect() const;
2730

2831
/**
2932
* @brief Mutator for the region's rectangle
@@ -33,7 +36,7 @@ class Region {
3336
/**
3437
* @brief Accessor for the region's subtile
3538
*/
36-
int get_sub_tile();
39+
int get_sub_tile() const;
3740

3841
/**
3942
* @brief Mutator for the region's subtile
@@ -84,7 +87,7 @@ bool do_regions_intersect(Region r1, Region r2);
8487
* @param r2 One of the regions to intersect
8588
*
8689
*/
87-
Region intersection(Region r1, Region r2);
90+
Region intersection(const Region& r1, const Region& r2);
8891

8992
///@brief Used to print data from a Region
9093
void print_region(FILE* fp, Region region);

vpr/src/pack/cluster.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,17 +1726,15 @@ static enum e_block_pack_status atom_cluster_floorplanning_check(const AtomBlock
17261726
PartitionRegion& temp_cluster_pr,
17271727
bool& cluster_pr_needs_update) {
17281728
auto& floorplanning_ctx = g_vpr_ctx.mutable_floorplanning();
1729-
VprConstraints ctx_constraints = floorplanning_ctx.constraints;
17301729

17311730
/*check if the atom can go in the cluster by checking if the atom and cluster have intersecting PartitionRegions*/
17321731

17331732
//get partition that atom belongs to
17341733
PartitionId partid;
1735-
partid = ctx_constraints.get_atom_partition(blk_id);
1734+
partid = floorplanning_ctx.constraints.get_atom_partition(blk_id);
17361735

17371736
PartitionRegion atom_pr;
17381737
PartitionRegion cluster_pr;
1739-
PartitionRegion intersect_pr;
17401738

17411739
//if the atom does not belong to a partition, it can be put in the cluster
17421740
//regardless of what the cluster's PartitionRegion is because it has no constraints
@@ -1748,7 +1746,7 @@ static enum e_block_pack_status atom_cluster_floorplanning_check(const AtomBlock
17481746
return BLK_PASSED;
17491747
} else {
17501748
//get pr of that partition
1751-
atom_pr = ctx_constraints.get_partition_pr(partid);
1749+
atom_pr = floorplanning_ctx.constraints.get_partition_pr(partid);
17521750

17531751
//intersect it with the pr of the current cluster
17541752
cluster_pr = floorplanning_ctx.cluster_constraints[clb_index];
@@ -1761,18 +1759,20 @@ static enum e_block_pack_status atom_cluster_floorplanning_check(const AtomBlock
17611759
}
17621760
return BLK_PASSED;
17631761
} else {
1764-
intersect_pr = intersection(cluster_pr, atom_pr);
1762+
//update cluster_pr with the intersection of the cluster's PartitionRegion
1763+
//and the atom's PartitionRegion
1764+
update_cluster_part_reg(cluster_pr, atom_pr);
17651765
}
17661766

1767-
if (intersect_pr.empty() == true) {
1767+
if (cluster_pr.empty() == true) {
17681768
if (verbosity > 3) {
17691769
VTR_LOG("\t\t\t Intersect: Atom block %d failed floorplanning check for cluster %d \n", blk_id, clb_index);
17701770
}
17711771
cluster_pr_needs_update = false;
17721772
return BLK_FAILED_FLOORPLANNING;
17731773
} else {
17741774
//update the cluster's PartitionRegion with the intersecting PartitionRegion
1775-
temp_cluster_pr = intersect_pr;
1775+
temp_cluster_pr = cluster_pr;
17761776
cluster_pr_needs_update = true;
17771777
if (verbosity > 3) {
17781778
VTR_LOG("\t\t\t Intersect: Atom block %d passed cluster %d, cluster PR was updated with intersection result \n", blk_id, clb_index);
@@ -2229,8 +2229,6 @@ static void start_new_cluster(t_cluster_placement_stats* cluster_placement_stats
22292229
auto& device_ctx = g_vpr_ctx.mutable_device();
22302230
auto& floorplanning_ctx = g_vpr_ctx.mutable_floorplanning();
22312231

2232-
VprConstraints ctx_constraints = floorplanning_ctx.constraints;
2233-
22342232
/*Cluster's PartitionRegion is empty initially, meaning it has no floorplanning constraints*/
22352233
PartitionRegion empty_pr;
22362234
floorplanning_ctx.cluster_constraints.push_back(empty_pr);

vpr/src/place/place_constraints.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ PartitionRegion constrained_macro_locs(const t_pl_macro& pl_macro) {
114114
}
115115

116116
/*returns true if location is compatible with floorplanning constraints, false if not*/
117+
/*
118+
* Even if the block passed in is from a macro, it will work because of the constraints
119+
* propagation that was done during initial placement.
120+
*/
117121
bool cluster_floorplanning_legal(ClusterBlockId blk_id, const t_pl_loc& loc) {
118122
auto& floorplanning_ctx = g_vpr_ctx.floorplanning();
119123

vpr/src/place/place_constraints.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Author: khalid88
77
*/
88
#include "move_transactions.h"
9+
#include "region.h"
910
#include "clustered_netlist_utils.h"
1011

1112
#ifndef VPR_SRC_PLACE_PLACE_CONSTRAINTS_H_

0 commit comments

Comments
 (0)