OpenSTA/sdc/CycleAccting.cc

432 lines
14 KiB
C++
Raw Normal View History

2018-09-28 17:54:21 +02:00
// OpenSTA, Static Timing Analyzer
// 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
// 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
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// 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 "CycleAccting.hh"
2020-04-05 20:35:51 +02:00
2019-01-17 00:37:31 +01:00
#include <cmath> // ceil
#include <algorithm> // max
2020-04-05 20:35:51 +02:00
2020-04-05 23:53:44 +02:00
#include "Debug.hh"
#include "Fuzzy.hh"
#include "Units.hh"
#include "TimingRole.hh"
#include "Clock.hh"
#include "Sdc.hh"
2018-09-28 17:54:21 +02:00
namespace sta {
CycleAcctings::CycleAcctings(Sdc *sdc) :
sdc_(sdc)
{
}
CycleAcctings::~CycleAcctings()
{
clear();
}
void
CycleAcctings::clear()
{
cycle_acctings_.deleteContentsClear();
}
// Determine cycle accounting "on demand".
CycleAccting *
CycleAcctings::cycleAccting(const ClockEdge *src,
const ClockEdge *tgt)
{
if (src == nullptr)
src = tgt;
CycleAccting probe(src, tgt);
CycleAccting *acct = cycle_acctings_.findKey(&probe);
if (acct == nullptr) {
acct = new CycleAccting(src, tgt);
if (src == sdc_->defaultArrivalClockEdge())
acct->findDefaultArrivalSrcDelays();
else
acct->findDelays(sdc_);
cycle_acctings_.insert(acct);
}
return acct;
}
void
CycleAcctings::reportClkToClkMaxCycleWarnings(Report *report)
{
// Find cycle acctings that exceed max cycle count. Eliminate
// duplicate warnings between different src/tgt clk edges.
ClockPairSet clk_warnings;
for (Clock *src_clk : *sdc_->clocks()) {
name, asString -> to_string, const commit d122d05822e02dcc08c665ac6ec7513791dd7209 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Mar 27 08:58:22 2025 -0700 rebase Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9c7ae9a7ddd885ebdab102d48b3f39dc5dacf948 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Mar 25 16:21:52 2025 -0700 write_spice8 Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2bd088f03bb2e414305232d9ebd76c9d1958ec81 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Mar 25 10:08:00 2025 -0700 liberty reader stringify Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 86974caf063433b37ed1378e7103db4b2e55a04c Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 20:25:39 2025 -0700 ConcreteLiberary/Cell/Port use string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 334476e185149a90b35cdd859e0a760ec9aa242a Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 20:16:08 2025 -0700 leak Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5130e8d44804f483d9099d48bb413a7f3362b4e1 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 15:57:14 2025 -0700 liberty parser stringify Signed-off-by: James Cherry <cherry@parallaxsw.com> commit d48eba88cbde9093e3eb12bcee8eb48ccd444434 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 11:16:04 2025 -0700 stringify Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 6913fb198d642f6b05a94fb1852064706a748b81 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 11:06:17 2025 -0700 stringify Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 371bca08ecf9bf816b7adcbb7ae1458c4073f5f8 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 10:44:31 2025 -0700 TableTemplate use string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 326465920a1f4a33dbe6be35cff5ca2245b6677e Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 09:04:55 2025 -0700 use string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit b93a542ddfbcb5c793c9b533cbe64ea20ec08f4a Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 08:59:01 2025 -0700 timingSenseString -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 6c121a0ff4231b37df076a62e83832897be62ff4 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Mar 23 16:09:47 2025 -0700 Corner use string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 07b989a5a43bf5d341aa6ba2880be663997577d5 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Mar 23 16:05:43 2025 -0700 Tag::to_string() Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 0b9480cc5a3fa9ef0cb1c6e8ba0d4a29de2df816 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Mar 23 15:53:29 2025 -0700 PathAnalysisPt::to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit a028659091e99270f7501615285730681ed59523 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Mar 23 12:19:03 2025 -0700 TimingRole stati alloc Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 495be6a57bda23d82e511282f5db7c188b32971b Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 21:36:52 2025 -0700 RiseFall/RiseFallBoth/Transition const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4c4b28adb383321b1172f4b774c7c4d9a1aee69f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 20:38:26 2025 -0700 TimingRole const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 54ab58ec7200d420bf3b5e709e74b652af88d508 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 14:15:07 2025 -0700 const MinMax Signed-off-by: James Cherry <cherry@parallaxsw.com> commit f70bb38df17b2ed758c7b6ba5647b7355366c0c0 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 13:14:31 2025 -0700 Transition::to_string(() Signed-off-by: James Cherry <cherry@parallaxsw.com> commit b3f3d67328194351fb8efac2219bcfbcec331552 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 12:33:25 2025 -0700 RiseFall::to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4046f8a376926dfde980860c51d2c5c70cf4a867 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Mar 20 09:04:10 2025 -0700 TimingRole::name -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cf4dd918eccb05d459f1804ced8365c81a5c6a50 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 20:14:42 2025 -0700 MinMax::asString -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit d80118117dda25be7b2b4896f19e955645c27f73 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 17:43:08 2025 -0700 TimingRole::name -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 284fa25c28aca998e8ce92e7b7bb927697494a13 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 17:02:27 2025 -0700 comment Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 646f19749b997e03dc4cbdf165cd7637010276d3 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 14:47:40 2025 -0700 FuncExpr::asString -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4f73d8e7ad21feac6f41130b7b070f3e345b6fb5 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 14:04:13 2025 -0700 Vertex::name -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 7c7ec486aaea86f6607a1ef72bb1a74dca603831 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 13:39:24 2025 -0700 Vertex::name -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2025-03-31 00:27:53 +02:00
for (const RiseFall *src_rf : RiseFall::range()) {
ClockEdge *src = src_clk->edge(src_rf);
for (Clock *tgt_clk : *sdc_->clocks()) {
name, asString -> to_string, const commit d122d05822e02dcc08c665ac6ec7513791dd7209 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Mar 27 08:58:22 2025 -0700 rebase Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9c7ae9a7ddd885ebdab102d48b3f39dc5dacf948 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Mar 25 16:21:52 2025 -0700 write_spice8 Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2bd088f03bb2e414305232d9ebd76c9d1958ec81 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Mar 25 10:08:00 2025 -0700 liberty reader stringify Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 86974caf063433b37ed1378e7103db4b2e55a04c Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 20:25:39 2025 -0700 ConcreteLiberary/Cell/Port use string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 334476e185149a90b35cdd859e0a760ec9aa242a Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 20:16:08 2025 -0700 leak Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5130e8d44804f483d9099d48bb413a7f3362b4e1 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 15:57:14 2025 -0700 liberty parser stringify Signed-off-by: James Cherry <cherry@parallaxsw.com> commit d48eba88cbde9093e3eb12bcee8eb48ccd444434 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 11:16:04 2025 -0700 stringify Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 6913fb198d642f6b05a94fb1852064706a748b81 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 11:06:17 2025 -0700 stringify Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 371bca08ecf9bf816b7adcbb7ae1458c4073f5f8 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 10:44:31 2025 -0700 TableTemplate use string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 326465920a1f4a33dbe6be35cff5ca2245b6677e Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 09:04:55 2025 -0700 use string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit b93a542ddfbcb5c793c9b533cbe64ea20ec08f4a Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 08:59:01 2025 -0700 timingSenseString -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 6c121a0ff4231b37df076a62e83832897be62ff4 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Mar 23 16:09:47 2025 -0700 Corner use string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 07b989a5a43bf5d341aa6ba2880be663997577d5 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Mar 23 16:05:43 2025 -0700 Tag::to_string() Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 0b9480cc5a3fa9ef0cb1c6e8ba0d4a29de2df816 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Mar 23 15:53:29 2025 -0700 PathAnalysisPt::to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit a028659091e99270f7501615285730681ed59523 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Mar 23 12:19:03 2025 -0700 TimingRole stati alloc Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 495be6a57bda23d82e511282f5db7c188b32971b Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 21:36:52 2025 -0700 RiseFall/RiseFallBoth/Transition const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4c4b28adb383321b1172f4b774c7c4d9a1aee69f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 20:38:26 2025 -0700 TimingRole const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 54ab58ec7200d420bf3b5e709e74b652af88d508 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 14:15:07 2025 -0700 const MinMax Signed-off-by: James Cherry <cherry@parallaxsw.com> commit f70bb38df17b2ed758c7b6ba5647b7355366c0c0 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 13:14:31 2025 -0700 Transition::to_string(() Signed-off-by: James Cherry <cherry@parallaxsw.com> commit b3f3d67328194351fb8efac2219bcfbcec331552 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 12:33:25 2025 -0700 RiseFall::to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4046f8a376926dfde980860c51d2c5c70cf4a867 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Mar 20 09:04:10 2025 -0700 TimingRole::name -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cf4dd918eccb05d459f1804ced8365c81a5c6a50 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 20:14:42 2025 -0700 MinMax::asString -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit d80118117dda25be7b2b4896f19e955645c27f73 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 17:43:08 2025 -0700 TimingRole::name -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 284fa25c28aca998e8ce92e7b7bb927697494a13 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 17:02:27 2025 -0700 comment Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 646f19749b997e03dc4cbdf165cd7637010276d3 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 14:47:40 2025 -0700 FuncExpr::asString -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4f73d8e7ad21feac6f41130b7b070f3e345b6fb5 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 14:04:13 2025 -0700 Vertex::name -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 7c7ec486aaea86f6607a1ef72bb1a74dca603831 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 13:39:24 2025 -0700 Vertex::name -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2025-03-31 00:27:53 +02:00
for (const RiseFall *tgt_rf : RiseFall::range()) {
ClockEdge *tgt = tgt_clk->edge(tgt_rf);
CycleAccting probe(src, tgt);
CycleAccting *acct = cycle_acctings_.findKey(&probe);
if (acct && acct->maxCyclesExceeded()) {
// Canonicalize the warning wrt src/tgt.
ClockPair clk_pair1(src_clk, tgt_clk);
ClockPair clk_pair2(tgt_clk, src_clk);
if (!clk_warnings.hasKey(clk_pair1)
&& !clk_warnings.hasKey(clk_pair2)) {
report->warn(1010, "No common period was found between clocks %s and %s.",
src_clk->name(),
tgt_clk->name());
clk_warnings.insert(clk_pair1);
}
}
}
}
}
}
}
////////////////////////////////////////////////////////////////
2018-09-28 17:54:21 +02:00
CycleAccting::CycleAccting(const ClockEdge *src,
const ClockEdge *tgt) :
src_(src),
tgt_(tgt),
max_cycles_exceeded_(false)
{
for (int i = 0; i <= TimingRole::index_max; i++) {
delay_[i] = MinMax::min()->initValue();
required_[i] = 0;
src_cycle_[i] = 0;
tgt_cycle_[i] = 0;
}
}
void
CycleAccting::findDelays(StaState *sta)
{
Debug *debug = sta->debug();
const Unit *time_unit = sta->units()->timeUnit();
2021-01-01 20:46:51 +01:00
debugPrint(debug, "cycle_acct", 1, "%s -> %s",
src_->name(),
tgt_->name());
2018-09-28 17:54:21 +02:00
const int setup_index = TimingRole::setup()->index();
const int latch_setup_index = TimingRole::latchSetup()->index();
const int data_check_setup_index = TimingRole::dataCheckSetup()->index();
const int hold_index = TimingRole::hold()->index();
const int gclk_hold_index = TimingRole::gatedClockHold()->index();
Clock *src_clk = src_->clock();
Clock *tgt_clk = tgt_->clock();
2019-01-17 00:37:31 +01:00
double tgt_opp_time1 = tgt_->opposite()->time();
2018-09-28 17:54:21 +02:00
double tgt_period = tgt_clk->period();
double src_period = src_clk->period();
if (tgt_period > 0.0 && src_period > 0.0) {
2019-01-17 00:37:31 +01:00
// If the clocks are related (ie, generated clock and its source) allow
// allow enough cycles to match up the common period.
int tgt_max_cycle;
if (tgt_period > src_period)
tgt_max_cycle = 100;
2018-09-28 17:54:21 +02:00
else {
2019-01-17 00:37:31 +01:00
int ratio = std::ceil(src_period / tgt_period);
2019-02-16 21:07:59 +01:00
tgt_max_cycle = std::max(ratio, 1000);
2018-09-28 17:54:21 +02:00
}
bool tgt_past_src = false;
bool src_past_tgt = false;
int tgt_cycle = firstCycle(tgt_);
int src_cycle = 0;
while (tgt_cycle <= tgt_max_cycle) {
2018-09-28 17:54:21 +02:00
double tgt_cycle_start = tgt_cycle * tgt_period;
double tgt_time = tgt_cycle_start + tgt_->time();
2019-01-17 00:37:31 +01:00
double tgt_opp_time = tgt_cycle_start + tgt_opp_time1;
for (src_cycle = firstCycle(src_);
2019-01-17 00:37:31 +01:00
;
2018-09-28 17:54:21 +02:00
src_cycle++) {
double src_cycle_start = src_cycle * src_period;
double src_time = src_cycle_start + src_->time();
2019-01-17 00:37:31 +01:00
// Make sure both setup and hold required are determined.
2018-09-28 17:54:21 +02:00
if (tgt_past_src && src_past_tgt
2019-01-17 00:37:31 +01:00
// Synchronicity achieved.
2018-09-28 17:54:21 +02:00
&& fuzzyEqual(src_cycle_start, tgt_cycle_start)) {
2021-01-01 20:46:51 +01:00
debugPrint(debug, "cycle_acct", 1, " setup = %s, required = %s",
time_unit->asString(delay_[setup_index]),
time_unit->asString(required_[setup_index]));
debugPrint(debug, "cycle_acct", 1, " hold = %s, required = %s",
time_unit->asString(delay_[hold_index]),
time_unit->asString(required_[hold_index]));
debugPrint(debug, "cycle_acct", 1,
" converged at src cycles = %d tgt cycles = %d",
src_cycle, tgt_cycle);
2018-09-28 17:54:21 +02:00
return;
}
2019-01-17 00:37:31 +01:00
2018-09-28 17:54:21 +02:00
if (fuzzyGreater(src_cycle_start, tgt_cycle_start + tgt_period)
&& src_past_tgt)
break;
2021-01-01 20:46:51 +01:00
debugPrint(debug, "cycle_acct", 2, " %s src cycle %d %s + %s = %s",
src_->name(),
src_cycle,
time_unit->asString(src_cycle_start),
time_unit->asString(src_->time()),
time_unit->asString(src_time));
debugPrint(debug, "cycle_acct", 2, " %s tgt cycle %d %s + %s = %s",
tgt_->name(),
tgt_cycle,
time_unit->asString(tgt_cycle_start),
time_unit->asString(tgt_->time()),
time_unit->asString(tgt_time));
2018-09-28 17:54:21 +02:00
// For setup checks, target has to be AFTER source.
if (fuzzyGreater(tgt_time, src_time)) {
tgt_past_src = true;
double delay = tgt_time - src_time;
if (fuzzyLess(delay, delay_[setup_index])) {
double required = tgt_time - src_cycle_start;
setSetupAccting(src_cycle, tgt_cycle, delay, required);
2021-01-01 20:46:51 +01:00
debugPrint(debug, "cycle_acct", 2,
" setup min delay = %s, required = %s",
time_unit->asString(delay_[setup_index]),
time_unit->asString(required_[setup_index]));
2018-09-28 17:54:21 +02:00
}
}
2019-01-17 00:37:31 +01:00
2018-09-28 17:54:21 +02:00
// Data check setup checks are zero cycle.
if (fuzzyLessEqual(tgt_time, src_time)) {
double setup_delay = src_time - tgt_time;
if (fuzzyLess(setup_delay, delay_[data_check_setup_index])) {
double setup_required = tgt_time - src_cycle_start;
setAccting(TimingRole::dataCheckSetup(), src_cycle, tgt_cycle,
setup_delay, setup_required);
double hold_required = tgt_time - (src_cycle_start + src_period);
double hold_delay = (src_period + src_time) - tgt_time;
setAccting(TimingRole::dataCheckHold(),
src_cycle + 1, tgt_cycle, hold_delay, hold_required);
}
}
2019-01-17 00:37:31 +01:00
2018-09-28 17:54:21 +02:00
// Latch setup cycle accting for the enable is the data clk edge
// closest to the disable (opposite) edge.
if (fuzzyGreater(tgt_opp_time, src_time)) {
double delay = tgt_opp_time - src_time;
if (fuzzyLess(delay, delay_[latch_setup_index])) {
double latch_tgt_time = tgt_time;
int latch_tgt_cycle = tgt_cycle;
// Enable time is the edge before the disable.
if (tgt_time > tgt_opp_time) {
latch_tgt_time -= tgt_period;
latch_tgt_cycle--;
}
double required = latch_tgt_time - src_cycle_start;
setAccting(TimingRole::latchSetup(),
src_cycle, latch_tgt_cycle, delay, required);
2021-01-01 20:46:51 +01:00
debugPrint(debug, "cycle_acct", 2,
" latch setup min delay = %s, required = %s",
time_unit->asString(delay_[latch_setup_index]),
time_unit->asString(required_[latch_setup_index]));
2018-09-28 17:54:21 +02:00
}
}
2019-01-17 00:37:31 +01:00
2018-09-28 17:54:21 +02:00
// For hold checks, target has to be BEFORE source.
if (fuzzyLessEqual(tgt_time, src_time)) {
double delay = src_time - tgt_time;
src_past_tgt = true;
if (fuzzyLess(delay, delay_[hold_index])) {
double required = tgt_time - src_cycle_start;
setHoldAccting(src_cycle, tgt_cycle, delay, required);
2021-01-01 20:46:51 +01:00
debugPrint(debug, "cycle_acct", 2,
" hold min delay = %s, required = %s",
time_unit->asString(delay_[hold_index]),
time_unit->asString(required_[hold_index]));
2018-09-28 17:54:21 +02:00
}
}
2019-01-17 00:37:31 +01:00
2018-09-28 17:54:21 +02:00
// Gated clock hold checks are in the same cycle as the
// setup check.
if (fuzzyLessEqual(tgt_opp_time, src_time)) {
double delay = src_time - tgt_time;
if (fuzzyLess(delay, delay_[gclk_hold_index])) {
double required = tgt_time - src_cycle_start;
setAccting(TimingRole::gatedClockHold(),
src_cycle, tgt_cycle, delay, required);
2021-01-01 20:46:51 +01:00
debugPrint(debug, "cycle_acct", 2,
" gated clk hold min delay = %s, required = %s",
time_unit->asString(delay_[gclk_hold_index]),
time_unit->asString(required_[gclk_hold_index]));
2018-09-28 17:54:21 +02:00
}
}
}
tgt_cycle++;
2018-09-28 17:54:21 +02:00
}
max_cycles_exceeded_ = true;
2021-01-01 20:46:51 +01:00
debugPrint(debug, "cycle_acct", 1,
" max cycles exceeded after %d src cycles, %d tgt_cycles",
src_cycle, tgt_cycle);
2018-09-28 17:54:21 +02:00
}
else if (tgt_period > 0.0)
findDefaultArrivalSrcDelays();
}
int
CycleAccting::firstCycle(const ClockEdge *clk_edge) const
{
if (clk_edge->time() < 0)
return 1;
else if (clk_edge->time() < clk_edge->clock()->period())
return 0;
else
return -1;
}
2018-09-28 17:54:21 +02:00
void
CycleAccting::setSetupAccting(int src_cycle,
int tgt_cycle,
float delay,
float req)
{
setAccting(TimingRole::setup(), src_cycle, tgt_cycle, delay, req);
setAccting(TimingRole::outputSetup(), src_cycle, tgt_cycle, delay, req);
setAccting(TimingRole::gatedClockSetup(), src_cycle, tgt_cycle, delay, req);
setAccting(TimingRole::recovery(), src_cycle, tgt_cycle, delay, req);
}
void
CycleAccting::setHoldAccting(int src_cycle,
int tgt_cycle,
float delay,
float req)
{
setAccting(TimingRole::hold(), src_cycle, tgt_cycle, delay, req);
setAccting(TimingRole::outputHold(), src_cycle, tgt_cycle, delay, req);
setAccting(TimingRole::removal(), src_cycle, tgt_cycle, delay, req);
setAccting(TimingRole::latchHold(), src_cycle, tgt_cycle, delay, req);
}
void
name, asString -> to_string, const commit d122d05822e02dcc08c665ac6ec7513791dd7209 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Mar 27 08:58:22 2025 -0700 rebase Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 9c7ae9a7ddd885ebdab102d48b3f39dc5dacf948 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Mar 25 16:21:52 2025 -0700 write_spice8 Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2bd088f03bb2e414305232d9ebd76c9d1958ec81 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Mar 25 10:08:00 2025 -0700 liberty reader stringify Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 86974caf063433b37ed1378e7103db4b2e55a04c Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 20:25:39 2025 -0700 ConcreteLiberary/Cell/Port use string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 334476e185149a90b35cdd859e0a760ec9aa242a Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 20:16:08 2025 -0700 leak Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 5130e8d44804f483d9099d48bb413a7f3362b4e1 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 15:57:14 2025 -0700 liberty parser stringify Signed-off-by: James Cherry <cherry@parallaxsw.com> commit d48eba88cbde9093e3eb12bcee8eb48ccd444434 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 11:16:04 2025 -0700 stringify Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 6913fb198d642f6b05a94fb1852064706a748b81 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 11:06:17 2025 -0700 stringify Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 371bca08ecf9bf816b7adcbb7ae1458c4073f5f8 Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 10:44:31 2025 -0700 TableTemplate use string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 326465920a1f4a33dbe6be35cff5ca2245b6677e Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 09:04:55 2025 -0700 use string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit b93a542ddfbcb5c793c9b533cbe64ea20ec08f4a Author: James Cherry <cherry@parallaxsw.com> Date: Mon Mar 24 08:59:01 2025 -0700 timingSenseString -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 6c121a0ff4231b37df076a62e83832897be62ff4 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Mar 23 16:09:47 2025 -0700 Corner use string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 07b989a5a43bf5d341aa6ba2880be663997577d5 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Mar 23 16:05:43 2025 -0700 Tag::to_string() Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 0b9480cc5a3fa9ef0cb1c6e8ba0d4a29de2df816 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Mar 23 15:53:29 2025 -0700 PathAnalysisPt::to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit a028659091e99270f7501615285730681ed59523 Author: James Cherry <cherry@parallaxsw.com> Date: Sun Mar 23 12:19:03 2025 -0700 TimingRole stati alloc Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 495be6a57bda23d82e511282f5db7c188b32971b Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 21:36:52 2025 -0700 RiseFall/RiseFallBoth/Transition const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4c4b28adb383321b1172f4b774c7c4d9a1aee69f Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 20:38:26 2025 -0700 TimingRole const Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 54ab58ec7200d420bf3b5e709e74b652af88d508 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 14:15:07 2025 -0700 const MinMax Signed-off-by: James Cherry <cherry@parallaxsw.com> commit f70bb38df17b2ed758c7b6ba5647b7355366c0c0 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 13:14:31 2025 -0700 Transition::to_string(() Signed-off-by: James Cherry <cherry@parallaxsw.com> commit b3f3d67328194351fb8efac2219bcfbcec331552 Author: James Cherry <cherry@parallaxsw.com> Date: Sat Mar 22 12:33:25 2025 -0700 RiseFall::to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4046f8a376926dfde980860c51d2c5c70cf4a867 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Mar 20 09:04:10 2025 -0700 TimingRole::name -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cf4dd918eccb05d459f1804ced8365c81a5c6a50 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 20:14:42 2025 -0700 MinMax::asString -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit d80118117dda25be7b2b4896f19e955645c27f73 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 17:43:08 2025 -0700 TimingRole::name -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 284fa25c28aca998e8ce92e7b7bb927697494a13 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 17:02:27 2025 -0700 comment Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 646f19749b997e03dc4cbdf165cd7637010276d3 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 14:47:40 2025 -0700 FuncExpr::asString -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 4f73d8e7ad21feac6f41130b7b070f3e345b6fb5 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 14:04:13 2025 -0700 Vertex::name -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 7c7ec486aaea86f6607a1ef72bb1a74dca603831 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Mar 19 13:39:24 2025 -0700 Vertex::name -> to_string Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
2025-03-31 00:27:53 +02:00
CycleAccting::setAccting(const TimingRole *role,
2018-09-28 17:54:21 +02:00
int src_cycle,
int tgt_cycle,
float delay,
float req)
{
int index = role->index();
src_cycle_[index] = src_cycle;
tgt_cycle_[index] = tgt_cycle;
delay_[index] = delay;
required_[index] = req;
}
void
CycleAccting::findDefaultArrivalSrcDelays()
{
const Clock *tgt_clk = tgt_->clock();
float tgt_time = tgt_->time();
float tgt_period = tgt_clk->period();
// Unclocked arrival setup check is in cycle zero.
if (tgt_time > tgt_period)
setDefaultSetupAccting(0, 0, tgt_time - tgt_period, tgt_time - tgt_period);
else if (tgt_time > 0.0)
setDefaultSetupAccting(0, 0, tgt_time, tgt_time);
else
setDefaultSetupAccting(0, 1, tgt_period, tgt_period);
setDefaultHoldAccting(0, 0, 0.0, tgt_time);
}
void
CycleAccting::setDefaultSetupAccting(int src_cycle,
int tgt_cycle,
float delay,
float req)
{
setSetupAccting(src_cycle, tgt_cycle, delay, req);
setAccting(TimingRole::latchSetup(), src_cycle, tgt_cycle, delay, req);
setAccting(TimingRole::dataCheckSetup(), src_cycle, tgt_cycle, delay, req);
}
void
CycleAccting::setDefaultHoldAccting(int src_cycle,
int tgt_cycle,
float delay,
float req)
{
setHoldAccting(src_cycle, tgt_cycle, delay, req);
setAccting(TimingRole::dataCheckHold(), src_cycle, tgt_cycle, delay, req);
}
float
CycleAccting::requiredTime(const TimingRole *check_role)
{
return required_[check_role->index()];
}
float
CycleAccting::sourceTimeOffset(const TimingRole *check_role)
{
return sourceCycle(check_role) * src_->clock()->period();
}
int
CycleAccting::sourceCycle(const TimingRole *check_role)
{
return src_cycle_[check_role->index()];
}
int
CycleAccting::targetCycle(const TimingRole *check_role)
{
return tgt_cycle_[check_role->index()];
}
float
CycleAccting::targetTimeOffset(const TimingRole *check_role)
{
return targetCycle(check_role) * tgt_->clock()->period();
}
2019-03-13 01:25:53 +01:00
////////////////////////////////////////////////////////////////
2018-09-28 17:54:21 +02:00
bool
CycleAcctingLess::operator()(const CycleAccting *acct1,
const CycleAccting *acct2) const
{
int src_index1 = acct1->src()->index();
int src_index2 = acct2->src()->index();
return src_index1 < src_index2
|| (src_index1 == src_index2
&& acct1->target()->index() < acct2->target()->index());
}
2019-08-08 23:13:02 +02:00
size_t
2019-03-13 01:25:53 +01:00
CycleAcctingHash::operator()(const CycleAccting *acct) const
{
return hashSum(acct->src()->index(), acct->target()->index());
}
bool
CycleAcctingEqual::operator()(const CycleAccting *acct1,
const CycleAccting *acct2) const
{
return acct1->src() == acct2->src()
&& acct1->target() == acct2->target();
}
2018-09-28 17:54:21 +02:00
} // namespace