1 // OpenSTA, Static Timing Analyzer
2 // Copyright (c) 2020, Parallax Software, Inc.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
16 
17 #pragma once
18 
19 #include "DisallowCopyAssign.hh"
20 #include "MinMax.hh"
21 #include "RiseFallMinMax.hh"
22 #include "ConcreteLibrary.hh"
23 #include "RiseFallValues.hh"
24 #include "MinMaxValues.hh"
25 #include "Transition.hh"
26 #include "Delay.hh"
27 #include "LibertyClass.hh"
28 
29 namespace sta {
30 
31 class LibertyCellIterator;
32 class LibertyCellPortIterator;
33 class LibertyCellPortBitIterator;
34 class LibertyCellPgPortIterator;
35 class LibertyPortMemberIterator;
36 class ModeValueDef;
37 class TestCell;
38 class PatternMatch;
39 class LatchEnable;
40 class Report;
41 class Debug;
42 class LibertyBuilder;
43 class LibertyReader;
44 class OcvDerate;
45 class TimingArcAttrs;
46 class InternalPowerAttrs;
47 class LibertyPgPort;
48 class StaState;
49 
50 typedef Set<Library*> LibrarySet;
51 typedef Map<const char*, TableTemplate*, CharPtrLess> TableTemplateMap;
52 typedef Map<const char*, BusDcl *, CharPtrLess> BusDclMap;
53 typedef Map<const char*, ScaleFactors*, CharPtrLess> ScaleFactorsMap;
54 typedef Map<const char*, Wireload*, CharPtrLess> WireloadMap;
55 typedef Map<const char*, WireloadSelection*, CharPtrLess> WireloadSelectionMap;
56 typedef Map<const char*, OperatingConditions*,
57 	    CharPtrLess> OperatingConditionsMap;
58 typedef Map<LibertyPort*, Sequential*> PortToSequentialMap;
59 typedef Vector<TimingArcSet*> TimingArcSetSeq;
60 typedef Set<TimingArcSet*, TimingArcSetLess> TimingArcSetMap;
61 typedef Map<LibertyPortPair, TimingArcSetSeq*,
62 	    LibertyPortPairLess> LibertyPortPairTimingArcMap;
63 typedef Vector<InternalPower*> InternalPowerSeq;
64 typedef Map<const LibertyPort *, InternalPowerSeq> PortInternalPowerSeq;
65 typedef Vector<LeakagePower*> LeakagePowerSeq;
66 typedef Map<const LibertyPort*, TimingArcSetSeq*> LibertyPortTimingArcMap;
67 typedef Map<const OperatingConditions*, LibertyCell*> ScaledCellMap;
68 typedef Map<const OperatingConditions*, LibertyPort*> ScaledPortMap;
69 typedef Map<const char *, ModeDef*, CharPtrLess> ModeDefMap;
70 typedef Map<const char *, ModeValueDef*, CharPtrLess> ModeValueMap;
71 typedef Map<TimingArcSet*, LatchEnable*> LatchEnableMap;
72 typedef Map<const char *, OcvDerate*, CharPtrLess> OcvDerateMap;
73 typedef Vector<TimingArcAttrs*> TimingArcAttrsSeq;
74 typedef Vector<InternalPowerAttrs*> InternalPowerAttrsSeq;
75 typedef Map<const char *, float, CharPtrLess> SupplyVoltageMap;
76 typedef Map<const char *, LibertyPgPort*, CharPtrLess> LibertyPgPortMap;
77 
78 enum class ClockGateType { none, latch_posedge, latch_negedge, other };
79 
80 enum class DelayModelType { cmos_linear, cmos_pwl, cmos2, table, polynomial, dcm };
81 
82 enum class ScaleFactorPvt { process, volt, temp, count, unknown };
83 
84 enum class TableTemplateType { delay, power, output_current, ocv, count };
85 
86 void
87 initLiberty();
88 void
89 deleteLiberty();
90 
91 ScaleFactorPvt
92 findScaleFactorPvt(const char *name);
93 const char *
94 scaleFactorPvtName(ScaleFactorPvt pvt);
95 
96 ScaleFactorType
97 findScaleFactorType(const char *name);
98 const char *
99 scaleFactorTypeName(ScaleFactorType type);
100 bool
101 scaleFactorTypeRiseFallSuffix(ScaleFactorType type);
102 bool
103 scaleFactorTypeRiseFallPrefix(ScaleFactorType type);
104 bool
105 scaleFactorTypeLowHighSuffix(ScaleFactorType type);
106 
107 // Timing sense as a string.
108 const char *
109 timingSenseString(TimingSense sense);
110 
111 // Opposite timing sense.
112 TimingSense
113 timingSenseOpposite(TimingSense sense);
114 
115 class LibertyLibrary : public ConcreteLibrary
116 {
117 public:
118   LibertyLibrary(const char *name,
119 		 const char *filename);
120   virtual ~LibertyLibrary();
121   LibertyCell *findLibertyCell(const char *name) const;
122   void findLibertyCellsMatching(PatternMatch *pattern,
123 				LibertyCellSeq *cells);
124   // Liberty cells that are buffers.
125   LibertyCellSeq *buffers();
126 
delayModelType() const127   DelayModelType delayModelType() const { return delay_model_type_; }
128   void setDelayModelType(DelayModelType type);
129   void addBusDcl(BusDcl *bus_dcl);
130   BusDcl *findBusDcl(const char *name) const;
131   void addTableTemplate(TableTemplate *tbl_template,
132 			TableTemplateType type);
133   TableTemplate *findTableTemplate(const char *name,
134 				   TableTemplateType type);
nominalProcess()135   float nominalProcess() { return nominal_process_; }
136   void setNominalProcess(float process);
nominalVoltage() const137   float nominalVoltage() const { return nominal_voltage_; }
138   void setNominalVoltage(float voltage);
nominalTemperature() const139   float nominalTemperature() const { return nominal_temperature_; }
140   void setNominalTemperature(float temperature);
141   void setScaleFactors(ScaleFactors *scales);
142   // Add named scale factor group.
143   void addScaleFactors(ScaleFactors *scales);
144   ScaleFactors *findScaleFactors(const char *name);
scaleFactors() const145   ScaleFactors *scaleFactors() const { return scale_factors_; }
146   float scaleFactor(ScaleFactorType type,
147 		    const Pvt *pvt) const;
148   float scaleFactor(ScaleFactorType type,
149 		    const LibertyCell *cell,
150 		    const Pvt *pvt) const;
151   float scaleFactor(ScaleFactorType type,
152 		    int tr_index,
153 		    const LibertyCell *cell,
154 		    const Pvt *pvt) const;
155   void setWireSlewDegradationTable(TableModel *model,
156 				   RiseFall *rf);
157   TableModel *wireSlewDegradationTable(const RiseFall *rf) const;
158   float degradeWireSlew(const LibertyCell *cell,
159 			const RiseFall *rf,
160 			const Pvt *pvt,
161 			float in_slew,
162 			float wire_delay) const;
163   // Check for supported axis variables.
164   // Return true if axes are supported.
165   static bool checkSlewDegradationAxes(Table *table);
166 
defaultInputPinCap() const167   float defaultInputPinCap() const { return default_input_pin_cap_; }
168   void setDefaultInputPinCap(float cap);
defaultOutputPinCap() const169   float defaultOutputPinCap() const { return default_output_pin_cap_; }
170   void setDefaultOutputPinCap(float cap);
defaultBidirectPinCap() const171   float defaultBidirectPinCap() const { return default_bidirect_pin_cap_; }
172   void setDefaultBidirectPinCap(float cap);
173 
174   void defaultIntrinsic(const RiseFall *rf,
175                         // Return values.
176                         float &intrisic,
177                         bool &exists) const;
178   void setDefaultIntrinsic(const RiseFall *rf,
179 			   float value);
180   // Uses defaultOutputPinRes or defaultBidirectPinRes based on dir.
181   void defaultPinResistance(const RiseFall *rf,
182 			    const PortDirection *dir,
183 			    // Return values.
184 			    float &res,
185 			    bool &exists) const;
186   void defaultBidirectPinRes(const RiseFall *rf,
187 			     // Return values.
188 			     float &res,
189 			     bool &exists) const;
190   void setDefaultBidirectPinRes(const RiseFall *rf,
191 				float value);
192   void defaultOutputPinRes(const RiseFall *rf,
193 			   // Return values.
194 			   float &res,
195 			   bool &exists) const;
196   void setDefaultOutputPinRes(const RiseFall *rf,
197 			      float value);
198 
199   void defaultMaxSlew(float &slew,
200 		      bool &exists) const;
201   void setDefaultMaxSlew(float slew);
202   void defaultMaxCapacitance(float &cap,
203 			     bool &exists) const;
204   void setDefaultMaxCapacitance(float cap);
205   void defaultMaxFanout(float &fanout,
206 			bool &exists) const;
207   void setDefaultMaxFanout(float fanout);
208   void defaultFanoutLoad(// Return values.
209 			 float &fanout,
210 			 bool &exists) const;
211   void setDefaultFanoutLoad(float load);
212 
213   // Logic thresholds.
214   float inputThreshold(const RiseFall *rf) const;
215   void setInputThreshold(const RiseFall *rf,
216 			 float th);
217   float outputThreshold(const RiseFall *rf) const;
218   void setOutputThreshold(const RiseFall *rf,
219 			  float th);
220   // Slew thresholds (measured).
221   float slewLowerThreshold(const RiseFall *rf) const;
222   void setSlewLowerThreshold(const RiseFall *rf,
223 			     float th);
224   float slewUpperThreshold(const RiseFall *rf) const;
225   void setSlewUpperThreshold(const RiseFall *rf,
226 			     float th);
227   // The library and delay calculator use the liberty slew upper/lower
228   // (measured) thresholds for the table axes and value.  These slews
229   // are scaled by slew_derate_from_library to get slews reported to
230   // the user.
231   // slew(measured) = slew_derate_from_library * slew(table)
232   //   measured is from slew_lower_threshold to slew_upper_threshold
233   float slewDerateFromLibrary() const;
234   void setSlewDerateFromLibrary(float derate);
235 
units()236   Units *units() { return units_; }
units() const237   const Units *units() const { return units_; }
238 
239   Wireload *findWireload(const char *name) const;
240   void setDefaultWireload(Wireload *wireload);
241   Wireload *defaultWireload() const;
242   WireloadSelection *findWireloadSelection(const char *name) const;
243   WireloadSelection *defaultWireloadSelection() const;
244 
245   void addWireload(Wireload *wireload);
246   WireloadMode defaultWireloadMode() const;
247   void setDefaultWireloadMode(WireloadMode mode);
248   void addWireloadSelection(WireloadSelection *selection);
249   void setDefaultWireloadSelection(WireloadSelection *selection);
250 
251   OperatingConditions *findOperatingConditions(const char *name);
252   OperatingConditions *defaultOperatingConditions() const;
253   void addOperatingConditions(OperatingConditions *op_cond);
254   void setDefaultOperatingConditions(OperatingConditions *op_cond);
255 
256   // AOCV
257   // Zero means the ocv depth is not specified.
258   float ocvArcDepth() const;
259   void setOcvArcDepth(float depth);
260   OcvDerate *defaultOcvDerate() const;
261   void setDefaultOcvDerate(OcvDerate *derate);
262   OcvDerate *findOcvDerate(const char *derate_name);
263   void addOcvDerate(OcvDerate *derate);
264   void addSupplyVoltage(const char *suppy_name,
265 			float voltage);
266   bool supplyExists(const char *suppy_name) const;
267   void supplyVoltage(const char *supply_name,
268 		     // Return value.
269 		     float &voltage,
270 		     bool &exists) const;
271 
272   // Make scaled cell.  Call LibertyCell::addScaledCell after it is complete.
273   LibertyCell *makeScaledCell(const char *name,
274 			      const char *filename);
275 
276   static void
277   makeCornerMap(LibertyLibrary *lib,
278 		int ap_index,
279 		Network *network,
280 		Report *report);
281   static void
282   makeCornerMap(LibertyCell *link_cell,
283 		LibertyCell *map_cell,
284 		int ap_index,
285 		Report *report);
286   static void
287   makeCornerMap(LibertyCell *cell1,
288 		LibertyCell *cell2,
289 		bool link,
290 		int ap_index,
291 		Report *report);
292 
293 protected:
294   float degradeWireSlew(const LibertyCell *cell,
295 			const Pvt *pvt,
296 			const TableModel *model,
297 			float in_slew,
298 			float wire_delay) const;
299 
300   Units *units_;
301   DelayModelType delay_model_type_;
302   BusDclMap bus_dcls_;
303   TableTemplateMap template_maps_[int(TableTemplateType::count)];
304   float nominal_process_;
305   float nominal_voltage_;
306   float nominal_temperature_;
307   ScaleFactors *scale_factors_;
308   ScaleFactorsMap scale_factors_map_;
309   TableModel *wire_slew_degradation_tbls_[RiseFall::index_count];
310   float default_input_pin_cap_;
311   float default_output_pin_cap_;
312   float default_bidirect_pin_cap_;
313   RiseFallValues default_intrinsic_;
314   RiseFallValues default_inout_pin_res_;
315   RiseFallValues default_output_pin_res_;
316   float default_fanout_load_;
317   bool default_fanout_load_exists_;
318   float default_max_cap_;
319   bool default_max_cap_exists_;
320   float default_max_fanout_;
321   bool default_max_fanout_exists_;
322   float default_max_slew_;
323   bool default_max_slew_exists_;
324   float input_threshold_[RiseFall::index_count];
325   float output_threshold_[RiseFall::index_count];
326   float slew_lower_threshold_[RiseFall::index_count];
327   float slew_upper_threshold_[RiseFall::index_count];
328   float slew_derate_from_library_;
329   WireloadMap wireloads_;
330   Wireload *default_wire_load_;
331   WireloadMode default_wire_load_mode_;
332   WireloadSelection *default_wire_load_selection_;
333   WireloadSelectionMap wire_load_selections_;
334   OperatingConditionsMap operating_conditions_;
335   OperatingConditions *default_operating_conditions_;
336   float ocv_arc_depth_;
337   OcvDerate *default_ocv_derate_;
338   OcvDerateMap ocv_derate_map_;
339   SupplyVoltageMap supply_voltage_map_;
340   LibertyCellSeq *buffers_;
341 
342   // Set if any library has rise/fall capacitances.
343   static bool found_rise_fall_caps_;
344   static constexpr float input_threshold_default_ = .5;
345   static constexpr float output_threshold_default_ = .5;
346   static constexpr float slew_lower_threshold_default_ = .2;
347   static constexpr float slew_upper_threshold_default_ = .8;
348 
349 private:
350   DISALLOW_COPY_AND_ASSIGN(LibertyLibrary);
351 
352   friend class LibertyCell;
353   friend class LibertyCellIterator;
354   friend class TableTemplateIterator;
355   friend class OperatingConditionsIterator;
356 };
357 
358 class LibertyCellIterator : public Iterator<LibertyCell*>
359 {
360 public:
361   explicit LibertyCellIterator(const LibertyLibrary *library);
362   bool hasNext();
363   LibertyCell *next();
364 
365 private:
366   DISALLOW_COPY_AND_ASSIGN(LibertyCellIterator);
367 
368   ConcreteCellMap::ConstIterator iter_;
369 };
370 
371 class TableTemplateIterator : public TableTemplateMap::ConstIterator
372 {
373 public:
TableTemplateIterator(const LibertyLibrary * library,TableTemplateType type)374   TableTemplateIterator(const LibertyLibrary *library,
375 			TableTemplateType type) :
376     TableTemplateMap::ConstIterator(library->template_maps_[int(type)]) {}
377 };
378 
379 class OperatingConditionsIterator : public OperatingConditionsMap::ConstIterator
380 {
381 public:
OperatingConditionsIterator(const LibertyLibrary * library)382   OperatingConditionsIterator(const LibertyLibrary *library) :
383     OperatingConditionsMap::ConstIterator(library->operating_conditions_) {}
384 };
385 
386 ////////////////////////////////////////////////////////////////
387 
388 class LibertyCell : public ConcreteCell
389 {
390 public:
391   LibertyCell(LibertyLibrary *library,
392 	      const char *name,
393 	      const char *filename);
394   virtual ~LibertyCell();
libertyLibrary() const395   LibertyLibrary *libertyLibrary() const { return liberty_library_; }
libertyLibrary()396   LibertyLibrary *libertyLibrary() { return liberty_library_; }
397   LibertyPort *findLibertyPort(const char *name) const;
398   void findLibertyPortsMatching(PatternMatch *pattern,
399 				LibertyPortSeq *ports) const;
hasInternalPorts() const400   bool hasInternalPorts() const { return has_internal_ports_; }
401   LibertyPgPort *findPgPort(const char *name) const;
pgPortCount() const402   size_t pgPortCount() const { return pg_port_map_.size(); }
scaleFactors() const403   ScaleFactors *scaleFactors() const { return scale_factors_; }
404   void setScaleFactors(ScaleFactors *scale_factors);
405   ModeDef *makeModeDef(const char *name);
406   ModeDef *findModeDef(const char *name);
407 
area() const408   float area() const { return area_; }
409   void setArea(float area);
dontUse() const410   bool dontUse() const { return dont_use_; }
411   void setDontUse(bool dont_use);
isMacro() const412   bool isMacro() const { return is_macro_; }
413   void setIsMacro(bool is_macro);
isMemory() const414   bool isMemory() const { return is_memory_; }
415   void setIsMemory(bool is_memory);
isPad() const416   bool isPad() const { return is_pad_; }
417   void setIsPad(bool is_pad);
isLevelShifter() const418   bool isLevelShifter() const { return is_level_shifter_; }
419   void setIsLevelShifter(bool is_level_shifter);
interfaceTiming() const420   bool interfaceTiming() const { return interface_timing_; }
421   void setInterfaceTiming(bool value);
422   bool isClockGateLatchPosedge() const;
423   bool isClockGateLatchNegedge() const;
424   bool isClockGateOther() const;
425   bool isClockGate() const;
426   void setClockGateType(ClockGateType type);
427   // from or to may be nullptr to wildcard.
428   TimingArcSetSeq *timingArcSets(const LibertyPort *from,
429 				 const LibertyPort *to) const;
430   size_t timingArcSetCount() const;
431   // Find a timing arc set equivalent to key.
432   TimingArcSet *findTimingArcSet(TimingArcSet *key) const;
433   TimingArcSet *findTimingArcSet(unsigned arc_set_index) const;
434   bool hasTimingArcs(LibertyPort *port) const;
435 
436   InternalPowerSeq *internalPowers();
437   InternalPowerSeq *internalPowers(const LibertyPort *port);
leakagePowers()438   LeakagePowerSeq *leakagePowers() { return &leakage_powers_; }
439   void leakagePower(// Return values.
440 		    float &leakage,
441 		    bool &exists) const;
leakagePowerExists() const442   bool leakagePowerExists() const { return leakage_power_exists_; }
443 
444   bool hasSequentials() const;
445   // Find the sequential with the output connected to an (internal) port.
446   Sequential *outputPortSequential(LibertyPort *port);
447 
448   // Find bus declaration local to this cell.
449   BusDcl *findBusDcl(const char *name) const;
450   // True when TimingArcSetBuilder::makeRegLatchArcs infers register
451   // timing arcs.
hasInferedRegTimingArcs() const452   bool hasInferedRegTimingArcs() const { return has_infered_reg_timing_arcs_; }
testCell() const453   TestCell *testCell() const { return test_cell_; }
454   bool isLatchData(LibertyPort *port);
455   void latchEnable(TimingArcSet *arc_set,
456 		   // Return values.
457 		   LibertyPort *&enable_port,
458 		   FuncExpr *&enable_func,
459 		   RiseFall *&enable_rf) const;
460   RiseFall *latchCheckEnableTrans(TimingArcSet *check_set);
isDisabledConstraint() const461   bool isDisabledConstraint() const { return is_disabled_constraint_; }
462   LibertyCell *cornerCell(int ap_index);
463 
464   // AOCV
465   float ocvArcDepth() const;
466   OcvDerate *ocvDerate() const;
467   OcvDerate *findOcvDerate(const char *derate_name);
468 
469   // Build helpers.
470   void makeSequential(int size,
471 		      bool is_register,
472 		      FuncExpr *clk,
473 		      FuncExpr *data,
474 		      FuncExpr *clear,
475 		      FuncExpr *preset,
476 		      LogicValue clr_preset_out,
477 		      LogicValue clr_preset_out_inv,
478 		      LibertyPort *output,
479 		      LibertyPort *output_inv);
480   void addBusDcl(BusDcl *bus_dcl);
481   // Add scaled cell after it is complete.
482   void addScaledCell(OperatingConditions *op_cond,
483 		     LibertyCell *scaled_cell);
484   unsigned addTimingArcSet(TimingArcSet *set);
485   void addTimingArcAttrs(TimingArcAttrs *attrs);
486   void addInternalPower(InternalPower *power);
487   void addInternalPowerAttrs(InternalPowerAttrs *attrs);
488   void addLeakagePower(LeakagePower *power);
489   void setLeakagePower(float leakage);
490   void setOcvArcDepth(float depth);
491   void setOcvDerate(OcvDerate *derate);
492   void addOcvDerate(OcvDerate *derate);
493   void addPgPort(LibertyPgPort *pg_port);
494   void setTestCell(TestCell *test);
495   void setHasInferedRegTimingArcs(bool infered);
496   void setIsDisabledConstraint(bool is_disabled);
497   void setCornerCell(LibertyCell *corner_cell,
498 		     int ap_index);
499   // Call after cell is finished being constructed.
500   void finish(bool infer_latches,
501 	      Report *report,
502 	      Debug *debug);
503   bool isBuffer() const;
504   bool isInverter() const;
505   // Only valid when isBuffer() returns true.
506   void bufferPorts(// Return values.
507 		   LibertyPort *&input,
508 		   LibertyPort *&output) const;
509 
510 protected:
511   void addPort(ConcretePort *port);
512   void setHasInternalPorts(bool has_internal);
513   void setLibertyLibrary(LibertyLibrary *library);
514   void deleteTimingArcAttrs();
515   void makeLatchEnables(Report *report,
516 			Debug *debug);
517   FuncExpr *findLatchEnableFunc(LibertyPort *data,
518 				LibertyPort *enable) const;
519   LatchEnable *makeLatchEnable(LibertyPort *d,
520 			       LibertyPort *en,
521 			       LibertyPort *q,
522 			       TimingArcSet *d_to_q,
523 			       TimingArcSet *en_to_q,
524 			       TimingArcSet *setup_check,
525 			       Debug *debug);
526   void findDefaultCondArcs();
527   void translatePresetClrCheckRoles();
528   void inferLatchRoles(Debug *debug);
529   void deleteInternalPowerAttrs();
530   void makeTimingArcMap(Report *report);
531   void makeTimingArcPortMaps();
532   bool hasBufferFunc(const LibertyPort *input,
533 		     const LibertyPort *output) const;
534   bool hasInverterFunc(const LibertyPort *input,
535 		       const LibertyPort *output) const;
536 
537   LibertyLibrary *liberty_library_;
538   float area_;
539   bool dont_use_;
540   bool is_macro_;
541   bool is_memory_;
542   bool is_pad_;
543   bool is_level_shifter_;
544   bool has_internal_ports_;
545   bool interface_timing_;
546   ClockGateType clock_gate_type_;
547   TimingArcSetSeq timing_arc_sets_;
548   TimingArcSetMap timing_arc_set_map_;
549   LibertyPortPairTimingArcMap port_timing_arc_set_map_;
550   LibertyPortTimingArcMap timing_arc_set_from_map_;
551   LibertyPortTimingArcMap timing_arc_set_to_map_;
552   TimingArcAttrsSeq timing_arc_attrs_;
553   bool has_infered_reg_timing_arcs_;
554   InternalPowerSeq internal_powers_;
555   PortInternalPowerSeq port_internal_powers_;
556   InternalPowerAttrsSeq internal_power_attrs_;
557   LeakagePowerSeq leakage_powers_;
558   SequentialSeq sequentials_;
559   PortToSequentialMap port_to_seq_map_;
560   BusDclMap bus_dcls_;
561   ModeDefMap mode_defs_;
562   ScaleFactors *scale_factors_;
563   ScaledCellMap scaled_cells_;
564   TestCell *test_cell_;
565   // Latch D->Q to LatchEnable.
566   LatchEnableMap latch_d_to_q_map_;
567   // Latch EN->D setup to LatchEnable.
568   LatchEnableMap latch_check_map_;
569   // Ports that have latch D->Q timing arc sets from them.
570   LibertyPortSet latch_data_ports_;
571   float ocv_arc_depth_;
572   OcvDerate *ocv_derate_;
573   OcvDerateMap ocv_derate_map_;
574   bool is_disabled_constraint_;
575   Vector<LibertyCell*> corner_cells_;
576   float leakage_power_;
577   bool leakage_power_exists_;
578   LibertyPgPortMap pg_port_map_;
579 
580 private:
581   DISALLOW_COPY_AND_ASSIGN(LibertyCell);
582 
583   friend class LibertyLibrary;
584   friend class LibertyCellPortIterator;
585   friend class LibertyCellPgPortIterator;
586   friend class LibertyPort;
587   friend class LibertyBuilder;
588   friend class LibertyCellTimingArcSetIterator;
589   friend class LibertyCellSequentialIterator;
590 };
591 
592 class LibertyCellPortIterator : public Iterator<LibertyPort*>
593 {
594 public:
595   explicit LibertyCellPortIterator(const LibertyCell *cell);
596   bool hasNext();
597   LibertyPort *next();
598 
599 private:
600   DISALLOW_COPY_AND_ASSIGN(LibertyCellPortIterator);
601 
602   ConcretePortSeq::ConstIterator iter_;
603 };
604 
605 class LibertyCellPortBitIterator : public Iterator<LibertyPort*>
606 {
607 public:
608   explicit LibertyCellPortBitIterator(const LibertyCell *cell);
609   virtual ~LibertyCellPortBitIterator();
610   bool hasNext();
611   LibertyPort *next();
612 
613 private:
614   DISALLOW_COPY_AND_ASSIGN(LibertyCellPortBitIterator);
615 
616   ConcreteCellPortBitIterator *iter_;
617 };
618 
619 class LibertyCellPgPortIterator : public Iterator<LibertyPgPort*>
620 {
621 public:
622   LibertyCellPgPortIterator(const LibertyCell *cell);
623   bool hasNext();
624   LibertyPgPort *next();
625 
626 private:
627   DISALLOW_COPY_AND_ASSIGN(LibertyCellPgPortIterator);
628 
629   LibertyPgPortMap::Iterator iter_;
630 };
631 
632 class LibertyCellTimingArcSetIterator : public TimingArcSetSeq::ConstIterator
633 {
634 public:
635   LibertyCellTimingArcSetIterator(const LibertyCell *cell);
636   // from or to may be nullptr to wildcard.
637   LibertyCellTimingArcSetIterator(const LibertyCell *cell,
638 				  const LibertyPort *from,
639 				  const LibertyPort *to);
640 };
641 
642 class LibertyCellSequentialIterator : public SequentialSeq::ConstIterator
643 {
644 public:
LibertyCellSequentialIterator(const LibertyCell * cell)645   LibertyCellSequentialIterator(const LibertyCell *cell) :
646     SequentialSeq::ConstIterator(cell->sequentials_) {}
647 };
648 
649 ////////////////////////////////////////////////////////////////
650 
651 class LibertyPort : public ConcretePort
652 {
653 public:
libertyCell() const654   LibertyCell *libertyCell() const { return liberty_cell_; }
libertyLibrary() const655   LibertyLibrary *libertyLibrary() const { return liberty_cell_->libertyLibrary(); }
656   LibertyPort *findLibertyMember(int index) const;
657   LibertyPort *findLibertyBusBit(int index) const;
658   void fanoutLoad(// Return values.
659 		  float &fanout_load,
660 		  bool &exists) const;
661   void setFanoutLoad(float fanout_load);
662   float capacitance() const;
663   float capacitance(const MinMax *min_max) const;
664   float capacitance(const RiseFall *rf,
665 		    const MinMax *min_max) const;
666   void capacitance(const RiseFall *rf,
667 		   const MinMax *min_max,
668 		   // Return values.
669 		   float &cap,
670 		   bool &exists) const;
671   // Capacitance at op_cond derated by library/cell scale factors
672   // using pvt.
673   float capacitance(const RiseFall *rf,
674 		    const MinMax *min_max,
675 		    const OperatingConditions *op_cond,
676 		    const Pvt *pvt) const;
677   bool capacitanceIsOneValue() const;
678   void setCapacitance(float cap);
679   void setCapacitance(const RiseFall *rf,
680 		      const MinMax *min_max,
681 		      float cap);
682   // Max of rise/fall.
683   float driveResistance() const;
684   float driveResistance(const RiseFall *rf,
685 			const MinMax *min_max) const;
686   // Zero load delay.
687   ArcDelay intrinsicDelay(const StaState *sta) const;
688   ArcDelay intrinsicDelay(const RiseFall *rf,
689                           const MinMax *min_max,
690                           const StaState *sta) const;
function() const691   FuncExpr *function() const { return function_; }
692   void setFunction(FuncExpr *func);
functionRef()693   FuncExpr *&functionRef() { return function_; }
694   // Tristate enable function.
tristateEnable() const695   FuncExpr *tristateEnable() const { return tristate_enable_; }
696   void setTristateEnable(FuncExpr *enable);
tristateEnableRef()697   FuncExpr *&tristateEnableRef() { return tristate_enable_; }
698   void slewLimit(const MinMax *min_max,
699 		 // Return values.
700 		 float &limit,
701 		 bool &exists) const;
702   void setSlewLimit(float slew,
703 		    const MinMax *min_max);
704   void capacitanceLimit(const MinMax *min_max,
705 			// Return values.
706 			float &limit,
707 			bool &exists) const;
708   void setCapacitanceLimit(float cap,
709 			   const MinMax *min_max);
710   void fanoutLimit(const MinMax *min_max,
711 		   // Return values.
712 		   float &limit,
713 		   bool &exists) const;
714   void setFanoutLimit(float fanout,
715 		      const MinMax *min_max);
716   void minPeriod(const OperatingConditions *op_cond,
717 		 const Pvt *pvt,
718 		 float &min_period,
719 		 bool &exists) const;
720   // Unscaled value.
721   void minPeriod(float &min_period,
722 		 bool &exists) const;
723   void setMinPeriod(float min_period);
724   // high = rise, low = fall
725   void minPulseWidth(const RiseFall *hi_low,
726 		     const OperatingConditions *op_cond,
727 		     const Pvt *pvt,
728 		     float &min_width,
729 		     bool &exists) const;
730   // Unscaled value.
731   void minPulseWidth(const RiseFall *hi_low,
732 		     float &min_width,
733 		     bool &exists) const;
734   void setMinPulseWidth(RiseFall *hi_low,
735 			float min_width);
736   bool isClock() const;
737   void setIsClock(bool is_clk);
isClockGateClockPin() const738   bool isClockGateClockPin() const { return is_clk_gate_clk_pin_; }
739   void setIsClockGateClockPin(bool is_clk_gate_clk);
isClockGateEnablePin() const740   bool isClockGateEnablePin() const { return is_clk_gate_enable_pin_; }
741   void setIsClockGateEnablePin(bool is_clk_gate_enable);
isClockGateOutPin() const742   bool isClockGateOutPin() const { return is_clk_gate_out_pin_; }
743   void setIsClockGateOutPin(bool is_clk_gate_out);
isPllFeedbackPin() const744   bool isPllFeedbackPin() const { return is_pll_feedback_pin_; }
745   void setIsPllFeedbackPin(bool is_pll_feedback_pin);
746   // Has register/latch rise/fall edges from pin.
isRegClk() const747   bool isRegClk() const { return is_reg_clk_; }
748   void setIsRegClk(bool is_clk);
749   // Is the clock for timing checks.
isCheckClk() const750   bool isCheckClk() const { return is_check_clk_; }
751   void setIsCheckClk(bool is_clk);
pulseClkTrigger() const752   RiseFall *pulseClkTrigger() const { return pulse_clk_trigger_; }
753   // Rise for high, fall for low.
pulseClkSense() const754   RiseFall *pulseClkSense() const { return pulse_clk_sense_; }
755   void setPulseClk(RiseFall *rfigger,
756 		   RiseFall *sense);
isDisabledConstraint() const757   bool isDisabledConstraint() const { return is_disabled_constraint_; }
758   void setIsDisabledConstraint(bool is_disabled);
759   LibertyPort *cornerPort(int ap_index);
760   const LibertyPort *cornerPort(int ap_index) const;
761   void setCornerPort(LibertyPort *corner_port,
762 		     int ap_index);
relatedGroundPin() const763   const char *relatedGroundPin() const { return related_ground_pin_; }
764   void setRelatedGroundPin(const char *related_ground_pin);
relatedPowerPin() const765   const char *relatedPowerPin() const { return related_power_pin_; }
766   void setRelatedPowerPin(const char *related_power_pin);
767 
768   static bool equiv(const LibertyPort *port1,
769 		    const LibertyPort *port2);
770   static bool less(const LibertyPort *port1,
771 		   const LibertyPort *port2);
772 
773 protected:
774   // Constructor is internal to LibertyBuilder.
775   LibertyPort(LibertyCell *cell,
776 	      const char *name,
777 	      bool is_bus,
778 	      int from_index,
779 	      int to_index,
780 	      bool is_bundle,
781 	      ConcretePortSeq *members);
782   virtual ~LibertyPort();
783   void setDirection(PortDirection *dir);
784   void setMinPort(LibertyPort *min);
785   void addScaledPort(OperatingConditions *op_cond,
786 		     LibertyPort *scaled_port);
787 
788   LibertyCell *liberty_cell_;
789   FuncExpr *function_;
790   FuncExpr *tristate_enable_;
791   ScaledPortMap *scaled_ports_;
792   RiseFallMinMax capacitance_;
793   MinMaxFloatValues slew_limit_; // inputs and outputs
794   MinMaxFloatValues cap_limit_;    // outputs
795   float fanout_load_; // inputs
796   bool fanout_load_exists_;
797   MinMaxFloatValues fanout_limit_; // outputs
798   float min_period_;
799   float min_pulse_width_[RiseFall::index_count];
800   RiseFall *pulse_clk_trigger_;
801   RiseFall *pulse_clk_sense_;
802   const char *related_ground_pin_;
803   const char *related_power_pin_;
804   Vector<LibertyPort*> corner_ports_;
805 
806   unsigned int min_pulse_width_exists_:RiseFall::index_count;
807   bool min_period_exists_:1;
808   bool is_clk_:1;
809   bool is_reg_clk_:1;
810   bool is_check_clk_:1;
811   bool is_clk_gate_clk_pin_:1;
812   bool is_clk_gate_enable_pin_:1;
813   bool is_clk_gate_out_pin_:1;
814   bool is_pll_feedback_pin_:1;
815   bool is_disabled_constraint_:1;
816 
817 private:
818   DISALLOW_COPY_AND_ASSIGN(LibertyPort);
819 
820   friend class LibertyLibrary;
821   friend class LibertyCell;
822   friend class LibertyBuilder;
823   friend class LibertyReader;
824 };
825 
826 void
827 sortLibertyPortSet(LibertyPortSet *set,
828 		   LibertyPortSeq &ports);
829 
830 class LibertyPortMemberIterator : public Iterator<LibertyPort*>
831 {
832 public:
833   explicit LibertyPortMemberIterator(const LibertyPort *port);
834   virtual ~LibertyPortMemberIterator();
835   virtual bool hasNext();
836   virtual LibertyPort *next();
837 
838 private:
839   DISALLOW_COPY_AND_ASSIGN(LibertyPortMemberIterator);
840 
841   ConcretePortMemberIterator *iter_;
842 };
843 
844 // Process, voltage temperature.
845 class Pvt
846 {
847 public:
848   Pvt(float process,
849       float voltage,
850       float temperature);
~Pvt()851   virtual ~Pvt() {}
process() const852   float process() const { return process_; }
853   void setProcess(float process);
voltage() const854   float voltage() const { return voltage_; }
855   void setVoltage(float voltage);
temperature() const856   float temperature() const { return temperature_; }
857   void setTemperature(float temp);
858 
859 protected:
860   float process_;
861   float voltage_;
862   float temperature_;
863 
864 private:
865   DISALLOW_COPY_AND_ASSIGN(Pvt);
866 };
867 
868 class OperatingConditions : public Pvt
869 {
870 public:
871   explicit OperatingConditions(const char *name);
872   OperatingConditions(const char *name,
873 		      float process,
874 		      float voltage,
875 		      float temperature,
876 		      WireloadTree wire_load_tree);
877   virtual ~OperatingConditions();
name() const878   const char *name() const { return name_; }
wireloadTree() const879   WireloadTree wireloadTree() const { return wire_load_tree_; }
880   void setWireloadTree(WireloadTree tree);
881 
882 protected:
883   const char *name_;
884   WireloadTree wire_load_tree_;
885 
886 private:
887   DISALLOW_COPY_AND_ASSIGN(OperatingConditions);
888 };
889 
890 class ScaleFactors
891 {
892 public:
893   explicit ScaleFactors(const char *name);
894   ~ScaleFactors();
name() const895   const char *name() const { return name_; }
896   float scale(ScaleFactorType type,
897 	      ScaleFactorPvt pvt,
898 	      RiseFall *rf);
899   float scale(ScaleFactorType type,
900 	      ScaleFactorPvt pvt,
901 	      int tr_index);
902   float scale(ScaleFactorType type,
903 	      ScaleFactorPvt pvt);
904   void setScale(ScaleFactorType type,
905 		ScaleFactorPvt pvt,
906 		RiseFall *rf,
907 		float scale);
908   void setScale(ScaleFactorType type,
909 		ScaleFactorPvt pvt,
910 		float scale);
911   void print();
912 
913 protected:
914   const char *name_;
915   float scales_[scale_factor_type_count][int(ScaleFactorPvt::count)][RiseFall::index_count];
916 
917 private:
918   DISALLOW_COPY_AND_ASSIGN(ScaleFactors);
919 };
920 
921 class BusDcl
922 {
923 public:
924   BusDcl(const char *name,
925 	 int from,
926 	 int to);
927   ~BusDcl();
name() const928   const char *name() const { return name_; }
from() const929   int from() const { return from_; }
to() const930   int to() const { return to_; }
931 
932 protected:
933   const char *name_;
934   int from_;
935   int to_;
936 
937 private:
938   DISALLOW_COPY_AND_ASSIGN(BusDcl);
939 };
940 
941 // Cell mode_definition group.
942 class ModeDef
943 {
944 public:
945   ~ModeDef();
name() const946   const char *name() const { return name_; }
947   ModeValueDef *defineValue(const char *value,
948 			    FuncExpr *cond,
949 			    const char *sdf_cond);
950   ModeValueDef *findValueDef(const char *value);
values()951   ModeValueMap *values() { return &values_; }
952 
953 protected:
954   // Private to LibertyCell::makeModeDef.
955   explicit ModeDef(const char *name);
956 
957   const char *name_;
958   ModeValueMap values_;
959 
960 private:
961   DISALLOW_COPY_AND_ASSIGN(ModeDef);
962 
963   friend class LibertyCell;
964 };
965 
966 // Mode definition mode_value group.
967 class ModeValueDef
968 {
969 public:
970   ~ModeValueDef();
value() const971   const char *value() const { return value_; }
cond() const972   FuncExpr *cond() const { return cond_; }
condRef()973   FuncExpr *&condRef() { return cond_; }
sdfCond() const974   const char *sdfCond() const { return sdf_cond_; }
975   void setSdfCond(const char *sdf_cond);
976 
977 protected:
978   // Private to ModeDef::defineValue.
979   ModeValueDef(const char *value,
980 	       FuncExpr *cond,
981 	       const char *sdf_cond);
982 
983   const char *value_;
984   FuncExpr *cond_;
985   const char *sdf_cond_;
986 
987 private:
988   DISALLOW_COPY_AND_ASSIGN(ModeValueDef);
989 
990   friend class ModeDef;
991 };
992 
993 class TableTemplate
994 {
995 public:
996   explicit TableTemplate(const char *name);
997   TableTemplate(const char *name,
998 		TableAxis *axis1,
999 		TableAxis *axis2,
1000 		TableAxis *axis3);
1001   ~TableTemplate();
name() const1002   const char *name() const { return name_; }
1003   void setName(const char *name);
axis1() const1004   TableAxis *axis1() const { return axis1_; }
1005   void setAxis1(TableAxis *axis);
axis2() const1006   TableAxis *axis2() const { return axis2_; }
1007   void setAxis2(TableAxis *axis);
axis3() const1008   TableAxis *axis3() const { return axis3_; }
1009   void setAxis3(TableAxis *axis);
1010 
1011 protected:
1012   const char *name_;
1013   TableAxis *axis1_;
1014   TableAxis *axis2_;
1015   TableAxis *axis3_;
1016 
1017 private:
1018   DISALLOW_COPY_AND_ASSIGN(TableTemplate);
1019 };
1020 
1021 class TestCell
1022 {
1023 public:
1024   TestCell();
1025   TestCell(LibertyPort *data_in,
1026 	   LibertyPort *scan_in,
1027 	   LibertyPort *scan_enable,
1028 	   LibertyPort *scan_out,
1029 	   LibertyPort *scan_out_inv);
dataIn() const1030   LibertyPort *dataIn() const { return data_in_; }
1031   void setDataIn(LibertyPort *port);
scanIn() const1032   LibertyPort *scanIn() const { return scan_in_; }
1033   void setScanIn(LibertyPort *port);
scanEnable() const1034   LibertyPort *scanEnable() const { return scan_enable_; }
1035   void setScanEnable(LibertyPort *port);
scanOut() const1036   LibertyPort *scanOut() const { return scan_out_; }
1037   void setScanOut(LibertyPort *port);
scanOutInv() const1038   LibertyPort *scanOutInv() const { return scan_out_inv_; }
1039   void setScanOutInv(LibertyPort *port);
1040 
1041 protected:
1042   LibertyPort *data_in_;
1043   LibertyPort *scan_in_;
1044   LibertyPort *scan_enable_;
1045   LibertyPort *scan_out_;
1046   LibertyPort *scan_out_inv_;
1047 
1048 private:
1049   DISALLOW_COPY_AND_ASSIGN(TestCell);
1050 };
1051 
1052 class OcvDerate
1053 {
1054 public:
1055   OcvDerate(const char *name);
1056   ~OcvDerate();
name() const1057   const char *name() const { return name_; }
1058   Table *derateTable(const RiseFall *rf,
1059 		     const EarlyLate *early_late,
1060 		     PathType path_type);
1061   void setDerateTable(const RiseFall *rf,
1062 		      const EarlyLate *early_late,
1063 		      PathType path_type,
1064 		      Table *derate);
1065 
1066 private:
1067   const char *name_;
1068   // [rf_type][derate_type][path_type]
1069   Table *derate_[RiseFall::index_count][EarlyLate::index_count][path_type_count];
1070 };
1071 
1072 // Power/ground port.
1073 class LibertyPgPort
1074 {
1075 public:
1076   enum PgType { unknown,
1077 		primary_power, primary_ground,
1078 		backup_power, backup_ground,
1079 		internal_power, internal_ground,
1080 		nwell, pwell,
1081 		deepnwell, deeppwell};
1082   LibertyPgPort(const char *name,
1083 		LibertyCell *cell);
1084   ~LibertyPgPort();
name() const1085   const char *name() const { return name_; }
cell() const1086   LibertyCell *cell() const { return cell_; }
pgType() const1087   PgType pgType() const { return pg_type_; }
1088   void setPgType(PgType type);
voltageName() const1089   const char *voltageName() const { return voltage_name_; }
1090   void setVoltageName(const char *voltage_name);
1091   static bool equiv(const LibertyPgPort *port1,
1092 		    const LibertyPgPort *port2);
1093 
1094 private:
1095   const char *name_;
1096   PgType pg_type_;
1097   const char *voltage_name_;
1098   LibertyCell *cell_;
1099 };
1100 
1101 } // namespace
1102