Merge remote-tracking branch 'parallax/master'
Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
This commit is contained in:
commit
9c1a6b8ffc
File diff suppressed because it is too large
Load Diff
BIN
doc/OpenSTA.odt
BIN
doc/OpenSTA.odt
Binary file not shown.
BIN
doc/OpenSTA.pdf
BIN
doc/OpenSTA.pdf
Binary file not shown.
|
|
@ -120,7 +120,6 @@ public:
|
|||
bool isEnum() const { return is_enum_; }
|
||||
void setIsEnum(bool is_enum);
|
||||
void checkPrevPath(const StaState *sta) const;
|
||||
void checkPrevPaths(const StaState *sta) const;
|
||||
|
||||
static Path *vertexPath(const Path *path,
|
||||
const StaState *sta);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public:
|
|||
PwrActivity(float density,
|
||||
float duty,
|
||||
PwrActivityOrigin origin);
|
||||
void init();
|
||||
float density() const { return density_; }
|
||||
void setDensity(float density);
|
||||
float duty() const { return duty_; }
|
||||
|
|
|
|||
|
|
@ -408,6 +408,8 @@ public:
|
|||
TagGroupIndex tagGroupIndex(const Vertex *vertex) const;
|
||||
void setTagGroupIndex(const Vertex *vertex,
|
||||
TagGroupIndex tag_index);
|
||||
void checkPrevPaths() const;
|
||||
void deletePaths(Vertex *vertex);
|
||||
|
||||
protected:
|
||||
void init(StaState *sta);
|
||||
|
|
@ -543,7 +545,6 @@ protected:
|
|||
bool is_clk,
|
||||
const PathAnalysisPt *path_ap);
|
||||
void deletePaths();
|
||||
void deletePaths(Vertex *vertex);
|
||||
// Delete with incremental tns/wns update.
|
||||
void deletePathsIncr(Vertex *vertex);
|
||||
TagGroup *findTagGroup(TagGroupBldr *group_bldr);
|
||||
|
|
|
|||
|
|
@ -563,6 +563,20 @@ net_load_pins(Net *net)
|
|||
return pins;
|
||||
}
|
||||
|
||||
PinSet
|
||||
net_pins(Net *net)
|
||||
{
|
||||
Network *network = Sta::sta()->ensureLinked();
|
||||
PinSet pins(network);
|
||||
NetConnectedPinIterator *pin_iter = network->connectedPinIterator(net);
|
||||
while (pin_iter->hasNext()) {
|
||||
const Pin *pin = pin_iter->next();
|
||||
pins.insert(pin);
|
||||
}
|
||||
delete pin_iter;
|
||||
return pins;
|
||||
}
|
||||
|
||||
const char *
|
||||
pin_location(const Pin *pin)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -112,6 +112,13 @@ Power::setGlobalActivity(float density,
|
|||
activities_valid_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
Power::unsetGlobalActivity()
|
||||
{
|
||||
global_activity_.init();
|
||||
activities_valid_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
Power::setInputActivity(float density,
|
||||
float duty)
|
||||
|
|
@ -120,6 +127,13 @@ Power::setInputActivity(float density,
|
|||
activities_valid_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
Power::unsetInputActivity()
|
||||
{
|
||||
input_activity_.init();
|
||||
activities_valid_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
Power::setInputPortActivity(const Port *input_port,
|
||||
float density,
|
||||
|
|
@ -133,6 +147,17 @@ Power::setInputPortActivity(const Port *input_port,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Power::unsetInputPortActivity(const Port *input_port)
|
||||
{
|
||||
Instance *top_inst = network_->topInstance();
|
||||
const Pin *pin = network_->findPin(top_inst, input_port);
|
||||
if (pin) {
|
||||
user_activity_map_.erase(pin);
|
||||
activities_valid_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Power::setUserActivity(const Pin *pin,
|
||||
float density,
|
||||
|
|
@ -143,6 +168,13 @@ Power::setUserActivity(const Pin *pin,
|
|||
activities_valid_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
Power::unsetUserActivity(const Pin *pin)
|
||||
{
|
||||
user_activity_map_.erase(pin);
|
||||
activities_valid_ = false;
|
||||
}
|
||||
|
||||
PwrActivity &
|
||||
Power::userActivity(const Pin *pin)
|
||||
{
|
||||
|
|
@ -664,7 +696,7 @@ Power::ensureActivities()
|
|||
|
||||
// Initialize default input activity (after sdc is defined)
|
||||
// unless it has been set by command.
|
||||
if (input_activity_.density() == 0.0) {
|
||||
if (input_activity_.origin() == PwrActivityOrigin::unknown) {
|
||||
float min_period = clockMinPeriod();
|
||||
float density = 0.1 / (min_period != 0.0
|
||||
? min_period
|
||||
|
|
@ -1535,6 +1567,7 @@ PwrActivity::PwrActivity(float density,
|
|||
duty_(duty),
|
||||
origin_(origin)
|
||||
{
|
||||
check();
|
||||
}
|
||||
|
||||
PwrActivity::PwrActivity() :
|
||||
|
|
@ -1542,7 +1575,6 @@ PwrActivity::PwrActivity() :
|
|||
duty_(0.0),
|
||||
origin_(PwrActivityOrigin::unknown)
|
||||
{
|
||||
check();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1563,6 +1595,14 @@ PwrActivity::setOrigin(PwrActivityOrigin origin)
|
|||
origin_ = origin;
|
||||
}
|
||||
|
||||
void
|
||||
PwrActivity::init()
|
||||
{
|
||||
density_ = 0.0;
|
||||
duty_ = 0.0;
|
||||
origin_ = PwrActivityOrigin::unknown;
|
||||
}
|
||||
|
||||
void
|
||||
PwrActivity::set(float density,
|
||||
float duty,
|
||||
|
|
|
|||
|
|
@ -87,16 +87,20 @@ public:
|
|||
const Corner *corner);
|
||||
void setGlobalActivity(float activity,
|
||||
float duty);
|
||||
void unsetGlobalActivity();
|
||||
void setInputActivity(float activity,
|
||||
float duty);
|
||||
void unsetInputActivity();
|
||||
void setInputPortActivity(const Port *input_port,
|
||||
float activity,
|
||||
float duty);
|
||||
void unsetInputPortActivity(const Port *input_port);
|
||||
PwrActivity pinActivity(const Pin *pin);
|
||||
void setUserActivity(const Pin *pin,
|
||||
float activity,
|
||||
float duty,
|
||||
PwrActivityOrigin origin);
|
||||
void unsetUserActivity(const Pin *pin);
|
||||
void reportActivityAnnotation(bool report_unannotated,
|
||||
bool report_annotated);
|
||||
float clockMinPeriod();
|
||||
|
|
|
|||
|
|
@ -84,6 +84,13 @@ set_power_global_activity(float activity,
|
|||
power->setGlobalActivity(activity, duty);
|
||||
}
|
||||
|
||||
void
|
||||
unset_power_global_activity()
|
||||
{
|
||||
Power *power = Sta::sta()->power();
|
||||
power->unsetGlobalActivity();
|
||||
}
|
||||
|
||||
void
|
||||
set_power_input_activity(float activity,
|
||||
float duty)
|
||||
|
|
@ -92,6 +99,13 @@ set_power_input_activity(float activity,
|
|||
return power->setInputActivity(activity, duty);
|
||||
}
|
||||
|
||||
void
|
||||
unset_power_input_activity()
|
||||
{
|
||||
Power *power = Sta::sta()->power();
|
||||
return power->unsetInputActivity();
|
||||
}
|
||||
|
||||
void
|
||||
set_power_input_port_activity(const Port *input_port,
|
||||
float activity,
|
||||
|
|
@ -101,6 +115,13 @@ set_power_input_port_activity(const Port *input_port,
|
|||
return power->setInputPortActivity(input_port, activity, duty);
|
||||
}
|
||||
|
||||
void
|
||||
unset_power_input_port_activity(const Port *input_port)
|
||||
{
|
||||
Power *power = Sta::sta()->power();
|
||||
return power->unsetInputPortActivity(input_port);
|
||||
}
|
||||
|
||||
void
|
||||
set_power_pin_activity(const Pin *pin,
|
||||
float activity,
|
||||
|
|
@ -110,6 +131,13 @@ set_power_pin_activity(const Pin *pin,
|
|||
return power->setUserActivity(pin, activity, duty, PwrActivityOrigin::user);
|
||||
}
|
||||
|
||||
void
|
||||
unset_power_pin_activity(const Pin *pin)
|
||||
{
|
||||
Power *power = Sta::sta()->power();
|
||||
return power->unsetUserActivity(pin);
|
||||
}
|
||||
|
||||
float
|
||||
clock_min_period()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ proc set_power_activity { args } {
|
|||
foreach port $ports {
|
||||
if { [get_property $port "direction"] == "input" } {
|
||||
if { [is_clock_src [sta::get_port_pin $port]] } {
|
||||
sta_warn 303 "activity cannot be set on clock ports."
|
||||
sta_warn 310 "activity cannot be set on clock ports."
|
||||
} else {
|
||||
set_power_input_port_activity $port $density $duty
|
||||
}
|
||||
|
|
@ -306,6 +306,47 @@ proc set_power_activity { args } {
|
|||
|
||||
################################################################
|
||||
|
||||
define_cmd_args "unset_power_activity" { [-global]\
|
||||
[-input]\
|
||||
[-input_ports ports]\
|
||||
[-pins pins]\
|
||||
[-clock clock]}
|
||||
|
||||
proc unset_power_activity { args } {
|
||||
parse_key_args "unset_power_activity" args \
|
||||
keys {-input_ports -pins -clock} \
|
||||
flags {-global -input}
|
||||
|
||||
check_argc_eq0 "unset_power_activity" $args
|
||||
|
||||
if { [info exists flags(-global)] } {
|
||||
unset_power_global_activity
|
||||
}
|
||||
if { [info exists flags(-input)] } {
|
||||
unset_power_input_activity
|
||||
}
|
||||
if { [info exists keys(-input_ports)] } {
|
||||
set ports [get_ports_error "input_ports" $keys(-input_ports)]
|
||||
foreach port $ports {
|
||||
if { [get_property $port "direction"] == "input" } {
|
||||
if { [is_clock_src [sta::get_port_pin $port]] } {
|
||||
sta_warn 303 "activity cannot be set on clock ports."
|
||||
} else {
|
||||
unset_power_input_port_activity $port
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if { [info exists keys(-pins)] } {
|
||||
set pins [get_pins $keys(-pins)]
|
||||
foreach pin $pins {
|
||||
unset_power_pin_activity $pin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
# Deprecated 9/2024
|
||||
define_cmd_args "read_power_activities" { [-scope scope] -vcd filename }
|
||||
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ CheckCrpr::genClkSrcPaths(const Path *path)
|
|||
gclk_paths.push_back(path);
|
||||
Genclks *genclks = search_->genclks();
|
||||
while (clk_edge->clock()->isGenerated()) {
|
||||
Path *genclk_path = genclks->srcPath(clk_edge, clk_src, path_ap);
|
||||
const Path *genclk_path = genclks->srcPath(clk_edge, clk_src, path_ap);
|
||||
if (genclk_path == nullptr)
|
||||
break;
|
||||
clk_info = genclk_path->clkInfo(this);
|
||||
|
|
|
|||
|
|
@ -685,10 +685,10 @@ Genclks::seedSrcPins(Clock *gclk,
|
|||
const MinMax *min_max = path_ap->pathMinMax();
|
||||
const EarlyLate *early_late = min_max;
|
||||
for (const RiseFall *rf : RiseFall::range()) {
|
||||
Tag *tag = makeTag(gclk, master_clk, master_pin, rf,
|
||||
src_filter, path_ap);
|
||||
Arrival insert = search_->clockInsertion(master_clk, master_pin, rf,
|
||||
min_max, early_late, path_ap);
|
||||
Tag *tag = makeTag(gclk, master_clk, master_pin, rf,
|
||||
src_filter, insert, path_ap);
|
||||
tag_bldr.setArrival(tag, insert);
|
||||
}
|
||||
}
|
||||
|
|
@ -704,6 +704,7 @@ Genclks::makeTag(const Clock *gclk,
|
|||
const Pin *master_pin,
|
||||
const RiseFall *master_rf,
|
||||
FilterPath *src_filter,
|
||||
Arrival insert,
|
||||
const PathAnalysisPt *path_ap)
|
||||
{
|
||||
ExceptionState *state = src_filter->firstState();
|
||||
|
|
@ -715,7 +716,7 @@ Genclks::makeTag(const Clock *gclk,
|
|||
states->insert(state);
|
||||
ClkInfo *clk_info = search_->findClkInfo(master_clk->edge(master_rf),
|
||||
master_pin, true, nullptr, true,
|
||||
nullptr, 0.0, 0.0, nullptr,
|
||||
nullptr, insert, 0.0, nullptr,
|
||||
path_ap, nullptr);
|
||||
return search_->findTag(master_rf, path_ap, clk_info, false, nullptr, false,
|
||||
states, true);
|
||||
|
|
@ -855,11 +856,11 @@ Genclks::copyGenClkSrcPaths(Vertex *vertex,
|
|||
{
|
||||
auto itr = vertex_src_paths_map_.find(vertex);
|
||||
if (itr != vertex_src_paths_map_.end()) {
|
||||
std::vector<const Path*> &src_paths = itr->second;
|
||||
const std::vector<const Path*> &src_paths = itr->second;
|
||||
for (const Path *path : src_paths) {
|
||||
Path src_path = *path;
|
||||
Path *prev_path = src_path.prevPath();
|
||||
if (prev_path) {
|
||||
if (prev_path && !prev_path->isNull()) {
|
||||
Path *prev_vpath = Path::vertexPath(prev_path, this);
|
||||
src_path.setPrevPath(prev_vpath);
|
||||
}
|
||||
|
|
@ -921,7 +922,7 @@ Genclks::recordSrcPaths(Clock *gclk)
|
|||
size_t path_index = srcPathIndex(rf, path_ap);
|
||||
Path &src_path = src_paths[path_index];
|
||||
if ((!divide_by_1
|
||||
|| (inverting_path == invert))
|
||||
|| (inverting_path == invert))
|
||||
&& (!has_edges
|
||||
|| src_clk_rf == gclk->masterClkEdgeTr(rf))
|
||||
&& (src_path.isNull()
|
||||
|
|
@ -934,6 +935,7 @@ Genclks::recordSrcPaths(Clock *gclk)
|
|||
early_late->to_string().c_str(),
|
||||
rf->to_string().c_str(),
|
||||
delayAsString(path->arrival(), this));
|
||||
// If this path is replacing another one delete the previous one.
|
||||
delete src_path.prevPath();
|
||||
src_path = *path;
|
||||
Path *prev_copy = &src_path;
|
||||
|
|
@ -950,11 +952,13 @@ Genclks::recordSrcPaths(Clock *gclk)
|
|||
}
|
||||
}
|
||||
if (found_src_paths) {
|
||||
// Record vertex->genclk src paths.
|
||||
for (const Path &path : src_paths) {
|
||||
if (!path.isNull()) {
|
||||
const Path *p = &path;
|
||||
while (p) {
|
||||
vertex_src_paths_map_[p->vertex(this)].push_back(p);
|
||||
while (p && !p->isNull()) {
|
||||
Vertex *vertex = p->vertex(this);
|
||||
vertex_src_paths_map_[vertex].push_back(p);
|
||||
p = p->prevPath();
|
||||
}
|
||||
}
|
||||
|
|
@ -968,6 +972,12 @@ Genclks::recordSrcPaths(Clock *gclk)
|
|||
network_->pathName(gclk_pin),
|
||||
gclk->masterClk()->name());
|
||||
}
|
||||
// This can be narrowed to visited vertices.
|
||||
VertexIterator vertex_iter(graph_);
|
||||
while (vertex_iter.hasNext()) {
|
||||
Vertex *vertex = vertex_iter.next();
|
||||
search_->deletePaths(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -992,7 +1002,7 @@ Genclks::matchesSrcFilter(Path *path,
|
|||
return false;
|
||||
}
|
||||
|
||||
Path *
|
||||
const Path *
|
||||
Genclks::srcPath(const Path *clk_path) const
|
||||
{
|
||||
const Pin *src_pin = clk_path->pin(this);
|
||||
|
|
@ -1004,7 +1014,7 @@ Genclks::srcPath(const Path *clk_path) const
|
|||
insert_ap);
|
||||
}
|
||||
|
||||
Path *
|
||||
const Path *
|
||||
Genclks::srcPath(const ClockEdge *clk_edge,
|
||||
const Pin *src_pin,
|
||||
const PathAnalysisPt *path_ap) const
|
||||
|
|
@ -1012,7 +1022,7 @@ Genclks::srcPath(const ClockEdge *clk_edge,
|
|||
return srcPath(clk_edge->clock(), src_pin, clk_edge->transition(), path_ap);
|
||||
}
|
||||
|
||||
Path *
|
||||
const Path *
|
||||
Genclks::srcPath(const Clock *gclk,
|
||||
const Pin *src_pin,
|
||||
const RiseFall *rf,
|
||||
|
|
@ -1020,14 +1030,12 @@ Genclks::srcPath(const Clock *gclk,
|
|||
{
|
||||
auto itr = genclk_src_paths_.find(ClockPinPair(gclk, src_pin));
|
||||
if (itr != genclk_src_paths_.end()) {
|
||||
std::vector<Path> src_paths = itr->second;
|
||||
const std::vector<Path> &src_paths = itr->second;
|
||||
if (!src_paths.empty()) {
|
||||
size_t path_index = srcPathIndex(rf, path_ap);
|
||||
Path &src_path = src_paths[path_index];
|
||||
if (!src_path.isNull()) {
|
||||
Path *src_vpath = Path::vertexPath(src_path, this);
|
||||
return src_vpath;
|
||||
}
|
||||
const Path *src_path = &src_paths[path_index];
|
||||
if (!src_path->isNull())
|
||||
return src_path;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
|
@ -1042,12 +1050,14 @@ Genclks::updateSrcPathPrevs()
|
|||
const Path *p = &src_path;
|
||||
while (p) {
|
||||
Path *src_vpath = Path::vertexPath(p, this);
|
||||
Path *prev_path = p->prevPath();
|
||||
if (prev_path) {
|
||||
Path *prev_vpath = Path::vertexPath(prev_path, this);
|
||||
src_vpath->setPrevPath(prev_vpath);
|
||||
src_vpath->setPrevEdgeArc(p->prevEdge(this),
|
||||
p->prevArc(this), this);
|
||||
if (src_vpath) {
|
||||
Path *prev_path = p->prevPath();
|
||||
if (prev_path) {
|
||||
Path *prev_vpath = Path::vertexPath(prev_path, this);
|
||||
src_vpath->setPrevPath(prev_vpath);
|
||||
src_vpath->setPrevEdgeArc(p->prevEdge(this),
|
||||
p->prevArc(this), this);
|
||||
}
|
||||
}
|
||||
p = p->prevPath();
|
||||
}
|
||||
|
|
@ -1066,7 +1076,7 @@ Genclks::insertionDelay(const Clock *clk,
|
|||
const PathAnalysisPt *path_ap) const
|
||||
{
|
||||
PathAnalysisPt *insert_ap = path_ap->insertionAnalysisPt(early_late);
|
||||
Path *src_path = srcPath(clk, pin, rf, insert_ap);
|
||||
const Path *src_path = srcPath(clk, pin, rf, insert_ap);
|
||||
if (src_path)
|
||||
return src_path->arrival();
|
||||
else
|
||||
|
|
|
|||
|
|
@ -72,15 +72,15 @@ public:
|
|||
const EarlyLate *early_late,
|
||||
const PathAnalysisPt *path_ap) const;
|
||||
// Generated clock source path for a clock path root.
|
||||
Path *srcPath(const Path *clk_path) const;
|
||||
const Path *srcPath(const Path *clk_path) const;
|
||||
// Generated clock source path.
|
||||
Path *srcPath(const ClockEdge *clk_edge,
|
||||
const Pin *src_pin,
|
||||
const PathAnalysisPt *path_ap) const;
|
||||
Path *srcPath(const Clock *clk,
|
||||
const Pin *src_pin,
|
||||
const RiseFall *rf,
|
||||
const PathAnalysisPt *path_ap) const;
|
||||
const Path *srcPath(const ClockEdge *clk_edge,
|
||||
const Pin *src_pin,
|
||||
const PathAnalysisPt *path_ap) const;
|
||||
const Path *srcPath(const Clock *clk,
|
||||
const Pin *src_pin,
|
||||
const RiseFall *rf,
|
||||
const PathAnalysisPt *path_ap) const;
|
||||
Vertex *srcPath(const Pin *pin) const;
|
||||
Level clkPinMaxLevel(const Clock *clk) const;
|
||||
void copyGenClkSrcPaths(Vertex *vertex,
|
||||
|
|
@ -113,6 +113,7 @@ private:
|
|||
const Pin *master_pin,
|
||||
const RiseFall *rf,
|
||||
FilterPath *src_filter,
|
||||
Arrival insert,
|
||||
const PathAnalysisPt *path_ap);
|
||||
void seedSrcPins(Clock *clk,
|
||||
BfsBkwdIterator &iter);
|
||||
|
|
|
|||
|
|
@ -203,13 +203,17 @@ Path::init(Vertex *vertex,
|
|||
std::string
|
||||
Path::to_string(const StaState *sta) const
|
||||
{
|
||||
const PathAnalysisPt *path_ap = pathAnalysisPt(sta);
|
||||
return stringPrintTmp("%s %s %s/%d %d",
|
||||
vertex(sta)->to_string(sta).c_str(),
|
||||
transition(sta)->to_string().c_str(),
|
||||
path_ap->pathMinMax()->to_string().c_str(),
|
||||
path_ap->index(),
|
||||
tagIndex(sta));
|
||||
if (isNull())
|
||||
return "null path";
|
||||
else {
|
||||
const PathAnalysisPt *path_ap = pathAnalysisPt(sta);
|
||||
return stringPrintTmp("%s %s %s/%d %d",
|
||||
vertex(sta)->to_string(sta).c_str(),
|
||||
transition(sta)->to_string().c_str(),
|
||||
path_ap->pathMinMax()->to_string().c_str(),
|
||||
path_ap->index(),
|
||||
tagIndex(sta));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -366,10 +370,7 @@ Path::slack(const StaState *sta) const
|
|||
Path *
|
||||
Path::prevPath() const
|
||||
{
|
||||
if (prev_path_ && prev_path_->isNull())
|
||||
return nullptr;
|
||||
else
|
||||
return prev_path_;
|
||||
return prev_path_;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -440,19 +441,12 @@ Path::setPrevEdgeArc(Edge *prev_edge,
|
|||
prev_arc_idx_ = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Path::checkPrevPaths(const StaState *sta) const
|
||||
{
|
||||
const Path *path = this;
|
||||
while (path) {
|
||||
path->checkPrevPath(sta);
|
||||
path = path->prevPath();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Path::checkPrevPath(const StaState *sta) const
|
||||
{
|
||||
if (prev_path_ && prev_path_->isNull())
|
||||
sta->report()->reportLine("path %s prev path is null.",
|
||||
to_string(sta).c_str());
|
||||
if (prev_path_ && !prev_path_->isNull()) {
|
||||
Graph *graph = sta->graph();
|
||||
Edge *edge = prevEdge(sta);
|
||||
|
|
|
|||
|
|
@ -68,10 +68,9 @@ PathExpanded::expand(const Path *path,
|
|||
bool found_start = false;
|
||||
while (p) {
|
||||
const Path *prev_path = p->prevPath();
|
||||
const TimingArc *prev_arc = p->prevArc(sta_);
|
||||
|
||||
if (!found_start) {
|
||||
if (prev_arc) {
|
||||
if (prev_path) {
|
||||
const TimingArc *prev_arc = p->prevArc(sta_);
|
||||
const TimingRole *prev_role = prev_arc->role();
|
||||
if (prev_role == TimingRole::regClkToQ()
|
||||
|| prev_role == TimingRole::latchEnToQ()) {
|
||||
|
|
|
|||
|
|
@ -2391,8 +2391,8 @@ ReportPath::reportGenClkSrcPath1(const Clock *clk,
|
|||
{
|
||||
PathAnalysisPt *insert_ap = path_ap->insertionAnalysisPt(early_late);
|
||||
const MinMax *min_max = path_ap->pathMinMax();
|
||||
Path *src_path = search_->genclks()->srcPath(clk, clk_pin,
|
||||
clk_rf, insert_ap);
|
||||
const Path *src_path = search_->genclks()->srcPath(clk, clk_pin,
|
||||
clk_rf, insert_ap);
|
||||
if (src_path) {
|
||||
ClkInfo *src_clk_info = src_path->clkInfo(this);
|
||||
const ClockEdge *src_clk_edge = src_clk_info->clkEdge();
|
||||
|
|
|
|||
|
|
@ -1276,8 +1276,9 @@ Search::arrivalsChanged(Vertex *vertex,
|
|||
|| path1->tag(this) != path2->tag(this)
|
||||
|| !delayEqual(path1->arrival(), path2->arrival())
|
||||
|| path1->prevEdge(this) != path2->prevEdge(this)
|
||||
|| path1->prevArc(this) != path2->prevArc(this))
|
||||
return true;
|
||||
|| path1->prevArc(this) != path2->prevArc(this)
|
||||
|| path1->prevPath() != path2->prevPath())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2498,7 +2499,6 @@ Search::thruClkInfo(Path *from_path,
|
|||
const MinMax *min_max,
|
||||
const PathAnalysisPt *path_ap)
|
||||
{
|
||||
ClkInfo *to_clk_info = from_clk_info;
|
||||
bool changed = false;
|
||||
const ClockEdge *from_clk_edge = from_clk_info->clkEdge();
|
||||
const RiseFall *clk_rf = from_clk_edge->transition();
|
||||
|
|
@ -2585,13 +2585,15 @@ Search::thruClkInfo(Path *from_path,
|
|||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
to_clk_info = findClkInfo(from_clk_edge, from_clk_info->clkSrc(),
|
||||
to_clk_prop, gen_clk_src,
|
||||
from_clk_info->isGenClkSrcPath(),
|
||||
to_pulse_sense, to_insertion, to_latency,
|
||||
to_uncertainties, path_ap, to_crpr_clk_path);
|
||||
return to_clk_info;
|
||||
if (changed) {
|
||||
ClkInfo *to_clk_info = findClkInfo(from_clk_edge, from_clk_info->clkSrc(),
|
||||
to_clk_prop, gen_clk_src,
|
||||
from_clk_info->isGenClkSrcPath(),
|
||||
to_pulse_sense, to_insertion, to_latency,
|
||||
to_uncertainties, path_ap, to_crpr_clk_path);
|
||||
return to_clk_info;
|
||||
}
|
||||
return from_clk_info;
|
||||
}
|
||||
|
||||
// Find the tag for a path going from from_tag thru edge to to_pin.
|
||||
|
|
@ -2785,6 +2787,20 @@ Search::setVertexArrivals(Vertex *vertex,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Search::checkPrevPaths() const
|
||||
{
|
||||
VertexIterator vertex_iter(graph_);
|
||||
while (vertex_iter.hasNext()) {
|
||||
Vertex *vertex = vertex_iter.next();
|
||||
VertexPathIterator path_iter(vertex, graph_);
|
||||
while (path_iter.hasNext()) {
|
||||
Path *path = path_iter.next();
|
||||
path->checkPrevPath(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ReportPathLess
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -4960,9 +4960,7 @@ Sta::findFaninPins(PinSeq *to,
|
|||
ensureLevelized();
|
||||
PinSet fanin(network_);
|
||||
FaninSrchPred pred(thru_disabled, thru_constants, this);
|
||||
PinSeq::Iterator to_iter(to);
|
||||
while (to_iter.hasNext()) {
|
||||
const Pin *pin = to_iter.next();
|
||||
for (const Pin *pin : *to) {
|
||||
if (network_->isHierarchical(pin)) {
|
||||
EdgesThruHierPinIterator edge_iter(pin, network_, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,12 @@ proc get_fanin { args } {
|
|||
}
|
||||
parse_port_pin_net_arg $keys(-to) pins nets
|
||||
foreach net $nets {
|
||||
lappend pins [net_driver_pins $net]
|
||||
set net_pins [net_pins $net]
|
||||
if { $net_pins != {} } {
|
||||
lappend pins $net_pins
|
||||
} else {
|
||||
sta_warn 541 "No load pins connected to net [get_full_name $net]."
|
||||
}
|
||||
}
|
||||
set flat [info exists flags(-flat)]
|
||||
set only_insts [info exists flags(-only_cells)]
|
||||
|
|
|
|||
Loading…
Reference in New Issue