Files
OpenSTA/include/sta/TimingArc.hh
T

298 lines
9.7 KiB
C++
Raw Normal View History

2018-09-28 08:54:21 -07:00
// OpenSTA, Static Timing Analyzer
2026-03-10 13:21:17 -07:00
// Copyright (c) 2026, Parallax Software, Inc.
2018-09-28 08:54:21 -07:00
//
// 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
2022-01-04 10:17:08 -07:00
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2018-09-28 08:54:21 -07:00
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
2022-01-04 10:17:08 -07:00
// along with this program. If not, see <https://www.gnu.org/licenses/>.
2025-01-21 18:54:33 -07:00
//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// This notice may not be removed or altered from any source distribution.
2018-09-28 08:54:21 -07:00
2020-02-15 17:13:16 -07:00
#pragma once
2018-09-28 08:54:21 -07:00
2026-04-15 09:38:10 -07:00
#include <map>
2022-06-25 11:59:07 -07:00
#include <memory>
2026-02-04 18:33:04 -07:00
#include <string>
2026-01-03 16:59:35 -08:00
#include <vector>
2022-06-25 11:59:07 -07:00
2020-12-20 08:31:33 -07:00
#include "Delay.hh"
2020-04-05 14:53:44 -07:00
#include "LibertyClass.hh"
2026-04-15 09:38:10 -07:00
#include "Transition.hh"
2018-09-28 08:54:21 -07:00
namespace sta {
class TimingArcAttrs;
class WireTimingArc;
2024-06-27 13:57:58 -07:00
class GateTableModel;
2026-01-03 16:59:35 -08:00
class Scene;
2018-09-28 08:54:21 -07:00
2026-01-03 16:59:35 -08:00
using TimingArcSeq = std::vector<TimingArc*>;
using ScaledTimingModelMap = std::map<const OperatingConditions*, TimingModel*>;
2018-09-28 08:54:21 -07:00
2019-03-12 17:25:53 -07:00
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
};
2018-09-28 08:54:21 -07:00
2026-03-28 19:13:35 -07:00
std::string_view
2025-03-30 15:27:53 -07:00
to_string(TimingType type);
2018-09-28 08:54:21 -07:00
TimingType
2026-04-13 14:58:16 -07:00
findTimingType(std::string_view type_name);
2018-09-28 08:54:21 -07:00
bool
timingTypeIsCheck(TimingType type);
ScaleFactorType
timingTypeScaleFactorType(TimingType type);
////////////////////////////////////////////////////////////////
class TimingArcAttrs
{
public:
TimingArcAttrs();
2022-06-25 10:08:33 -07:00
TimingArcAttrs(TimingSense sense);
2026-02-27 16:57:08 -08:00
~TimingArcAttrs();
2018-09-28 08:54:21 -07:00
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_; }
void setCond(FuncExpr *cond);
2026-02-04 18:33:04 -07:00
const std::string &sdfCond() const { return sdf_cond_; }
2026-04-13 14:58:16 -07:00
void setSdfCond(std::string_view cond);
2026-02-04 18:33:04 -07:00
const std::string &sdfCondStart() const { return sdf_cond_start_; }
2026-04-13 14:58:16 -07:00
void setSdfCondStart(std::string_view cond);
2026-02-04 18:33:04 -07:00
const std::string &sdfCondEnd() const { return sdf_cond_end_; }
2026-04-13 14:58:16 -07:00
void setSdfCondEnd(std::string_view cond);
2026-02-04 18:33:04 -07:00
const std::string &modeName() const { return mode_name_; }
2026-04-13 14:58:16 -07:00
void setModeName(std::string_view name);
2026-02-04 18:33:04 -07:00
const std::string &modeValue() const { return mode_value_; }
2026-04-13 14:58:16 -07:00
void setModeValue(std::string_view value);
2023-10-04 14:33:09 -07:00
TimingModel *model(const RiseFall *rf) const;
void setModel(const RiseFall *rf,
2026-01-03 16:59:35 -08:00
TimingModel *model);
2018-09-28 08:54:21 -07:00
float ocvArcDepth() const { return ocv_arc_depth_; }
void setOcvArcDepth(float depth);
protected:
TimingType timing_type_;
TimingSense timing_sense_;
FuncExpr *cond_;
2026-02-04 18:33:04 -07:00
std::string sdf_cond_;
std::string sdf_cond_start_;
std::string sdf_cond_end_;
std::string mode_name_;
std::string mode_value_;
2018-11-26 09:15:52 -08:00
float ocv_arc_depth_;
2019-11-11 15:30:19 -07:00
TimingModel *models_[RiseFall::index_count];
2018-09-28 08:54:21 -07:00
};
// 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
{
2026-02-04 18:33:04 -07:00
friend class LibertyCell;
2018-09-28 08:54:21 -07:00
public:
2026-02-27 16:57:08 -08:00
~TimingArcSet();
2026-04-18 11:39:03 -07:00
std::string to_string() const;
2018-09-28 08:54:21 -07:00
LibertyCell *libertyCell() const;
LibertyPort *from() const { return from_; }
LibertyPort *to() const { return to_; }
2022-01-15 12:51:05 -07:00
bool isWire() const;
2018-09-28 08:54:21 -07:00
LibertyPort *relatedOut() const { return related_out_; }
2025-03-30 15:27:53 -07:00
const TimingRole *role() const { return role_; };
2026-02-04 18:33:04 -07:00
TimingType timingType() const { return attrs_->timingType(); }
2018-09-28 08:54:21 -07:00
TimingSense sense() const;
2026-02-04 18:33:04 -07:00
TimingModel *model(const RiseFall *rf) const { return attrs_->model(rf); }
2018-09-28 08:54:21 -07:00
// Rise/fall if the arc set is rising_edge or falling_edge.
2024-06-27 13:57:58 -07:00
const RiseFall *isRisingFallingEdge() const;
2018-09-28 08:54:21 -07:00
size_t arcCount() const { return arcs_.size(); }
TimingArcSeq &arcs() { return arcs_; }
// Return 1 or 2 arcs matching from transition.
2019-11-11 15:30:19 -07:00
void arcsFrom(const RiseFall *from_rf,
2026-01-03 16:59:35 -08:00
// Return values.
TimingArc *&arc1,
TimingArc *&arc2) const;
2022-06-06 20:57:09 -07:00
TimingArc *arcTo(const RiseFall *to_rf) const;
2018-09-28 08:54:21 -07:00
const TimingArcSeq &arcs() const { return arcs_; }
2026-02-04 18:33:04 -07:00
size_t addTimingArc(TimingArc *arc);
2018-09-28 08:54:21 -07:00
void deleteTimingArc(TimingArc *arc);
TimingArc *findTimingArc(unsigned arc_index);
2025-03-30 15:27:53 -07:00
void setRole(const TimingRole *role);
2022-06-25 10:31:18 -07:00
FuncExpr *cond() const { return attrs_->cond(); }
2018-09-28 08:54:21 -07:00
// 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);
2026-03-05 18:41:25 -07:00
const FuncExpr *when() const { return attrs_->cond(); }
2018-09-28 08:54:21 -07:00
// SDF IOPATHs match sdfCond.
// sdfCond (IOPATH) reuses sdfCondStart (timing check) variable.
2026-02-04 18:33:04 -07:00
const std::string &sdfCond() const { return attrs_->sdfCondStart(); }
2018-09-28 08:54:21 -07:00
// SDF timing checks match sdfCondStart/sdfCondEnd.
2026-02-04 18:33:04 -07:00
const std::string &sdfCondStart() const { return attrs_->sdfCondStart(); }
const std::string &sdfCondEnd() const { return attrs_->sdfCondEnd(); }
const std::string &modeName() const { return attrs_->modeName(); }
const std::string &modeValue() const { return attrs_->modeValue(); }
2018-09-28 08:54:21 -07:00
// Timing arc set index in cell.
2026-02-04 18:33:04 -07:00
size_t index() const { return index_; }
void setIndex(size_t index);
2018-09-28 08:54:21 -07:00
// OCV arc depth from timing/cell/library.
float ocvArcDepth() const;
static bool equiv(const TimingArcSet *set1,
2026-01-03 16:59:35 -08:00
const TimingArcSet *set2);
2018-09-28 08:54:21 -07:00
static bool less(const TimingArcSet *set1,
2026-01-03 16:59:35 -08:00
const TimingArcSet *set2);
2018-09-28 08:54:21 -07:00
static void init();
static void destroy();
// Psuedo definition for wire arcs.
static TimingArcSet *wireTimingArcSet() { return wire_timing_arc_set_; }
2019-11-11 15:30:19 -07:00
static int wireArcIndex(const RiseFall *rf);
2018-09-28 08:54:21 -07:00
static int wireArcCount() { return 2; }
2026-06-13 16:31:24 -07:00
// Psuedo definition for port ref_pin arcs.
static TimingArcSet *portRefPinTimingArcSet() { return port_refpin_timing_arc_set_; }
2018-09-28 08:54:21 -07:00
protected:
2025-03-30 15:27:53 -07:00
TimingArcSet(const TimingRole *role,
2022-06-25 11:59:07 -07:00
TimingArcAttrsPtr attrs);
2026-02-04 18:33:04 -07:00
TimingArcSet(LibertyCell *cell,
LibertyPort *from,
LibertyPort *to,
LibertyPort *related_out,
const TimingRole *role,
TimingArcAttrsPtr attrs,
size_t index);
2018-09-28 08:54:21 -07:00
LibertyPort *from_;
LibertyPort *to_;
LibertyPort *related_out_;
2025-03-30 15:27:53 -07:00
const TimingRole *role_;
2022-06-25 11:59:07 -07:00
// TimingArcAttrs are shared by TimingArcSets in a bus with timing groups.
TimingArcAttrsPtr attrs_;
2018-09-28 08:54:21 -07:00
TimingArcSeq arcs_;
bool is_cond_default_;
2026-02-04 18:33:04 -07:00
size_t index_;
2019-11-11 15:30:19 -07:00
TimingArc *from_arc1_[RiseFall::index_count];
TimingArc *from_arc2_[RiseFall::index_count];
2022-06-06 20:57:09 -07:00
TimingArc *to_arc_[RiseFall::index_count];
2018-09-28 08:54:21 -07:00
2022-06-25 11:59:07 -07:00
static TimingArcAttrsPtr wire_timing_arc_attrs_;
2018-09-28 08:54:21 -07:00
static TimingArcSet *wire_timing_arc_set_;
2026-06-13 16:31:24 -07:00
static TimingArcSet *port_refpin_timing_arc_set_;
2018-09-28 08:54:21 -07:00
};
// 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,
2026-01-03 16:59:35 -08:00
const Transition *from_rf,
const Transition *to_rf,
TimingModel *model);
2018-09-28 08:54:21 -07:00
~TimingArc();
2025-04-23 11:38:44 -07:00
std::string to_string() const;
2018-09-28 08:54:21 -07:00
LibertyPort *from() const { return set_->from(); }
LibertyPort *to() const { return set_->to(); }
2025-03-30 15:27:53 -07:00
const Transition *fromEdge() const { return from_rf_; }
const Transition *toEdge() const { return to_rf_; }
const TimingRole *role() const { return set_->role(); }
2018-09-28 08:54:21 -07:00
TimingArcSet *set() const { return set_; }
TimingSense sense() const;
// Index in TimingArcSet.
2026-02-27 16:57:08 -08:00
size_t index() const { return index_; }
2018-09-28 08:54:21 -07:00
TimingModel *model() const { return model_; }
2026-01-03 16:59:35 -08:00
GateTimingModel *gateModel(const Scene *scene,
const MinMax *min_max) const;
CheckTimingModel *checkModel(const Scene *scene,
const MinMax *min_max) const;
2024-06-27 13:57:58 -07:00
GateTableModel *gateTableModel() const;
2026-01-03 16:59:35 -08:00
GateTableModel *gateTableModel(const Scene *scene,
const MinMax *min_max) const;
2026-04-13 14:58:16 -07:00
const TimingArc *sceneArc(size_t lib_ap_index) const;
2026-01-03 16:59:35 -08:00
void setSceneArc(TimingArc *scene_arc,
2026-04-13 14:58:16 -07:00
size_t lib_ap_index);
2020-11-20 09:16:14 -07:00
float driveResistance() const;
2020-12-20 08:31:33 -07:00
ArcDelay intrinsicDelay() const;
2018-09-28 08:54:21 -07:00
static bool equiv(const TimingArc *arc1,
2026-01-03 16:59:35 -08:00
const TimingArc *arc2);
2018-09-28 08:54:21 -07:00
protected:
2026-01-03 16:59:35 -08:00
TimingModel *model(const Scene *scene,
const MinMax *min_max) const;
2026-02-27 16:57:08 -08:00
void setIndex(size_t index);
2018-09-28 08:54:21 -07:00
void addScaledModel(const OperatingConditions *op_cond,
2026-01-03 16:59:35 -08:00
TimingModel *scaled_model);
2018-09-28 08:54:21 -07:00
TimingArcSet *set_;
2025-03-30 15:27:53 -07:00
const Transition *from_rf_;
const Transition *to_rf_;
2018-09-28 08:54:21 -07:00
unsigned index_;
TimingModel *model_;
2026-04-13 14:58:16 -07:00
ScaledTimingModelMap *scaled_models_{nullptr};
2026-01-03 16:59:35 -08:00
std::vector<TimingArc*> scene_arcs_;
2018-09-28 08:54:21 -07:00
private:
friend class LibertyLibrary;
friend class LibertyCell;
friend class TimingArcSet;
};
2026-04-13 14:58:16 -07:00
} // namespace sta