rm unused Path* files
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
7700cf8a44
commit
94dd2da3d6
|
|
@ -1,78 +0,0 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SdcClass.hh"
|
||||
#include "SearchClass.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
// "Pointer" to a previous path on a vertex (PathVertex) thru an edge/arc.
|
||||
class PathPrev
|
||||
{
|
||||
public:
|
||||
PathPrev();
|
||||
PathPrev(const PathVertex *path,
|
||||
const Edge *prev_edge,
|
||||
const TimingArc *prev_arc,
|
||||
const StaState *sta);
|
||||
void init();
|
||||
void init(const PathPrev *path);
|
||||
void init(const PathPrev &path);
|
||||
void init(const PathVertex *path,
|
||||
const Edge *prev_edge,
|
||||
const TimingArc *prev_arc,
|
||||
const StaState *sta);
|
||||
bool isNull() const;
|
||||
const char *name(const StaState *sta) const;
|
||||
Vertex *vertex(const StaState *sta) const;
|
||||
VertexId vertexId(const StaState *sta) const;
|
||||
Edge *prevEdge(const StaState *sta) const;
|
||||
TimingArc *prevArc(const StaState *sta) const;
|
||||
Tag *tag(const StaState *sta) const;
|
||||
TagIndex tagIndex() const { return prev_tag_index_; }
|
||||
Arrival arrival(const StaState *sta) const;
|
||||
void prevPath(const StaState *sta,
|
||||
// Return values.
|
||||
Path &prev_path,
|
||||
TimingArc *&prev_arc) const;
|
||||
|
||||
static bool equal(const PathPrev *path1,
|
||||
const PathPrev *path2);
|
||||
static bool equal(const PathPrev &path1,
|
||||
const PathPrev &path2);
|
||||
static int cmp(const PathPrev &path1,
|
||||
const PathPrev &path2);
|
||||
|
||||
protected:
|
||||
PathPrev *prev_path_;
|
||||
Arrival arrival_;
|
||||
Required required_;
|
||||
EdgeId prev_edge_id_;
|
||||
TagIndex prev_tag_index_:tag_index_bit_count;
|
||||
unsigned prev_arc_idx_:2;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Vector.hh"
|
||||
#include "SearchClass.hh"
|
||||
#include "Path.hh"
|
||||
#include "Path.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
// Path reference to either a PathVertex or PathEnum.
|
||||
// This "could" be made smaller by using a union for
|
||||
// path_vertex_.vertex_ and path_enumed_ and a non-legal
|
||||
// value for path_vertex_.arrival_index_ (because a nullptr tag
|
||||
// in PathVertex is valid).
|
||||
class PathRef : public Path
|
||||
{
|
||||
public:
|
||||
PathRef();
|
||||
PathRef(const Path *path);
|
||||
PathRef(const PathRef &path);
|
||||
PathRef(const PathRef *path);
|
||||
PathRef(const PathVertex &path);
|
||||
void init();
|
||||
void init(const PathRef &path);
|
||||
void init(const PathRef *path);
|
||||
void init(const PathVertex &path);
|
||||
void init(const PathVertex *path);
|
||||
void init(const PathPrev &path,
|
||||
const StaState *sta);
|
||||
void init(Vertex *vertex,
|
||||
Tag *tag,
|
||||
int arrival_index);
|
||||
void init(PathEnumed *path);
|
||||
virtual void setRef(PathRef *ref) const;
|
||||
virtual bool isNull() const;
|
||||
virtual Vertex *vertex(const StaState *sta) const;
|
||||
virtual VertexId vertexId(const StaState *sta) const;
|
||||
virtual Tag *tag(const StaState *sta) const;
|
||||
virtual TagIndex tagIndex(const StaState *sta) const;
|
||||
virtual const RiseFall *transition(const StaState *sta) const;
|
||||
virtual int rfIndex(const StaState *sta) const;
|
||||
virtual PathAnalysisPt *pathAnalysisPt(const StaState *sta) const;
|
||||
virtual PathAPIndex pathAnalysisPtIndex(const StaState *sta) const;
|
||||
void arrivalIndex(int &arrival_index,
|
||||
bool &arrival_exists) const;
|
||||
virtual Arrival arrival(const StaState *sta) const;
|
||||
virtual void setArrival(Arrival arrival,
|
||||
const StaState *sta);
|
||||
virtual const Required &required(const StaState *sta) const;
|
||||
virtual void setRequired(const Required &required,
|
||||
const StaState *sta);
|
||||
virtual void prevPath(const StaState *sta,
|
||||
// Return values.
|
||||
PathRef &prev_path,
|
||||
TimingArc *&prev_arc) const;
|
||||
void deleteRep();
|
||||
|
||||
using Path::setRef;
|
||||
using Path::prevPath;
|
||||
|
||||
protected:
|
||||
PathVertex path_vertex_;
|
||||
PathEnumed *path_enumed_;
|
||||
|
||||
private:
|
||||
friend class PathVertex;
|
||||
friend class PathEnumed;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SearchClass.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
// "Pointer" to a vertex path because there is no real path object to point to.
|
||||
class PathVertexPtr
|
||||
{
|
||||
public:
|
||||
PathVertexPtr();
|
||||
PathVertexPtr(const PathVertex *path,
|
||||
const StaState *sta);
|
||||
void init();
|
||||
void init(const PathVertexPtr *path);
|
||||
void init(const PathVertexPtr &path);
|
||||
void init(const PathVertex *path,
|
||||
const StaState *sta);
|
||||
bool isNull() const;
|
||||
const char *name(const StaState *sta) const;
|
||||
Vertex *vertex(const StaState *sta) const;
|
||||
VertexId vertexId() const { return vertex_id_; }
|
||||
Tag *tag(const StaState *sta) const;
|
||||
TagIndex tagIndex() const { return tag_index_; }
|
||||
Arrival arrival(const StaState *sta) const;
|
||||
|
||||
static bool equal(const PathVertexPtr *path1,
|
||||
const PathVertexPtr *path2);
|
||||
static bool equal(const PathVertexPtr &path1,
|
||||
const PathVertexPtr &path2);
|
||||
static int cmp(const PathVertexPtr &path1,
|
||||
const PathVertexPtr &path2);
|
||||
|
||||
protected:
|
||||
VertexId vertex_id_;
|
||||
TagIndex tag_index_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,192 +0,0 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, 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 "PathEnumed.hh"
|
||||
|
||||
#include "Set.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Corner.hh"
|
||||
#include "Search.hh"
|
||||
#include "Tag.hh"
|
||||
#include "Path.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
PathEnumed:: PathEnumed(VertexId vertex_id,
|
||||
TagIndex tag_index,
|
||||
Arrival arrival,
|
||||
PathEnumed *prev_path,
|
||||
TimingArc *prev_arc) :
|
||||
Path(),
|
||||
prev_path_(prev_path),
|
||||
prev_arc_(prev_arc),
|
||||
arrival_(arrival),
|
||||
vertex_id_(vertex_id),
|
||||
tag_index_(tag_index)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
deletePathEnumed(PathEnumed *path)
|
||||
{
|
||||
while (path) {
|
||||
PathEnumed *prev = path->prevPathEnumed();
|
||||
delete path;
|
||||
path = prev;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PathEnumed::setRef(Path *ref) const
|
||||
{
|
||||
ref->init(const_cast<PathEnumed*>(this));
|
||||
}
|
||||
|
||||
Vertex *
|
||||
PathEnumed::vertex(const StaState *sta) const
|
||||
{
|
||||
const Graph *graph = sta->graph();
|
||||
return graph->vertex(vertex_id_);
|
||||
}
|
||||
|
||||
VertexId
|
||||
PathEnumed::vertexId(const StaState *) const
|
||||
{
|
||||
return vertex_id_;
|
||||
}
|
||||
|
||||
Tag *
|
||||
PathEnumed::tag(const StaState *sta) const
|
||||
{
|
||||
const Search *search = sta->search();
|
||||
return search->tag(tag_index_);
|
||||
}
|
||||
|
||||
void
|
||||
PathEnumed::setTag(Tag *tag)
|
||||
{
|
||||
tag_index_ = tag->index();
|
||||
}
|
||||
|
||||
const RiseFall *
|
||||
PathEnumed::transition(const StaState *sta) const
|
||||
{
|
||||
return tag(sta)->transition();
|
||||
}
|
||||
|
||||
int
|
||||
PathEnumed::trIndex(const StaState *sta) const
|
||||
{
|
||||
return tag(sta)->rfIndex();
|
||||
}
|
||||
|
||||
PathAnalysisPt *
|
||||
PathEnumed::pathAnalysisPt(const StaState *sta) const
|
||||
{
|
||||
const Corners *corners = sta->corners();
|
||||
return corners->findPathAnalysisPt(pathAnalysisPtIndex(sta));
|
||||
}
|
||||
|
||||
PathAPIndex
|
||||
PathEnumed::pathAnalysisPtIndex(const StaState *sta) const
|
||||
{
|
||||
return tag(sta)->pathAPIndex();
|
||||
}
|
||||
|
||||
Arrival
|
||||
PathEnumed::arrival(const StaState *) const
|
||||
{
|
||||
return arrival_;
|
||||
}
|
||||
|
||||
void
|
||||
PathEnumed::setArrival(Arrival arrival,
|
||||
const StaState *)
|
||||
{
|
||||
arrival_ = arrival;
|
||||
}
|
||||
|
||||
const Required &
|
||||
PathEnumed::required(const StaState *sta) const
|
||||
{
|
||||
// Required times are never needed for enumerated paths.
|
||||
sta->report()->critical(1380, "enumerated path required time");
|
||||
return delay_zero;
|
||||
}
|
||||
|
||||
void
|
||||
PathEnumed::setRequired(const Required &,
|
||||
const StaState *sta)
|
||||
{
|
||||
// Required times are never needed for enumerated paths.
|
||||
sta->report()->critical(1381, "enumerated path required time");
|
||||
}
|
||||
|
||||
Path *
|
||||
PathEnumed::prevPath(const StaState *) const
|
||||
{
|
||||
return prev_path_;
|
||||
}
|
||||
|
||||
void
|
||||
PathEnumed::prevPath(const StaState *,
|
||||
// Return values.
|
||||
Path &prev_path,
|
||||
TimingArc *&prev_arc) const
|
||||
{
|
||||
if (prev_path_) {
|
||||
prev_path_->setRef(prev_path);
|
||||
prev_arc = prev_arc_;
|
||||
}
|
||||
else {
|
||||
prev_path.init();
|
||||
prev_arc = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
TimingArc *
|
||||
PathEnumed::prevArc(const StaState *) const
|
||||
{
|
||||
return prev_arc_;
|
||||
}
|
||||
|
||||
PathEnumed *
|
||||
PathEnumed::prevPathEnumed() const
|
||||
{
|
||||
return prev_path_;
|
||||
}
|
||||
|
||||
void
|
||||
PathEnumed::setPrevPath(PathEnumed *prev)
|
||||
{
|
||||
prev_path_ = prev;
|
||||
}
|
||||
|
||||
void
|
||||
PathEnumed::setPrevArc(TimingArc *arc)
|
||||
{
|
||||
prev_arc_ = arc;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Path.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
// Implements Path API for paths returned by PathEnum.
|
||||
class PathEnumed : public Path
|
||||
{
|
||||
public:
|
||||
PathEnumed(VertexId vertex_id,
|
||||
TagIndex tag_index,
|
||||
Arrival arrival,
|
||||
PathEnumed *prev_path,
|
||||
TimingArc *prev_arc);
|
||||
virtual void setRef(Path *ref) const;
|
||||
virtual bool isNull() const { return vertex_id_ == 0; }
|
||||
virtual Vertex *vertex(const StaState *sta) const;
|
||||
virtual VertexId vertexId(const StaState *sta) const;
|
||||
virtual Tag *tag(const StaState *sta) const;
|
||||
virtual const RiseFall *transition(const StaState *sta) const;
|
||||
virtual int trIndex(const StaState *) const;
|
||||
virtual PathAnalysisPt *pathAnalysisPt(const StaState *sta) const;
|
||||
virtual PathAPIndex pathAnalysisPtIndex(const StaState *sta) const;
|
||||
virtual Arrival arrival(const StaState *sta) const;
|
||||
virtual void setArrival(Arrival arrival, const StaState *sta);
|
||||
virtual const Required &required(const StaState *sta) const;
|
||||
virtual void setRequired(const Required &required,
|
||||
const StaState *sta);
|
||||
virtual Path *prevPath(const StaState *sta) const;
|
||||
virtual void prevPath(const StaState *sta,
|
||||
// Return values.
|
||||
Path &prev_path,
|
||||
TimingArc *&prev_arc) const;
|
||||
virtual TimingArc *prevArc(const StaState *sta) const;
|
||||
PathEnumed *prevPathEnumed() const;
|
||||
void setPrevPath(PathEnumed *prev);
|
||||
void setPrevArc(TimingArc *arc);
|
||||
void setTag(Tag *tag);
|
||||
|
||||
using Path::setRef;
|
||||
using Path::prevPath;
|
||||
|
||||
protected:
|
||||
// Pointer to previous path.
|
||||
// A path is traversed by following prev_path/arcs.
|
||||
PathEnumed *prev_path_;
|
||||
TimingArc *prev_arc_;
|
||||
Arrival arrival_;
|
||||
VertexId vertex_id_;
|
||||
TagIndex tag_index_;
|
||||
};
|
||||
|
||||
void deletePathEnumed(PathEnumed *path);
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,246 +0,0 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, 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 "PathPrev.hh"
|
||||
|
||||
#include "Graph.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "SearchClass.hh"
|
||||
#include "Tag.hh"
|
||||
#include "TagGroup.hh"
|
||||
#include "Search.hh"
|
||||
#include "PathAnalysisPt.hh"
|
||||
#include "Path.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
PathPrev::PathPrev()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void
|
||||
PathPrev::init()
|
||||
{
|
||||
prev_edge_id_ = edge_id_null;
|
||||
prev_arc_idx_ = 0;
|
||||
prev_tag_index_ = tag_index_null;
|
||||
}
|
||||
|
||||
void
|
||||
PathPrev::init(const PathPrev *path)
|
||||
{
|
||||
if (path) {
|
||||
prev_edge_id_ = path->prev_edge_id_;
|
||||
prev_arc_idx_ = path->prev_arc_idx_;
|
||||
prev_tag_index_ = path->prev_tag_index_;
|
||||
}
|
||||
else
|
||||
init();
|
||||
}
|
||||
|
||||
void
|
||||
PathPrev::init(const PathPrev &path)
|
||||
{
|
||||
prev_edge_id_ = path.prev_edge_id_;
|
||||
prev_arc_idx_ = path.prev_arc_idx_;
|
||||
prev_tag_index_ = path.prev_tag_index_;
|
||||
}
|
||||
|
||||
void
|
||||
PathPrev::init(const PathVertex *path,
|
||||
const Edge *prev_edge,
|
||||
const TimingArc *prev_arc,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (path == nullptr || path->isNull())
|
||||
init();
|
||||
else {
|
||||
const Graph *graph = sta->graph();
|
||||
prev_edge_id_ = graph->id(prev_edge);
|
||||
prev_arc_idx_ = prev_arc->index();
|
||||
prev_tag_index_ = path->tag(sta)->index();
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
PathPrev::name(const StaState *sta) const
|
||||
{
|
||||
const Network *network = sta->network();
|
||||
const Search *search = sta->search();
|
||||
Vertex *vertex = this->vertex(sta);
|
||||
if (vertex) {
|
||||
const char *vertex_name = vertex->name(network);
|
||||
const Tag *tag = this->tag(search);
|
||||
const RiseFall *rf = tag->transition();
|
||||
const char *rf_str = rf->asString();
|
||||
const PathAnalysisPt *path_ap = tag->pathAnalysisPt(sta);
|
||||
int ap_index = path_ap->index();
|
||||
const char *min_max = path_ap->pathMinMax()->asString();
|
||||
TagIndex tag_index = tag->index();
|
||||
return stringPrintTmp("%s %s %s/%d %d",
|
||||
vertex_name, rf_str, min_max,
|
||||
ap_index, tag_index);
|
||||
}
|
||||
else
|
||||
return "NULL";
|
||||
}
|
||||
|
||||
bool
|
||||
PathPrev::isNull() const
|
||||
{
|
||||
return prev_edge_id_ == edge_id_null;
|
||||
}
|
||||
|
||||
VertexId
|
||||
PathPrev::vertexId(const StaState *sta) const
|
||||
{
|
||||
if (prev_edge_id_ == edge_id_null)
|
||||
return vertex_id_null;
|
||||
else {
|
||||
const Graph *graph = sta->graph();
|
||||
const Edge *edge = graph->edge(prev_edge_id_);
|
||||
return edge->from();
|
||||
}
|
||||
}
|
||||
|
||||
Vertex *
|
||||
PathPrev::vertex(const StaState *sta) const
|
||||
{
|
||||
if (prev_edge_id_ == edge_id_null)
|
||||
return nullptr;
|
||||
else {
|
||||
const Graph *graph = sta->graph();
|
||||
const Edge *edge = graph->edge(prev_edge_id_);
|
||||
return edge->from(graph);
|
||||
}
|
||||
}
|
||||
|
||||
Edge *
|
||||
PathPrev::prevEdge(const StaState *sta) const
|
||||
{
|
||||
if (prev_edge_id_ == edge_id_null)
|
||||
return nullptr;
|
||||
else {
|
||||
const Graph *graph = sta->graph();
|
||||
return graph->edge(prev_edge_id_);
|
||||
}
|
||||
}
|
||||
|
||||
TimingArc *
|
||||
PathPrev::prevArc(const StaState *sta) const
|
||||
{
|
||||
if (prev_edge_id_ == edge_id_null)
|
||||
return nullptr;
|
||||
else {
|
||||
const Graph *graph = sta->graph();
|
||||
const Edge *edge = graph->edge(prev_edge_id_);
|
||||
TimingArcSet *arc_set = edge->timingArcSet();
|
||||
return arc_set->findTimingArc(prev_arc_idx_);
|
||||
}
|
||||
}
|
||||
|
||||
Tag *
|
||||
PathPrev::tag(const StaState *sta) const
|
||||
{
|
||||
const Search *search = sta->search();
|
||||
return search->tag(prev_tag_index_);
|
||||
}
|
||||
|
||||
Arrival
|
||||
PathPrev::arrival(const StaState *sta) const
|
||||
{
|
||||
Graph *graph = sta->graph();
|
||||
const Search *search = sta->search();
|
||||
Tag *tag = search->tag(prev_tag_index_);
|
||||
Vertex *vertex = this->vertex(sta);
|
||||
TagGroup *tag_group = search->tagGroup(vertex);
|
||||
if (tag_group) {
|
||||
int arrival_index;
|
||||
bool arrival_exists;
|
||||
tag_group->arrivalIndex(tag, arrival_index, arrival_exists);
|
||||
if (!arrival_exists)
|
||||
sta->report()->critical(1420, "tag group missing tag");
|
||||
Arrival *arrivals = graph->arrivals(vertex);
|
||||
if (arrivals)
|
||||
return arrivals[arrival_index];
|
||||
else
|
||||
sta->report()->critical(1421, "missing arrivals");
|
||||
}
|
||||
else
|
||||
sta->report()->error(1422, "missing arrivals.");
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void
|
||||
PathPrev::prevPath(const StaState *sta,
|
||||
// Return values.
|
||||
PathRef &prev_path,
|
||||
TimingArc *&prev_arc) const
|
||||
{
|
||||
PathVertex path_vertex(this, sta);
|
||||
path_vertex.prevPath(sta, prev_path, prev_arc);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
bool
|
||||
PathPrev::equal(const PathPrev *path1,
|
||||
const PathPrev *path2)
|
||||
{
|
||||
return path1->prev_edge_id_ == path2->prev_edge_id_
|
||||
&& path1->prev_tag_index_ == path2->prev_tag_index_;
|
||||
}
|
||||
|
||||
bool
|
||||
PathPrev::equal(const PathPrev &path1,
|
||||
const PathPrev &path2)
|
||||
{
|
||||
return path1.prev_edge_id_ == path2.prev_edge_id_
|
||||
&& path1.prev_tag_index_ == path2.prev_tag_index_;
|
||||
}
|
||||
|
||||
int
|
||||
PathPrev::cmp(const PathPrev &path1,
|
||||
const PathPrev &path2)
|
||||
{
|
||||
EdgeId edge_id1 = path1.prev_edge_id_;
|
||||
EdgeId edge_id2 = path2.prev_edge_id_;
|
||||
if (edge_id1 == edge_id2) {
|
||||
TagIndex tag_index1 = path1.prev_tag_index_;
|
||||
TagIndex tag_index2 = path2.prev_tag_index_;
|
||||
if (tag_index1 == tag_index2)
|
||||
return 0;
|
||||
else if (tag_index1 < tag_index2)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
else if (edge_id1 < edge_id2)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,283 +0,0 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, 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 "PathRef.hh"
|
||||
|
||||
#include "Graph.hh"
|
||||
#include "TagGroup.hh"
|
||||
#include "Path.hh"
|
||||
#include "Search.hh"
|
||||
|
||||
|
||||
namespace sta {
|
||||
|
||||
PathRef::PathRef() :
|
||||
path_enumed_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
PathRef::PathRef(const Path *path) :
|
||||
path_enumed_(nullptr)
|
||||
{
|
||||
if (path)
|
||||
path->setRef(this);
|
||||
}
|
||||
|
||||
PathRef::PathRef(const PathRef &path) :
|
||||
path_vertex_(path.path_vertex_),
|
||||
path_enumed_(path.path_enumed_)
|
||||
{
|
||||
}
|
||||
|
||||
PathRef::PathRef(const PathRef *path) :
|
||||
path_vertex_(path->path_vertex_),
|
||||
path_enumed_(path->path_enumed_)
|
||||
{
|
||||
}
|
||||
|
||||
PathRef::PathRef(const PathVertex &path) :
|
||||
path_vertex_(&path),
|
||||
path_enumed_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::init()
|
||||
{
|
||||
path_vertex_.init();
|
||||
path_enumed_ = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::init(const PathRef &path)
|
||||
{
|
||||
path_vertex_ = path.path_vertex_;
|
||||
path_enumed_ = path.path_enumed_;
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::init(const PathRef *path)
|
||||
{
|
||||
path_vertex_ = path->path_vertex_;
|
||||
path_enumed_ = path->path_enumed_;
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::init(const PathVertex *path)
|
||||
{
|
||||
path_vertex_ = path;
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::init(const PathVertex &path)
|
||||
{
|
||||
path_vertex_ = path;
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::init(const PathPrev &path,
|
||||
const StaState *sta)
|
||||
{
|
||||
int arrival_index = 0;
|
||||
TagIndex tag_index = path.tagIndex();
|
||||
Tag *tag = nullptr;
|
||||
if (tag_index != tag_index_null) {
|
||||
const Search *search = sta->search();
|
||||
tag = search->tag(tag_index);
|
||||
Vertex *vertex = path.vertex(sta);
|
||||
TagGroup *tag_group = search->tagGroup(vertex);
|
||||
if (tag_group) {
|
||||
bool arrival_exists;
|
||||
tag_group->arrivalIndex(tag, arrival_index, arrival_exists);
|
||||
}
|
||||
}
|
||||
path_vertex_.init(path.vertex(sta), tag, arrival_index);
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::init(Vertex *vertex,
|
||||
Tag *tag,
|
||||
int arrival_index)
|
||||
{
|
||||
path_vertex_.init(vertex, tag, arrival_index);
|
||||
path_enumed_ = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::init(PathEnumed *path)
|
||||
{
|
||||
path_enumed_ = path;
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::setRef(PathRef *ref) const
|
||||
{
|
||||
ref->path_vertex_ = path_vertex_;
|
||||
ref->path_enumed_ = path_enumed_;
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::deleteRep()
|
||||
{
|
||||
if (path_enumed_)
|
||||
deletePathEnumed(path_enumed_);
|
||||
}
|
||||
|
||||
bool
|
||||
PathRef::isNull() const
|
||||
{
|
||||
return path_enumed_ == nullptr
|
||||
&& path_vertex_.isNull();
|
||||
}
|
||||
|
||||
Vertex *
|
||||
PathRef::vertex(const StaState *sta) const
|
||||
{
|
||||
if (path_enumed_)
|
||||
return path_enumed_->vertex(sta);
|
||||
else
|
||||
return path_vertex_.vertex(sta);
|
||||
}
|
||||
|
||||
VertexId
|
||||
PathRef::vertexId(const StaState *sta) const
|
||||
{
|
||||
if (path_enumed_)
|
||||
return path_enumed_->vertexId(sta);
|
||||
else
|
||||
return path_vertex_.vertexId(sta);
|
||||
}
|
||||
|
||||
Tag *
|
||||
PathRef::tag(const StaState *sta) const
|
||||
{
|
||||
if (path_enumed_)
|
||||
return path_enumed_->tag(sta);
|
||||
else
|
||||
return path_vertex_.tag(sta);
|
||||
}
|
||||
|
||||
TagIndex
|
||||
PathRef::tagIndex(const StaState *sta) const
|
||||
{
|
||||
if (path_enumed_)
|
||||
return path_enumed_->tagIndex(sta);
|
||||
else
|
||||
return path_vertex_.tagIndex(sta);
|
||||
}
|
||||
|
||||
const RiseFall *
|
||||
PathRef::transition(const StaState *sta) const
|
||||
{
|
||||
if (path_enumed_)
|
||||
return path_enumed_->transition(sta);
|
||||
else
|
||||
return path_vertex_.transition(sta);
|
||||
}
|
||||
|
||||
int
|
||||
PathRef::rfIndex(const StaState *sta) const
|
||||
{
|
||||
if (path_enumed_)
|
||||
return path_enumed_->rfIndex(sta);
|
||||
else
|
||||
return path_vertex_.rfIndex(sta);
|
||||
}
|
||||
|
||||
PathAnalysisPt *
|
||||
PathRef::pathAnalysisPt(const StaState *sta) const
|
||||
{
|
||||
if (path_enumed_)
|
||||
return path_enumed_->pathAnalysisPt(sta);
|
||||
else
|
||||
return path_vertex_.pathAnalysisPt(sta);
|
||||
}
|
||||
|
||||
PathAPIndex
|
||||
PathRef::pathAnalysisPtIndex(const StaState *sta) const
|
||||
{
|
||||
if (path_enumed_)
|
||||
return path_enumed_->pathAnalysisPtIndex(sta);
|
||||
else
|
||||
return path_vertex_.pathAnalysisPtIndex(sta);
|
||||
}
|
||||
|
||||
Arrival
|
||||
PathRef::arrival(const StaState *sta) const
|
||||
{
|
||||
if (path_enumed_)
|
||||
return path_enumed_->arrival(sta);
|
||||
else
|
||||
return path_vertex_.arrival(sta);
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::setArrival(Arrival arrival,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (path_enumed_)
|
||||
return path_enumed_->setArrival(arrival, sta);
|
||||
else
|
||||
return path_vertex_.setArrival(arrival, sta);
|
||||
}
|
||||
|
||||
const Required &
|
||||
PathRef::required(const StaState *sta) const
|
||||
{
|
||||
if (path_enumed_)
|
||||
return path_enumed_->required(sta);
|
||||
else
|
||||
return path_vertex_.required(sta);
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::setRequired(const Required &required,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (path_enumed_)
|
||||
return path_enumed_->setRequired(required, sta);
|
||||
else
|
||||
return path_vertex_.setRequired(required, sta);
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::prevPath(const StaState *sta,
|
||||
// Return values.
|
||||
PathRef &prev_path,
|
||||
TimingArc *&prev_arc) const
|
||||
{
|
||||
if (path_enumed_)
|
||||
path_enumed_->prevPath(sta, prev_path, prev_arc);
|
||||
else
|
||||
path_vertex_.prevPath(sta, prev_path, prev_arc);
|
||||
}
|
||||
|
||||
void
|
||||
PathRef::arrivalIndex(int &arrival_index,
|
||||
bool &arrival_exists) const
|
||||
{
|
||||
return path_vertex_.arrivalIndex(arrival_index, arrival_exists);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,628 +0,0 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, 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 "Path.hh"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "Fuzzy.hh"
|
||||
#include "Graph.hh"
|
||||
#include "ExceptionPath.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "GraphDelayCalc.hh"
|
||||
#include "Corner.hh"
|
||||
#include "Tag.hh"
|
||||
#include "TagGroup.hh"
|
||||
#include "PathAnalysisPt.hh"
|
||||
#include "PathRef.hh"
|
||||
#include "PathPrev.hh"
|
||||
#include "PathVertexPtr.hh"
|
||||
#include "Search.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
PathVertex::PathVertex() :
|
||||
vertex_(nullptr),
|
||||
tag_(nullptr),
|
||||
arrival_index_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PathVertex::PathVertex(const PathVertex &path) :
|
||||
vertex_(path.vertex_),
|
||||
tag_(path.tag_),
|
||||
arrival_index_(path.arrival_index_)
|
||||
{
|
||||
}
|
||||
|
||||
PathVertex::PathVertex(const PathVertex *path) :
|
||||
vertex_(nullptr),
|
||||
tag_(nullptr),
|
||||
arrival_index_(0)
|
||||
{
|
||||
if (path) {
|
||||
vertex_ = path->vertex_;
|
||||
tag_ = path->tag_;
|
||||
arrival_index_ = path->arrival_index_;
|
||||
}
|
||||
}
|
||||
|
||||
PathVertex::PathVertex(Vertex *vertex,
|
||||
Tag *tag,
|
||||
const StaState *sta)
|
||||
{
|
||||
init(vertex, tag, sta);
|
||||
}
|
||||
|
||||
PathVertex::PathVertex(Vertex *vertex,
|
||||
Tag *tag,
|
||||
int arrival_index) :
|
||||
vertex_(vertex),
|
||||
tag_(tag),
|
||||
arrival_index_(arrival_index)
|
||||
{
|
||||
}
|
||||
|
||||
PathVertex::PathVertex(const PathPrev *path,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (path)
|
||||
init(path->vertex(sta), path->tag(sta), sta);
|
||||
else
|
||||
init();
|
||||
}
|
||||
|
||||
PathVertex::PathVertex(const PathPrev &path,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (path.isNull())
|
||||
init();
|
||||
else
|
||||
init(path.vertex(sta), path.tag(sta), sta);
|
||||
}
|
||||
|
||||
PathVertex::PathVertex(const PathVertexPtr &path,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (path.isNull())
|
||||
init();
|
||||
else
|
||||
init(path.vertex(sta), path.tag(sta), sta);
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::init()
|
||||
{
|
||||
vertex_ = nullptr;
|
||||
tag_ = nullptr;
|
||||
arrival_index_ = 0;
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::init(Vertex *vertex,
|
||||
Tag *tag,
|
||||
const StaState *sta)
|
||||
{
|
||||
vertex_ = nullptr;
|
||||
tag_ = nullptr;
|
||||
arrival_index_ = 0;
|
||||
const Search *search = sta->search();
|
||||
TagGroup *tag_group = search->tagGroup(vertex);
|
||||
if (tag_group) {
|
||||
bool arrival_exists;
|
||||
tag_group->arrivalIndex(tag, arrival_index_, arrival_exists);
|
||||
if (arrival_exists) {
|
||||
vertex_ = vertex;
|
||||
tag_ = tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::init(Vertex *vertex,
|
||||
Tag *tag,
|
||||
int arrival_index)
|
||||
{
|
||||
vertex_ = vertex;
|
||||
tag_ = tag;
|
||||
arrival_index_ = arrival_index;
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::init(const PathPrev *path,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (path)
|
||||
init(path->vertex(sta), path->tag(sta), sta);
|
||||
else
|
||||
init();
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::init(const PathPrev &path,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (!path.isNull())
|
||||
init(path.vertex(sta), path.tag(sta), sta);
|
||||
else
|
||||
init();
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::init(const PathVertexPtr &path,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (!path.isNull())
|
||||
init(path.vertex(sta), path.tag(sta), sta);
|
||||
else
|
||||
init();
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::operator=(const PathVertex &path)
|
||||
{
|
||||
vertex_ = path.vertex_;
|
||||
tag_ = path.tag_;
|
||||
arrival_index_ = path.arrival_index_;
|
||||
}
|
||||
|
||||
bool
|
||||
PathVertex::isNull() const
|
||||
{
|
||||
return tag_ == nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::setRef(PathRef *ref) const
|
||||
{
|
||||
ref->init(vertex_, tag_, arrival_index_);
|
||||
}
|
||||
|
||||
VertexId
|
||||
PathVertex::vertexId(const StaState *sta) const
|
||||
{
|
||||
const Graph *graph = sta->graph();
|
||||
return graph->id(vertex_);
|
||||
}
|
||||
|
||||
TagIndex
|
||||
PathVertex::tagIndex(const StaState *) const
|
||||
{
|
||||
return tag_->index();
|
||||
}
|
||||
|
||||
const RiseFall *
|
||||
PathVertex::transition(const StaState *) const
|
||||
{
|
||||
return tag_->transition();
|
||||
}
|
||||
|
||||
int
|
||||
PathVertex::rfIndex(const StaState *) const
|
||||
{
|
||||
return tag_->rfIndex();
|
||||
}
|
||||
|
||||
PathAnalysisPt *
|
||||
PathVertex::pathAnalysisPt(const StaState *sta) const
|
||||
{
|
||||
return tag_->pathAnalysisPt(sta);
|
||||
}
|
||||
|
||||
PathAPIndex
|
||||
PathVertex::pathAnalysisPtIndex(const StaState *) const
|
||||
{
|
||||
return tag_->pathAPIndex();
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::arrivalIndex(int &arrival_index,
|
||||
bool &arrival_exists) const
|
||||
{
|
||||
if (tag_) {
|
||||
arrival_index = arrival_index_;
|
||||
arrival_exists = true;
|
||||
}
|
||||
else
|
||||
arrival_exists = false;
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::setArrivalIndex(int arrival_index)
|
||||
{
|
||||
arrival_index_ = arrival_index;
|
||||
}
|
||||
|
||||
Arrival
|
||||
PathVertex::arrival(const StaState *sta) const
|
||||
{
|
||||
Arrival *arrivals = sta->graph()->arrivals(vertex_);
|
||||
if (arrivals)
|
||||
return arrivals[arrival_index_];
|
||||
else {
|
||||
sta->report()->error(1400, "missing arrivals.");
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::setArrival(Arrival arrival,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (tag_) {
|
||||
Arrival *arrivals = sta->graph()->arrivals(vertex_);
|
||||
if (arrivals)
|
||||
arrivals[arrival_index_] = arrival;
|
||||
else
|
||||
sta->report()->error(1401, "missing arrivals.");
|
||||
}
|
||||
}
|
||||
|
||||
const Required &
|
||||
PathVertex::required(const StaState *sta) const
|
||||
{
|
||||
if (tag_) {
|
||||
Required *requireds = sta->graph()->requireds(vertex_);
|
||||
if (requireds)
|
||||
return requireds[arrival_index_];
|
||||
}
|
||||
return delayInitValue(minMax(sta)->opposite());
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::setRequired(const Required &required,
|
||||
const StaState *sta)
|
||||
{
|
||||
Graph *graph = sta->graph();
|
||||
Required *requireds = graph->requireds(vertex_);
|
||||
if (requireds == nullptr) {
|
||||
const Search *search = sta->search();
|
||||
TagGroup *tag_group = search->tagGroup(vertex_);
|
||||
if (tag_group) {
|
||||
int arrival_count = tag_group->arrivalCount();
|
||||
requireds = graph->makeRequireds(vertex_, arrival_count);
|
||||
}
|
||||
else
|
||||
sta->report()->error(1402, "missing requireds.");
|
||||
}
|
||||
requireds[arrival_index_] = required;
|
||||
}
|
||||
|
||||
bool
|
||||
PathVertex::equal(const PathVertex *path1,
|
||||
const PathVertex *path2)
|
||||
{
|
||||
return path1->vertex_ == path2->vertex_
|
||||
&& path1->tag_ == path2->tag_;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// EvalPred but search to clk source pin.
|
||||
class PrevPred2 : public SearchPred0
|
||||
{
|
||||
public:
|
||||
explicit PrevPred2(const StaState *sta);
|
||||
virtual bool searchThru(Edge *edge);
|
||||
};
|
||||
|
||||
PrevPred2::PrevPred2(const StaState *sta) :
|
||||
SearchPred0(const_cast<StaState*>(sta))
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
PrevPred2::searchThru(Edge *edge)
|
||||
{
|
||||
const Sdc *sdc = sta_->sdc();
|
||||
TimingRole *role = edge->role();
|
||||
return SearchPred0::searchThru(edge)
|
||||
&& (sdc->dynamicLoopBreaking()
|
||||
|| !edge->isDisabledLoop())
|
||||
&& !role->isTimingCheck();
|
||||
}
|
||||
|
||||
class PrevPathVisitor : public PathVisitor
|
||||
{
|
||||
public:
|
||||
PrevPathVisitor(const Path *path,
|
||||
SearchPred *pred,
|
||||
const StaState *sta);
|
||||
virtual VertexVisitor *copy() const;
|
||||
virtual void visit(Vertex *) {}
|
||||
virtual bool visitFromToPath(const Pin *from_pin,
|
||||
Vertex *from_vertex,
|
||||
const RiseFall *from_rf,
|
||||
Tag *from_tag,
|
||||
PathVertex *from_path,
|
||||
const Arrival &from_arrival,
|
||||
Edge *edge,
|
||||
TimingArc *arc,
|
||||
ArcDelay arc_delay,
|
||||
Vertex *to_vertex,
|
||||
const RiseFall *to_rf,
|
||||
Tag *to_tag,
|
||||
Arrival &to_arrival,
|
||||
const MinMax *min_max,
|
||||
const PathAnalysisPt *path_ap);
|
||||
PathVertex &prevPath() { return prev_path_; }
|
||||
TimingArc *prevArc() const { return prev_arc_; }
|
||||
|
||||
protected:
|
||||
Tag *unfilteredTag(const Tag *tag) const;
|
||||
|
||||
const Path *path_;
|
||||
Arrival path_arrival_;
|
||||
Tag *path_tag_;
|
||||
int path_rf_index_;
|
||||
PathAPIndex path_ap_index_;
|
||||
PathVertex prev_path_;
|
||||
TimingArc *prev_arc_;
|
||||
float dcalc_tol_;
|
||||
};
|
||||
|
||||
PrevPathVisitor::PrevPathVisitor(const Path *path,
|
||||
SearchPred *pred,
|
||||
const StaState *sta) :
|
||||
PathVisitor(pred, sta),
|
||||
path_(path),
|
||||
path_arrival_(path->arrival(sta)),
|
||||
path_tag_(path->tag(sta)),
|
||||
path_rf_index_(path->rfIndex(sta)),
|
||||
path_ap_index_(path->pathAnalysisPtIndex(sta)),
|
||||
prev_path_(),
|
||||
prev_arc_(nullptr),
|
||||
dcalc_tol_(sta->graphDelayCalc()->incrementalDelayTolerance())
|
||||
{
|
||||
}
|
||||
|
||||
VertexVisitor *
|
||||
PrevPathVisitor::copy() const
|
||||
{
|
||||
return new PrevPathVisitor(path_, pred_, this);
|
||||
}
|
||||
|
||||
bool
|
||||
PrevPathVisitor::visitFromToPath(const Pin *,
|
||||
Vertex *,
|
||||
const RiseFall *,
|
||||
Tag *from_tag,
|
||||
PathVertex *from_path,
|
||||
const Arrival &,
|
||||
Edge *,
|
||||
TimingArc *arc,
|
||||
ArcDelay,
|
||||
Vertex *,
|
||||
const RiseFall *to_rf,
|
||||
Tag *to_tag,
|
||||
Arrival &to_arrival,
|
||||
const MinMax *,
|
||||
const PathAnalysisPt *path_ap)
|
||||
{
|
||||
PathAPIndex path_ap_index = path_ap->index();
|
||||
if (to_rf->index() == path_rf_index_
|
||||
&& path_ap_index == path_ap_index_
|
||||
&& delayEqual(to_arrival, path_arrival_)
|
||||
&& (tagMatch(to_tag, path_tag_, this)
|
||||
// If the filter exception became active searching from
|
||||
// from_path to to_path the tag includes the filter, but
|
||||
// to_vertex still has paths from previous searches that do
|
||||
// not have the filter.
|
||||
|| (!from_tag->isFilter()
|
||||
&& to_tag->isFilter()
|
||||
&& tagMatch(unfilteredTag(to_tag), path_tag_, this)))) {
|
||||
int arrival_index;
|
||||
bool arrival_exists;
|
||||
from_path->arrivalIndex(arrival_index, arrival_exists);
|
||||
if (arrival_exists) {
|
||||
prev_path_ = from_path;
|
||||
prev_arc_ = arc;
|
||||
// Stop looking for the previous path/arc.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Tag *
|
||||
PrevPathVisitor::unfilteredTag(const Tag *tag) const
|
||||
{
|
||||
ExceptionStateSet *unfiltered_states = nullptr;
|
||||
const ExceptionStateSet *states = tag->states();
|
||||
ExceptionStateSet::ConstIterator state_iter(states);
|
||||
while (state_iter.hasNext()) {
|
||||
ExceptionState *state = state_iter.next();
|
||||
ExceptionPath *except = state->exception();
|
||||
if (!except->isFilter()) {
|
||||
if (unfiltered_states == nullptr)
|
||||
unfiltered_states = new ExceptionStateSet();
|
||||
unfiltered_states->insert(state);
|
||||
}
|
||||
}
|
||||
return search_->findTag(tag->transition(),
|
||||
corners_->findPathAnalysisPt(tag->pathAPIndex()),
|
||||
tag->clkInfo(),
|
||||
tag->isClock(),
|
||||
tag->inputDelay(),
|
||||
tag->isSegmentStart(),
|
||||
unfiltered_states, true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
PathVertex::prevPath(const StaState *sta,
|
||||
// Return values.
|
||||
PathVertex &prev_path,
|
||||
TimingArc *&prev_arc) const
|
||||
{
|
||||
PrevPred2 pred(sta);
|
||||
PrevPathVisitor visitor(this, &pred, sta);
|
||||
visitor.visitFaninPaths(vertex(sta));
|
||||
prev_path = visitor.prevPath();
|
||||
prev_arc = visitor.prevArc();
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::prevPath(const StaState *sta,
|
||||
// Return values.
|
||||
PathVertex &prev_path) const
|
||||
{
|
||||
PrevPred2 pred(sta);
|
||||
PrevPathVisitor visitor(this, &pred, sta);
|
||||
visitor.visitFaninPaths(vertex(sta));
|
||||
prev_path = visitor.prevPath();
|
||||
}
|
||||
|
||||
void
|
||||
PathVertex::prevPath(const StaState *sta,
|
||||
// Return values.
|
||||
PathRef &prev_path,
|
||||
TimingArc *&prev_arc) const
|
||||
{
|
||||
const Graph *graph = sta->graph();
|
||||
Vertex *vertex = this->vertex(graph);
|
||||
PathPrev *prev_paths = vertex->prevPaths();
|
||||
if (prev_paths) {
|
||||
PathPrev &prev = prev_paths[arrival_index_];
|
||||
prev_path.init(prev, sta);
|
||||
prev_arc = prev.isNull() ? nullptr : prev.prevArc(sta);
|
||||
}
|
||||
else {
|
||||
PathVertex prev;
|
||||
prevPath(sta, prev, prev_arc);
|
||||
prev.setRef(prev_path);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
VertexPathIterator::VertexPathIterator(Vertex *vertex,
|
||||
const StaState *sta) :
|
||||
search_(sta->search()),
|
||||
vertex_(vertex),
|
||||
rf_(nullptr),
|
||||
path_ap_(nullptr),
|
||||
min_max_(nullptr)
|
||||
{
|
||||
TagGroup *tag_group = search_->tagGroup(vertex);
|
||||
if (tag_group) {
|
||||
arrival_iter_.init(tag_group->arrivalMap());
|
||||
findNext();
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over vertex paths with the same transition and
|
||||
// analysis pt but different but different tags.
|
||||
VertexPathIterator::VertexPathIterator(Vertex *vertex,
|
||||
const RiseFall *rf,
|
||||
const PathAnalysisPt *path_ap,
|
||||
const StaState *sta) :
|
||||
search_(sta->search()),
|
||||
vertex_(vertex),
|
||||
rf_(rf),
|
||||
path_ap_(path_ap),
|
||||
min_max_(nullptr)
|
||||
{
|
||||
TagGroup *tag_group = search_->tagGroup(vertex);
|
||||
if (tag_group) {
|
||||
arrival_iter_.init(tag_group->arrivalMap());
|
||||
findNext();
|
||||
}
|
||||
}
|
||||
|
||||
VertexPathIterator::VertexPathIterator(Vertex *vertex,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max,
|
||||
const StaState *sta) :
|
||||
search_(sta->search()),
|
||||
vertex_(vertex),
|
||||
rf_(rf),
|
||||
path_ap_(nullptr),
|
||||
min_max_(min_max)
|
||||
{
|
||||
TagGroup *tag_group = search_->tagGroup(vertex);
|
||||
if (tag_group) {
|
||||
arrival_iter_.init(tag_group->arrivalMap());
|
||||
findNext();
|
||||
}
|
||||
}
|
||||
|
||||
VertexPathIterator::VertexPathIterator(Vertex *vertex,
|
||||
const RiseFall *rf,
|
||||
const PathAnalysisPt *path_ap,
|
||||
const MinMax *min_max,
|
||||
const StaState *sta) :
|
||||
search_(sta->search()),
|
||||
vertex_(vertex),
|
||||
rf_(rf),
|
||||
path_ap_(path_ap),
|
||||
min_max_(min_max)
|
||||
{
|
||||
TagGroup *tag_group = search_->tagGroup(vertex);
|
||||
if (tag_group) {
|
||||
arrival_iter_.init(tag_group->arrivalMap());
|
||||
findNext();
|
||||
}
|
||||
}
|
||||
|
||||
VertexPathIterator::~VertexPathIterator()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
VertexPathIterator::hasNext()
|
||||
{
|
||||
return !next_.isNull();
|
||||
}
|
||||
|
||||
void
|
||||
VertexPathIterator::findNext()
|
||||
{
|
||||
while (arrival_iter_.hasNext()) {
|
||||
Tag *tag;
|
||||
int arrival_index;
|
||||
arrival_iter_.next(tag, arrival_index);
|
||||
if ((rf_ == nullptr
|
||||
|| tag->rfIndex() == rf_->index())
|
||||
&& (path_ap_ == nullptr
|
||||
|| tag->pathAPIndex() == path_ap_->index())
|
||||
&& (min_max_ == nullptr
|
||||
|| tag->pathAnalysisPt(search_)->pathMinMax() == min_max_)) {
|
||||
next_.init(vertex_, tag, arrival_index);
|
||||
return;
|
||||
}
|
||||
}
|
||||
next_.init();
|
||||
}
|
||||
|
||||
PathVertex *
|
||||
VertexPathIterator::next()
|
||||
{
|
||||
path_ = next_;
|
||||
findNext();
|
||||
return &path_;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, 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 "PathVertexPtr.hh"
|
||||
|
||||
#include "Graph.hh"
|
||||
#include "TimingArc.hh"
|
||||
#include "SearchClass.hh"
|
||||
#include "Tag.hh"
|
||||
#include "TagGroup.hh"
|
||||
#include "Search.hh"
|
||||
#include "PathAnalysisPt.hh"
|
||||
#include "PathVertex.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
PathVertexPtr::PathVertexPtr() :
|
||||
vertex_id_(vertex_id_null),
|
||||
tag_index_(tag_index_null)
|
||||
{
|
||||
}
|
||||
|
||||
PathVertexPtr::PathVertexPtr(const PathVertex *path,
|
||||
const StaState *sta)
|
||||
{
|
||||
init(path, sta);
|
||||
}
|
||||
|
||||
void
|
||||
PathVertexPtr::init()
|
||||
{
|
||||
vertex_id_ = vertex_id_null;
|
||||
tag_index_ = tag_index_null;
|
||||
}
|
||||
|
||||
void
|
||||
PathVertexPtr::init(const PathVertexPtr *path)
|
||||
{
|
||||
if (path) {
|
||||
vertex_id_ = path->vertex_id_;
|
||||
tag_index_ = path->tag_index_;
|
||||
}
|
||||
else {
|
||||
vertex_id_ = vertex_id_null;
|
||||
tag_index_ = tag_index_null;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PathVertexPtr::init(const PathVertexPtr &path)
|
||||
{
|
||||
vertex_id_ = path.vertex_id_;
|
||||
tag_index_ = path.tag_index_;
|
||||
}
|
||||
|
||||
void
|
||||
PathVertexPtr::init(const PathVertex *path,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (path == nullptr || path->isNull())
|
||||
init();
|
||||
else {
|
||||
vertex_id_ = path->vertexId(sta);
|
||||
tag_index_ = path->tagIndex(sta);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
PathVertexPtr::name(const StaState *sta) const
|
||||
{
|
||||
const Network *network = sta->network();
|
||||
const Search *search = sta->search();
|
||||
Vertex *vertex = this->vertex(sta);
|
||||
if (vertex) {
|
||||
const char *vertex_name = vertex->name(network);
|
||||
const Tag *tag = this->tag(search);
|
||||
const RiseFall *rf = tag->transition();
|
||||
const char *rf_str = rf->asString();
|
||||
const PathAnalysisPt *path_ap = tag->pathAnalysisPt(sta);
|
||||
int ap_index = path_ap->index();
|
||||
const char *min_max = path_ap->pathMinMax()->asString();
|
||||
TagIndex tag_index = tag->index();
|
||||
return stringPrintTmp("%s %s %s/%d %d",
|
||||
vertex_name, rf_str, min_max,
|
||||
ap_index, tag_index);
|
||||
}
|
||||
else
|
||||
return "NULL";
|
||||
}
|
||||
|
||||
bool
|
||||
PathVertexPtr::isNull() const
|
||||
{
|
||||
return vertex_id_ == vertex_id_null;
|
||||
}
|
||||
|
||||
Vertex *
|
||||
PathVertexPtr::vertex(const StaState *sta) const
|
||||
{
|
||||
if (vertex_id_ == vertex_id_null)
|
||||
return nullptr;
|
||||
else {
|
||||
const Graph *graph = sta->graph();
|
||||
return graph->vertex(vertex_id_);
|
||||
}
|
||||
}
|
||||
|
||||
Tag *
|
||||
PathVertexPtr::tag(const StaState *sta) const
|
||||
{
|
||||
const Search *search = sta->search();
|
||||
return search->tag(tag_index_);
|
||||
}
|
||||
|
||||
Arrival
|
||||
PathVertexPtr::arrival(const StaState *sta) const
|
||||
{
|
||||
const Vertex *vertex = this->vertex(sta);
|
||||
Arrival *arrivals = sta->graph()->arrivals(vertex);
|
||||
if (arrivals) {
|
||||
const Search *search = sta->search();
|
||||
TagGroup *tag_group = search->tagGroup(vertex);
|
||||
Tag *tag = this->tag(sta);
|
||||
int arrival_index;
|
||||
bool arrival_exists;
|
||||
tag_group->arrivalIndex(tag, arrival_index, arrival_exists);
|
||||
if (arrival_exists)
|
||||
return arrivals[arrival_index];
|
||||
else {
|
||||
sta->report()->error(1403, "missing arrival.");
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
sta->report()->error(1404, "missing arrivals.");
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
bool
|
||||
PathVertexPtr::equal(const PathVertexPtr *path1,
|
||||
const PathVertexPtr *path2)
|
||||
{
|
||||
return path1->vertex_id_ == path2->vertex_id_
|
||||
&& path1->tag_index_ == path2->tag_index_;
|
||||
}
|
||||
|
||||
bool
|
||||
PathVertexPtr::equal(const PathVertexPtr &path1,
|
||||
const PathVertexPtr &path2)
|
||||
{
|
||||
return path1.vertex_id_ == path2.vertex_id_
|
||||
&& path1.tag_index_ == path2.tag_index_;
|
||||
}
|
||||
|
||||
int
|
||||
PathVertexPtr::cmp(const PathVertexPtr &path1,
|
||||
const PathVertexPtr &path2)
|
||||
{
|
||||
VertexId vertex_id1 = path1.vertex_id_;
|
||||
VertexId vertex_id2 = path2.vertex_id_;
|
||||
if (vertex_id1 == vertex_id2) {
|
||||
TagIndex tag_index1 = path1.tagIndex();
|
||||
TagIndex tag_index2 = path2.tagIndex();
|
||||
if (tag_index1 == tag_index2)
|
||||
return 0;
|
||||
else if (tag_index1 < tag_index2)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
else if (vertex_id1 < vertex_id2)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Loading…
Reference in New Issue