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