Files
OpenSTA/sdc/Clock.cc
James Cherry 3f7df84fb8 Network::id for maps/sets
commit be70d30ae05665021254b0d7e69fb8d2f0a82890
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 17 17:04:49 2023 -0700

    cmp

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 4d4ef96948afe3d6a00c4521aeb5bc74274f5737
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 17 16:08:50 2023 -0700

    rvo, const

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit bb584e4264af2bea867b17d07e8d38c0e9eb0025
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 17 15:05:00 2023 -0700

    const

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit a08fe558bca6b769b2728882258bd85aed990a27
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 17 14:57:33 2023 -0700

    LibertyPortPair no ptrs

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 4d3bd60c109d1ce9d0589d746f4968fa7bebd90d
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 17 14:13:07 2023 -0700

    cleanup

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit dc25ff77771cfbe26f9318bad2b3c45879614783
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 17 14:06:13 2023 -0700

    const

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 06e81586ce11a0cc06948ed78fef99353077d69e
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 17 14:01:10 2023 -0700

    sortByName

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 9d8592aff5b246f83e47e1b94490e3cef8d8e119
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 17 11:57:17 2023 -0700

    sort pred

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 462a8e14df8b561ddfc842addc62c4b8435b6347
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 17 11:09:57 2023 -0700

    const

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 69f71505b684e88b22d395510429497e87bf1015
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 17 10:45:14 2023 -0700

    flush ConstPortSeq

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 6429d578b78eac3fe7e99fcd67a120789932b2eb
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 17 09:19:15 2023 -0700

    rm ConstNetSet

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit f247930b16e40560b957a36af68947249ed1ef04
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 17 08:50:50 2023 -0700

    sortPathNames

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 4ca2b0e0af7252c7bcbc65cf141d0ce40634d329
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 16 10:14:05 2023 -0700

    const

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 3d18640d2ebc4aae3098c7e7242a554fcb64fd42
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 16 09:41:27 2023 -0700

    set_input/ouput_delay -reference_pin

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit d4a0854dd2102f46f96a94fb9eb8749f1593a85f
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 16 09:13:46 2023 -0700

    PinPairSet no malloc

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit a6f1583fc6a856c5ecc0dcb15a1d8b1f61e30718
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 16 08:53:33 2023 -0700

    no malloc for EdgePins

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit c8e4b92e8b619109d6aa3c141c720646067ccb4b
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 16 06:31:08 2023 +0000

    leak

commit abab99e0fc3e466d914f6c1705aa08cdc204df51
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 16 06:07:36 2023 +0000

    leaks

commit d1913b554bb6e98b89673d80d2295f552eb4ffca
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 19:48:39 2023 -0700

    LibertyCell::checkCornerCell

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit bcc172237d48deed647374f9592bac70bd2d5425
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 18:19:47 2023 -0700

    rvo

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 8ef9800b87f5e5548055a13afc21397f28a6bcf7
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 18:07:46 2023 -0700

    sdc net id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit d7235abed04ced4e2d84e91bf9968e621268567d
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 16:00:27 2023 -0700

    range iter

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit a22f91a3c54c644574339d1126821d9bc8045bd6
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 15:52:50 2023 -0700

    range iter

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 762615ce3de91d950eeaaa4680549a45b13e0e0a
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 15:42:19 2023 -0700

    range iter

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 7e0c531613d343d23f064c24873bf5a498f6f4ce
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 12:26:49 2023 -0700

    rm removeLoadCaps, removeNetLoadCaps

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit f2e88c6082e2d4605e9849348008bf4065401fc8
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 12:21:03 2023 -0700

    sdc rm map ptrs

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit b5939666188c0b94dfe957e22bbd8a92f4786125
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 11:36:16 2023 -0700

    sdc rm map ptrs

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit a435081bafe10260743319f53a59cbe2ed0388b7
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 08:43:37 2023 -0700

    sdc rm map ptrs

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit acfb247559db7b726d47f203613488df0f7add53
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 08:38:07 2023 -0700

    sdc rm map ptrs

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 7541b71da92ea15085615988a1e6ea1d4d53d8d6
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 08:00:55 2023 -0700

    sdc rm map ptrs

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit d033210132656ea68fa834228575b9def1d02d90
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 07:52:03 2023 -0700

    sdc rm map ptrs

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit ca6e9ecb7821b83ab024c4fee6df8f7fc8fc2ce2
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 07:38:12 2023 -0700

    instance_pvt_maps_

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 631e4209b596386f5818045d521784db5239f58d
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 07:26:42 2023 -0700

    rm GroupPathIterator

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 059c32afa87617fff530c9afa1ef8005a136739d
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Jan 14 20:07:44 2023 -0700

    rm ClockIterator

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit c65fe873a6a6696220bbb44c4ecac87d5ca978ac
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Jan 14 19:45:58 2023 -0700

    rvo

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit ce15c9a0cc78915acddc2f03749573d989ae96d6
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 15 01:04:03 2023 +0000

    leaks

