// 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 . #include "TimingRole.hh" namespace sta { TimingRole *TimingRole::wire_; TimingRole *TimingRole::combinational_; TimingRole *TimingRole::tristate_enable_; TimingRole *TimingRole::tristate_disable_; TimingRole *TimingRole::reg_clk_q_; TimingRole *TimingRole::reg_set_clr_; TimingRole *TimingRole::latch_en_q_; TimingRole *TimingRole::latch_d_q_; TimingRole *TimingRole::sdf_iopath_; TimingRole *TimingRole::setup_; TimingRole *TimingRole::hold_; TimingRole *TimingRole::recovery_; TimingRole *TimingRole::removal_; TimingRole *TimingRole::width_; TimingRole *TimingRole::period_; TimingRole *TimingRole::skew_; TimingRole *TimingRole::nochange_; TimingRole *TimingRole::output_setup_; TimingRole *TimingRole::output_hold_; TimingRole *TimingRole::gated_clk_setup_; TimingRole *TimingRole::gated_clk_hold_; TimingRole *TimingRole::latch_setup_; TimingRole *TimingRole::latch_hold_; TimingRole *TimingRole::data_check_setup_; TimingRole *TimingRole::data_check_hold_; TimingRole *TimingRole::non_seq_setup_; TimingRole *TimingRole::non_seq_hold_; TimingRoleMap TimingRole::timing_roles_; void TimingRole::init() { wire_ = new TimingRole("wire", false, false, false, nullptr, nullptr, 0); combinational_ = new TimingRole("combinational", true, false, false, nullptr, nullptr, 1); tristate_enable_ = new TimingRole("tristate enable", true, false, false, nullptr, nullptr, 2); tristate_disable_ = new TimingRole("tristate disable", true, false, false, nullptr, nullptr, 3); reg_clk_q_ = new TimingRole("Reg Clk to Q", true, false, false, nullptr, nullptr, 4); reg_set_clr_ = new TimingRole("Reg Set/Clr", true, false, false, nullptr, nullptr, 5); latch_en_q_ = new TimingRole("Latch En to Q", true, false, false, nullptr, TimingRole::regClkToQ(), 6); latch_d_q_ = new TimingRole("Latch D to Q", true, false, false, nullptr, nullptr, 7); sdf_iopath_ = new TimingRole("sdf IOPATH", true, false, false, nullptr, nullptr, 8); setup_ = new TimingRole("setup", false, true, false, MinMax::max(), nullptr, 9); hold_ = new TimingRole("hold", false, true, false, MinMax::min(), nullptr, 10); recovery_ = new TimingRole("recovery", false, true, false, MinMax::max(), TimingRole::setup(), 11); removal_ = new TimingRole("removal", false, true, false, MinMax::min(), TimingRole::hold(), 12); width_ = new TimingRole("width", false, true, false, nullptr, nullptr, 13); period_ = new TimingRole("period", false, true, false, nullptr, nullptr, 14); skew_ = new TimingRole("skew", false, true, false, nullptr, nullptr, 15); nochange_ = new TimingRole("nochange", true, false, false, nullptr, nullptr, 16); output_setup_ = new TimingRole("output setup", false, true, false, MinMax::max(), TimingRole::setup(), 17); output_hold_ = new TimingRole("output hold", false, true, false, MinMax::min(), TimingRole::hold(), 18); gated_clk_setup_ = new TimingRole("clock gating setup", false, true, false, MinMax::max(), TimingRole::setup(),19); gated_clk_hold_ = new TimingRole("clock gating hold", false, true, false, MinMax::min(), TimingRole::hold(),20); latch_setup_ = new TimingRole("latch setup", false, true, false, MinMax::max(), TimingRole::setup(),21); latch_hold_ = new TimingRole("latch hold", false, true, false, MinMax::min(), TimingRole::hold(),22); data_check_setup_ = new TimingRole("data check setup", false, true, false, MinMax::max(),TimingRole::setup(),23); data_check_hold_ = new TimingRole("data check hold", false, true, false, MinMax::min(), TimingRole::hold(), 24); non_seq_setup_ = new TimingRole("setup", false, true, true, MinMax::max(), TimingRole::setup(), 25); non_seq_hold_ = new TimingRole("hold", false, true, true, MinMax::min(), TimingRole::hold(), 26); } void TimingRole::destroy() { delete wire_; wire_ = nullptr; delete combinational_; combinational_ = nullptr; delete tristate_enable_; tristate_enable_ = nullptr; delete tristate_disable_; tristate_disable_ = nullptr; delete reg_clk_q_; reg_clk_q_ = nullptr; delete reg_set_clr_; reg_set_clr_ = nullptr; delete latch_en_q_; latch_en_q_ = nullptr; delete latch_d_q_; latch_d_q_ = nullptr; delete sdf_iopath_; sdf_iopath_ = nullptr; delete setup_; setup_ = nullptr; delete hold_; hold_ = nullptr; delete recovery_; recovery_ = nullptr; delete removal_; removal_ = nullptr; delete width_; width_ = nullptr; delete period_; period_ = nullptr; delete skew_; skew_ = nullptr; delete nochange_; nochange_ = nullptr; delete output_setup_; output_setup_ = nullptr; delete output_hold_; output_hold_ = nullptr; delete gated_clk_setup_; gated_clk_setup_ = nullptr; delete gated_clk_hold_; gated_clk_hold_ = nullptr; delete latch_setup_; latch_setup_ = nullptr; delete latch_hold_; latch_hold_ = nullptr; delete data_check_setup_; data_check_setup_ = nullptr; delete data_check_hold_; data_check_hold_ = nullptr; delete non_seq_setup_; non_seq_setup_ = nullptr; delete non_seq_hold_; non_seq_hold_ = nullptr; timing_roles_.clear(); } TimingRole::TimingRole(const char *name, bool is_sdf_iopath, bool is_timing_check, bool is_non_seq_check, MinMax *path_min_max, TimingRole *generic_role, int index) : name_(name), is_timing_check_(is_timing_check), is_sdf_iopath_(is_sdf_iopath), is_non_seq_check_(is_non_seq_check), generic_role_(generic_role), index_(index), path_min_max_(path_min_max) { timing_roles_[name] = this; } TimingRole * TimingRole::find(const char *name) { return timing_roles_[name]; } const TimingRole * TimingRole::sdfRole() const { if (is_sdf_iopath_) return sdf_iopath_; else return this; } const TimingRole * TimingRole::genericRole() const { if (generic_role_ == nullptr) return this; else return generic_role_; } const EarlyLate * TimingRole::tgtClkEarlyLate() const { return path_min_max_->opposite(); } bool TimingRole::isWire() const { return this == wire_; } bool TimingRole::isAsyncTimingCheck() const { return this == recovery_ || this == removal_; } bool TimingRole::isDataCheck() const { return this == data_check_setup_ || this == data_check_hold_; } bool TimingRole::less(const TimingRole *role1, const TimingRole *role2) { return role1->index() < role2->index(); } } // namespace