1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // BSD 3-Clause License
4 //
5 // Copyright (c) 2019, The Regents of the University of California
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are met:
10 //
11 // * Redistributions of source code must retain the above copyright notice, this
12 // list of conditions and the following disclaimer.
13 //
14 // * Redistributions in binary form must reproduce the above copyright notice,
15 // this list of conditions and the following disclaimer in the documentation
16 // and/or other materials provided with the distribution.
17 //
18 // * Neither the name of the copyright holder nor the names of its
19 // contributors may be used to endorse or promote products derived from
20 // this software without specific prior written permission.
21 //
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 // POSSIBILITY OF SUCH DAMAGE.
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35
36 #include "Grid.h"
37
38 #include <complex>
39
40 namespace grt {
41
init(const long lower_left_x,const long lower_left_y,const long upper_right_x,const long upper_right_y,const long tile_width,const long tile_height,const int x_grids,const int y_grids,const bool perfect_regular_x,const bool perfect_regular_y,const int num_layers,const std::vector<int> & spacings,const std::vector<int> & min_widths,const std::vector<int> & horizontal_capacities,const std::vector<int> & vertical_capacities,const std::map<int,std::vector<odb::Rect>> & obstructions)42 void Grid::init(const long lower_left_x,
43 const long lower_left_y,
44 const long upper_right_x,
45 const long upper_right_y,
46 const long tile_width,
47 const long tile_height,
48 const int x_grids,
49 const int y_grids,
50 const bool perfect_regular_x,
51 const bool perfect_regular_y,
52 const int num_layers,
53 const std::vector<int>& spacings,
54 const std::vector<int>& min_widths,
55 const std::vector<int>& horizontal_capacities,
56 const std::vector<int>& vertical_capacities,
57 const std::map<int, std::vector<odb::Rect>>& obstructions)
58 {
59 lower_left_x_ = lower_left_x;
60 lower_left_y_ = lower_left_y;
61 upper_right_x_ = upper_right_x;
62 upper_right_y_ = upper_right_y;
63 tile_width_ = tile_width;
64 tile_height_ = tile_height;
65 x_grids_ = x_grids;
66 y_grids_ = y_grids;
67 perfect_regular_x_ = perfect_regular_x;
68 perfect_regular_y_ = perfect_regular_y;
69 num_layers_ = num_layers;
70 spacings_ = spacings;
71 min_widths_ = min_widths;
72 horizontal_edges_capacities_ = horizontal_capacities;
73 vertical_edges_capacities_ = vertical_capacities;
74 obstructions_ = obstructions;
75 }
76
clear()77 void Grid::clear()
78 {
79 spacings_.clear();
80 min_widths_.clear();
81 horizontal_edges_capacities_.clear();
82 vertical_edges_capacities_.clear();
83 obstructions_.clear();
84 }
85
getPositionOnGrid(const odb::Point & position)86 odb::Point Grid::getPositionOnGrid(const odb::Point& position)
87 {
88 int x = position.x();
89 int y = position.y();
90
91 // Computing x and y center:
92 int gcell_id_x = floor((float) ((x - lower_left_x_) / tile_width_));
93 int gcell_id_y = floor((float) ((y - lower_left_y_) / tile_height_));
94
95 if (gcell_id_x >= x_grids_)
96 gcell_id_x--;
97
98 if (gcell_id_y >= y_grids_)
99 gcell_id_y--;
100
101 int center_x = (gcell_id_x * tile_width_) + (tile_width_ / 2) + lower_left_x_;
102 int center_y = (gcell_id_y * tile_height_) + (tile_height_ / 2) + lower_left_y_;
103
104 return odb::Point(center_x, center_y);
105 }
106
getBlockedTiles(const odb::Rect & obstruction,odb::Rect & first_tile_bds,odb::Rect & last_tile_bds)107 std::pair<Grid::TILE, Grid::TILE> Grid::getBlockedTiles(
108 const odb::Rect& obstruction,
109 odb::Rect& first_tile_bds,
110 odb::Rect& last_tile_bds)
111 {
112 std::pair<TILE, TILE> tiles;
113 TILE first_tile;
114 TILE last_tile;
115
116 odb::Point lower = obstruction.ll(); // lower bound of obstruction
117 odb::Point upper = obstruction.ur(); // upper bound of obstruction
118
119 lower
120 = getPositionOnGrid(lower); // translate lower bound of obstruction to
121 // the center of the tile where it is inside
122 upper
123 = getPositionOnGrid(upper); // translate upper bound of obstruction to
124 // the center of the tile where it is inside
125
126 // Get x and y indices of first blocked tile
127 first_tile._x = (lower.x() - (getTileWidth() / 2)) / getTileWidth();
128 first_tile._y = (lower.y() - (getTileHeight() / 2)) / getTileHeight();
129
130 // Get x and y indices of last blocked tile
131 last_tile._x = (upper.x() - (getTileWidth() / 2)) / getTileWidth();
132 last_tile._y = (upper.y() - (getTileHeight() / 2)) / getTileHeight();
133
134 tiles = std::make_pair(first_tile, last_tile);
135
136 odb::Point ll_first_tile = odb::Point(lower.x() - (getTileWidth() / 2),
137 lower.y() - (getTileHeight() / 2));
138 odb::Point ur_first_tile = odb::Point(lower.x() + (getTileWidth() / 2),
139 lower.y() + (getTileHeight() / 2));
140
141 odb::Point ll_last_tile = odb::Point(upper.x() - (getTileWidth() / 2),
142 upper.y() - (getTileHeight() / 2));
143 odb::Point ur_last_tile = odb::Point(upper.x() + (getTileWidth() / 2),
144 upper.y() + (getTileHeight() / 2));
145
146 if ((upper_right_x_ - ur_last_tile.x()) / getTileWidth() < 1) {
147 ur_last_tile.setX(upper_right_x_);
148 }
149 if ((upper_right_y_ - ur_last_tile.y()) / getTileHeight() < 1) {
150 ur_last_tile.setY(upper_right_y_);
151 }
152
153 first_tile_bds = odb::Rect(ll_first_tile, ur_first_tile);
154 last_tile_bds = odb::Rect(ll_last_tile, ur_last_tile);
155
156 return tiles;
157 }
158
computeTileReduce(const odb::Rect & obs,const odb::Rect & tile,int track_space,bool first,bool direction)159 int Grid::computeTileReduce(const odb::Rect& obs,
160 const odb::Rect& tile,
161 int track_space,
162 bool first,
163 bool direction)
164 {
165 int reduce = -1;
166 if (direction == RoutingLayer::VERTICAL) {
167 if (obs.xMin() >= tile.xMin() && obs.xMax() <= tile.xMax()) {
168 reduce = ceil(std::abs(obs.xMax() - obs.xMin()) / track_space);
169 } else if (first) {
170 reduce = ceil(std::abs(tile.xMax() - obs.xMin()) / track_space);
171 } else {
172 reduce = ceil(std::abs(obs.xMax() - tile.xMin()) / track_space);
173 }
174 } else {
175 if (obs.yMin() >= tile.yMin() && obs.yMax() <= tile.yMax()) {
176 reduce = ceil(std::abs(obs.yMax() - obs.yMin()) / track_space);
177 } else if (first) {
178 reduce = ceil(std::abs(tile.yMax() - obs.yMin()) / track_space);
179 } else {
180 reduce = ceil(std::abs(obs.yMax() - tile.yMin()) / track_space);
181 }
182 }
183
184 return reduce;
185 }
186
getMiddle()187 odb::Point Grid::getMiddle()
188 {
189 return odb::Point((lower_left_x_ + (upper_right_x_ - lower_left_x_) / 2.0),
190 (lower_left_y_ + (upper_right_y_ - lower_left_y_) / 2.0));
191 }
192
getGridArea() const193 odb::Rect Grid::getGridArea() const
194 {
195 return odb::Rect(lower_left_x_, lower_left_y_, upper_right_x_, upper_right_y_);
196 }
197
198 } // namespace grt
199