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 "dbTechLayerAntennaRule.h"
34
35 #include "db.h"
36 #include "dbDatabase.h"
37 #include "dbMaster.h"
38 #include "dbTable.h"
39 #include "dbTable.hpp"
40 #include "dbTech.h"
41 #include "dbTechLayer.h"
42 #include "lefout.h"
43
44 namespace odb {
45
46 template class dbTable<_dbTechLayerAntennaRule>;
47 template class dbTable<_dbTechAntennaPinModel>;
48
49 using std::vector;
50
operator ==(const _ARuleFactor & rhs) const51 bool _ARuleFactor::operator==(const _ARuleFactor& rhs) const
52 {
53 if (_factor != rhs._factor)
54 return false;
55
56 if (_explicit != rhs._explicit)
57 return false;
58
59 if (_diff_use_only != rhs._diff_use_only)
60 return false;
61
62 return true;
63 }
64
differences(dbDiff & diff,const char * field,const _ARuleFactor & rhs) const65 void _ARuleFactor::differences(dbDiff& diff,
66 const char* field,
67 const _ARuleFactor& rhs) const
68 {
69 if (field)
70 diff.begin_object("<> %s\n", field);
71 else
72 diff.begin_object("<> _ARuleFactor\n");
73
74 DIFF_FIELD(_factor);
75 DIFF_FIELD(_explicit);
76 DIFF_FIELD(_diff_use_only);
77
78 diff.end_object();
79 }
80
out(dbDiff & diff,char side,const char * field) const81 void _ARuleFactor::out(dbDiff& diff, char side, const char* field) const
82 {
83 if (field)
84 diff.begin_object("%c %s\n", side, field);
85 else
86 diff.begin_object("%c _ARuleFactor\n", side);
87
88 DIFF_OUT_FIELD(_factor);
89 DIFF_OUT_FIELD(_explicit);
90 DIFF_OUT_FIELD(_diff_use_only);
91 diff.end_object();
92 }
93
operator ==(const _ARuleRatio & rhs) const94 bool _ARuleRatio::operator==(const _ARuleRatio& rhs) const
95 {
96 if (_ratio != rhs._ratio)
97 return false;
98
99 if (_diff_idx != rhs._diff_idx)
100 return false;
101
102 if (_diff_ratio != rhs._diff_ratio)
103 return false;
104
105 return true;
106 }
107
differences(dbDiff & diff,const char * field,const _ARuleRatio & rhs) const108 void _ARuleRatio::differences(dbDiff& diff,
109 const char* field,
110 const _ARuleRatio& rhs) const
111 {
112 if (field)
113 diff.begin_object("<> %s\n", field);
114 else
115 diff.begin_object("<> _ARuleRatio\n");
116
117 DIFF_FIELD(_ratio);
118 DIFF_VECTOR(_diff_idx);
119 DIFF_VECTOR(_diff_ratio);
120 diff.end_object();
121 }
122
out(dbDiff & diff,char side,const char * field) const123 void _ARuleRatio::out(dbDiff& diff, char side, const char* field) const
124 {
125 if (field)
126 diff.begin_object("%c %s\n", side, field);
127 else
128 diff.begin_object("%c _ARuleRatio\n", side);
129
130 DIFF_OUT_FIELD(_ratio);
131 DIFF_OUT_VECTOR(_diff_idx);
132 DIFF_OUT_VECTOR(_diff_ratio);
133 diff.end_object();
134 }
135
operator ==(const _dbTechLayerAntennaRule & rhs) const136 bool _dbTechLayerAntennaRule::operator==(
137 const _dbTechLayerAntennaRule& rhs) const
138 {
139 if (_layer != rhs._layer)
140 return false;
141
142 if (_area_mult != rhs._area_mult)
143 return false;
144
145 if (_sidearea_mult != rhs._sidearea_mult)
146 return false;
147
148 if (_par_area_val != rhs._par_area_val)
149 return false;
150
151 if (_cum_area_val != rhs._cum_area_val)
152 return false;
153
154 if (_par_sidearea_val != rhs._par_sidearea_val)
155 return false;
156
157 if (_cum_sidearea_val != rhs._cum_sidearea_val)
158 return false;
159
160 if (_area_diff_reduce_val != rhs._area_diff_reduce_val)
161 return false;
162
163 if (_gate_plus_diff_factor != rhs._gate_plus_diff_factor)
164 return false;
165
166 if (_area_minus_diff_factor != rhs._area_minus_diff_factor)
167 return false;
168
169 if (_has_antenna_cumroutingpluscut != rhs._has_antenna_cumroutingpluscut)
170 return false;
171
172 return true;
173 }
174
differences(dbDiff & diff,const char * field,const _dbTechLayerAntennaRule & rhs) const175 void _dbTechLayerAntennaRule::differences(
176 dbDiff& diff,
177 const char* field,
178 const _dbTechLayerAntennaRule& rhs) const
179 {
180 DIFF_BEGIN
181 DIFF_FIELD(_layer);
182 DIFF_STRUCT(_area_mult);
183 DIFF_STRUCT(_sidearea_mult);
184 DIFF_STRUCT(_par_area_val);
185 DIFF_STRUCT(_cum_area_val);
186 DIFF_STRUCT(_par_sidearea_val);
187 DIFF_STRUCT(_cum_sidearea_val);
188 DIFF_STRUCT(_area_diff_reduce_val);
189 DIFF_FIELD(_gate_plus_diff_factor);
190 DIFF_FIELD(_area_minus_diff_factor);
191 DIFF_FIELD(_has_antenna_cumroutingpluscut);
192 DIFF_END
193 }
194
out(dbDiff & diff,char side,const char * field) const195 void _dbTechLayerAntennaRule::out(dbDiff& diff,
196 char side,
197 const char* field) const
198 {
199 DIFF_OUT_BEGIN
200 DIFF_OUT_FIELD(_layer);
201 DIFF_OUT_STRUCT(_area_mult);
202 DIFF_OUT_STRUCT(_sidearea_mult);
203 DIFF_OUT_STRUCT(_par_area_val);
204 DIFF_OUT_STRUCT(_cum_area_val);
205 DIFF_OUT_STRUCT(_par_sidearea_val);
206 DIFF_OUT_STRUCT(_cum_sidearea_val);
207 DIFF_OUT_STRUCT(_area_diff_reduce_val);
208 DIFF_OUT_FIELD(_gate_plus_diff_factor);
209 DIFF_OUT_FIELD(_area_minus_diff_factor);
210 DIFF_OUT_FIELD(_has_antenna_cumroutingpluscut);
211 DIFF_END
212 }
213
operator ==(const _dbTechAntennaAreaElement & rhs) const214 bool _dbTechAntennaAreaElement::operator==(
215 const _dbTechAntennaAreaElement& rhs) const
216 {
217 if (_area != rhs._area)
218 return false;
219
220 if (_lyidx != rhs._lyidx)
221 return false;
222
223 return true;
224 }
225
differences(dbDiff & diff,const char * field,const _dbTechAntennaAreaElement & rhs) const226 void _dbTechAntennaAreaElement::differences(
227 dbDiff& diff,
228 const char* field,
229 const _dbTechAntennaAreaElement& rhs) const
230 {
231 if (field)
232 diff.begin_object("<> %s\n", field);
233 else
234 diff.begin_object("<> _dbTechAntennaAreaElement\n");
235
236 DIFF_FIELD(_area);
237 DIFF_FIELD(_lyidx);
238 diff.end_object();
239 }
240
out(dbDiff & diff,char side,const char * field) const241 void _dbTechAntennaAreaElement::out(dbDiff& diff,
242 char side,
243 const char* field) const
244 {
245 if (field)
246 diff.begin_object("%c %s\n", side, field);
247 else
248 diff.begin_object("%c _dbTechAntennaAreaElement\n", side);
249
250 DIFF_OUT_FIELD(_area);
251 DIFF_OUT_FIELD(_lyidx);
252 diff.end_object();
253 }
254
operator ==(const _dbTechAntennaPinModel & rhs) const255 bool _dbTechAntennaPinModel::operator==(const _dbTechAntennaPinModel& rhs) const
256 {
257 if (_mterm != rhs._mterm)
258 return false;
259
260 if (_gate_area != rhs._gate_area)
261 return false;
262
263 if (_max_area_car != rhs._max_area_car)
264 return false;
265
266 if (_max_sidearea_car != rhs._max_sidearea_car)
267 return false;
268
269 if (_max_cut_car != rhs._max_cut_car)
270 return false;
271
272 return true;
273 }
274
differences(dbDiff & diff,const char * field,const _dbTechAntennaPinModel & rhs) const275 void _dbTechAntennaPinModel::differences(
276 dbDiff& diff,
277 const char* field,
278 const _dbTechAntennaPinModel& rhs) const
279 {
280 DIFF_BEGIN
281 DIFF_FIELD(_mterm);
282 DIFF_VECTOR_PTR(_gate_area);
283 DIFF_VECTOR_PTR(_max_area_car);
284 DIFF_VECTOR_PTR(_max_sidearea_car);
285 DIFF_VECTOR_PTR(_max_cut_car);
286 DIFF_END
287 }
288
out(dbDiff & diff,char side,const char * field) const289 void _dbTechAntennaPinModel::out(dbDiff& diff,
290 char side,
291 const char* field) const
292 {
293 DIFF_OUT_BEGIN
294 DIFF_OUT_FIELD(_mterm);
295 DIFF_OUT_VECTOR_PTR(_gate_area);
296 DIFF_OUT_VECTOR_PTR(_max_area_car);
297 DIFF_OUT_VECTOR_PTR(_max_sidearea_car);
298 DIFF_OUT_VECTOR_PTR(_max_cut_car);
299 DIFF_END
300 }
301
302 ////////////////////////////////////////////////////////////////////
303 //
304 // _ARuleFactor - Methods
305 //
306 ////////////////////////////////////////////////////////////////////
307
setFactor(double factor,bool diffuse)308 void _ARuleFactor::setFactor(double factor, bool diffuse)
309 {
310 assert(factor > 0.0);
311 _factor = factor;
312 _diff_use_only = diffuse;
313 _explicit = true;
314 }
315
operator <<(dbOStream & stream,const _ARuleFactor & arf)316 dbOStream& operator<<(dbOStream& stream, const _ARuleFactor& arf)
317 {
318 stream << arf._factor;
319 stream << arf._explicit;
320 stream << arf._diff_use_only;
321 return stream;
322 }
323
operator >>(dbIStream & stream,_ARuleFactor & arf)324 dbIStream& operator>>(dbIStream& stream, _ARuleFactor& arf)
325 {
326 stream >> arf._factor;
327 stream >> arf._explicit;
328 stream >> arf._diff_use_only;
329 return stream;
330 }
331
332 ////////////////////////////////////////////////////////////////////
333 //
334 // _ARuleRatio - Methods
335 //
336 ////////////////////////////////////////////////////////////////////
337
setRatio(double ratio)338 void _ARuleRatio::setRatio(double ratio)
339 {
340 assert(ratio > 0);
341 _ratio = ratio;
342 }
343
setDiff(double ratio)344 void _ARuleRatio::setDiff(double ratio)
345 {
346 assert(ratio > 0);
347 assert((_diff_idx.size() == 0) && (_diff_ratio.size() == 0));
348 _diff_idx.assign(1, 0.0);
349 _diff_ratio.assign(1, ratio);
350 }
351
setDiff(const vector<double> & diff_idx,const vector<double> & ratios)352 void _ARuleRatio::setDiff(const vector<double>& diff_idx,
353 const vector<double>& ratios)
354 {
355 assert((_diff_idx.size() == 0) && (_diff_ratio.size() == 0));
356 _diff_idx = diff_idx;
357 _diff_ratio = ratios;
358 }
359
operator <<(dbOStream & stream,const _ARuleRatio & arrt)360 dbOStream& operator<<(dbOStream& stream, const _ARuleRatio& arrt)
361 {
362 stream << arrt._ratio;
363 stream << arrt._diff_idx;
364 stream << arrt._diff_ratio;
365 return stream;
366 }
367
operator >>(dbIStream & stream,_ARuleRatio & arrt)368 dbIStream& operator>>(dbIStream& stream, _ARuleRatio& arrt)
369 {
370 stream >> arrt._ratio;
371 stream >> arrt._diff_idx;
372 stream >> arrt._diff_ratio;
373 return stream;
374 }
375
376 ////////////////////////////////////////////////////////////////////
377 //
378 // _dbTechLayerAntennaRule - Methods
379 //
380 ////////////////////////////////////////////////////////////////////
381
_dbTechAntennaAreaElement()382 _dbTechAntennaAreaElement::_dbTechAntennaAreaElement()
383 {
384 _area = -1.0;
385 _lyidx = dbIdValidation::invalidId();
386 }
387
operator <<(dbOStream & stream,const _dbTechLayerAntennaRule & inrule)388 dbOStream& operator<<(dbOStream& stream, const _dbTechLayerAntennaRule& inrule)
389 {
390 stream << inrule._layer;
391 stream << inrule._area_mult;
392 stream << inrule._sidearea_mult;
393 stream << inrule._par_area_val;
394 stream << inrule._cum_area_val;
395 stream << inrule._par_sidearea_val;
396 stream << inrule._cum_sidearea_val;
397 stream << inrule._area_diff_reduce_val;
398 stream << inrule._gate_plus_diff_factor;
399 stream << inrule._area_minus_diff_factor;
400 stream << inrule._has_antenna_cumroutingpluscut;
401 return stream;
402 }
403
operator >>(dbIStream & stream,_dbTechLayerAntennaRule & inrule)404 dbIStream& operator>>(dbIStream& stream, _dbTechLayerAntennaRule& inrule)
405 {
406 stream >> inrule._layer;
407 stream >> inrule._area_mult;
408 stream >> inrule._sidearea_mult;
409 stream >> inrule._par_area_val;
410 stream >> inrule._cum_area_val;
411 stream >> inrule._par_sidearea_val;
412 stream >> inrule._cum_sidearea_val;
413 stream >> inrule._area_diff_reduce_val;
414 stream >> inrule._gate_plus_diff_factor;
415 stream >> inrule._area_minus_diff_factor;
416 stream >> inrule._has_antenna_cumroutingpluscut;
417 return stream;
418 }
419
420 ////////////////////////////////////////////////////////////////////
421 //
422 // dbTechLayerAntennaRule - Methods
423 //
424 ////////////////////////////////////////////////////////////////////
425
isValid() const426 bool dbTechLayerAntennaRule::isValid() const
427 {
428 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
429
430 return ((ant_rule->_par_area_val._ratio > 0)
431 || (ant_rule->_cum_area_val._ratio > 0)
432 || (ant_rule->_par_sidearea_val._ratio > 0)
433 || (ant_rule->_cum_sidearea_val._ratio > 0));
434 }
435
writeLef(lefout & writer) const436 void dbTechLayerAntennaRule::writeLef(lefout& writer) const
437 {
438 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
439
440 if (ant_rule->_area_mult._explicit) {
441 fprintf(writer.out(),
442 " ANTENNAAREAFACTOR %g %s;\n",
443 ant_rule->_area_mult._factor,
444 ant_rule->_area_mult._diff_use_only ? "DIFFUSEONLY " : "");
445 }
446
447 if (ant_rule->_has_antenna_cumroutingpluscut) {
448 fprintf(writer.out(), " ANTENNACUMROUTINGPLUSCUT ;\n");
449 }
450
451 if (ant_rule->_gate_plus_diff_factor > 0.0) {
452 fprintf(writer.out(),
453 " ANTENNAGATEPLUSDIFF %g ;\n",
454 ant_rule->_gate_plus_diff_factor);
455 }
456
457 if (ant_rule->_area_minus_diff_factor > 0.0) {
458 fprintf(writer.out(),
459 " ANTENNAAREAMINUSDIFF %g ;\n",
460 ant_rule->_area_minus_diff_factor);
461 }
462
463 if (ant_rule->_sidearea_mult._explicit) {
464 fprintf(writer.out(),
465 " ANTENNASIDEAREAFACTOR %g %s;\n",
466 ant_rule->_sidearea_mult._factor,
467 ant_rule->_sidearea_mult._diff_use_only ? "DIFFUSEONLY" : "");
468 }
469
470 dbVector<double>::const_iterator diffdx_itr;
471 dbVector<double>::const_iterator ratio_itr;
472
473 if (ant_rule->_par_area_val._ratio > 0)
474 fprintf(writer.out(),
475 " ANTENNAAREARATIO %g ;\n",
476 ant_rule->_par_area_val._ratio);
477
478 if ((ant_rule->_par_area_val._diff_ratio.size() == 1)
479 && (ant_rule->_par_area_val._diff_ratio[0] > 0))
480 fprintf(writer.out(),
481 " ANTENNADIFFAREARATIO %g ;\n",
482 ant_rule->_par_area_val._diff_ratio[0]);
483
484 if (ant_rule->_par_area_val._diff_ratio.size() > 1) {
485 fprintf(writer.out(), " ANTENNADIFFAREARATIO PWL ( ");
486 for (diffdx_itr = ant_rule->_par_area_val._diff_idx.begin(),
487 ratio_itr = ant_rule->_par_area_val._diff_ratio.begin();
488 diffdx_itr != ant_rule->_par_area_val._diff_idx.end()
489 && ratio_itr != ant_rule->_par_area_val._diff_ratio.end();
490 diffdx_itr++, ratio_itr++)
491 fprintf(writer.out(), "( %g %g ) ", *diffdx_itr, *ratio_itr);
492 fprintf(writer.out(), ") ;\n");
493 }
494
495 if (ant_rule->_cum_area_val._ratio > 0)
496 fprintf(writer.out(),
497 " ANTENNACUMAREARATIO %g ;\n",
498 ant_rule->_cum_area_val._ratio);
499
500 if ((ant_rule->_cum_area_val._diff_ratio.size() == 1)
501 && (ant_rule->_cum_area_val._diff_ratio[0] > 0))
502 fprintf(writer.out(),
503 " ANTENNACUMDIFFAREARATIO %g ;\n",
504 ant_rule->_cum_area_val._diff_ratio[0]);
505
506 if (ant_rule->_cum_area_val._diff_ratio.size() > 1) {
507 fprintf(writer.out(), " ANTENNACUMDIFFAREARATIO PWL ( ");
508 for (diffdx_itr = ant_rule->_cum_area_val._diff_idx.begin(),
509 ratio_itr = ant_rule->_cum_area_val._diff_ratio.begin();
510 diffdx_itr != ant_rule->_cum_area_val._diff_idx.end()
511 && ratio_itr != ant_rule->_cum_area_val._diff_ratio.end();
512 diffdx_itr++, ratio_itr++)
513 fprintf(writer.out(), "( %g %g ) ", *diffdx_itr, *ratio_itr);
514 fprintf(writer.out(), ") ;\n");
515 }
516
517 if (ant_rule->_par_sidearea_val._ratio > 0)
518 fprintf(writer.out(),
519 " ANTENNASIDEAREARATIO %g ;\n",
520 ant_rule->_par_sidearea_val._ratio);
521
522 if ((ant_rule->_par_sidearea_val._diff_ratio.size() == 1)
523 && (ant_rule->_par_sidearea_val._diff_ratio[0] > 0))
524 fprintf(writer.out(),
525 " ANTENNADIFFSIDEAREARATIO %g ;\n",
526 ant_rule->_par_sidearea_val._diff_ratio[0]);
527
528 if (ant_rule->_par_sidearea_val._diff_ratio.size() > 1) {
529 fprintf(writer.out(), " ANTENNADIFFSIDEAREARATIO PWL ( ");
530 for (diffdx_itr = ant_rule->_par_sidearea_val._diff_idx.begin(),
531 ratio_itr = ant_rule->_par_sidearea_val._diff_ratio.begin();
532 diffdx_itr != ant_rule->_par_sidearea_val._diff_idx.end()
533 && ratio_itr != ant_rule->_par_sidearea_val._diff_ratio.end();
534 diffdx_itr++, ratio_itr++)
535 fprintf(writer.out(), "( %g %g ) ", *diffdx_itr, *ratio_itr);
536 fprintf(writer.out(), ") ;\n");
537 }
538
539 if (ant_rule->_cum_sidearea_val._ratio > 0)
540 fprintf(writer.out(),
541 " ANTENNACUMSIDEAREARATIO %g ;\n",
542 ant_rule->_cum_sidearea_val._ratio);
543
544 if ((ant_rule->_cum_sidearea_val._diff_ratio.size() == 1)
545 && (ant_rule->_cum_sidearea_val._diff_ratio[0] > 0))
546 fprintf(writer.out(),
547 " ANTENNACUMDIFFSIDEAREARATIO %g ;\n",
548 ant_rule->_cum_sidearea_val._diff_ratio[0]);
549
550 if (ant_rule->_cum_sidearea_val._diff_ratio.size() > 1) {
551 fprintf(writer.out(), " ANTENNACUMDIFFSIDEAREARATIO PWL ( ");
552 for (diffdx_itr = ant_rule->_cum_sidearea_val._diff_idx.begin(),
553 ratio_itr = ant_rule->_cum_sidearea_val._diff_ratio.begin();
554 diffdx_itr != ant_rule->_cum_sidearea_val._diff_idx.end()
555 && ratio_itr != ant_rule->_cum_sidearea_val._diff_ratio.end();
556 diffdx_itr++, ratio_itr++)
557 fprintf(writer.out(), "( %g %g ) ", *diffdx_itr, *ratio_itr);
558 fprintf(writer.out(), ") ;\n");
559 }
560
561 if (ant_rule->_area_diff_reduce_val._diff_ratio.size() > 1) {
562 fprintf(writer.out(), " ANTENNAAREADIFFREDUCEPWL ( ");
563 for (diffdx_itr = ant_rule->_area_diff_reduce_val._diff_idx.begin(),
564 ratio_itr = ant_rule->_area_diff_reduce_val._diff_ratio.begin();
565 diffdx_itr != ant_rule->_area_diff_reduce_val._diff_idx.end()
566 && ratio_itr != ant_rule->_area_diff_reduce_val._diff_ratio.end();
567 diffdx_itr++, ratio_itr++)
568 fprintf(writer.out(), "( %g %g ) ", *diffdx_itr, *ratio_itr);
569 fprintf(writer.out(), ") ;\n");
570 }
571 }
572
hasAreaFactor() const573 bool dbTechLayerAntennaRule::hasAreaFactor() const
574 {
575 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
576 return ant_rule->_area_mult._explicit;
577 }
578
hasSideAreaFactor() const579 bool dbTechLayerAntennaRule::hasSideAreaFactor() const
580 {
581 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
582 return ant_rule->_sidearea_mult._explicit;
583 }
584
getAreaFactor() const585 double dbTechLayerAntennaRule::getAreaFactor() const
586 {
587 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
588 return ant_rule->_area_mult._factor;
589 }
590
getSideAreaFactor() const591 double dbTechLayerAntennaRule::getSideAreaFactor() const
592 {
593 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
594 return ant_rule->_sidearea_mult._factor;
595 }
596
isAreaFactorDiffUseOnly() const597 bool dbTechLayerAntennaRule::isAreaFactorDiffUseOnly() const
598 {
599 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
600 return ant_rule->_area_mult._diff_use_only;
601 }
602
isSideAreaFactorDiffUseOnly() const603 bool dbTechLayerAntennaRule::isSideAreaFactorDiffUseOnly() const
604 {
605 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
606 return ant_rule->_sidearea_mult._diff_use_only;
607 }
608
setAreaFactor(double factor,bool diffuse)609 void dbTechLayerAntennaRule::setAreaFactor(double factor, bool diffuse)
610 {
611 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
612
613 ant_rule->_area_mult.setFactor(factor, diffuse);
614 }
615
setSideAreaFactor(double factor,bool diffuse)616 void dbTechLayerAntennaRule::setSideAreaFactor(double factor, bool diffuse)
617 {
618 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
619
620 ant_rule->_sidearea_mult.setFactor(factor, diffuse);
621 }
622
getPAR() const623 double dbTechLayerAntennaRule::getPAR() const
624 {
625 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
626 return ant_rule->_par_area_val._ratio;
627 }
628
getCAR() const629 double dbTechLayerAntennaRule::getCAR() const
630 {
631 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
632 return ant_rule->_cum_area_val._ratio;
633 }
634
getPSR() const635 double dbTechLayerAntennaRule::getPSR() const
636 {
637 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
638 return ant_rule->_par_sidearea_val._ratio;
639 }
640
getCSR() const641 double dbTechLayerAntennaRule::getCSR() const
642 {
643 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
644 return ant_rule->_cum_sidearea_val._ratio;
645 }
646
getDiffPAR() const647 dbTechLayerAntennaRule::pwl_pair dbTechLayerAntennaRule::getDiffPAR() const
648 {
649 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
650 auto& rule = ant_rule->_par_area_val;
651 return pwl_pair{rule._diff_idx, rule._diff_ratio};
652 }
653
getDiffCAR() const654 dbTechLayerAntennaRule::pwl_pair dbTechLayerAntennaRule::getDiffCAR() const
655 {
656 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
657 auto& rule = ant_rule->_cum_area_val;
658 return pwl_pair{rule._diff_idx, rule._diff_ratio};
659 }
660
getDiffPSR() const661 dbTechLayerAntennaRule::pwl_pair dbTechLayerAntennaRule::getDiffPSR() const
662 {
663 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
664 auto& rule = ant_rule->_par_sidearea_val;
665 return pwl_pair{rule._diff_idx, rule._diff_ratio};
666 }
667
getDiffCSR() const668 dbTechLayerAntennaRule::pwl_pair dbTechLayerAntennaRule::getDiffCSR() const
669 {
670 auto ant_rule = (const _dbTechLayerAntennaRule*) this;
671 auto& rule = ant_rule->_cum_sidearea_val;
672 return pwl_pair{rule._diff_idx, rule._diff_ratio};
673 }
674
setPAR(double ratio)675 void dbTechLayerAntennaRule::setPAR(double ratio)
676 {
677 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
678
679 ant_rule->_par_area_val.setRatio(ratio);
680 }
681
setCAR(double ratio)682 void dbTechLayerAntennaRule::setCAR(double ratio)
683 {
684 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
685
686 ant_rule->_cum_area_val.setRatio(ratio);
687 }
688
setPSR(double ratio)689 void dbTechLayerAntennaRule::setPSR(double ratio)
690 {
691 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
692
693 ant_rule->_par_sidearea_val.setRatio(ratio);
694 }
695
setCSR(double ratio)696 void dbTechLayerAntennaRule::setCSR(double ratio)
697 {
698 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
699
700 ant_rule->_cum_sidearea_val.setRatio(ratio);
701 }
702
setDiffPAR(double ratio)703 void dbTechLayerAntennaRule::setDiffPAR(double ratio)
704 {
705 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
706
707 ant_rule->_par_area_val.setDiff(ratio);
708 }
709
setDiffCAR(double ratio)710 void dbTechLayerAntennaRule::setDiffCAR(double ratio)
711 {
712 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
713
714 ant_rule->_cum_area_val.setDiff(ratio);
715 }
716
setDiffPSR(double ratio)717 void dbTechLayerAntennaRule::setDiffPSR(double ratio)
718 {
719 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
720
721 ant_rule->_par_sidearea_val.setDiff(ratio);
722 }
723
setDiffCSR(double ratio)724 void dbTechLayerAntennaRule::setDiffCSR(double ratio)
725 {
726 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
727
728 ant_rule->_cum_sidearea_val.setDiff(ratio);
729 }
730
setDiffPAR(const vector<double> & diff_idx,const vector<double> & ratios)731 void dbTechLayerAntennaRule::setDiffPAR(const vector<double>& diff_idx,
732 const vector<double>& ratios)
733 {
734 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
735
736 ant_rule->_par_area_val.setDiff(diff_idx, ratios);
737 }
738
setDiffCAR(const vector<double> & diff_idx,const vector<double> & ratios)739 void dbTechLayerAntennaRule::setDiffCAR(const vector<double>& diff_idx,
740 const vector<double>& ratios)
741 {
742 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
743
744 ant_rule->_cum_area_val.setDiff(diff_idx, ratios);
745 }
746
setDiffPSR(const vector<double> & diff_idx,const vector<double> & ratios)747 void dbTechLayerAntennaRule::setDiffPSR(const vector<double>& diff_idx,
748 const vector<double>& ratios)
749 {
750 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
751
752 ant_rule->_par_sidearea_val.setDiff(diff_idx, ratios);
753 }
754
setDiffCSR(const vector<double> & diff_idx,const vector<double> & ratios)755 void dbTechLayerAntennaRule::setDiffCSR(const vector<double>& diff_idx,
756 const vector<double>& ratios)
757 {
758 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
759
760 ant_rule->_cum_sidearea_val.setDiff(diff_idx, ratios);
761 }
762
getAntennaRule(dbTech * _tech,uint dbid)763 dbTechLayerAntennaRule* dbTechLayerAntennaRule::getAntennaRule(dbTech* _tech,
764 uint dbid)
765 {
766 _dbTech* tech = (_dbTech*) _tech;
767 return (dbTechLayerAntennaRule*) tech->_antenna_rule_tbl->getPtr(dbid);
768 }
769
hasAntennaCumRoutingPlusCut() const770 bool dbTechLayerAntennaRule::hasAntennaCumRoutingPlusCut() const
771 {
772 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
773 return ant_rule->_has_antenna_cumroutingpluscut;
774 }
775
setAntennaCumRoutingPlusCut(bool value)776 void dbTechLayerAntennaRule::setAntennaCumRoutingPlusCut(bool value)
777 {
778 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
779 ant_rule->_has_antenna_cumroutingpluscut = value;
780 }
781
getGatePlusDiffFactor() const782 double dbTechLayerAntennaRule::getGatePlusDiffFactor() const
783 {
784 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
785 return ant_rule->_gate_plus_diff_factor;
786 }
787
setGatePlusDiffFactor(double factor)788 void dbTechLayerAntennaRule::setGatePlusDiffFactor(double factor)
789 {
790 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
791 ant_rule->_gate_plus_diff_factor = factor;
792 }
793
getAreaMinusDiffFactor() const794 double dbTechLayerAntennaRule::getAreaMinusDiffFactor() const
795 {
796 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
797 return ant_rule->_area_minus_diff_factor;
798 }
799
setAreaMinusDiffFactor(double factor)800 void dbTechLayerAntennaRule::setAreaMinusDiffFactor(double factor)
801 {
802 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
803 ant_rule->_area_minus_diff_factor = factor;
804 }
805
getAreaDiffReduce() const806 dbTechLayerAntennaRule::pwl_pair dbTechLayerAntennaRule::getAreaDiffReduce()
807 const
808 {
809 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
810 auto& rule = ant_rule->_area_diff_reduce_val;
811 return pwl_pair{rule._diff_idx, rule._diff_ratio};
812 }
813
setAreaDiffReduce(const std::vector<double> & areas,const std::vector<double> & factors)814 void dbTechLayerAntennaRule::setAreaDiffReduce(
815 const std::vector<double>& areas,
816 const std::vector<double>& factors)
817 {
818 _dbTechLayerAntennaRule* ant_rule = (_dbTechLayerAntennaRule*) this;
819 ant_rule->_area_diff_reduce_val.setDiff(areas, factors);
820 }
821
822 ////////////////////////////////////////////////////////////////////
823 //
824 // _dbTechAntennaAreaElement - Methods
825 //
826 ////////////////////////////////////////////////////////////////////
827
_dbTechAntennaAreaElement(const _dbTechAntennaAreaElement & e)828 _dbTechAntennaAreaElement::_dbTechAntennaAreaElement(
829 const _dbTechAntennaAreaElement& e)
830 : _area(e._area), _lyidx(e._lyidx)
831 {
832 }
833
operator <<(dbOStream & stream,const _dbTechAntennaAreaElement * aae)834 dbOStream& operator<<(dbOStream& stream, const _dbTechAntennaAreaElement* aae)
835 {
836 stream << aae->_area;
837 stream << aae->_lyidx;
838 return stream;
839 }
840
operator >>(dbIStream & stream,_dbTechAntennaAreaElement * & aae)841 dbIStream& operator>>(dbIStream& stream, _dbTechAntennaAreaElement*& aae)
842 {
843 aae = new _dbTechAntennaAreaElement;
844 stream >> aae->_area;
845 stream >> aae->_lyidx;
846 return stream;
847 }
848
849 //
850 // Allocate a new element and add to container. Layer argument is optional
851 //
create(dbVector<_dbTechAntennaAreaElement * > & incon,double inarea,dbTechLayer * inly)852 void _dbTechAntennaAreaElement::create(
853 dbVector<_dbTechAntennaAreaElement*>& incon,
854 double inarea,
855 dbTechLayer* inly)
856 {
857 if (inarea < 0.0)
858 return;
859
860 _dbTechAntennaAreaElement* aae = new _dbTechAntennaAreaElement;
861 aae->_area = inarea;
862 if (inly)
863 aae->_lyidx = inly->getId();
864
865 incon.push_back(aae);
866 }
867
868 //
869 // Write out antenna element info given header string and file.
870 //
writeLef(const char * header,dbTech * tech,lefout & writer) const871 void _dbTechAntennaAreaElement::writeLef(const char* header,
872 dbTech* tech,
873 lefout& writer) const
874 {
875 fprintf(writer.out(), " %s %g ", header, _area);
876 if (_lyidx != dbIdValidation::invalidId())
877 fprintf(writer.out(),
878 "LAYER %s ",
879 dbTechLayer::getTechLayer(tech, _lyidx)->getName().c_str());
880 fprintf(writer.out(), ";\n");
881 }
882
883 ////////////////////////////////////////////////////////////////////
884 //
885 // _dbTechAntennaPinModel methods here.
886 //
887 ////////////////////////////////////////////////////////////////////
888
_dbTechAntennaPinModel(_dbDatabase *,const _dbTechAntennaPinModel & m)889 _dbTechAntennaPinModel::_dbTechAntennaPinModel(_dbDatabase*,
890 const _dbTechAntennaPinModel& m)
891 : _mterm(m._mterm)
892 {
893 dbVector<_dbTechAntennaAreaElement*>::const_iterator itr;
894
895 for (itr = m._gate_area.begin(); itr != m._gate_area.end(); ++itr) {
896 _dbTechAntennaAreaElement* e = new _dbTechAntennaAreaElement(*(*itr));
897 ZALLOCATED(e);
898 _gate_area.push_back(e);
899 }
900
901 for (itr = m._max_area_car.begin(); itr != m._max_area_car.end(); ++itr) {
902 _dbTechAntennaAreaElement* e = new _dbTechAntennaAreaElement(*(*itr));
903 ZALLOCATED(e);
904 _max_area_car.push_back(e);
905 }
906
907 for (itr = m._max_sidearea_car.begin(); itr != m._max_sidearea_car.end();
908 ++itr) {
909 _dbTechAntennaAreaElement* e = new _dbTechAntennaAreaElement(*(*itr));
910 ZALLOCATED(e);
911 _max_sidearea_car.push_back(e);
912 }
913
914 for (itr = m._max_cut_car.begin(); itr != m._max_cut_car.end(); ++itr) {
915 _dbTechAntennaAreaElement* e = new _dbTechAntennaAreaElement(*(*itr));
916 ZALLOCATED(e);
917 _max_cut_car.push_back(e);
918 }
919 }
920
operator <<(dbOStream & stream,const _dbTechAntennaPinModel & inmod)921 dbOStream& operator<<(dbOStream& stream, const _dbTechAntennaPinModel& inmod)
922 {
923 stream << inmod._mterm;
924 stream << inmod._gate_area;
925 stream << inmod._max_area_car;
926 stream << inmod._max_sidearea_car;
927 stream << inmod._max_cut_car;
928
929 return stream;
930 }
931
operator >>(dbIStream & stream,_dbTechAntennaPinModel & inmod)932 dbIStream& operator>>(dbIStream& stream, _dbTechAntennaPinModel& inmod)
933 {
934 stream >> inmod._mterm;
935 stream >> inmod._gate_area;
936 stream >> inmod._max_area_car;
937 stream >> inmod._max_sidearea_car;
938 stream >> inmod._max_cut_car;
939 return stream;
940 }
941
942 ////////////////////////////////////////////////////////////////////
943 //
944 // dbTechAntennaPinModel methods here.
945 //
946 ////////////////////////////////////////////////////////////////////
947
addGateAreaEntry(double inval,dbTechLayer * refly)948 void dbTechAntennaPinModel::addGateAreaEntry(double inval, dbTechLayer* refly)
949 {
950 _dbTechAntennaPinModel* xmod = (_dbTechAntennaPinModel*) this;
951 _dbTechAntennaAreaElement::create(xmod->_gate_area, inval, refly);
952 }
953
addMaxAreaCAREntry(double inval,dbTechLayer * refly)954 void dbTechAntennaPinModel::addMaxAreaCAREntry(double inval, dbTechLayer* refly)
955 {
956 _dbTechAntennaPinModel* xmod = (_dbTechAntennaPinModel*) this;
957 _dbTechAntennaAreaElement::create(xmod->_max_area_car, inval, refly);
958 }
959
addMaxSideAreaCAREntry(double inval,dbTechLayer * refly)960 void dbTechAntennaPinModel::addMaxSideAreaCAREntry(double inval,
961 dbTechLayer* refly)
962 {
963 _dbTechAntennaPinModel* xmod = (_dbTechAntennaPinModel*) this;
964 _dbTechAntennaAreaElement::create(xmod->_max_sidearea_car, inval, refly);
965 }
966
addMaxCutCAREntry(double inval,dbTechLayer * refly)967 void dbTechAntennaPinModel::addMaxCutCAREntry(double inval, dbTechLayer* refly)
968 {
969 _dbTechAntennaPinModel* xmod = (_dbTechAntennaPinModel*) this;
970 _dbTechAntennaAreaElement::create(xmod->_max_cut_car, inval, refly);
971 }
972
getAntennaValues(_dbDatabase * db,const dbVector<_dbTechAntennaAreaElement * > & elements,std::vector<std::pair<double,dbTechLayer * >> & result)973 void _dbTechAntennaPinModel::getAntennaValues(
974 _dbDatabase* db,
975 const dbVector<_dbTechAntennaAreaElement*>& elements,
976 std::vector<std::pair<double, dbTechLayer*>>& result)
977 {
978 _dbTech* tech = (_dbTech*) ((dbDatabase*) db)->getTech();
979
980 for (auto elem : elements) {
981 dbTechLayer* layer = nullptr;
982 dbId<_dbTechLayer> layerId = elem->getLayerId();
983 if (layerId.isValid()) {
984 layer = (dbTechLayer*) tech->_layer_tbl->getPtr(layerId);
985 }
986 result.emplace_back(elem->getArea(), layer);
987 }
988 }
989
getGateArea(std::vector<std::pair<double,dbTechLayer * >> & data)990 void dbTechAntennaPinModel::getGateArea(
991 std::vector<std::pair<double, dbTechLayer*>>& data)
992 {
993 _dbTechAntennaPinModel* xmod = (_dbTechAntennaPinModel*) this;
994 xmod->getAntennaValues(getImpl()->getDatabase(), xmod->_gate_area, data);
995 }
996
getMaxAreaCAR(std::vector<std::pair<double,dbTechLayer * >> & data)997 void dbTechAntennaPinModel::getMaxAreaCAR(
998 std::vector<std::pair<double, dbTechLayer*>>& data)
999 {
1000 _dbTechAntennaPinModel* xmod = (_dbTechAntennaPinModel*) this;
1001 xmod->getAntennaValues(getImpl()->getDatabase(), xmod->_max_area_car, data);
1002 }
1003
getMaxSideAreaCAR(std::vector<std::pair<double,dbTechLayer * >> & data)1004 void dbTechAntennaPinModel::getMaxSideAreaCAR(
1005 std::vector<std::pair<double, dbTechLayer*>>& data)
1006 {
1007 _dbTechAntennaPinModel* xmod = (_dbTechAntennaPinModel*) this;
1008 xmod->getAntennaValues(
1009 getImpl()->getDatabase(), xmod->_max_sidearea_car, data);
1010 }
1011
getMaxCutCAR(std::vector<std::pair<double,dbTechLayer * >> & data)1012 void dbTechAntennaPinModel::getMaxCutCAR(
1013 std::vector<std::pair<double, dbTechLayer*>>& data)
1014 {
1015 _dbTechAntennaPinModel* xmod = (_dbTechAntennaPinModel*) this;
1016 xmod->getAntennaValues(getImpl()->getDatabase(), xmod->_max_cut_car, data);
1017 }
1018
writeLef(dbTech * tech,lefout & writer) const1019 void dbTechAntennaPinModel::writeLef(dbTech* tech, lefout& writer) const
1020 {
1021 _dbTechAntennaPinModel* xmod = (_dbTechAntennaPinModel*) this;
1022 dbVector<_dbTechAntennaAreaElement*>::iterator ant_iter;
1023
1024 for (ant_iter = xmod->_gate_area.begin(); ant_iter != xmod->_gate_area.end();
1025 ant_iter++)
1026 (*ant_iter)->writeLef("ANTENNAGATEAREA", tech, writer);
1027
1028 for (ant_iter = xmod->_max_area_car.begin();
1029 ant_iter != xmod->_max_area_car.end();
1030 ant_iter++)
1031 (*ant_iter)->writeLef("ANTENNAMAXAREACAR", tech, writer);
1032
1033 for (ant_iter = xmod->_max_sidearea_car.begin();
1034 ant_iter != xmod->_max_sidearea_car.end();
1035 ant_iter++)
1036 (*ant_iter)->writeLef("ANTENNAMAXSIDEAREACAR", tech, writer);
1037
1038 for (ant_iter = xmod->_max_cut_car.begin();
1039 ant_iter != xmod->_max_cut_car.end();
1040 ant_iter++)
1041 (*ant_iter)->writeLef("ANTENNAMAXCUTCAR", tech, writer);
1042 }
1043
getAntennaPinModel(dbMaster * _master,uint dbid)1044 dbTechAntennaPinModel* dbTechAntennaPinModel::getAntennaPinModel(
1045 dbMaster* _master,
1046 uint dbid)
1047 {
1048 _dbMaster* master = (_dbMaster*) _master;
1049 return (dbTechAntennaPinModel*) master->_antenna_pin_model_tbl->getPtr(dbid);
1050 }
1051
1052 } // namespace odb
1053