Files
OpenSTA/include/sta/ExceptionPath.hh
T

700 lines
24 KiB
C++
Raw Normal View History

2018-09-28 08:54:21 -07:00
// OpenSTA, Static Timing Analyzer
2026-03-10 13:21:17 -07:00
// Copyright (c) 2026, Parallax Software, Inc.
2018-09-28 08:54:21 -07: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 10:17:08 -07:00
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2018-09-28 08:54:21 -07:00
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
2022-01-04 10:17:08 -07:00
// along with this program. If not, see <https://www.gnu.org/licenses/>.
2025-01-21 18:54:33 -07: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 08:54:21 -07:00
2020-02-15 17:13:16 -07:00
#pragma once
2018-09-28 08:54:21 -07:00
2026-03-15 14:35:24 -07:00
#include <string>
2026-03-28 19:13:35 -07:00
#include <string_view>
2026-01-03 16:59:35 -08:00
#include <vector>
2020-04-05 14:53:44 -07:00
#include "Error.hh"
#include "SdcClass.hh"
2026-04-15 09:38:10 -07:00
#include "SdcCmdComment.hh"
2018-09-28 08:54:21 -07:00
namespace sta {
2019-11-11 15:30:19 -07:00
class RiseFall;
class RiseFallBoth;
2018-09-28 08:54:21 -07:00
class MinMaxAll;
class Network;
class Pin;
class Clock;
class ExceptionPt;
class ExceptionFrom;
class ExceptionThru;
class ExceptionTo;
class ExceptionState;
2026-01-03 16:59:35 -08:00
using ExceptionPathSeq = std::vector<ExceptionPath*>;
2018-09-28 08:54:21 -07:00
class ExceptionPath : public SdcCmdComment
{
public:
ExceptionPath(ExceptionFrom *from,
2026-01-03 16:59:35 -08:00
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
bool own_pts,
int priority,
2026-03-28 19:13:35 -07:00
std::string_view comment);
2018-09-28 08:54:21 -07:00
virtual ~ExceptionPath();
2024-07-25 08:18:36 -07:00
size_t id() const { return id_; }
void setId(size_t id);
2018-09-28 08:54:21 -07:00
virtual bool isFalse() const { return false; }
virtual bool isLoop() const { return false; }
virtual bool isMultiCycle() const { return false; }
virtual bool isPathDelay() const { return false; }
virtual bool isGroupPath() const { return false; }
virtual bool isFilter() const { return false; }
virtual ExceptionPathType type() const = 0;
2026-03-15 14:35:24 -07:00
virtual std::string to_string(const Network *network) const;
2026-04-13 14:58:16 -07:00
virtual std::string_view typeString() const = 0;
2018-09-28 08:54:21 -07:00
ExceptionFrom *from() const { return from_; }
ExceptionThruSeq *thrus() const { return thrus_; }
ExceptionTo *to() const { return to_; }
ExceptionPt *firstPt();
2023-06-15 09:52:32 -07:00
bool intersectsPts(ExceptionPath *exception,
const Network *network) const;
2018-09-28 08:54:21 -07:00
const MinMaxAll *minMax() const { return min_max_; }
virtual bool matches(const MinMax *min_max,
2026-01-03 16:59:35 -08:00
bool exact) const;
2019-11-11 15:30:19 -07:00
bool matchesFirstPt(const RiseFall *to_rf,
2026-01-03 16:59:35 -08:00
const MinMax *min_max);
2018-09-28 08:54:21 -07:00
ExceptionState *firstState();
virtual bool resetMatch(ExceptionFrom *from,
2026-01-03 16:59:35 -08:00
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
2023-06-15 09:52:32 -07:00
const Network *network);
2018-09-28 08:54:21 -07:00
// The priority remains the same even though pin/clock/net/inst objects
// are added to the exceptions points during exception merging because
// only exceptions with the same priority are merged.
virtual int priority(const MinMax *) const { return priority_; }
int priority() const { return priority_; }
void setPriority(int priority);
virtual int typePriority() const = 0;
// Exception type priorities are spaced to accomodate
// fromThruToPriority from 0 thru 127.
static int falsePathPriority() { return 4000; }
static int pathDelayPriority() { return 3000; }
static int multiCyclePathPriority() { return 2000; }
static int filterPathPriority() { return 1000; }
static int groupPathPriority() { return 0; }
// Compare the value (path delay or cycle count) to another exception
// of the same priority. Because the exception "values" are floats,
// they cannot be coded into the priority.
virtual bool tighterThan(ExceptionPath *exception) const = 0;
static int fromThruToPriority(ExceptionFrom *from,
2026-01-03 16:59:35 -08:00
ExceptionThruSeq *thrus,
ExceptionTo *to);
2019-08-08 14:13:02 -07:00
size_t hash() const;
size_t hash(ExceptionPt *missing_pt) const;
2018-09-28 08:54:21 -07:00
// Mergeable properties (independent of exception points).
2019-11-25 13:48:53 -07:00
virtual bool mergeable(ExceptionPath *exception) const;
2018-09-28 08:54:21 -07:00
bool mergeablePts(ExceptionPath *exception) const;
bool mergeablePts(ExceptionPath *exception2,
2026-01-03 16:59:35 -08:00
ExceptionPt *missing_pt2,
ExceptionPt *&missing_pt) const;
2018-09-28 08:54:21 -07:00
// Overrides properties (independent of exception points).
virtual bool overrides(ExceptionPath *exception) const = 0;
virtual ExceptionPath *clone(ExceptionFrom *from,
2026-01-03 16:59:35 -08:00
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool own_pts) = 0;
void deleteInstance(const Instance *inst,
const Network *network);
2018-09-28 08:54:21 -07:00
// Default handlers.
virtual bool useEndClk() const { return false; }
virtual int pathMultiplier() const { return 0; }
virtual float delay() const { return 0.0; }
2026-03-28 19:13:35 -07:00
virtual std::string_view name() const { return {}; }
2018-09-28 08:54:21 -07:00
virtual bool isDefault() const { return false; }
2025-02-01 14:53:28 -08:00
virtual bool ignoreClkLatency() const { return false; }
2025-05-20 14:52:04 -07:00
virtual bool breakPath() const { return false; }
2018-09-28 08:54:21 -07:00
protected:
2026-03-15 14:35:24 -07:00
std::string fromThruToString(const Network *network) const;
2018-09-28 08:54:21 -07:00
void makeStates();
ExceptionFrom *from_;
ExceptionThruSeq *thrus_;
ExceptionTo *to_;
const MinMaxAll *min_max_;
bool own_pts_;
int priority_;
2026-04-15 09:38:10 -07:00
size_t id_{0}; // Unique ID assigned by Sdc.
2018-09-28 08:54:21 -07:00
ExceptionState *states_;
};
// set_false_path
class FalsePath : public ExceptionPath
{
public:
FalsePath(ExceptionFrom *from,
2026-01-03 16:59:35 -08:00
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
bool own_pts,
2026-03-28 19:13:35 -07:00
std::string_view comment);
2018-09-28 08:54:21 -07:00
FalsePath(ExceptionFrom *from,
2026-01-03 16:59:35 -08:00
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
bool own_pts,
int priority,
2026-03-28 19:13:35 -07:00
std::string_view comment);
2026-03-09 17:43:03 -07:00
ExceptionPath *clone(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool own_pts) override;
bool isFalse() const override { return true; }
ExceptionPathType type() const override { return ExceptionPathType::false_path; }
2026-04-13 14:58:16 -07:00
std::string_view typeString() const override;
2026-03-09 17:43:03 -07:00
bool mergeable(ExceptionPath *exception) const override;
bool overrides(ExceptionPath *exception) const override;
int typePriority() const override;
bool tighterThan(ExceptionPath *exception) const override;
2018-09-28 08:54:21 -07:00
};
// Loop paths are false paths used to disable paths around
// combinational loops when dynamic loop breaking is enabled.
class LoopPath : public FalsePath
{
public:
LoopPath(ExceptionThruSeq *thrus,
2026-01-03 16:59:35 -08:00
bool own_pts);
2026-03-09 17:43:03 -07:00
bool isLoop() const override { return true; }
ExceptionPathType type() const override { return ExceptionPathType::loop; }
2026-04-13 14:58:16 -07:00
std::string_view typeString() const override;
2026-03-09 17:43:03 -07:00
bool mergeable(ExceptionPath *exception) const override;
2018-09-28 08:54:21 -07:00
};
// set_max_delay/set_min_delay
class PathDelay : public ExceptionPath
{
public:
PathDelay(ExceptionFrom *from,
2026-01-03 16:59:35 -08:00
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMax *min_max,
bool ignore_clk_latency,
2025-05-20 14:52:04 -07:00
bool break_path,
2026-01-03 16:59:35 -08:00
float delay,
bool own_pts,
2026-03-28 19:13:35 -07:00
std::string_view comment);
2026-03-09 17:43:03 -07:00
ExceptionPath *clone(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool own_pts) override;
bool isPathDelay() const override { return true; }
ExceptionPathType type() const override { return ExceptionPathType::path_delay; }
2026-03-15 14:35:24 -07:00
std::string to_string(const Network *network) const override;
2026-04-13 14:58:16 -07:00
std::string_view typeString() const override;
2026-03-09 17:43:03 -07:00
bool mergeable(ExceptionPath *exception) const override;
bool overrides(ExceptionPath *exception) const override;
float delay() const override { return delay_; }
int typePriority() const override;
bool tighterThan(ExceptionPath *exception) const override;
bool ignoreClkLatency() const override { return ignore_clk_latency_; }
bool breakPath() const override { return break_path_; }
2018-09-28 08:54:21 -07:00
protected:
bool ignore_clk_latency_;
2025-05-20 14:52:04 -07:00
bool break_path_;
2018-09-28 08:54:21 -07:00
float delay_;
};
// set_multicycle_path
class MultiCyclePath : public ExceptionPath
{
public:
MultiCyclePath(ExceptionFrom *from,
2026-01-03 16:59:35 -08:00
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
bool use_end_clk,
int path_multiplier,
bool own_pts,
2026-03-28 19:13:35 -07:00
std::string_view comment);
2026-03-09 17:43:03 -07:00
ExceptionPath *clone(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool own_pts) override;
bool isMultiCycle() const override { return true; }
ExceptionPathType type() const override { return ExceptionPathType::multi_cycle; }
bool matches(const MinMax *min_max,
bool exactly) const override;
2026-03-15 14:35:24 -07:00
std::string to_string(const Network *network) const override;
2026-04-13 14:58:16 -07:00
std::string_view typeString() const override;
2026-03-09 17:43:03 -07:00
bool mergeable(ExceptionPath *exception) const override;
bool overrides(ExceptionPath *exception) const override;
bool useEndClk() const override { return use_end_clk_; }
int pathMultiplier(const MinMax *min_max) const; // overload, not override
int pathMultiplier() const override { return path_multiplier_; }
int priority(const MinMax *min_max) const override;
int typePriority() const override;
bool tighterThan(ExceptionPath *exception) const override;
2018-09-28 08:54:21 -07:00
using ExceptionPath::priority;
protected:
bool use_end_clk_;
int path_multiplier_;
};
// Filter used restrict path reporting -from/-thru nets/pins.
class FilterPath : public ExceptionPath
{
public:
FilterPath(ExceptionFrom *from,
2026-01-03 16:59:35 -08:00
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool own_pts);
2026-03-09 17:43:03 -07:00
ExceptionPath *clone(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool own_pts) override;
bool isFilter() const override { return true; }
ExceptionPathType type() const override { return ExceptionPathType::filter; }
2026-04-13 14:58:16 -07:00
std::string_view typeString() const override;
2026-03-09 17:43:03 -07:00
bool mergeable(ExceptionPath *exception) const override;
bool overrides(ExceptionPath *exception) const override;
bool resetMatch(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
const Network *network) override;
int typePriority() const override;
bool tighterThan(ExceptionPath *exception) const override;
2018-09-28 08:54:21 -07:00
};
class GroupPath : public ExceptionPath
{
public:
2026-03-28 19:13:35 -07:00
GroupPath(std::string_view name,
2026-01-03 16:59:35 -08:00
bool is_default,
ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool own_pts,
2026-03-28 19:13:35 -07:00
std::string_view comment);
2026-03-09 17:43:03 -07:00
ExceptionPath *clone(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool own_pts) override;
bool isGroupPath() const override { return true; }
ExceptionPathType type() const override { return ExceptionPathType::group_path; }
2026-04-13 14:58:16 -07:00
std::string_view typeString() const override;
2026-03-09 17:43:03 -07:00
bool mergeable(ExceptionPath *exception) const override;
bool overrides(ExceptionPath *exception) const override;
int typePriority() const override;
bool tighterThan(ExceptionPath *exception) const override;
2026-03-28 19:13:35 -07:00
std::string_view name() const override { return name_; }
2026-03-09 17:43:03 -07:00
bool isDefault() const override { return is_default_; }
2018-09-28 08:54:21 -07:00
protected:
2026-03-15 14:35:24 -07:00
std::string name_;
2018-09-28 08:54:21 -07:00
bool is_default_;
};
// Base class for Exception from/thru/to.
class ExceptionPt
{
public:
2019-11-11 15:30:19 -07:00
ExceptionPt(const RiseFallBoth *rf,
2026-01-03 16:59:35 -08:00
bool own_pts);
2026-04-13 14:58:16 -07:00
virtual ~ExceptionPt() = default;
2018-09-28 08:54:21 -07:00
virtual bool isFrom() const { return false; }
virtual bool isThru() const { return false; }
virtual bool isTo() const { return false; }
2019-11-11 15:30:19 -07:00
const RiseFallBoth *transition() const { return rf_; }
2018-09-28 08:54:21 -07:00
virtual PinSet *pins() = 0;
virtual ClockSet *clks() = 0;
virtual InstanceSet *instances() = 0;
virtual NetSet *nets() = 0;
virtual EdgePinsSet *edges() = 0;
2019-08-08 14:13:02 -07:00
size_t hash() const;
2023-01-19 11:23:45 -07:00
virtual int compare(ExceptionPt *pt,
const Network *network) const = 0;
virtual void mergeInto(ExceptionPt *pt,
const Network *network) = 0;
2018-09-28 08:54:21 -07:00
// All pins and instance/net pins.
2023-06-29 17:06:07 -07:00
virtual PinSet allPins(const Network *network) = 0;
2018-09-28 08:54:21 -07:00
virtual int typePriority() const = 0;
2026-03-15 14:35:24 -07:00
virtual std::string to_string(const Network *network) const = 0;
2018-09-28 08:54:21 -07:00
virtual size_t objectCount() const = 0;
2023-01-19 11:23:45 -07:00
virtual void addPin(const Pin *pin,
const Network *network) = 0;
2018-09-28 08:54:21 -07:00
virtual void addClock(Clock *clk) = 0;
2023-01-19 11:23:45 -07:00
virtual void addInstance(const Instance *inst,
const Network *network) = 0;
virtual void addNet(const Net *net,
const Network *network) = 0;
virtual void addEdge(const EdgePins &edge,
const Network *network) = 0;
2018-09-28 08:54:21 -07:00
virtual void connectPinAfter(PinSet *,
Network *network) = 0;
virtual void deletePinBefore(const Pin *pin,
Network *network) = 0;
2018-09-28 08:54:21 -07:00
protected:
2019-11-11 15:30:19 -07:00
const RiseFallBoth *rf_;
2018-09-28 08:54:21 -07:00
// True when the pin/net/inst/edge sets are owned by the exception point.
bool own_pts_;
// Hash is cached because there may be many objects to speed up
// exception merging.
2026-04-15 09:38:10 -07:00
size_t hash_{0};
2018-09-28 08:54:21 -07:00
2026-03-15 14:35:24 -07:00
// Maximum number of objects for to_string() to show.
static const int to_string_max_objects_;
2019-08-08 14:13:02 -07:00
static const size_t hash_clk = 3;
static const size_t hash_pin = 5;
static const size_t hash_net = 7;
static const size_t hash_inst = 11;
2018-09-28 08:54:21 -07:00
};
class ExceptionFromTo : public ExceptionPt
{
public:
2023-01-19 11:23:45 -07:00
ExceptionFromTo(PinSet *pins,
ClockSet *clks,
2026-01-03 16:59:35 -08:00
InstanceSet *insts,
const RiseFallBoth *rf,
bool own_pts,
2023-01-19 11:23:45 -07:00
const Network *network);
2026-04-13 14:58:16 -07:00
~ExceptionFromTo() override;
2026-03-09 17:43:03 -07:00
PinSet *pins() override { return pins_; }
2018-09-28 08:54:21 -07:00
bool hasPins() const;
2026-03-09 17:43:03 -07:00
ClockSet *clks() override { return clks_; }
2018-09-28 08:54:21 -07:00
bool hasClocks() const;
2026-03-09 17:43:03 -07:00
InstanceSet *instances() override { return insts_; }
2018-09-28 08:54:21 -07:00
bool hasInstances() const;
2026-03-09 17:43:03 -07:00
NetSet *nets() override { return nullptr; }
EdgePinsSet *edges() override { return nullptr; }
2018-09-28 08:54:21 -07:00
bool hasObjects() const;
2023-01-19 11:23:45 -07:00
void deleteObjects(ExceptionFromTo *pt,
const Network *network);
2026-03-09 17:43:03 -07:00
PinSet allPins(const Network *network) override;
2018-09-28 08:54:21 -07:00
bool equal(ExceptionFromTo *from_to) const;
2026-03-09 17:43:03 -07:00
int compare(ExceptionPt *pt,
const Network *network) const override;
void mergeInto(ExceptionPt *pt,
const Network *network) override;
2026-03-15 14:35:24 -07:00
std::string to_string(const Network *network) const override;
2026-03-09 17:43:03 -07:00
size_t objectCount() const override;
2018-09-28 08:54:21 -07:00
void deleteClock(Clock *clk);
2026-03-09 17:43:03 -07:00
void addPin(const Pin *pin,
const Network *network) override;
void addClock(Clock *clk) override;
void addInstance(const Instance *inst,
const Network *network) override;
void addNet(const Net *,
const Network *) override {}
void addEdge(const EdgePins &,
const Network *) override {}
void connectPinAfter(PinSet *,
Network *) override {}
void deletePinBefore(const Pin *,
Network *) override;
void deleteInstance(const Instance *inst,
const Network *network);
2018-09-28 08:54:21 -07:00
protected:
2023-01-19 11:23:45 -07:00
virtual void findHash(const Network *network);
2018-09-28 08:54:21 -07:00
2023-01-19 11:23:45 -07:00
void deletePin(const Pin *pin,
const Network *network);
2018-09-28 08:54:21 -07:00
virtual const char *cmdKeyword() const = 0;
PinSet *pins_;
ClockSet *clks_;
InstanceSet *insts_;
};
class ExceptionFrom : public ExceptionFromTo
{
public:
ExceptionFrom(PinSet *pins,
2026-01-03 16:59:35 -08:00
ClockSet *clks,
InstanceSet *insts,
const RiseFallBoth *rf,
bool own_pts,
2023-01-19 11:23:45 -07:00
const Network *network);
ExceptionFrom *clone(const Network *network);
2026-03-09 17:43:03 -07:00
bool isFrom() const override { return true; }
2023-06-15 09:52:32 -07:00
bool intersectsPts(ExceptionFrom *from,
const Network *network) const;
2026-03-09 17:43:03 -07:00
int typePriority() const override { return 0; }
2018-09-28 08:54:21 -07:00
protected:
2026-03-09 17:43:03 -07:00
const char *cmdKeyword() const override;
void findHash(const Network *network) override;
2018-09-28 08:54:21 -07:00
};
class ExceptionTo : public ExceptionFromTo
{
public:
ExceptionTo(PinSet *pins,
2026-01-03 16:59:35 -08:00
ClockSet *clks,
InstanceSet *insts,
// -to|-rise_to|-fall_to
const RiseFallBoth *rf,
// -rise|-fall endpoint transition.
const RiseFallBoth *end_rf,
bool own_pts,
2023-01-19 11:23:45 -07:00
const Network *network);
ExceptionTo *clone(const Network *network);
2026-03-09 17:43:03 -07:00
bool isTo() const override { return true; }
2026-03-15 14:35:24 -07:00
std::string to_string(const Network *network) const override;
2019-11-11 15:30:19 -07:00
const RiseFallBoth *endTransition() { return end_rf_; }
2023-06-15 09:52:32 -07:00
bool intersectsPts(ExceptionTo *to,
const Network *network) const;
2026-03-09 17:43:03 -07:00
int typePriority() const override { return 1; }
2018-09-28 08:54:21 -07:00
bool matches(const Pin *pin,
2026-01-03 16:59:35 -08:00
const ClockEdge *clk_edge,
const RiseFall *end_rf,
const Network *network) const;
2018-09-28 08:54:21 -07:00
bool matches(const Pin *pin,
2026-01-03 16:59:35 -08:00
const RiseFall *end_rf) const;
2018-09-28 08:54:21 -07:00
bool matches(const Clock *clk) const;
2022-08-08 21:33:58 -07:00
bool matches(const Pin *pin,
const RiseFall *end_rf,
const Network *network) const;
2018-09-28 08:54:21 -07:00
bool matchesFilter(const Pin *pin,
2026-01-03 16:59:35 -08:00
const ClockEdge *clk_edge,
const RiseFall *end_rf,
const Network *network) const;
2026-03-09 17:43:03 -07:00
int compare(ExceptionPt *pt,
const Network *network) const override;
2018-09-28 08:54:21 -07:00
protected:
bool matches(const Pin *pin,
2026-01-03 16:59:35 -08:00
const ClockEdge *clk_edge,
const RiseFall *end_rf,
bool inst_matches_reg_clk_pin,
const Network *network) const;
2026-03-09 17:43:03 -07:00
const char *cmdKeyword() const override;
2018-09-28 08:54:21 -07:00
// -rise|-fall endpoint transition.
2019-11-11 15:30:19 -07:00
const RiseFallBoth *end_rf_;
2018-09-28 08:54:21 -07:00
};
class ExceptionThru : public ExceptionPt
{
public:
ExceptionThru(PinSet *pins,
2026-01-03 16:59:35 -08:00
NetSet *nets,
InstanceSet *insts,
const RiseFallBoth *rf,
bool own_pts,
const Network *network);
2026-04-13 14:58:16 -07:00
~ExceptionThru() override;
2018-09-28 08:54:21 -07:00
ExceptionThru *clone(const Network *network);
2026-03-15 14:35:24 -07:00
std::string to_string(const Network *network) const override;
2026-03-09 17:43:03 -07:00
bool isThru() const override { return true; }
PinSet *pins() override { return pins_; }
EdgePinsSet *edges() override { return edges_; }
NetSet *nets() override { return nets_; }
InstanceSet *instances() override { return insts_; }
ClockSet *clks() override { return nullptr; }
2018-09-28 08:54:21 -07:00
bool hasObjects() const;
2023-01-19 11:23:45 -07:00
void deleteObjects(ExceptionThru *pt,
const Network *network);
2026-03-09 17:43:03 -07:00
PinSet allPins(const Network *network) override;
2018-09-28 08:54:21 -07:00
bool matches(const Pin *from_pin,
2026-01-03 16:59:35 -08:00
const Pin *to_pin,
const RiseFall *to_rf,
const Network *network);
2018-09-28 08:54:21 -07:00
bool equal(ExceptionThru *thru) const;
2026-03-09 17:43:03 -07:00
int compare(ExceptionPt *pt,
const Network *network) const override;
void mergeInto(ExceptionPt *pt,
const Network *network) override;
2023-06-15 09:52:32 -07:00
bool intersectsPts(ExceptionThru *thru,
const Network *network) const;
2026-03-09 17:43:03 -07:00
int typePriority() const override { return 2; }
size_t objectCount() const override;
void addPin(const Pin *pin,
const Network *network) override;
void addEdge(const EdgePins &edge,
const Network *network) override;
void addNet(const Net *net,
const Network *network) override;
void addInstance(const Instance *inst,
const Network *network) override;
void addClock(Clock *) override {}
2026-04-13 14:58:16 -07:00
void connectPinAfter(PinSet *drvrs,
Network *network) override;
void deletePinBefore(const Pin *pin,
Network *network) override;
void deleteInstance(const Instance *inst,
const Network *network);
protected:
void findHash(const Network *network);
2023-01-19 11:23:45 -07:00
void deletePin(const Pin *pin,
const Network *network);
void deleteEdge(const EdgePins &edge);
void deleteNet(const Net *net,
const Network *network);
2018-09-28 08:54:21 -07:00
void makeAllEdges(const Network *network);
void makePinEdges(const Network *network);
void makeNetEdges(const Network *network);
void makeInstEdges(const Network *network);
void makeHpinEdges(const Pin *pin,
2026-01-03 16:59:35 -08:00
const Network *network);
2023-01-19 11:23:45 -07:00
void makePinEdges(const Pin *pin,
2026-01-03 16:59:35 -08:00
const Network *network);
2023-01-19 11:23:45 -07:00
void makeNetEdges(const Net *net,
2026-01-03 16:59:35 -08:00
const Network *network);
2018-09-28 08:54:21 -07:00
void makeInstEdges(Instance *inst,
2026-01-03 16:59:35 -08:00
Network *network);
2023-01-19 11:23:45 -07:00
void deletePinEdges(const Pin *pin,
2026-01-03 16:59:35 -08:00
Network *network);
2018-09-28 08:54:21 -07:00
void deleteNetEdges(Net *net,
2026-01-03 16:59:35 -08:00
const Network *network);
2018-09-28 08:54:21 -07:00
void deleteInstEdges(Instance *inst,
2026-01-03 16:59:35 -08:00
Network *network);
2018-09-28 08:54:21 -07:00
// Leaf/port pins.
PinSet *pins_;
// Graph edges that traverse thru hierarchical pins.
2026-04-15 09:38:10 -07:00
EdgePinsSet *edges_{nullptr};
2018-09-28 08:54:21 -07:00
NetSet *nets_;
InstanceSet *insts_;
};
ExceptionThruSeq *
exceptionThrusClone(ExceptionThruSeq *thrus,
2026-01-03 16:59:35 -08:00
const Network *network);
2018-09-28 08:54:21 -07:00
// Iterate uniformly across exception from/thru/to's.
class ExceptionPtIterator
{
public:
2026-01-03 16:59:35 -08:00
ExceptionPtIterator(const ExceptionPath *exception);
2018-09-28 08:54:21 -07:00
bool hasNext();
ExceptionPt *next();
private:
const ExceptionPath *exception_;
2026-04-15 09:38:10 -07:00
bool from_done_{false};
2026-01-03 16:59:35 -08:00
ExceptionThruSeq::iterator thru_iter_;
2026-04-15 09:38:10 -07:00
bool to_done_{false};
2018-09-28 08:54:21 -07:00
};
// Visitor for exception point sets expanded into single object paths.
// For example:
// -from {A B} -to {C D}
// expands into
// -from A -to C
// -from A -to D
// -from B -to C
// -from B -to D
class ExpandedExceptionVisitor
{
public:
ExpandedExceptionVisitor(ExceptionPath *exception,
2026-01-03 16:59:35 -08:00
const Network *network);
2018-09-28 08:54:21 -07:00
void visitExpansions();
// From/thrus/to have a single exception point (pin/instance/net/clock).
virtual void visit(ExceptionFrom *from,
2026-01-03 16:59:35 -08:00
ExceptionThruSeq *thrus,
ExceptionTo *to) = 0;
2018-09-28 08:54:21 -07:00
protected:
ExceptionPath *exception_;
const Network *network_;
private:
void expandFrom();
void expandThrus(ExceptionFrom *expanded_from);
void expandThru(ExceptionFrom *expanded_from,
2026-01-03 16:59:35 -08:00
size_t next_thru_idx,
ExceptionThruSeq *expanded_thrus);
2018-09-28 08:54:21 -07:00
void expandTo(ExceptionFrom *expanded_from,
2026-01-03 16:59:35 -08:00
ExceptionThruSeq *expanded_thrus);
2018-09-28 08:54:21 -07:00
};
// States used by tags to know what exception points have been seen
// so far in a path.
class ExceptionState
{
public:
ExceptionState(ExceptionPath *exception,
2026-01-03 16:59:35 -08:00
ExceptionThru *next_thru,
int index);
2018-09-28 08:54:21 -07:00
ExceptionPath *exception() { return exception_; }
2023-01-19 11:23:45 -07:00
const ExceptionPath *exception() const { return exception_; }
2018-09-28 08:54:21 -07:00
bool matchesNextThru(const Pin *from_pin,
2026-01-03 16:59:35 -08:00
const Pin *to_pin,
const RiseFall *to_rf,
const MinMax *min_max,
const Network *network) const;
2018-09-28 08:54:21 -07:00
bool isComplete() const;
ExceptionThru *nextThru() const { return next_thru_; }
ExceptionState *nextState() const { return next_state_; }
void setNextState(ExceptionState *next_state);
2023-01-19 11:23:45 -07:00
int index() const { return index_; }
2019-08-08 14:13:02 -07:00
size_t hash() const;
2018-09-28 08:54:21 -07:00
private:
ExceptionPath *exception_;
ExceptionThru *next_thru_;
2026-04-15 09:38:10 -07:00
ExceptionState *next_state_{nullptr};
2018-09-28 08:54:21 -07:00
int index_;
};
2026-01-03 16:59:35 -08:00
int
exceptionStateCmp(const ExceptionState *state1,
const ExceptionState *state2);
2025-09-12 09:10:03 -07:00
2018-09-28 08:54:21 -07:00
// Exception thrown by check.
2020-02-15 18:10:24 -07:00
class EmptyExpceptionPt : public Exception
2018-09-28 08:54:21 -07:00
{
public:
2026-04-13 14:58:16 -07:00
const char *what() const noexcept override;
2018-09-28 08:54:21 -07:00
};
2023-01-19 11:23:45 -07:00
class ExceptionPathLess
{
public:
ExceptionPathLess(const Network *network);
bool operator()(const ExceptionPath *except1,
2026-01-03 16:59:35 -08:00
const ExceptionPath *except2) const;
2023-01-19 11:23:45 -07:00
private:
const Network *network_;
};
2018-09-28 08:54:21 -07:00
// Throws EmptyExpceptionPt it finds an empty exception point.
void
checkFromThrusTo(ExceptionFrom *from,
2026-01-03 16:59:35 -08:00
ExceptionThruSeq *thrus,
ExceptionTo *to);
2018-09-28 08:54:21 -07:00
2026-04-13 14:58:16 -07:00
} // namespace sta