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