commit f97955a0c7e70b65ceb3f697ff47c0524a9b3cd4
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Jan 14 01:17:58 2023 +0000

    leaks

commit 7cdd65684adeb14e02827f5d93e7fab3b19af5dd
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Jan 13 16:07:47 2023 -0700

    leaks

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit ee97c7e50394a3927458e7ef09c5dbeb27719d15
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Jan 13 11:52:48 2023 -0700

    swig rm Tmp collections

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit c49935da8704e41459280971b7645fccd97e3d13
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Jan 13 11:18:36 2023 -0700

    swig rm Tmp types

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 4320b00ce700914843006f592126cd8cc1c4657a
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Jan 13 10:55:10 2023 -0700

    swig rm TmpPinSet, TmpPinSeq

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit ff6004910980c9b09b41f63a553a4481404cc539
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Jan 13 10:45:06 2023 -0700

    swig rm Tmp collections

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 9a5bf5c1a3e5a6d2996b3ab327fa2f3015f2ff20
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Jan 13 10:15:29 2023 -0700

    swig rm one TmpPinSet

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit f441116b56e23849485b2393b30e7086c33165a8
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Jan 13 09:16:56 2023 -0700

    leak

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 050b08df8618340b568d9cd41fd3d5f052e2c680
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Jan 13 09:10:53 2023 -0700

    leak

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit be8c17f3a715ab53140748dc1d94698209965cf9
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Jan 13 08:59:06 2023 -0700

    leak

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit e43b82f8fb52eaeda90e3c7e76cf350ae6735ebd
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 12 18:57:49 2023 -0700

    range iter

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 8db56209de7805ac2574fd2f76170bf68afd156d
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 12 18:08:54 2023 -0700

    GroupPathSet net id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit cb7917f9827c2ea3afebd735cd4508405a0d77d4
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 12 12:00:15 2023 -0700

    DataCheckLess net id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit d9da3c62d7a76699c6ad62cebb1f5c39f89722fa
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 12 11:42:27 2023 -0700

    rm hashPtr uses

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 5bbea162bb1e023aba813598c7992c740ddf9d0b
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 12 11:30:12 2023 -0700

    EdgePins has use net id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit df38405e2ebaabdd7bbf99f3b19d78b25bd95720
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 12 09:51:38 2023 -0700

    ExceptionPath hash use net id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 9a6dcfa54c54c9f50b14248a2449c70c20a0d977
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 12 08:56:49 2023 -0700

    ClockInsertion, ClockLatency net id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit dbb6dc0b8c93812458df31e93f08e0dbd74e8105
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 12 08:34:03 2023 -0700

    ExceptionStateSet obj id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 70b8721c48ec0816289ee09b664c332ee095875f
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 12 08:14:37 2023 -0700

    ClockGroups cmp

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 4c6c4ca191a99cd8541e106fec3202ee14968f39
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 12 07:38:17 2023 -0700

    ClockGroup typedef to ClockSet

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 66f425315e16deee5f00b05c0a505766e7afbf01
Author: James Cherry <cherry@parallaxsw.com>
Date:   Wed Jan 11 20:32:38 2023 -0700

    set cmps

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit a94866c7828af5b6714e3e4fffc13bdaf5155c0e
Author: James Cherry <cherry@parallaxsw.com>
Date:   Wed Jan 11 19:08:09 2023 -0700

    net use id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 6348320908f42ebb5262117182e13d0024f65537
