2018-09-28 17:54:21 +02:00
|
|
|
// OpenSTA, Static Timing Analyzer
|
2025-01-22 02:54:33 +01:00
|
|
|
// Copyright (c) 2025, Parallax Software, Inc.
|
2018-09-28 17:54:21 +02: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 18:17:08 +01:00
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2018-09-28 17:54:21 +02:00
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
2022-01-04 18:17:08 +01:00
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2025-01-22 02:54:33 +01: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 17:54:21 +02:00
|
|
|
|
2020-04-05 23:53:44 +02:00
|
|
|
#include "TimingRole.hh"
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
namespace sta {
|
|
|
|
|
|
|
|
|
|
TimingRoleMap TimingRole::timing_roles_;
|
2025-03-31 00:27:53 +02:00
|
|
|
const TimingRole TimingRole::wire_("wire", false, false, false, nullptr, nullptr, 0);
|
|
|
|
|
const TimingRole TimingRole::combinational_("combinational", true, false, false,
|
|
|
|
|
nullptr, nullptr, 1);
|
|
|
|
|
const TimingRole TimingRole::tristate_enable_("tristate enable",
|
|
|
|
|
true, false, false,
|
|
|
|
|
nullptr, nullptr, 2);
|
|
|
|
|
const TimingRole TimingRole::tristate_disable_("tristate disable",
|
|
|
|
|
true, false, false,
|
|
|
|
|
nullptr, nullptr, 3);
|
|
|
|
|
const TimingRole TimingRole::reg_clk_q_("Reg Clk to Q", true, false, false,
|
|
|
|
|
nullptr, nullptr, 4);
|
|
|
|
|
const TimingRole TimingRole::reg_set_clr_("Reg Set/Clr", true, false, false,
|
|
|
|
|
nullptr, nullptr, 5);
|
|
|
|
|
const TimingRole TimingRole::latch_en_q_("Latch En to Q", true, false, false,
|
|
|
|
|
nullptr, TimingRole::regClkToQ(), 6);
|
|
|
|
|
const TimingRole TimingRole::latch_d_q_("Latch D to Q", true, false, false,
|
|
|
|
|
nullptr, nullptr, 7);
|
|
|
|
|
const TimingRole TimingRole::sdf_iopath_("sdf IOPATH", true, false, false,
|
|
|
|
|
nullptr, nullptr, 8);
|
|
|
|
|
const TimingRole TimingRole::setup_("setup", false, true, false,
|
|
|
|
|
MinMax::max(), nullptr, 9);
|
|
|
|
|
const TimingRole TimingRole::hold_("hold", false, true, false,
|
|
|
|
|
MinMax::min(), nullptr, 10);
|
|
|
|
|
const TimingRole TimingRole::recovery_("recovery", false, true, false,
|
|
|
|
|
MinMax::max(), TimingRole::setup(), 11);
|
|
|
|
|
const TimingRole TimingRole::removal_("removal", false, true, false,
|
|
|
|
|
MinMax::min(), TimingRole::hold(), 12);
|
|
|
|
|
const TimingRole TimingRole::width_("width", false, true, false,
|
|
|
|
|
nullptr, nullptr, 13);
|
|
|
|
|
const TimingRole TimingRole::period_("period", false, true, false,
|
|
|
|
|
nullptr, nullptr, 14);
|
|
|
|
|
const TimingRole TimingRole::skew_("skew", false, true, false,
|
|
|
|
|
nullptr, nullptr, 15);
|
|
|
|
|
const TimingRole TimingRole::nochange_("nochange", true, false, false,
|
|
|
|
|
nullptr, nullptr, 16);
|
|
|
|
|
const TimingRole TimingRole::output_setup_("output setup", false, true, false,
|
|
|
|
|
MinMax::max(), TimingRole::setup(), 17);
|
|
|
|
|
const TimingRole TimingRole::output_hold_("output hold", false, true, false,
|
|
|
|
|
MinMax::min(), TimingRole::hold(), 18);
|
|
|
|
|
const TimingRole TimingRole::gated_clk_setup_("clock gating setup",
|
|
|
|
|
false, true, false,
|
|
|
|
|
MinMax::max(), TimingRole::setup(),19);
|
|
|
|
|
const TimingRole TimingRole::gated_clk_hold_("clock gating hold", false, true, false,
|
|
|
|
|
MinMax::min(), TimingRole::hold(),20);
|
|
|
|
|
const TimingRole TimingRole::latch_setup_("latch setup", false, true, false,
|
|
|
|
|
MinMax::max(), TimingRole::setup(),21);
|
|
|
|
|
const TimingRole TimingRole::latch_hold_("latch hold", false, true, false,
|
|
|
|
|
MinMax::min(), TimingRole::hold(),22);
|
|
|
|
|
const TimingRole TimingRole::data_check_setup_("data check setup",
|
|
|
|
|
false, true, false,
|
|
|
|
|
MinMax::max(),TimingRole::setup(),23);
|
|
|
|
|
const TimingRole TimingRole::data_check_hold_("data check hold", false, true, false,
|
|
|
|
|
MinMax::min(), TimingRole::hold(), 24);
|
|
|
|
|
const TimingRole TimingRole::non_seq_setup_("non-sequential setup", false, true, true,
|
|
|
|
|
MinMax::max(), TimingRole::setup(), 25);
|
|
|
|
|
const TimingRole TimingRole::non_seq_hold_("non-sequential hold", false, true, true,
|
|
|
|
|
MinMax::min(), TimingRole::hold(), 26);
|
|
|
|
|
const TimingRole TimingRole::clock_tree_path_min_("min clock tree path", false, false,
|
|
|
|
|
false, MinMax::min(), nullptr, 27);
|
|
|
|
|
const TimingRole TimingRole::clock_tree_path_max_("max clock tree path", false, false,
|
|
|
|
|
false, MinMax::max(), nullptr, 28);
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
TimingRole::TimingRole(const char *name,
|
|
|
|
|
bool is_sdf_iopath,
|
|
|
|
|
bool is_timing_check,
|
|
|
|
|
bool is_non_seq_check,
|
2025-03-31 00:27:53 +02:00
|
|
|
const MinMax *path_min_max,
|
|
|
|
|
const TimingRole *generic_role,
|
2018-09-28 17:54:21 +02:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-31 00:27:53 +02:00
|
|
|
const TimingRole *
|
2018-09-28 17:54:21 +02:00
|
|
|
TimingRole::find(const char *name)
|
|
|
|
|
{
|
|
|
|
|
return timing_roles_[name];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const TimingRole *
|
|
|
|
|
TimingRole::sdfRole() const
|
|
|
|
|
{
|
|
|
|
|
if (is_sdf_iopath_)
|
2025-03-31 00:27:53 +02:00
|
|
|
return &sdf_iopath_;
|
2018-09-28 17:54:21 +02:00
|
|
|
else
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const TimingRole *
|
|
|
|
|
TimingRole::genericRole() const
|
|
|
|
|
{
|
2019-03-13 01:25:53 +01:00
|
|
|
if (generic_role_ == nullptr)
|
2018-09-28 17:54:21 +02:00
|
|
|
return this;
|
|
|
|
|
else
|
|
|
|
|
return generic_role_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const EarlyLate *
|
|
|
|
|
TimingRole::tgtClkEarlyLate() const
|
|
|
|
|
{
|
|
|
|
|
return path_min_max_->opposite();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
TimingRole::isWire() const
|
|
|
|
|
{
|
2025-03-31 00:27:53 +02:00
|
|
|
return this == &wire_;
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
TimingRole::isAsyncTimingCheck() const
|
|
|
|
|
{
|
2025-03-31 00:27:53 +02:00
|
|
|
return this == &recovery_
|
|
|
|
|
|| this == &removal_;
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
TimingRole::isDataCheck() const
|
|
|
|
|
{
|
2025-03-31 00:27:53 +02:00
|
|
|
return this == &data_check_setup_
|
|
|
|
|
|| this == &data_check_hold_;
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
2021-11-04 18:30:23 +01:00
|
|
|
bool
|
|
|
|
|
TimingRole::isLatchDtoQ() const
|
|
|
|
|
{
|
2025-03-31 00:27:53 +02:00
|
|
|
return this == &latch_d_q_;
|
2021-11-04 18:30:23 +01:00
|
|
|
}
|
|
|
|
|
|
2024-04-17 20:49:19 +02:00
|
|
|
bool
|
|
|
|
|
TimingRole::isTimingCheckBetween() const
|
|
|
|
|
{
|
|
|
|
|
return is_timing_check_
|
2025-03-31 00:27:53 +02:00
|
|
|
&& this != &width_
|
|
|
|
|
&& this != &period_;
|
2024-04-17 20:49:19 +02:00
|
|
|
}
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
bool
|
|
|
|
|
TimingRole::less(const TimingRole *role1,
|
|
|
|
|
const TimingRole *role2)
|
|
|
|
|
{
|
|
|
|
|
return role1->index() < role2->index();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace
|