Files
OpenSTA/search/ClkNetwork.cc
T
James Cherry 2c866d5f2d bfs update kahns prep
commit 4075953c9798444b9d5275f8fa0320f74b9bf1ef
Author: James Cherry <[email protected]>
Date:   Sat Jul 4 09:00:48 2026 -0700

    bfs resort hasNext

    Signed-off-by: James Cherry <[email protected]>

commit 4fb0dd19e479f507935129fe940bcd1cf93b29d0
Author: James Cherry <[email protected]>
Date:   Thu Jul 2 12:23:54 2026 -0700

    ApiChanges

    Signed-off-by: James Cherry <[email protected]>

commit 510afbc1403c9fd2b764b4f3a71dddabd696f052
Author: James Cherry <[email protected]>
Date:   Thu Jul 2 11:07:44 2026 -0700

    bfs enqueueFanin/out

    Signed-off-by: James Cherry <[email protected]>

commit 9a5aa570e910c289b276a519bdf532dfa2e28c5f
Author: James Cherry <[email protected]>
Date:   Thu Jul 2 10:41:27 2026 -0700

    Revert "bfs continueFrom/enqueueFanin/out"

    This reverts commit d18498c947a7df2b615fafda38fbdbe8033eca9d.

commit 02a253ab252f6637cfea29bdd788cb25da16813d
Author: James Cherry <[email protected]>
Date:   Thu Jul 2 08:21:49 2026 -0700

    Revert "Bfs rm search_pred"

    This reverts commit d858b3380b5e1d81ff6162b6378672a6099a246f.

commit 0adf03613d91c5774545d12cba1dc52052ca732a
Author: James Cherry <[email protected]>
Date:   Thu Jul 2 08:08:04 2026 -0700

    Genclks::ensureMaster

    Signed-off-by: James Cherry <[email protected]>

commit 089b373c548b77f9189a2617c3168867de620dfe
Author: James Cherry <[email protected]>
Date:   Wed Jul 1 17:50:43 2026 -0700

    Search::ensureDownstreamClkPins() use dfs

    Signed-off-by: James Cherry <[email protected]>

commit 000ca16adb9bdcb92266e5f242629bc3e8612658
Author: James Cherry <[email protected]>
Date:   Wed Jul 1 10:03:57 2026 -0700

    ApiChangeLog

    Signed-off-by: James Cherry <[email protected]>

commit d858b3380b5e1d81ff6162b6378672a6099a246f
Author: James Cherry <[email protected]>
Date:   Wed Jul 1 09:56:53 2026 -0700

    Bfs rm search_pred

    Signed-off-by: James Cherry <[email protected]>

commit d18498c947a7df2b615fafda38fbdbe8033eca9d
Author: James Cherry <[email protected]>
Date:   Wed Jul 1 08:07:15 2026 -0700

    bfs continueFrom/enqueueFanin/out

    Signed-off-by: James Cherry <[email protected]>

commit a8c55b12b3ad7a1041766775727ad758ae8c6d18
Author: James Cherry <[email protected]>
Date:   Tue Jun 30 10:07:46 2026 -0700

    bfs continue

    Signed-off-by: James Cherry <[email protected]>

commit 8530dcd86b7ee736f1858143c3b2cee57cdbc991
Author: James Cherry <[email protected]>
Date:   Tue Jun 30 07:15:28 2026 -0700

    Graph::visitFanin/out uninline edge iter

    Signed-off-by: James Cherry <[email protected]>

commit 1ba1f4576f4b72c64db742369a63dcf8726ba002
Author: James Cherry <[email protected]>
Date:   Mon Jun 29 21:09:17 2026 -0700

    BfsIterator rm Iterator<Vector> subclass

    Signed-off-by: James Cherry <[email protected]>

commit b3ddd2580298958ad6da8225ecac0d255315504c
Author: James Cherry <[email protected]>
Date:   Mon Jun 29 20:15:23 2026 -0700

    ClkNetwork::findClkPins use VertexQueue instead of bfs

    Signed-off-by: James Cherry <[email protected]>