Author: James Cherry <cherry@parallaxsw.com>
Date:   Wed Jan 11 11:52:13 2023 -0700

    exception id cmp

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 0edfca41b6d6408ac17f8dfe10e697c55146c1ef
Author: James Cherry <cherry@parallaxsw.com>
Date:   Wed Jan 11 10:47:02 2023 -0700

    range iter

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 44ad77985da9f0b9e7f4780e3f233c8d94fa7db7
Author: James Cherry <cherry@parallaxsw.com>
Date:   Wed Jan 11 08:27:58 2023 -0700

    non-ptr set cmp

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 36de7d88c3fa683465604a9e16b2fc1f6bc5fdd0
Author: James Cherry <cherry@parallaxsw.com>
Date:   Wed Jan 11 08:00:54 2023 -0700

    range iteration

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 4a31a2c8d9bdae58b09af8c05a64702ea3ac6c15
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 10 16:43:54 2023 -0700

    tcl types

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 056a7447b494a4c8ecc9764650d78a5bed3d87e8
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 10 16:10:36 2023 -0700

    tcl types

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 97239554c7625ba50ee729260f08eda7dec02365
Author: James Cherry <cherry@parallaxsw.com>
Date:   Tue Jan 10 13:10:42 2023 -0700

    use RVO

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit c3247d8937d483102e3e1f2b69d7ac1d331ba9d4
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 9 22:41:20 2023 -0700

    swig template seq's

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 5431c06feb256adb46858819fcf5d513cfa6b5ec
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 9 20:50:24 2023 -0700

    swig set in template

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 592ad641bf01d3beb862314a0d8986f66e258642
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 9 17:27:25 2023 -0700

    network return containers

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit c95f8b77e0d6bd5ffa5ba8102413c70883c756e1
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 9 12:15:37 2023 -0700

    PinSeq const

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 702e7f9ba2f901066a38f32e67b35602b6c7bbdf
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 9 12:02:29 2023 -0700

    InstanceSeq const

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 44fc25ba4a15e4ae570d74af27c9435872a126e0
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 9 12:01:45 2023 -0700

    NetSeq const

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 03b2725c81f5d52c33c875b55056c11d482144f1
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 9 11:33:18 2023 -0700

    rm PortPair

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 3fb82a7344dc053171c9883a113764ba691ab827
Author: James Cherry <cherry@parallaxsw.com>
Date:   Mon Jan 9 11:20:53 2023 -0700

    PinSet id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 3dd31f027e15d40d62a11d0a88ef2a115f01fb73
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 8 15:03:33 2023 -0700

    InstanceSet id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit a91dea5cc0af3bede36b3faed13adb05239ff907
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 8 11:40:15 2023 -0700

    NetSet id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit b91e4b6410134eccae7969ddcfb0b27933b2e746
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 8 10:44:47 2023 -0700

    CellSet, PortSet id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 6f891f77fae5a6b19c1454a1a4b4e3dfae0b5c50
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 8 10:29:25 2023 -0700

    network object sets

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit eb8c627a57ecc6e7c5846a01d62b090ff91c08bf
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sun Jan 8 10:09:00 2023 -0700

    PinSet1

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 8e864ecbdf87000fbb3c3097c39f06173c941e35
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Jan 7 17:13:03 2023 -0700

    concrete network object id

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

Signed-off-by: James Cherry <cherry@parallaxsw.com>
2023-01-19 11:23:45 -07:00

745 lines
16 KiB
C++

