Skip to content

Commit 37095c7

Browse files
authored
Merge pull request #1535 from verilog-to-routing/new_constraints_class
Created draft of new constraints class header file
2 parents ab5f508 + 687105b commit 37095c7

11 files changed

+820
-0
lines changed

libs/libvtrutil/src/vtr_geometry.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ class Rect {
141141
template<class T>
142142
Rect<T> bounding_box(const Rect<T>& lhs, const Rect<T>& rhs);
143143

144+
//Return the intersection of two given rectangles
145+
template<class T>
146+
Rect<T> intersection(const Rect<T>& lhs, const Rect<T>& rhs);
147+
144148
//Sample on a uniformly spaced grid within a rectangle
145149
// sample(vtr::Rect(l, h), 0, 0, M) == l
146150
// sample(vtr::Rect(l, h), M, M, M) == h

libs/libvtrutil/src/vtr_geometry.tpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ Rect<T> bounding_box(const Rect<T>& lhs, const Rect<T>& rhs) {
182182
std::max(lhs.ymax(), rhs.ymax()));
183183
}
184184

185+
template<class T>
186+
Rect<T> intersection(const Rect<T>& lhs, const Rect<T>& rhs) {
187+
return Rect<T>(std::max(lhs.xmin(), rhs.xmin()),
188+
std::max(lhs.ymin(), rhs.ymin()),
189+
std::min(lhs.xmax(), rhs.xmax()),
190+
std::min(lhs.ymax(), rhs.ymax()));
191+
}
185192
//Only defined for integral types
186193
template<typename T, typename std::enable_if<std::is_integral<T>::value>::type...>
187194
Point<T> sample(const vtr::Rect<T>& r, T x, T y, T d) {

vpr/src/base/partition.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include "partition.h"
2+
#include <algorithm>
3+
#include <vector>
4+
5+
const std::string Partition::get_name() {
6+
return name;
7+
}
8+
9+
void Partition::set_name(std::string _part_name) {
10+
name = _part_name;
11+
}
12+
13+
const PartitionRegion Partition::get_part_region() {
14+
return part_region;
15+
}
16+
17+
void Partition::set_part_region(PartitionRegion pr) {
18+
part_region = pr;
19+
}

vpr/src/base/partition.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#ifndef PARTITION_H
2+
#define PARTITION_H
3+
4+
#include "vtr_strong_id.h"
5+
#include "region.h"
6+
#include "atom_netlist_fwd.h"
7+
#include "partition_region.h"
8+
/**
9+
* @file
10+
* @brief This file defines the data for a partition: a grouping of atoms that are constrained to a portion of an FPGA.
11+
*
12+
* A partition defines the atoms that are assigned to it, and the locations in which they can be placed.
13+
* The locations are a union of rectangles in x, y, sub_tile space.
14+
* Common cases include a single rectangle or a single x, y, sub_tile (specific location). More complex partitions
15+
* with L, T or other shapes can be created with a union of multiple rectangles.
16+
*/
17+
18+
/// @brief Type tag for PartitionId
19+
struct partition_id_tag;
20+
21+
/// @brief A unique identifier for a partition
22+
typedef vtr::StrongId<partition_id_tag> PartitionId;
23+
24+
class Partition {
25+
public:
26+
const std::string get_name();
27+
28+
void set_name(std::string _part_name);
29+
30+
/**
31+
* @brief Set the PartitionRegion (union of rectangular regions) for this partition
32+
*
33+
* @param pr The PartitionRegion belonging to the partition
34+
*/
35+
void set_part_region(PartitionRegion pr);
36+
37+
/**
38+
* @brief Get the PartitionRegion (union of rectangular regions) for this partition
39+
*/
40+
const PartitionRegion get_part_region();
41+
42+
private:
43+
std::string name; ///< name of the partition, name will be unique across partitions
44+
PartitionRegion part_region; ///< the union of regions that the partition can be placed in
45+
};
46+
47+
#endif /* PARTITION_H */

vpr/src/base/partition_region.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include "partition_region.h"
2+
3+
PartitionRegion PartitionRegion::get_intersection(PartitionRegion part_region) {
4+
/**for N regions in part_region and M in the calling object you can get anywhere from
5+
* 0 to M*N regions in the resulting vector. Only intersection regions with non-zero area rectangles and
6+
* equivalent subtiles are put in the resulting vector
7+
* Rectangles are not merged even if it would be possible
8+
*/
9+
PartitionRegion pr;
10+
Region intersect_region;
11+
bool regions_intersect;
12+
for (unsigned int i = 0; i < partition_region.size(); i++) {
13+
for (unsigned int j = 0; j < part_region.partition_region.size(); j++) {
14+
regions_intersect = partition_region[i].do_regions_intersect(part_region.partition_region[j]);
15+
if (regions_intersect) {
16+
intersect_region = partition_region[i].regions_intersection(part_region.partition_region[j]);
17+
pr.partition_region.push_back(intersect_region);
18+
}
19+
}
20+
}
21+
22+
return pr;
23+
}
24+
25+
void PartitionRegion::add_to_part_region(Region region) {
26+
partition_region.push_back(region);
27+
}
28+
29+
std::vector<Region> PartitionRegion::get_partition_region() {
30+
return partition_region;
31+
}

vpr/src/base/partition_region.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#ifndef PARTITION_REGIONS_H
2+
#define PARTITION_REGIONS_H
3+
4+
#include "region.h"
5+
#include "atom_netlist_fwd.h"
6+
7+
/**
8+
* @file
9+
* @brief This file defines the PartitionRegions class. The PartitionRegions class is used to store the union
10+
* of regions that a partition can be placed in.
11+
*/
12+
13+
class PartitionRegion {
14+
public:
15+
/**
16+
* @brief Return the intersection of two PartitionRegions
17+
*
18+
* @param part_region The PartitionRegion that the calling object will be intersected with
19+
*/
20+
PartitionRegion get_intersection(PartitionRegion part_region);
21+
22+
/**
23+
* @brief Add a region to the union of regions belonging to the partition
24+
*
25+
* @param region The region to be added to the calling object
26+
*/
27+
void add_to_part_region(Region region);
28+
29+
/**
30+
* @brief Return the union of regions
31+
*/
32+
std::vector<Region> get_partition_region();
33+
34+
private:
35+
std::vector<Region> partition_region; ///< union of rectangular regions that a partition can be placed in
36+
};
37+
38+
#endif /* PARTITION_REGIONS_H */

vpr/src/base/region.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#include "region.h"
2+
3+
/// @brief sentinel value for indicating that a subtile has not been specified
4+
constexpr int NO_SUBTILE = -1;
5+
6+
Region::Region() {
7+
sub_tile = NO_SUBTILE;
8+
9+
//default rect for a region is (-1, -1, -1, -1)
10+
region_bounds.set_xmin(-1);
11+
region_bounds.set_ymin(-1);
12+
region_bounds.set_xmax(-1);
13+
region_bounds.set_ymax(-1);
14+
}
15+
16+
vtr::Rect<int> Region::get_region_rect() {
17+
return region_bounds;
18+
}
19+
20+
void Region::set_region_rect(int _xmin, int _ymin, int _xmax, int _ymax) {
21+
region_bounds.set_xmin(_xmin);
22+
region_bounds.set_xmax(_xmax);
23+
region_bounds.set_ymin(_ymin);
24+
region_bounds.set_ymax(_ymax);
25+
}
26+
27+
int Region::get_sub_tile() {
28+
return sub_tile;
29+
}
30+
31+
void Region::set_sub_tile(int _sub_tile) {
32+
sub_tile = _sub_tile;
33+
}
34+
35+
bool Region::do_regions_intersect(Region region) {
36+
bool intersect = true;
37+
38+
vtr::Rect<int> region_rect = region.get_region_rect();
39+
vtr::Rect<int> intersect_rect;
40+
41+
intersect_rect = intersection(region_bounds, region_rect);
42+
43+
/**
44+
* if the intersection rectangle is empty or the subtile of the two regions does not match,
45+
* the regions do not intersect
46+
*/
47+
if (intersect_rect.empty() || sub_tile != region.get_sub_tile()) {
48+
return intersect = false;
49+
}
50+
51+
return intersect;
52+
}
53+
54+
Region Region::regions_intersection(Region region) {
55+
Region intersect;
56+
57+
/**
58+
* If the subtiles of the two regions don't match, there is no intersection.
59+
* If they do match, the intersection function if used to get the overlap of the two regions' rectangles.
60+
* If there is no overlap, an empty rectangle will be returned.
61+
*/
62+
if (sub_tile == region.get_sub_tile()) {
63+
intersect.set_sub_tile(sub_tile);
64+
vtr::Rect<int> region_rect = region.get_region_rect();
65+
vtr::Rect<int> intersect_rect;
66+
67+
intersect_rect = intersection(region_bounds, region_rect);
68+
69+
intersect.set_region_rect(intersect_rect.xmin(), intersect_rect.ymin(), intersect_rect.xmax(), intersect_rect.ymax());
70+
}
71+
72+
return intersect;
73+
}
74+
75+
bool Region::locked() {
76+
return region_bounds.xmin() == region_bounds.xmax() && region_bounds.ymin() == region_bounds.ymax() && sub_tile != NO_SUBTILE;
77+
}
78+
79+
bool Region::empty() {
80+
return region_bounds.empty();
81+
}

vpr/src/base/region.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#ifndef REGION_H
2+
#define REGION_H
3+
4+
#include <vtr_geometry.h>
5+
6+
/**
7+
* @file
8+
* @brief This file defines the Region class. The Region class stores the data for each constraint region.
9+
*
10+
* This includes the x and y bounds of the region rectangle and its sub_tile. To lock a block down to a specific location,
11+
* when defining the region specify xmin = xmax, ymin = ymax, and specify a subtile value.
12+
*
13+
*/
14+
15+
class Region {
16+
public:
17+
Region();
18+
19+
vtr::Rect<int> get_region_rect();
20+
21+
void set_region_rect(int _xmin, int _ymin, int _xmax, int _ymax);
22+
23+
int get_sub_tile();
24+
25+
void set_sub_tile(int _sub_tile);
26+
27+
/**
28+
* @brief Return whether the region is empty, based on whether the region rectangle is empty
29+
*/
30+
bool empty();
31+
32+
/**
33+
* @brief Returns whether two regions intersect
34+
*
35+
* Intersection is the area of overlap between the rectangles of two regions,
36+
* given that both regions have matching subtile values, or no subtiles assigned to them
37+
* The overlap is inclusive of the x and y boundaries of the rectangles
38+
*
39+
* @param region The region to intersect with the calling object
40+
*/
41+
bool do_regions_intersect(Region region);
42+
43+
/**
44+
* @brief Returns the coordinates of intersection of two regions
45+
*
46+
* @param region The region to intersect with the calling object
47+
*/
48+
Region regions_intersection(Region region);
49+
50+
/**
51+
* @brief Checks whether a block is locked down to a specific x, y, subtile location
52+
*/
53+
bool locked();
54+
55+
private:
56+
//may need to include zmin, zmax for future use in 3D FPGA designs
57+
vtr::Rect<int> region_bounds; ///< xmin, ymin, xmax, ymax inclusive
58+
int sub_tile; ///< users will optionally select a subtile
59+
};
60+
61+
#endif /* REGION_H */

vpr/src/base/vpr_constraints.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "vpr_constraints.h"
2+
3+
void VprConstraints::add_constrained_atom(const AtomBlockId blk_id, const PartitionId part_id) {
4+
constrained_atoms.insert({blk_id, part_id});
5+
6+
auto got = constrained_atoms.find(blk_id);
7+
8+
if (got == constrained_atoms.end()) {
9+
constrained_atoms.insert({blk_id, part_id});
10+
} else {
11+
got->second = part_id;
12+
}
13+
}
14+
15+
PartitionId VprConstraints::get_atom_partition(AtomBlockId blk_id) {
16+
PartitionId part_id;
17+
18+
auto got = constrained_atoms.find(blk_id);
19+
20+
if (got == constrained_atoms.end()) {
21+
return part_id = PartitionId::INVALID();
22+
} else {
23+
return got->second;
24+
}
25+
}
26+
27+
void VprConstraints::add_partition(Partition part) {
28+
partitions.push_back(part);
29+
}
30+
31+
Partition VprConstraints::get_partition(PartitionId part_id) {
32+
return partitions[part_id];
33+
}
34+
35+
std::vector<AtomBlockId> VprConstraints::get_part_atoms(PartitionId part_id) {
36+
std::vector<AtomBlockId> part_atoms;
37+
38+
for (auto& it : constrained_atoms) {
39+
if (it.second == part_id) {
40+
part_atoms.push_back(it.first);
41+
}
42+
}
43+
44+
return part_atoms;
45+
}

0 commit comments

Comments
 (0)