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