// OpenSTA, Static Timing Analyzer // Copyright (c) 2020, Parallax Software, Inc. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "Machine.hh" #include "DisallowCopyAssign.hh" #include "Vector.hh" #include "Transition.hh" #include "Delay.hh" #include "LibertyClass.hh" namespace sta { class TimingArcAttrs; class WireTimingArc; class WireTimingArcSetArcIterator; class TimingArcSetArcIterator; typedef int TimingArcIndex; typedef Vector TimingArcSeq; typedef Map ScaledTimingModelMap; enum class TimingType { clear, combinational, combinational_fall, combinational_rise, falling_edge, hold_falling, hold_rising, min_pulse_width, minimum_period, nochange_high_high, nochange_high_low, nochange_low_high, nochange_low_low, non_seq_hold_falling, non_seq_hold_rising, non_seq_setup_falling, non_seq_setup_rising, preset, recovery_falling, recovery_rising, removal_falling, removal_rising, retaining_time, rising_edge, setup_falling, setup_rising, skew_falling, skew_rising, three_state_disable, three_state_disable_fall, three_state_disable_rise, three_state_enable, three_state_enable_fall, three_state_enable_rise, min_clock_tree_path, max_clock_tree_path, unknown }; const char * timingTypeString(TimingType type); TimingType findTimingType(const char *string); bool timingTypeIsCheck(TimingType type); ScaleFactorType timingTypeScaleFactorType(TimingType type); //////////////////////////////////////////////////////////////// class TimingArcAttrs { public: TimingArcAttrs(); virtual ~TimingArcAttrs(); void deleteContents(); TimingType timingType() const { return timing_type_; } void setTimingType(TimingType type); TimingSense timingSense() const { return timing_sense_; } void setTimingSense(TimingSense sense); FuncExpr *cond() const { return cond_; } FuncExpr *&condRef() { return cond_; } const char *sdfCond() const { return sdf_cond_; } void setSdfCond(const char *cond); const char *sdfCondStart() const { return sdf_cond_start_; } void setSdfCondStart(const char *cond); const char *sdfCondEnd() const { return sdf_cond_end_; } void setSdfCondEnd(const char *cond); const char *modeName() const { return mode_name_; } void setModeName(const char *name); const char *modeValue() const { return mode_value_; } void setModeValue(const char *value); TimingModel *model(RiseFall *rf) const; void setModel(RiseFall *rf, TimingModel *model); float ocvArcDepth() const { return ocv_arc_depth_; } void setOcvArcDepth(float depth); protected: TimingType timing_type_; TimingSense timing_sense_; FuncExpr *cond_; const char *sdf_cond_; const char *sdf_cond_start_; const char *sdf_cond_end_; const char *mode_name_; const char *mode_value_; float ocv_arc_depth_; TimingModel *models_[RiseFall::index_count]; private: DISALLOW_COPY_AND_ASSIGN(TimingArcAttrs); }; // A timing arc set is a group of related timing arcs between from/to // a pair of cell ports. Wire timing arcs are a special set owned by // the TimingArcSet class. // // See ~LibertyCell for delete of TimingArcSet members. class TimingArcSet { public: TimingArcSet(LibertyCell *cell, LibertyPort *from, LibertyPort *to, LibertyPort *related_out, TimingRole *role, TimingArcAttrs *attrs); virtual ~TimingArcSet(); LibertyCell *libertyCell() const; LibertyPort *from() const { return from_; } LibertyPort *to() const { return to_; } LibertyPort *relatedOut() const { return related_out_; } TimingRole *role() const { return role_; }; TimingSense sense() const; // Rise/fall if the arc set is rising_edge or falling_edge. RiseFall *isRisingFallingEdge() const; size_t arcCount() const { return arcs_.size(); } TimingArcSeq &arcs() { return arcs_; } // Return 1 or 2 arcs matching from transition. void arcsFrom(const RiseFall *from_rf, // Return values. TimingArc *&arc1, TimingArc *&arc2); const TimingArcSeq &arcs() const { return arcs_; } // Use the TimingArcSetArcIterator(arc_set) constructor instead. TimingArcSetArcIterator *timingArcIterator() __attribute__ ((deprecated)); TimingArcIndex addTimingArc(TimingArc *arc); void deleteTimingArc(TimingArc *arc); TimingArc *findTimingArc(unsigned arc_index); void setRole(TimingRole *role); FuncExpr *cond() const { return cond_; } // Cond default is the timing arcs with no condition when there are // other conditional timing arcs between the same pins. bool isCondDefault() const { return is_cond_default_; } void setIsCondDefault(bool is_default); // SDF IOPATHs match sdfCond. // sdfCond (IOPATH) reuses sdfCondStart (timing check) variable. const char *sdfCond() const { return sdf_cond_start_; } // SDF timing checks match sdfCondStart/sdfCondEnd. const char *sdfCondStart() const { return sdf_cond_start_; } const char *sdfCondEnd() const { return sdf_cond_end_; } const char *modeName() const { return mode_name_; } const char *modeValue() const { return mode_value_; } // Timing arc set index in cell. TimingArcIndex index() const { return index_; } bool isDisabledConstraint() const { return is_disabled_constraint_; } void setIsDisabledConstraint(bool is_disabled); // OCV arc depth from timing/cell/library. float ocvArcDepth() const; static bool equiv(const TimingArcSet *set1, const TimingArcSet *set2); static bool less(const TimingArcSet *set1, const TimingArcSet *set2); static void init(); static void destroy(); // Psuedo definition for wire arcs. static TimingArcSet *wireTimingArcSet() { return wire_timing_arc_set_; } static int wireArcIndex(const RiseFall *rf); static int wireArcCount() { return 2; } protected: void init(LibertyCell *cell); TimingArcSet(TimingRole *role); LibertyPort *from_; LibertyPort *to_; LibertyPort *related_out_; TimingRole *role_; TimingArcSeq arcs_; FuncExpr *cond_; bool is_cond_default_; const char *sdf_cond_start_; const char *sdf_cond_end_; const char *mode_name_; const char *mode_value_; float ocv_arc_depth_; unsigned index_; bool is_disabled_constraint_; TimingArc *from_arc1_[RiseFall::index_count]; TimingArc *from_arc2_[RiseFall::index_count]; static TimingArcSet *wire_timing_arc_set_; private: DISALLOW_COPY_AND_ASSIGN(TimingArcSet); }; class TimingArcSetArcIterator : public TimingArcSeq::ConstIterator { public: TimingArcSetArcIterator(const TimingArcSet *set); private: DISALLOW_COPY_AND_ASSIGN(TimingArcSetArcIterator); }; // A timing arc is a single from/to transition between two ports. // The timing model parameters used for delay calculation are also found here. class TimingArc { public: TimingArc(TimingArcSet *set, Transition *from_rf, Transition *to_rf, TimingModel *model); ~TimingArc(); LibertyPort *from() const { return set_->from(); } LibertyPort *to() const { return set_->to(); } Transition *fromTrans() const { return from_rf_; } Transition *toTrans() const { return to_rf_; } TimingRole *role() const { return set_->role(); } TimingArcSet *set() const { return set_; } TimingSense sense() const; // Index in TimingArcSet. unsigned index() const { return index_; } TimingModel *model(const OperatingConditions *op_cond) const; TimingModel *model() const { return model_; } TimingArc *cornerArc(int ap_index); void setCornerArc(TimingArc *corner_arc, int ap_index); float driveResistance() const; ArcDelay intrinsicDelay() const; static bool equiv(const TimingArc *arc1, const TimingArc *arc2); protected: void setIndex(unsigned index); void addScaledModel(const OperatingConditions *op_cond, TimingModel *scaled_model); TimingArcSet *set_; Transition *from_rf_; Transition *to_rf_; unsigned index_; TimingModel *model_; ScaledTimingModelMap *scaled_models_; Vector corner_arcs_; private: DISALLOW_COPY_AND_ASSIGN(TimingArc); friend class LibertyLibrary; friend class LibertyCell; friend class TimingArcSet; }; } // namespace