commit 9e73154db48a7301be4039a25aec1fef589ef18a
Author: James Cherry <[email protected]>
Date:   Mon Jun 29 18:39:39 2026 -0700

    Search::ensureDownstreamClkPins use VertexQueue

    Signed-off-by: James Cherry <[email protected]>

commit 9cd1b160e126ccacc47375ef508fdbb580bfa162
Author: James Cherry <[email protected]>
Date:   Mon Jun 29 11:18:03 2026 -0700

    comment

    Signed-off-by: James Cherry <[email protected]>

commit 0baf3838e2b8faa5fea560b0c95431b277631fea
Author: James Cherry <[email protected]>
Date:   Mon Jun 29 10:57:39 2026 -0700

    findClkArrivals use invalid for clk fringe

    Signed-off-by: James Cherry <[email protected]>

commit e82ccd10a5e4bd69e41ce889685d7a130ae79ed6
Author: James Cherry <[email protected]>
Date:   Sun Jun 28 20:36:48 2026 -0700

    Search::findClkArrivals

    Signed-off-by: James Cherry <[email protected]>

commit cb66a72686c8728141c72ceb593b8a4b895ff696
Author: James Cherry <[email protected]>
Date:   Sun Jun 28 10:11:55 2026 -0700

    rm Search::postponeClkFanouts

    Signed-off-by: James Cherry <[email protected]>

Signed-off-by: James Cherry <[email protected]>
2026-07-04 09:04:31 -07:00

281 lines
6.3 KiB
C++