// OpenSTA, Static Timing Analyzer
// Copyright (c) 2022, 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 <https://www.gnu.org/licenses/>.
#include "Clock.hh"
#include <algorithm>
#include "Error.hh"
#include "StringUtil.hh"
#include "MinMax.hh"
#include "Transition.hh"
#include "TimingRole.hh"
#include "Network.hh"
#include "Graph.hh"
#include "Sdc.hh"
namespace sta {
static bool
isPowerOfTwo(int i);
Clock::Clock(const char *name,
int index,
const Network *network) :
name_(stringCopy(name)),
pins_(network),
add_to_pins_(false),
leaf_pins_(network),
period_(0.0),
waveform_(nullptr),
waveform_valid_(false),
index_(index),
clk_edges_(nullptr),
is_propagated_(false),
uncertainties_(nullptr),
is_generated_(false),
src_pin_(nullptr),
master_clk_(nullptr),
master_clk_infered_(false),
divide_by_(0),
multiply_by_(0),
duty_cycle_(0),
invert_(false),
combinational_(false),
edges_(nullptr),
edge_shifts_(nullptr)
{
makeClkEdges();
}
void
Clock::initClk(PinSet *pins,
bool add_to_pins,
float period,
FloatSeq *waveform,
const char *comment,
const Network *network)
{
is_generated_ = false;
setPins(pins, network);
add_to_pins_ = add_to_pins;
delete waveform_;
waveform_ = waveform;
waveform_valid_ = true;
period_ = period;
setClkEdgeTimes();
setComment(comment);
}
bool
Clock::isVirtual() const
{
return pins_.empty();
}
void
Clock::setPins(PinSet *pins,
const Network *network)
{
if (pins)
pins_ = *pins;
delete pins;
makeLeafPins(network);
}
void
Clock::makeLeafPins(const Network *network)
{
leaf_pins_.clear();
PinSet::Iterator pin_iter(pins_);
while (pin_iter.hasNext()) {
const Pin *pin = pin_iter.next();
findLeafDriverPins(pin, network, &leaf_pins_);
}
}
void
Clock::setMasterClk(Clock *master)
{
master_clk_ = master;
waveform_valid_ = false;
}
void
Clock::makeClkEdges()
{
clk_edges_ = new ClockEdge*[RiseFall::index_count];
for (auto tr : RiseFall::range()) {
clk_edges_[tr->index()] = new ClockEdge(this, tr);
}
}
Clock::~Clock()
{
stringDelete(name_);
if (clk_edges_) {
delete clk_edges_[RiseFall::riseIndex()];
delete clk_edges_[RiseFall::fallIndex()];
delete [] clk_edges_;
}
delete waveform_;
delete edges_;
delete edge_shifts_;
delete uncertainties_;
}
void
Clock::addPin(const Pin *pin)
{
pins_.insert(pin);
leaf_pins_.insert(pin);
}
void
Clock::deletePin(const Pin *pin)
{
pins_.erase(pin);
}
void
Clock::setAddToPins(bool add_to_pins)
{
add_to_pins_ = add_to_pins;
}
void
Clock::setClkEdgeTimes()
{
setClkEdgeTime(RiseFall::rise());
setClkEdgeTime(RiseFall::fall());
}
void
Clock::setClkEdgeTime(const RiseFall *rf)
{
float time = (rf == RiseFall::rise()) ? (*waveform_)[0]:(*waveform_)[1];
clk_edges_[rf->index()]->setTime(time);
}
const Pin *
Clock::defaultPin() const
{
PinSet::ConstIterator pin_iter(leaf_pins_);
if (pin_iter.hasNext())
return pin_iter.next();
else
return nullptr;
}
ClockEdge *
Clock::edge(const RiseFall *rf) const
{
return clk_edges_[rf->index()];
}
void
Clock::setIsPropagated(bool propagated)
{
is_propagated_ = propagated;
}
void
Clock::slew(const RiseFall *rf,
const MinMax *min_max,
// Return values.
float &slew,
bool &exists) const
{
slews_.value(rf, min_max, slew, exists);
}
float
Clock::slew(const RiseFall *rf,
const MinMax *min_max) const
{
float slew;
bool exists;
slews_.value(rf, min_max, slew, exists);
if (!exists)
slew = 0.0;
return slew;
}
void
Clock::setSlew(const RiseFallBoth *rf,
const MinMaxAll *min_max,
float slew)
{
slews_.setValue(rf, min_max, slew);
}
void
Clock::setSlew(const RiseFall *rf,
const MinMax *min_max,
float slew)
{
slews_.setValue(rf, min_max, slew);
}
void
Clock::removeSlew()
{
slews_.clear();
}
void
Clock::setSlewLimit(const RiseFallBoth *rf,
const PathClkOrData clk_data,
const MinMax *min_max,
float slew)
{
slew_limits_[int(clk_data)].setValue(rf, min_max, slew);
}
void
Clock::slewLimit(const RiseFall *rf,
const PathClkOrData clk_data,
const MinMax *min_max,
// Return values.
float &slew,
bool &exists) const
{
slew_limits_[int(clk_data)].value(rf, min_max, slew, exists);
}
void
Clock::uncertainty(const SetupHold *setup_hold,
// Return values.
float &uncertainty,
bool &exists) const
{
if (uncertainties_)
uncertainties_->value(setup_hold, uncertainty, exists);
else {
uncertainty = 0.0F;
exists = false;
}
}
void
Clock::setUncertainty(const SetupHoldAll *setup_hold,
float uncertainty)
{
if (uncertainties_ == nullptr)
uncertainties_ = new ClockUncertainties;
uncertainties_->setValue(setup_hold, uncertainty);
}
void
Clock::setUncertainty(const SetupHold *setup_hold,
float uncertainty)
{
if (uncertainties_ == nullptr)
uncertainties_ = new ClockUncertainties;
uncertainties_->setValue(setup_hold, uncertainty);
}
void
Clock::removeUncertainty(const SetupHoldAll *setup_hold)
{
if (uncertainties_) {
uncertainties_->removeValue(setup_hold);
if (uncertainties_->empty()) {
delete uncertainties_;
uncertainties_ = nullptr;
}
}
}
void
Clock::waveformInvalid()
{
waveform_valid_ = false;
}
////////////////////////////////////////////////////////////////
void
Clock::initGeneratedClk(PinSet *pins,
bool add_to_pins,
Pin *src_pin,
Clock *master_clk,
int divide_by,
int multiply_by,
float duty_cycle,
bool invert,
bool combinational,
IntSeq *edges,
FloatSeq *edge_shifts,
bool is_propagated,
const char *comment,
const Network *network)
{
is_generated_ = true;
setPins(pins, network);
add_to_pins_ = add_to_pins;
src_pin_ = src_pin;
master_clk_ = master_clk;
master_clk_infered_ = false;
waveform_valid_ = false;
divide_by_ = divide_by;
multiply_by_ = multiply_by;
duty_cycle_ = duty_cycle;
invert_ = invert;
combinational_ = combinational;
is_propagated_ = is_propagated;
setComment(comment);
delete edges_;
if (edges
&& edges->empty()) {
delete edges;
edges = nullptr;
}
edges_ = edges;
delete edge_shifts_;
if (edge_shifts
&& edge_shifts->empty()) {
delete edge_shifts;
edge_shifts = nullptr;
}
edge_shifts_ = edge_shifts;
}
void
Clock::setInferedMasterClk(Clock *master_clk)
{
master_clk_ = master_clk;
master_clk_infered_ = true;
waveform_valid_ = false;
}
bool
Clock::isGenerated() const
{
return is_generated_;
}
bool
Clock::isGeneratedWithPropagatedMaster() const
{
return is_generated_
&& master_clk_
// Insertion is zero if the master clock is ideal.
&& master_clk_->isPropagated();
}
void
Clock::generate(const Clock *src_clk)
{
if (waveform_ == nullptr)
waveform_ = new FloatSeq;
else
waveform_->clear();
if (divide_by_ == 1.0) {
period_ = src_clk->period();
const FloatSeq *src_wave = src_clk->waveform();
waveform_->push_back((*src_wave)[0]);
waveform_->push_back((*src_wave)[1]);
}
else if (divide_by_ > 1) {
if (isPowerOfTwo(divide_by_)) {
period_ = src_clk->period() * divide_by_;
const FloatSeq *src_wave = src_clk->waveform();
float rise = (*src_wave)[0];
waveform_->push_back(rise);
waveform_->push_back(rise + period_ / 2);
}
else
generateScaledClk(src_clk, static_cast<float>(divide_by_));
}
else if (multiply_by_ >= 1)
generateScaledClk(src_clk, 1.0F / multiply_by_);
else if (edges_)
generateEdgesClk(src_clk);
if (invert_) {
float first_time = (*waveform_)[0];
float offset = (first_time >= period_) ? period_ : 0.0F;
size_t edge_count = waveform_->size();
for (size_t i = 0; i < edge_count - 1; i++)
(*waveform_)[i] = (*waveform_)[i + 1] - offset;
(*waveform_)[edge_count - 1] = first_time - offset + period_;
}
setClkEdgeTimes();
waveform_valid_ = true;
}
void
Clock::generateScaledClk(const Clock *src_clk,
float scale)
{
period_ = src_clk->period() * scale;
if (duty_cycle_ != 0.0) {
float rise = (*src_clk->waveform())[0] * scale;
waveform_->push_back(rise);
waveform_->push_back(rise + period_ * duty_cycle_ / 100.0F);
}
else {
FloatSeq::ConstIterator wave_iter(src_clk->waveform());
while (wave_iter.hasNext()) {
float time = wave_iter.next();
waveform_->push_back(time * scale);
}
}
}
void
Clock::generateEdgesClk(const Clock *src_clk)
{
// The create_generated_clock tcl cmd and Sta::makeClock
// enforce this restriction.
if (edges_->size() == 3) {
const FloatSeq *src_wave = src_clk->waveform();
size_t src_size = src_wave->size();
float src_period = src_clk->period();
int edge0_1 = (*edges_)[0] - 1;
float rise = (*src_wave)[edge0_1 % src_size]
+ (edge0_1 / src_size) * src_period;
if (edge_shifts_)
rise += (*edge_shifts_)[0];
waveform_->push_back(rise);
int edge1_1 = (*edges_)[1] - 1;
float fall = (*src_wave)[edge1_1 % src_size]
+ (edge1_1 / src_size) * src_period;
if (edge_shifts_)
fall += (*edge_shifts_)[1];
waveform_->push_back(fall);
int edge2_1 = (*edges_)[2] - 1;
period_ = (*src_wave)[edge2_1 % src_size]
+ (edge2_1 / src_size) * src_period - rise;
if (edge_shifts_)
period_ += (*edge_shifts_)[2];
}
else
criticalError(244, "generated clock edges size is not three.");
}
static bool
isPowerOfTwo(int i)
{
return (i & (i - 1)) == 0;
}
const RiseFall *
Clock::masterClkEdgeTr(const RiseFall *rf) const
{
int edge_index = (rf == RiseFall::rise()) ? 0 : 1;
return ((*edges_)[edge_index] - 1) % 2
? RiseFall::fall()
: RiseFall::rise();
}
void
Clock::srcPinVertices(VertexSet &src_vertices,
const Network *network,
Graph *graph)
{
if (network->isHierarchical(src_pin_)) {
// Use the clocks on a non-hierarchical pin on the same net.
PinSet leaf_pins(network);
findLeafDriverPins(src_pin_, network, &leaf_pins);
PinSet::Iterator pin_iter(leaf_pins);
while (pin_iter.hasNext()) {
const Pin *pin = pin_iter.next();
Vertex *vertex, *bidirect_drvr_vertex;
graph->pinVertices(pin, vertex, bidirect_drvr_vertex);
if (vertex)
src_vertices.insert(vertex);
if (bidirect_drvr_vertex)
src_vertices.insert(bidirect_drvr_vertex);
}
}
else {
Vertex *vertex = graph->pinDrvrVertex(src_pin_);
src_vertices.insert(vertex);
}
}
bool
Clock::isDivideByOneCombinational() const
{
return combinational_
&& divide_by_ == 1
&& multiply_by_ == 0
&& edge_shifts_ == 0;
}
////////////////////////////////////////////////////////////////
ClockEdge::ClockEdge(Clock *clock,
RiseFall *rf) :
clock_(clock),
rf_(rf),
name_(stringPrint("%s %s", clock_->name(), rf_->asString())),
time_(0.0),
index_(clock_->index() * RiseFall::index_count + rf_->index())
{
}
ClockEdge::~ClockEdge()
{
stringDelete(name_);
}
void
ClockEdge::setTime(float time)
{
time_ = time;
}
ClockEdge *
ClockEdge::opposite() const
{
return clock_->edge(rf_->opposite());
}
float
ClockEdge::pulseWidth() const
{
ClockEdge *opp_clk_edge = opposite();
float width = opp_clk_edge->time() - time_;
if (width < 0.0)
width += clock_->period();
return width;
}
////////////////////////////////////////////////////////////////
int
clkCmp(const Clock *clk1,
const Clock *clk2)
{
if (clk1 == nullptr && clk2)
return -1;
else if (clk1 == nullptr && clk2 == nullptr)
return 0;
else if (clk1 && clk2 == nullptr)
return 1;
else {
int index1 = clk1->index();
int index2 = clk2->index();
if (index1 < index2)
return -1;
else if (index1 == index2)
return 0;
else
return 1;
}
}
int
clkEdgeCmp(const ClockEdge *clk_edge1,
const ClockEdge *clk_edge2)
{
if (clk_edge1 == nullptr && clk_edge2)
return -1;
else if (clk_edge1 == nullptr && clk_edge2 == nullptr)
return 0;
else if (clk_edge1 && clk_edge2 == nullptr)
return 1;
else {
int index1 = clk_edge1->index();
int index2 = clk_edge2->index();
if (index1 == index2)
return 0;
else if (index1 < index2)
return -1;
else
return 1;
}
}
bool
clkEdgeLess(const ClockEdge *clk_edge1,
const ClockEdge *clk_edge2)
{
return clkEdgeCmp(clk_edge1, clk_edge2) < 0;
}
////////////////////////////////////////////////////////////////
InterClockUncertainty::InterClockUncertainty(const Clock *src,
const Clock *target) :
src_(src),
target_(target)
{
}
bool
InterClockUncertainty::empty() const
{
return uncertainties_[RiseFall::riseIndex()].empty()
&& uncertainties_[RiseFall::fallIndex()].empty();
}
void
InterClockUncertainty::uncertainty(const RiseFall *src_rf,
const RiseFall *tgt_rf,
const SetupHold *setup_hold,
float &uncertainty,
bool &exists) const
{
uncertainties_[src_rf->index()].value(tgt_rf, setup_hold,
uncertainty, exists);
}
void
InterClockUncertainty::setUncertainty(const RiseFallBoth *src_rf,
const RiseFallBoth *tgt_rf,
const SetupHoldAll *setup_hold,
float uncertainty)
{
for (auto src_rf_index : src_rf->rangeIndex())
uncertainties_[src_rf_index].setValue(tgt_rf, setup_hold, uncertainty);
}
void
InterClockUncertainty::removeUncertainty(const RiseFallBoth *src_rf,
const RiseFallBoth *tgt_rf,
const SetupHoldAll *setup_hold)
{
for (auto src_rf_index : src_rf->rangeIndex())
uncertainties_[src_rf_index].removeValue(tgt_rf, setup_hold);
}
const RiseFallMinMax *
InterClockUncertainty::uncertainties(RiseFall *src_rf) const
{
return &uncertainties_[src_rf->index()];
}
bool
InterClockUncertaintyLess::operator()(const InterClockUncertainty *inter1,
const InterClockUncertainty *inter2)const
{
return inter1->src()->index() < inter2->src()->index()
|| (inter1->src() == inter2->src()
&& inter1->target()->index() < inter2->target()->index());
}
////////////////////////////////////////////////////////////////
bool
ClockNameLess::operator()(const Clock *clk1,
const Clock *clk2)
{
return stringLess(clk1->name(), clk2->name());
}
bool
ClockIndexLess::operator()(const Clock *clk1,
const Clock *clk2) const
{
return (clk1 == nullptr && clk2)
|| (clk1 && clk2
&& clk1->index() < clk2->index());
}
ClockSeq
sortByName(ClockSet *set)
{
ClockSeq clks;
for (Clock *clk : *set)
clks.push_back(clk);
sort(clks, ClockNameLess());
return clks;
}
////////////////////////////////////////////////////////////////
bool
ClockSetLess::operator()(const ClockSet *set1,
const ClockSet *set2) const
{
return sta::compare(set1, set2) < 0;
}
int
compare(const ClockSet *set1,
const ClockSet *set2)
{
size_t size1 = set1 ? set1->size() : 0;
size_t size2 = set2 ? set2->size() : 0;
if (size1 == size2) {
ClockSet::ConstIterator iter1(set1);
ClockSet::ConstIterator iter2(set2);
while (iter1.hasNext() && iter2.hasNext()) {
Clock *clk1 = iter1.next();
Clock *clk2 = iter2.next();
int id1 = clk1->index();
int id2 = clk2->index();
if (id1 < id2)
return -1;
else if (id1 > id2)
return 1;
}
// Sets are equal.
return 0;
}
else
return (size1 > size2) ? 1 : -1;
}
} // namespace