1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2019, Nefelus Inc
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 // list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 // this list of conditions and the following disclaimer in the documentation
15 // and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32
33 #include "ZException.h"
34 #include "db.h"
35 #include "dbShape.h"
36
37 namespace odb {
38
dbInstShapeItr(bool expand_vias)39 dbInstShapeItr::dbInstShapeItr(bool expand_vias)
40 {
41 _state = 0;
42 _inst = NULL;
43 _master = NULL;
44 _mpin = NULL;
45 _type = ALL;
46 _via = NULL;
47 _via_x = 0;
48 _via_y = 0;
49 _expand_vias = expand_vias;
50 }
51
begin(dbInst * inst,IteratorType type)52 void dbInstShapeItr::begin(dbInst* inst, IteratorType type)
53 {
54 int x, y;
55 _inst = inst;
56 _inst->getOrigin(x, y);
57 _master = _inst->getMaster();
58 _transform = dbTransform(inst->getOrient(), Point(x, y));
59 _type = type;
60 _state = 0;
61 }
62
begin(dbInst * inst,IteratorType type,const dbTransform & t)63 void dbInstShapeItr::begin(dbInst* inst,
64 IteratorType type,
65 const dbTransform& t)
66 {
67 int x, y;
68 _inst = inst;
69 _inst->getOrigin(x, y);
70 _master = _inst->getMaster();
71 _transform = dbTransform(inst->getOrient(), Point(x, y));
72 _transform.concat(t);
73 _type = type;
74 _state = 0;
75 }
76
getViaBox(dbBox * box,dbShape & shape)77 void dbInstShapeItr::getViaBox(dbBox* box, dbShape& shape)
78 {
79 Rect b;
80 box->getBox(b);
81 int xmin = b.xMin() + _via_x;
82 int ymin = b.yMin() + _via_y;
83 int xmax = b.xMax() + _via_x;
84 int ymax = b.yMax() + _via_y;
85 Rect r(xmin, ymin, xmax, ymax);
86 _transform.apply(r);
87 shape.setViaBox(_via, box->getTechLayer(), r);
88 }
89
getShape(dbBox * box,dbShape & shape)90 void dbInstShapeItr::getShape(dbBox* box, dbShape& shape)
91 {
92 Rect r;
93 box->getBox(r);
94 _transform.apply(r);
95
96 dbTechVia* via = box->getTechVia();
97
98 if (via)
99 shape.setVia(via, r);
100 else
101 shape.setSegment(box->getTechLayer(), r);
102 }
103
104 #define INIT 0
105 #define MTERM_ITR 1
106 #define MPIN_ITR 2
107 #define MBOX_ITR 3
108 #define OBS_ITR 4
109 #define VIA_BOX_ITR 5
110 #define PINS_DONE 6
111
next(dbShape & shape)112 bool dbInstShapeItr::next(dbShape& shape)
113 {
114 ZASSERT(_inst);
115
116 next_state:
117
118 switch (_state) {
119 case INIT: {
120 if (_type == OBSTRUCTIONS) {
121 _boxes = _master->getObstructions();
122 _box_itr = _boxes.begin();
123 _state = OBS_ITR;
124 } else {
125 _mterms = _master->getMTerms();
126 _mterm_itr = _mterms.begin();
127 _state = MTERM_ITR;
128 }
129
130 goto next_state;
131 }
132
133 case MTERM_ITR: {
134 if (_mterm_itr == _mterms.end())
135 _state = PINS_DONE;
136 else {
137 dbMTerm* mterm = *_mterm_itr;
138 ++_mterm_itr;
139 _mpins = mterm->getMPins();
140 _mpin_itr = _mpins.begin();
141 _state = MPIN_ITR;
142 }
143
144 goto next_state;
145 }
146
147 case MPIN_ITR: {
148 if (_mpin_itr == _mpins.end())
149 _state = MTERM_ITR;
150 else {
151 _mpin = *_mpin_itr;
152 ++_mpin_itr;
153 _boxes = _mpin->getGeometry();
154 _box_itr = _boxes.begin();
155 _state = MBOX_ITR;
156 }
157
158 goto next_state;
159 }
160
161 case MBOX_ITR: {
162 if (_box_itr == _boxes.end())
163 _state = MPIN_ITR;
164 else {
165 dbBox* box = *_box_itr;
166 ++_box_itr;
167
168 if ((_expand_vias == false) || (box->isVia() == false)) {
169 getShape(box, shape);
170 return true;
171 }
172
173 else {
174 box->getViaXY(_via_x, _via_y);
175 _via = box->getTechVia();
176 assert(_via);
177 _via_boxes = _via->getBoxes();
178 _via_box_itr = _via_boxes.begin();
179 _prev_state = MBOX_ITR;
180 _state = VIA_BOX_ITR;
181 }
182 }
183
184 goto next_state;
185 }
186
187 case OBS_ITR: {
188 if (_box_itr == _boxes.end())
189 return false;
190
191 else {
192 dbBox* box = *_box_itr;
193 ++_box_itr;
194
195 if ((_expand_vias == false) || (box->isVia() == false)) {
196 getShape(box, shape);
197 return true;
198 }
199
200 else {
201 box->getViaXY(_via_x, _via_y);
202 _via = box->getTechVia();
203 assert(_via);
204 _via_boxes = _via->getBoxes();
205 _via_box_itr = _via_boxes.begin();
206 _prev_state = OBS_ITR;
207 _state = VIA_BOX_ITR;
208 }
209 }
210 goto next_state;
211 }
212
213 case VIA_BOX_ITR: {
214 if (_via_box_itr == _via_boxes.end())
215 _state = _prev_state;
216 else {
217 dbBox* box = *_via_box_itr;
218 ++_via_box_itr;
219 getViaBox(box, shape);
220 return true;
221 }
222
223 goto next_state;
224 }
225
226 case PINS_DONE: {
227 if (_type == ALL) {
228 _type = OBSTRUCTIONS;
229 _state = INIT;
230 goto next_state;
231 }
232
233 return false;
234 }
235 }
236
237 return false;
238 }
239
240 } // namespace odb
241