// OpenSTA, Static Timing Analyzer
// Copyright (c) 2026, 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/>.
//
// 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.
#include "ClkNetwork.hh"
#include <queue>
#include "Debug.hh"
#include "Graph.hh"
#include "Mode.hh"
#include "Network.hh"
#include "Sdc.hh"
#include "Search.hh"
#include "SearchPred.hh"
namespace sta {
ClkNetwork::ClkNetwork(Mode *mode,
StaState *sta) :
StaState(sta),
mode_(mode)
{
}
ClkNetwork::~ClkNetwork()
{
deleteContents(clk_pins_map_);
}
void
ClkNetwork::ensureClkNetwork()
{
if (!clk_pins_valid_)
findClkPins();
}
void
ClkNetwork::clear()
{
clk_pins_valid_ = false;
pin_clks_map_.clear();
deleteContents(clk_pins_map_);
pin_ideal_clks_map_.clear();
}
void
ClkNetwork::clkPinsInvalid()
{
debugPrint(debug_, "clk_network", 1, "clk network invalid");
clk_pins_valid_ = false;
}
void
ClkNetwork::deletePinBefore(const Pin *pin)
{
if (isClock(pin))
clkPinsInvalid();
}
void
ClkNetwork::disconnectPinBefore(const Pin *pin)
{
if (isClock(pin))
clkPinsInvalid();
}
void
ClkNetwork::connectPinAfter(const Pin *pin)
{
if (network_->isRegClkPin(pin))
clkPinsInvalid();
}
class ClkSearchPred : public ClkTreeSearchPred
{
public:
ClkSearchPred(const StaState *sta);
bool searchTo(const Vertex *to,
const Mode *mode) const override;
};
ClkSearchPred::ClkSearchPred(const StaState *sta) :
ClkTreeSearchPred(sta)
{
}
bool
ClkSearchPred::searchTo(const Vertex *to,
const Mode *mode) const
{
return !mode->sdc()->isLeafPinClock(to->pin());
}
void
ClkNetwork::findClkPins()
{
debugPrint(debug_, "clk_network", 1, "find clk network");
clear();
findClkPins(false, pin_clks_map_);
findClkPins(true, pin_ideal_clks_map_);
clk_pins_valid_ = true;
}
void
ClkNetwork::findClkPins(bool ideal_only,
PinClksMap &pin_clks_map)
{
const Sdc *sdc = mode_->sdc();
ClkSearchPred srch_pred(this);
for (Clock *clk : sdc->clocks()) {
if (!ideal_only
|| !clk->isPropagated()) {
PinSet *clk_pins = clk_pins_map_[clk];
if (clk_pins == nullptr) {
clk_pins = new PinSet(network_);
clk_pins_map_[clk] = clk_pins;
}
std::queue<Vertex *> queue;
VertexSet visited = makeVertexSet(this);
auto enqueue = [&queue, &visited] (Vertex *vertex) {
if (vertex && !visited.contains(vertex)) {
visited.insert(vertex);
queue.push(vertex);
}
};
for (const Pin *pin : clk->leafPins()) {
if (!ideal_only
|| !sdc->isPropagatedClock(pin)) {
Vertex *vertex, *bidirect_drvr_vertex;
graph_->pinVertices(pin, vertex, bidirect_drvr_vertex);
enqueue(vertex);
enqueue(bidirect_drvr_vertex);
}
}
while (!queue.empty()) {
Vertex *vertex = queue.front();
queue.pop();
const Pin *pin = vertex->pin();
if (!ideal_only
|| !sdc->isPropagatedClock(pin)) {
clk_pins->insert(pin);
ClockSet &pin_clks = pin_clks_map[pin];
pin_clks.insert(clk);
graph_->visitFanouts(vertex, &srch_pred,
[&queue, &visited] (Vertex *fanout) {
if (!visited.contains(fanout)) {
visited.insert(fanout);
queue.push(fanout);
}
});
}
}
}
}
}
bool
ClkNetwork::isClock(const Pin *pin) const
{
return pin_clks_map_.contains(pin);
}
bool
ClkNetwork::isClock(const Vertex *vertex) const
{
return isClock(vertex->pin());
}
bool
ClkNetwork::isClock(const Net *net) const
{
bool is_clk = false;
NetConnectedPinIterator *pin_iter = network_->pinIterator(net);
while (pin_iter->hasNext()) {
const Pin *pin = pin_iter->next();
if (isClock(pin)) {
is_clk = true;
break;
}
}
delete pin_iter;
return is_clk;
}
bool
ClkNetwork::isIdealClock(const Pin *pin) const
{
return pin_ideal_clks_map_.contains(pin);
}
bool
ClkNetwork::isIdealClock(const Vertex *vertex) const
{
return isIdealClock(vertex->pin());
}
bool
ClkNetwork::isPropagatedClock(const Pin *pin) const
{
return pin_clks_map_.contains(pin)
&& !pin_ideal_clks_map_.contains(pin);
}
const ClockSet *
ClkNetwork::clocks(const Pin *pin) const
{
auto itr = pin_clks_map_.find(pin);
if (itr != pin_clks_map_.end())
return &itr->second;
else
return nullptr;
}
const ClockSet *
ClkNetwork::clocks(const Vertex *vertex) const
{
return clocks(vertex->pin());
}
const ClockSet *
ClkNetwork::idealClocks(const Pin *pin) const
{
auto itr = pin_ideal_clks_map_.find(pin);
if (itr != pin_ideal_clks_map_.end())
return &itr->second;
else
return nullptr;
}
const PinSet *
ClkNetwork::pins(const Clock *clk)
{
if (clk_pins_map_.contains(clk))
return clk_pins_map_[clk];
else
return nullptr;
}
float
ClkNetwork::idealClkSlew(const Pin *pin,
const RiseFall *rf,
const MinMax *min_max) const
{
const ClockSet *clks = idealClocks(pin);
if (clks && !clks->empty()) {
float slew = min_max->initValue();
for (Clock *clk : *clks) {
float clk_slew = clk->slew(rf, min_max);
if (min_max->compare(clk_slew, slew))
slew = clk_slew;
}
return slew;
}
else
return 0.0;
}
} // namespace sta