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