Merge remote-tracking branch 'parallax/master'
This commit is contained in:
commit
2debe54ede
|
|
@ -1322,7 +1322,7 @@ Edge::arcDelayAnnotated(const TimingArc *arc,
|
|||
{
|
||||
size_t index = arc->index() * ap_count + ap_index;
|
||||
if (arc_delay_annotated_is_bits_)
|
||||
return arc_delay_annotated_.bits_ & (1 << index);
|
||||
return arc_delay_annotated_.bits_ & arcDelayAnnotateBit(index);
|
||||
else
|
||||
return (*arc_delay_annotated_.seq_)[index];
|
||||
}
|
||||
|
|
@ -1334,7 +1334,7 @@ Edge::setArcDelayAnnotated(const TimingArc *arc,
|
|||
bool annotated)
|
||||
{
|
||||
size_t index = arc->index() * ap_count + ap_index;
|
||||
if (index > sizeof(intptr_t) * 8
|
||||
if (index > sizeof(uintptr_t) * 8
|
||||
&& arc_delay_annotated_is_bits_) {
|
||||
arc_delay_annotated_is_bits_ = false;
|
||||
size_t bit_count = ap_count * RiseFall::index_count * 2;
|
||||
|
|
@ -1342,9 +1342,9 @@ Edge::setArcDelayAnnotated(const TimingArc *arc,
|
|||
}
|
||||
if (arc_delay_annotated_is_bits_) {
|
||||
if (annotated)
|
||||
arc_delay_annotated_.bits_ |= (1 << index);
|
||||
arc_delay_annotated_.bits_ |= arcDelayAnnotateBit(index);
|
||||
else
|
||||
arc_delay_annotated_.bits_ &= ~(1 << index);
|
||||
arc_delay_annotated_.bits_ &= ~arcDelayAnnotateBit(index);
|
||||
}
|
||||
else
|
||||
(*arc_delay_annotated_.seq_)[index] = annotated;
|
||||
|
|
@ -1368,6 +1368,12 @@ Edge::setDelayAnnotationIsIncremental(bool is_incr)
|
|||
delay_annotation_is_incremental_ = is_incr;
|
||||
}
|
||||
|
||||
uintptr_t
|
||||
Edge::arcDelayAnnotateBit(size_t index)
|
||||
{
|
||||
return static_cast<uintptr_t>(1) << index;
|
||||
}
|
||||
|
||||
const TimingRole *
|
||||
Edge::role() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -667,6 +667,10 @@ private:
|
|||
int index_;
|
||||
};
|
||||
|
||||
bool
|
||||
exceptionStateLess(const ExceptionState *state1,
|
||||
const ExceptionState *state2);
|
||||
|
||||
// Exception thrown by check.
|
||||
class EmptyExpceptionPt : public Exception
|
||||
{
|
||||
|
|
|
|||
|
|
@ -421,6 +421,7 @@ protected:
|
|||
DcalcAPIndex ap_index,
|
||||
DcalcAPIndex ap_count,
|
||||
bool annotated);
|
||||
static uintptr_t arcDelayAnnotateBit(size_t index);
|
||||
|
||||
TimingArcSet *arc_set_;
|
||||
VertexId from_;
|
||||
|
|
|
|||
|
|
@ -149,8 +149,8 @@ public:
|
|||
exists_[mm_index] = false;
|
||||
}
|
||||
|
||||
static bool equal(MinMaxValues *values1,
|
||||
MinMaxValues *values2)
|
||||
static bool equal(const MinMaxValues *values1,
|
||||
const MinMaxValues *values2)
|
||||
{
|
||||
return ((!values1->exists_[MinMax::minIndex()]
|
||||
&& !values2->exists_[MinMax::minIndex()])
|
||||
|
|
@ -166,6 +166,32 @@ public:
|
|||
== values2->values_[MinMax::maxIndex()]));
|
||||
}
|
||||
|
||||
static int cmp(const MinMaxValues *values1,
|
||||
const MinMaxValues *values2)
|
||||
{
|
||||
if (!values1->exists_[MinMax::minIndex()]
|
||||
&& values2->exists_[MinMax::minIndex()])
|
||||
return -1;
|
||||
if (values1->exists_[MinMax::minIndex()]
|
||||
&& !values2->exists_[MinMax::minIndex()])
|
||||
return 1;
|
||||
if (!values1->exists_[MinMax::maxIndex()]
|
||||
&& values2->exists_[MinMax::maxIndex()])
|
||||
return -1;
|
||||
if (values1->exists_[MinMax::maxIndex()]
|
||||
&& !values2->exists_[MinMax::maxIndex()])
|
||||
return 1;
|
||||
if (values1->values_[MinMax::minIndex()] < values2->values_[MinMax::minIndex()])
|
||||
return -1;
|
||||
if (values1->values_[MinMax::minIndex()] > values2->values_[MinMax::minIndex()])
|
||||
return 1;
|
||||
if (values1->values_[MinMax::maxIndex()] < values2->values_[MinMax::maxIndex()])
|
||||
return -1;
|
||||
if (values1->values_[MinMax::maxIndex()] > values2->values_[MinMax::maxIndex()])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
TYPE values_[MinMax::index_count];
|
||||
bool exists_[MinMax::index_count];
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class Path
|
|||
{
|
||||
public:
|
||||
Path();
|
||||
Path(Path *path);
|
||||
Path(const Path *path);
|
||||
Path(Vertex *vertex,
|
||||
Tag *tag,
|
||||
const StaState *sta);
|
||||
|
|
@ -89,7 +89,7 @@ public:
|
|||
TagIndex tagIndex(const StaState *sta) const;
|
||||
void setTag(Tag *tag);
|
||||
size_t pathIndex(const StaState *sta) const;
|
||||
ClkInfo *clkInfo(const StaState *sta) const;
|
||||
const ClkInfo *clkInfo(const StaState *sta) const;
|
||||
const ClockEdge *clkEdge(const StaState *sta) const;
|
||||
const Clock *clock(const StaState *sta) const;
|
||||
bool isClock(const StaState *sta) const;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public:
|
|||
const std::string property);
|
||||
|
||||
// Define handler for external property.
|
||||
// proerties->defineProperty("foo",
|
||||
// properties->defineProperty("foo",
|
||||
// [] (const Instance *, Sta *) -> PropertyValue {
|
||||
// return PropertyValue("bar");
|
||||
// });
|
||||
|
|
@ -116,6 +116,8 @@ public:
|
|||
PropertyRegistry<const Pin *>::PropertyHandler handler);
|
||||
void defineProperty(std::string &property,
|
||||
PropertyRegistry<const Net *>::PropertyHandler handler);
|
||||
void defineProperty(std::string &property,
|
||||
PropertyRegistry<const Clock *>::PropertyHandler handler);
|
||||
|
||||
protected:
|
||||
PropertyValue portSlew(const Port *port,
|
||||
|
|
@ -159,6 +161,7 @@ protected:
|
|||
PropertyRegistry<const Instance*> registry_instance_;
|
||||
PropertyRegistry<const Pin*> registry_pin_;
|
||||
PropertyRegistry<const Net*> registry_net_;
|
||||
PropertyRegistry<const Clock*> registry_clock_;
|
||||
|
||||
Sta *sta_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class CheckCrpr;
|
|||
class Genclks;
|
||||
class Corner;
|
||||
|
||||
typedef Set<ClkInfo*, ClkInfoLess> ClkInfoSet;
|
||||
typedef Set<const ClkInfo*, ClkInfoLess> ClkInfoSet;
|
||||
typedef UnorderedSet<Tag*, TagHash, TagEqual> TagSet;
|
||||
typedef UnorderedSet<TagGroup*, TagGroupHash, TagGroupEqual> TagGroupSet;
|
||||
typedef Map<Vertex*, Slack> VertexSlackMap;
|
||||
|
|
@ -158,7 +158,7 @@ public:
|
|||
// Clock arrival respecting ideal clock insertion delay and latency.
|
||||
Arrival clkPathArrival(const Path *clk_path) const;
|
||||
Arrival clkPathArrival(const Path *clk_path,
|
||||
ClkInfo *clk_info,
|
||||
const ClkInfo *clk_info,
|
||||
const ClockEdge *clk_edge,
|
||||
const MinMax *min_max,
|
||||
const PathAnalysisPt *path_ap) const;
|
||||
|
|
@ -244,7 +244,7 @@ public:
|
|||
const RiseFall *from_rf,
|
||||
const Clock *clk,
|
||||
const RiseFall *clk_rf,
|
||||
ClkInfo *clk_info,
|
||||
const ClkInfo *clk_info,
|
||||
const Pin *to_pin,
|
||||
const RiseFall *to_rf,
|
||||
const MinMax *min_max,
|
||||
|
|
@ -263,9 +263,9 @@ public:
|
|||
bool arc_delay_min_max_eq,
|
||||
const MinMax *min_max,
|
||||
const PathAnalysisPt *path_ap);
|
||||
ClkInfo *thruClkInfo(Path *from_path,
|
||||
const ClkInfo *thruClkInfo(Path *from_path,
|
||||
Vertex *from_vertex,
|
||||
ClkInfo *from_clk_info,
|
||||
const ClkInfo *from_clk_info,
|
||||
bool from_is_clk,
|
||||
Edge *edge,
|
||||
Vertex *to_vertex,
|
||||
|
|
@ -274,7 +274,7 @@ public:
|
|||
bool arc_delay_min_max_eq,
|
||||
const MinMax *min_max,
|
||||
const PathAnalysisPt *path_ap);
|
||||
ClkInfo *clkInfoWithCrprClkPath(ClkInfo *from_clk_info,
|
||||
const ClkInfo *clkInfoWithCrprClkPath(const ClkInfo *from_clk_info,
|
||||
Path *from_path,
|
||||
const PathAnalysisPt *path_ap);
|
||||
void seedClkArrivals(const Pin *pin,
|
||||
|
|
@ -323,7 +323,7 @@ public:
|
|||
|
||||
Tag *findTag(const RiseFall *rf,
|
||||
const PathAnalysisPt *path_ap,
|
||||
ClkInfo *tag_clk,
|
||||
const ClkInfo *tag_clk,
|
||||
bool is_clk,
|
||||
InputDelay *input_delay,
|
||||
bool is_segment_start,
|
||||
|
|
@ -331,7 +331,7 @@ public:
|
|||
bool own_states);
|
||||
void reportTags() const;
|
||||
void reportClkInfos() const;
|
||||
virtual ClkInfo *findClkInfo(const ClockEdge *clk_edge,
|
||||
const ClkInfo *findClkInfo(const ClockEdge *clk_edge,
|
||||
const Pin *clk_src,
|
||||
bool is_propagated,
|
||||
const Pin *gen_clk_src,
|
||||
|
|
@ -342,7 +342,7 @@ public:
|
|||
ClockUncertainties *uncertainties,
|
||||
const PathAnalysisPt *path_ap,
|
||||
Path *crpr_clk_path);
|
||||
ClkInfo *findClkInfo(const ClockEdge *clk_edge,
|
||||
const ClkInfo *findClkInfo(const ClockEdge *clk_edge,
|
||||
const Pin *clk_src,
|
||||
bool is_propagated,
|
||||
Arrival insertion,
|
||||
|
|
@ -515,13 +515,13 @@ protected:
|
|||
const Pin *from_pin,
|
||||
const RiseFall *from_rf,
|
||||
bool from_is_clk,
|
||||
ClkInfo *from_clk_info,
|
||||
const ClkInfo *from_clk_info,
|
||||
const Pin *to_pin,
|
||||
const RiseFall *to_rf,
|
||||
bool to_is_clk,
|
||||
bool to_is_reg_clk,
|
||||
bool to_is_segment_start,
|
||||
ClkInfo *to_clk_info,
|
||||
const ClkInfo *to_clk_info,
|
||||
InputDelay *to_input_delay,
|
||||
const MinMax *min_max,
|
||||
const PathAnalysisPt *path_ap);
|
||||
|
|
|
|||
|
|
@ -490,6 +490,9 @@ PropActivityVisitor::visit(Vertex *vertex)
|
|||
}
|
||||
if (network_->isDriver(pin)) {
|
||||
LibertyPort *port = network_->libertyPort(pin);
|
||||
LibertyCell *test_cell = port->libertyCell()->testCell();
|
||||
if (test_cell)
|
||||
port = test_cell->findLibertyPort(port->name());
|
||||
if (port) {
|
||||
FuncExpr *func = port->function();
|
||||
if (func) {
|
||||
|
|
@ -519,8 +522,12 @@ PropActivityVisitor::visit(Vertex *vertex)
|
|||
}
|
||||
if (changed) {
|
||||
LibertyCell *cell = network_->libertyCell(inst);
|
||||
if (network_->isLoad(pin) && cell) {
|
||||
if (cell->hasSequentials()) {
|
||||
if (cell) {
|
||||
LibertyCell *test_cell = cell->libertyCell()->testCell();
|
||||
if (network_->isLoad(pin)) {
|
||||
if (cell->hasSequentials()
|
||||
|| (test_cell
|
||||
&& test_cell->hasSequentials())) {
|
||||
debugPrint(debug_, "power_activity", 3, "pending seq %s",
|
||||
network_->pathName(inst));
|
||||
visited_regs_.insert(inst);
|
||||
|
|
@ -537,6 +544,7 @@ PropActivityVisitor::visit(Vertex *vertex)
|
|||
}
|
||||
bfs_->enqueueAdjacentVertices(vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if the activity changed.
|
||||
|
|
@ -725,12 +733,9 @@ Power::ensureActivities()
|
|||
int pass = 1;
|
||||
while (!regs.empty() && pass < max_activity_passes_) {
|
||||
visitor.init();
|
||||
InstanceSet::Iterator reg_iter(regs);
|
||||
while (reg_iter.hasNext()) {
|
||||
const Instance *reg = reg_iter.next();
|
||||
for (const Instance *reg : regs)
|
||||
// Propagate activiities across register D->Q.
|
||||
seedRegOutputActivities(reg, bfs);
|
||||
}
|
||||
// Propagate register output activities through
|
||||
// combinational logic.
|
||||
bfs.visit(levelize_->maxLevel(), &visitor);
|
||||
|
|
@ -771,7 +776,11 @@ Power::seedRegOutputActivities(const Instance *inst,
|
|||
BfsFwdIterator &bfs)
|
||||
{
|
||||
LibertyCell *cell = network_->libertyCell(inst);
|
||||
for (Sequential *seq : cell->sequentials()) {
|
||||
LibertyCell *test_cell = cell->testCell();
|
||||
const SequentialSeq &seqs = test_cell
|
||||
? test_cell->sequentials()
|
||||
: cell->sequentials();
|
||||
for (Sequential *seq : seqs) {
|
||||
seedRegOutputActivities(inst, seq, seq->output(), false);
|
||||
seedRegOutputActivities(inst, seq, seq->outputInv(), true);
|
||||
// Enqueue register output pins with functions that reference
|
||||
|
|
@ -780,6 +789,8 @@ Power::seedRegOutputActivities(const Instance *inst,
|
|||
while (pin_iter->hasNext()) {
|
||||
Pin *pin = pin_iter->next();
|
||||
LibertyPort *port = network_->libertyPort(pin);
|
||||
if (test_cell)
|
||||
port = test_cell->findLibertyPort(port->name());
|
||||
if (port) {
|
||||
FuncExpr *func = port->function();
|
||||
Vertex *vertex = graph_->pinDrvrVertex(pin);
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ VcdParse::read(const char *filename,
|
|||
Stats stats(debug_, report_);
|
||||
filename_ = filename;
|
||||
reader_ = reader;
|
||||
file_line_ = 1;
|
||||
stmt_line_ = 1;
|
||||
file_line_ = 0;
|
||||
stmt_line_ = 0;
|
||||
std::string token = getToken();
|
||||
while (!token.empty()) {
|
||||
if (token == "$date")
|
||||
|
|
@ -205,11 +205,19 @@ void
|
|||
VcdParse::parseVarValues()
|
||||
{
|
||||
string token = getToken();
|
||||
bool first_time = true;
|
||||
while (!token.empty()) {
|
||||
char char0 = toupper(token[0]);
|
||||
if (char0 == '#' && token.size() > 1) {
|
||||
VcdTime time = stoll(token.substr(1));
|
||||
if (first_time) {
|
||||
prev_time_ = time;
|
||||
first_time = false;
|
||||
reader_->setTimeMin(time);
|
||||
}
|
||||
else
|
||||
prev_time_ = time_;
|
||||
time_ = stoll(token.substr(1));
|
||||
time_ = time;
|
||||
if (time_ > prev_time_)
|
||||
reader_->varMinDeltaTime(time_ - prev_time_);
|
||||
}
|
||||
|
|
@ -286,20 +294,18 @@ VcdParse::getToken()
|
|||
{
|
||||
string token;
|
||||
int ch = gzgetc(stream_);
|
||||
if (ch == '\n')
|
||||
file_line_++;
|
||||
// skip whitespace
|
||||
while (ch != EOF && isspace(ch)) {
|
||||
ch = gzgetc(stream_);
|
||||
if (ch == '\n')
|
||||
file_line_++;
|
||||
ch = gzgetc(stream_);
|
||||
}
|
||||
while (ch != EOF && !isspace(ch)) {
|
||||
token.push_back(ch);
|
||||
ch = gzgetc(stream_);
|
||||
}
|
||||
if (ch == '\n')
|
||||
file_line_++;
|
||||
}
|
||||
if (ch == EOF)
|
||||
return "";
|
||||
else
|
||||
|
|
|
|||
|
|
@ -104,7 +104,8 @@ public:
|
|||
virtual void setTimeUnit(const std::string &time_unit,
|
||||
double time_unit_scale,
|
||||
double time_scale) = 0;
|
||||
virtual void setTimeMax(VcdTime time_max) = 0;
|
||||
virtual void setTimeMin(VcdTime time) = 0;
|
||||
virtual void setTimeMax(VcdTime time) = 0;
|
||||
virtual void varMinDeltaTime(VcdTime min_delta_time) = 0;
|
||||
virtual bool varIdValid(const std::string &id) = 0;
|
||||
virtual void makeVar(const VcdScope &scope,
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ public:
|
|||
Report *report,
|
||||
Debug *debug);
|
||||
VcdTime timeMax() const { return time_max_; }
|
||||
VcdTime timeMin() const { return time_min_; }
|
||||
const VcdIdCountsMap &countMap() const { return vcd_count_map_; }
|
||||
double timeScale() const { return time_scale_; }
|
||||
|
||||
|
|
@ -137,7 +138,8 @@ public:
|
|||
void setTimeUnit(const string &time_unit,
|
||||
double time_unit_scale,
|
||||
double time_scale) override;
|
||||
void setTimeMax(VcdTime time_max) override;
|
||||
void setTimeMin(VcdTime time) override;
|
||||
void setTimeMax(VcdTime time) override;
|
||||
void varMinDeltaTime(VcdTime) override {}
|
||||
bool varIdValid(const string &id) override;
|
||||
void makeVar(const VcdScope &scope,
|
||||
|
|
@ -164,6 +166,7 @@ private:
|
|||
Debug *debug_;
|
||||
|
||||
double time_scale_;
|
||||
VcdTime time_min_;
|
||||
VcdTime time_max_;
|
||||
VcdIdCountsMap vcd_count_map_;
|
||||
};
|
||||
|
|
@ -177,7 +180,8 @@ VcdCountReader::VcdCountReader(const char *scope,
|
|||
report_(report),
|
||||
debug_(debug),
|
||||
time_scale_(1.0),
|
||||
time_max_(0.0)
|
||||
time_min_(0),
|
||||
time_max_(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -190,9 +194,15 @@ VcdCountReader::setTimeUnit(const string &,
|
|||
}
|
||||
|
||||
void
|
||||
VcdCountReader::setTimeMax(VcdTime time_max)
|
||||
VcdCountReader::setTimeMin(VcdTime time)
|
||||
{
|
||||
time_max_ = time_max;
|
||||
time_min_ = time;
|
||||
}
|
||||
|
||||
void
|
||||
VcdCountReader::setTimeMax(VcdTime time)
|
||||
{
|
||||
time_max_ = time;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -400,14 +410,16 @@ ReadVcdActivities::readActivities()
|
|||
void
|
||||
ReadVcdActivities::setActivities()
|
||||
{
|
||||
VcdTime time_min = vcd_reader_.timeMin();
|
||||
VcdTime time_max = vcd_reader_.timeMax();
|
||||
VcdTime time_delta = time_max - time_min;
|
||||
double time_scale = vcd_reader_.timeScale();
|
||||
for (auto& [id, vcd_counts] : vcd_reader_.countMap()) {
|
||||
for (const VcdCount &vcd_count : vcd_counts) {
|
||||
double transition_count = vcd_count.transitionCount();
|
||||
VcdTime high_time = vcd_count.highTime(time_max);
|
||||
float duty = static_cast<double>(high_time) / time_max;
|
||||
float density = transition_count / (time_max * time_scale);
|
||||
float duty = static_cast<double>(high_time) / time_delta;
|
||||
float density = transition_count / (time_delta * time_scale);
|
||||
if (debug_->check("read_vcd_activities", 1)) {
|
||||
for (const Pin *pin : vcd_count.pins()) {
|
||||
debugPrint(debug_, "read_vcd_activities", 1,
|
||||
|
|
@ -433,8 +445,9 @@ ReadVcdActivities::checkClkPeriod(const Pin *pin,
|
|||
double transition_count)
|
||||
{
|
||||
VcdTime time_max = vcd_reader_.timeMax();
|
||||
VcdTime time_min = vcd_reader_.timeMin();
|
||||
double time_scale = vcd_reader_.timeScale();
|
||||
double sim_period = time_max * time_scale / (transition_count / 2.0);
|
||||
double sim_period = (time_max - time_min) * time_scale / (transition_count / 2.0);
|
||||
ClockSet *clks = sdc_->findLeafPinClocks(pin);
|
||||
if (clks) {
|
||||
for (Clock *clk : *clks) {
|
||||
|
|
@ -449,4 +462,4 @@ ReadVcdActivities::checkClkPeriod(const Pin *pin,
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -2280,17 +2280,23 @@ ExceptionState::hash() const
|
|||
}
|
||||
|
||||
bool
|
||||
ExceptionStateLess::operator()(const ExceptionState *state1,
|
||||
const ExceptionState *state2) const
|
||||
exceptionStateLess(const ExceptionState *state1,
|
||||
const ExceptionState *state2)
|
||||
{
|
||||
const ExceptionPath *except1 = state1->exception();
|
||||
const ExceptionPath *except2 = state2->exception();
|
||||
return except1->id() < except2->id()
|
||||
//return except1 < except2
|
||||
|| (except1 == except2
|
||||
&& state1->index() < state2->index());
|
||||
}
|
||||
|
||||
bool
|
||||
ExceptionStateLess::operator()(const ExceptionState *state1,
|
||||
const ExceptionState *state2) const
|
||||
{
|
||||
return exceptionStateLess(state1, state2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
ExceptionPathLess::ExceptionPathLess(const Network *network) :
|
||||
|
|
|
|||
|
|
@ -322,8 +322,8 @@ MinPulseWidthCheck::closePath(const StaState *sta) const
|
|||
const RiseFall *open_rf = open_path_->transition(sta);
|
||||
const RiseFall *close_rf = open_rf->opposite();
|
||||
Tag *open_tag = open_path_->tag(sta);
|
||||
ClkInfo *open_clk_info = open_tag->clkInfo();
|
||||
ClkInfo close_clk_info(open_clk_info->clkEdge()->opposite(),
|
||||
const ClkInfo *open_clk_info = open_tag->clkInfo();
|
||||
const ClkInfo close_clk_info(open_clk_info->clkEdge()->opposite(),
|
||||
open_clk_info->clkSrc(),
|
||||
open_clk_info->isPropagated(),
|
||||
open_clk_info->genClkSrc(),
|
||||
|
|
@ -350,7 +350,7 @@ MinPulseWidthCheck::closePath(const StaState *sta) const
|
|||
close_ap, sta);
|
||||
while (close_iter.hasNext()) {
|
||||
Path *close_path = close_iter.next();
|
||||
if (tagMatchNoPathAp(close_path->tag(sta), &close_tag)) {
|
||||
if (Tag::matchNoPathAp(close_path->tag(sta), &close_tag)) {
|
||||
debugPrint(sta->debug(), "mpw", 3, " match %s",
|
||||
close_path->tag(sta)->to_string(sta).c_str());
|
||||
return close_path;
|
||||
|
|
@ -394,7 +394,7 @@ const ClockEdge *
|
|||
MinPulseWidthCheck::closeClkEdge(const StaState *sta) const
|
||||
{
|
||||
Tag *open_tag = open_path_->tag(sta);
|
||||
ClkInfo *open_clk_info = open_tag->clkInfo();
|
||||
const ClkInfo *open_clk_info = open_tag->clkInfo();
|
||||
return open_clk_info->clkEdge()->opposite();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
#include "ClkInfo.hh"
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "Units.hh"
|
||||
#include "Network.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Sdc.hh"
|
||||
|
|
@ -44,7 +47,7 @@ ClkInfo::ClkInfo(const ClockEdge *clk_edge,
|
|||
float latency,
|
||||
ClockUncertainties *uncertainties,
|
||||
PathAPIndex path_ap_index,
|
||||
Path *crpr_clk_path,
|
||||
const Path *crpr_clk_path,
|
||||
const StaState *sta) :
|
||||
clk_edge_(clk_edge),
|
||||
clk_src_(clk_src),
|
||||
|
|
@ -55,6 +58,7 @@ ClkInfo::ClkInfo(const ClockEdge *clk_edge,
|
|||
latency_(latency),
|
||||
is_propagated_(is_propagated),
|
||||
is_gen_clk_src_path_(is_gen_clk_src_path),
|
||||
crpr_path_refs_filter_(crpr_clk_path ? crpr_clk_path->tag(sta)->isFilter() : false),
|
||||
is_pulse_clk_(pulse_clk_sense != nullptr),
|
||||
pulse_clk_sense_(pulse_clk_sense ? pulse_clk_sense->index() : 0),
|
||||
path_ap_index_(path_ap_index)
|
||||
|
|
@ -78,19 +82,26 @@ ClkInfo::findHash(const StaState *sta)
|
|||
hashIncr(hash_, network->vertexId(clk_src_));
|
||||
if (gen_clk_src_)
|
||||
hashIncr(hash_, network->vertexId(gen_clk_src_));
|
||||
hashIncr(hash_, crprClkVertexId(sta));
|
||||
if (crpr_clk_path_.isNull())
|
||||
hashIncr(hash_, vertex_id_null);
|
||||
else {
|
||||
hashIncr(hash_, crpr_clk_path_.vertexId(sta));
|
||||
hashIncr(hash_, crpr_clk_path_.tag(sta)->hash(false, sta));
|
||||
}
|
||||
|
||||
std::hash<float> hash_float;
|
||||
if (uncertainties_) {
|
||||
float uncertainty;
|
||||
bool exists;
|
||||
uncertainties_->value(MinMax::min(), uncertainty, exists);
|
||||
if (exists)
|
||||
hashIncr(hash_, uncertainty * 1E+12F);
|
||||
hashIncr(hash_, hash_float(uncertainty));
|
||||
uncertainties_->value(MinMax::max(), uncertainty, exists);
|
||||
if (exists)
|
||||
hashIncr(hash_, uncertainty * 1E+12F);
|
||||
hashIncr(hash_, hash_float(uncertainty));
|
||||
}
|
||||
hashIncr(hash_, latency_ * 1E+12F);
|
||||
hashIncr(hash_, delayAsFloat(insertion_) * 1E+12F);
|
||||
hashIncr(hash_, hash_float(latency_));
|
||||
hashIncr(hash_, hash_float(delayAsFloat(insertion_)));
|
||||
hashIncr(hash_, is_propagated_);
|
||||
hashIncr(hash_, is_gen_clk_src_path_);
|
||||
hashIncr(hash_, is_pulse_clk_);
|
||||
|
|
@ -101,18 +112,12 @@ ClkInfo::findHash(const StaState *sta)
|
|||
VertexId
|
||||
ClkInfo::crprClkVertexId(const StaState *sta) const
|
||||
{
|
||||
if (crpr_clk_path_.isNull())
|
||||
return vertex_id_null;
|
||||
else
|
||||
return crpr_clk_path_.vertexId(sta);
|
||||
}
|
||||
|
||||
Path *
|
||||
ClkInfo::crprClkPath(const StaState *sta)
|
||||
{
|
||||
if (crpr_clk_path_.isNull())
|
||||
return nullptr;
|
||||
else
|
||||
return Path::vertexPath(crpr_clk_path_, sta);
|
||||
}
|
||||
|
||||
|
|
@ -125,6 +130,15 @@ ClkInfo::crprClkPath(const StaState *sta) const
|
|||
return Path::vertexPath(crpr_clk_path_, sta);
|
||||
}
|
||||
|
||||
const Path *
|
||||
ClkInfo::crprClkPathRaw() const
|
||||
{
|
||||
if (crpr_clk_path_.isNull())
|
||||
return nullptr;
|
||||
else
|
||||
return &crpr_clk_path_;
|
||||
}
|
||||
|
||||
std::string
|
||||
ClkInfo::to_string(const StaState *sta) const
|
||||
{
|
||||
|
|
@ -150,13 +164,37 @@ ClkInfo::to_string(const StaState *sta) const
|
|||
|
||||
if (!crpr_clk_path_.isNull()) {
|
||||
const Pin *crpr_clk_pin = crpr_clk_path_.vertex(sta)->pin();
|
||||
result += " crpr_pin ";
|
||||
result += " crpr ";
|
||||
result += network->pathName(crpr_clk_pin);
|
||||
result += "/";
|
||||
result += std::to_string(crpr_clk_path_.tag(sta)->index());
|
||||
}
|
||||
|
||||
if (is_gen_clk_src_path_)
|
||||
result += " genclk";
|
||||
if (gen_clk_src_) {
|
||||
result += " ";
|
||||
result += network->pathName(gen_clk_src_);
|
||||
}
|
||||
|
||||
if (insertion_ > 0.0) {
|
||||
result += " insert";
|
||||
result += std::to_string(insertion_);
|
||||
}
|
||||
|
||||
if (uncertainties_) {
|
||||
result += " uncertain ";
|
||||
float uncertainty;
|
||||
bool exists;
|
||||
uncertainties_->value(MinMax::min(), uncertainty, exists);
|
||||
if (exists)
|
||||
result += sta->units()->timeUnit()->asString(uncertainty);
|
||||
uncertainties_->value(MinMax::max(), uncertainty, exists);
|
||||
if (exists) {
|
||||
result += ":";
|
||||
result += sta->units()->timeUnit()->asString(uncertainty);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -178,13 +216,6 @@ ClkInfo::pulseClkSense() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
ClkInfo::refsFilter(const StaState *sta) const
|
||||
{
|
||||
return !crpr_clk_path_.isNull()
|
||||
&& crpr_clk_path_.tag(sta)->isFilter();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t
|
||||
|
|
@ -204,36 +235,15 @@ bool
|
|||
ClkInfoEqual::operator()(const ClkInfo *clk_info1,
|
||||
const ClkInfo *clk_info2) const
|
||||
{
|
||||
return clkInfoEqual(clk_info1, clk_info2, sta_);
|
||||
return ClkInfo::equal(clk_info1, clk_info2, sta_);
|
||||
}
|
||||
|
||||
bool
|
||||
clkInfoEqual(const ClkInfo *clk_info1,
|
||||
ClkInfo::equal(const ClkInfo *clk_info1,
|
||||
const ClkInfo *clk_info2,
|
||||
const StaState *sta)
|
||||
{
|
||||
bool crpr_on = sta->crprActive();
|
||||
ClockUncertainties *uncertainties1 = clk_info1->uncertainties();
|
||||
ClockUncertainties *uncertainties2 = clk_info2->uncertainties();
|
||||
return clk_info1->clkEdge() == clk_info2->clkEdge()
|
||||
&& clk_info1->pathAPIndex() == clk_info2->pathAPIndex()
|
||||
&& clk_info1->clkSrc() == clk_info2->clkSrc()
|
||||
&& clk_info1->genClkSrc() == clk_info2->genClkSrc()
|
||||
&& (!crpr_on
|
||||
|| Path::equal(clk_info1->crprClkPath(sta),
|
||||
clk_info2->crprClkPath(sta),
|
||||
sta))
|
||||
&& ((uncertainties1 == nullptr
|
||||
&& uncertainties2 == nullptr)
|
||||
|| (uncertainties1 && uncertainties2
|
||||
&& MinMaxValues<float>::equal(uncertainties1,
|
||||
uncertainties2)))
|
||||
&& clk_info1->insertion() == clk_info2->insertion()
|
||||
&& clk_info1->latency() == clk_info2->latency()
|
||||
&& clk_info1->isPropagated() == clk_info2->isPropagated()
|
||||
&& clk_info1->isGenClkSrcPath() == clk_info2->isGenClkSrcPath()
|
||||
&& clk_info1->isPulseClk() == clk_info2->isPulseClk()
|
||||
&& clk_info1->pulseClkSenseTrIndex() == clk_info2->pulseClkSenseTrIndex();
|
||||
return ClkInfo::cmp(clk_info1, clk_info2, sta) == 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -247,11 +257,11 @@ bool
|
|||
ClkInfoLess::operator()(const ClkInfo *clk_info1,
|
||||
const ClkInfo *clk_info2) const
|
||||
{
|
||||
return clkInfoCmp(clk_info1, clk_info2, sta_) < 0;
|
||||
return ClkInfo::cmp(clk_info1, clk_info2, sta_) < 0;
|
||||
}
|
||||
|
||||
int
|
||||
clkInfoCmp(const ClkInfo *clk_info1,
|
||||
ClkInfo::cmp(const ClkInfo *clk_info1,
|
||||
const ClkInfo *clk_info2,
|
||||
const StaState *sta)
|
||||
{
|
||||
|
|
@ -271,24 +281,29 @@ clkInfoCmp(const ClkInfo *clk_info1,
|
|||
if (path_ap_index1 > path_ap_index2)
|
||||
return 1;
|
||||
|
||||
const Network *network = sta->network();
|
||||
const Pin *clk_src1 = clk_info1->clkSrc();
|
||||
const Pin *clk_src2 = clk_info2->clkSrc();
|
||||
if (clk_src1 < clk_src2)
|
||||
int clk_src_id1 = clk_src1 ? network->id(clk_src1) : -1;
|
||||
int clk_src_id2 = clk_src2 ? network->id(clk_src2) : -1;
|
||||
if (clk_src_id1 < clk_src_id2)
|
||||
return -1;
|
||||
if (clk_src1 > clk_src2)
|
||||
if (clk_src_id1 > clk_src_id2)
|
||||
return 1;
|
||||
|
||||
const Pin *gen_clk_src1 = clk_info1->genClkSrc();
|
||||
const Pin *gen_clk_src2 = clk_info2->genClkSrc();
|
||||
if (gen_clk_src1 < gen_clk_src2)
|
||||
int gen_clk_src_id1 = gen_clk_src1 ? network->id(gen_clk_src1) : -1;
|
||||
int gen_clk_src_id2 = gen_clk_src2 ? network->id(gen_clk_src2) : -1;
|
||||
if (gen_clk_src_id1 < gen_clk_src_id2)
|
||||
return -1;
|
||||
if (gen_clk_src1 > gen_clk_src2)
|
||||
if (gen_clk_src_id1 > gen_clk_src_id2)
|
||||
return 1;
|
||||
|
||||
bool crpr_on = sta->crprActive();
|
||||
if (crpr_on) {
|
||||
const Path *crpr_path1 = clk_info1->crprClkPath(sta);
|
||||
const Path *crpr_path2 = clk_info2->crprClkPath(sta);
|
||||
const Path *crpr_path1 = clk_info1->crprClkPathRaw();
|
||||
const Path *crpr_path2 = clk_info2->crprClkPathRaw();
|
||||
int path_cmp = Path::cmp(crpr_path1, crpr_path2, sta);
|
||||
if (path_cmp != 0)
|
||||
return path_cmp;
|
||||
|
|
@ -296,11 +311,15 @@ clkInfoCmp(const ClkInfo *clk_info1,
|
|||
|
||||
const ClockUncertainties *uncertainties1 = clk_info1->uncertainties();
|
||||
const ClockUncertainties *uncertainties2 = clk_info2->uncertainties();
|
||||
if (uncertainties1 < uncertainties2)
|
||||
if (uncertainties1 == nullptr && uncertainties2)
|
||||
return -1;
|
||||
if (uncertainties1 > uncertainties2)
|
||||
if (uncertainties1 && uncertainties2 == nullptr)
|
||||
return 1;
|
||||
|
||||
if (uncertainties1 && uncertainties2) {
|
||||
int uncertain_cmp = ClockUncertainties::cmp(uncertainties1, uncertainties2);
|
||||
if (uncertain_cmp != 0)
|
||||
return uncertain_cmp;
|
||||
}
|
||||
const Arrival &insert1 = clk_info1->insertion();
|
||||
const Arrival &insert2 = clk_info2->insertion();
|
||||
if (delayLess(insert1, insert2, sta))
|
||||
|
|
@ -336,8 +355,8 @@ clkInfoCmp(const ClkInfo *clk_info1,
|
|||
if (is_pulse_clk1 && !is_pulse_clk2)
|
||||
return 1;
|
||||
|
||||
int pulse_clk_sense_index1 = clk_info1->pulseClkSenseTrIndex();
|
||||
int pulse_clk_sense_index2 = clk_info2->pulseClkSenseTrIndex();
|
||||
int pulse_clk_sense_index1 = clk_info1->pulseClkSenseRfIndex();
|
||||
int pulse_clk_sense_index2 = clk_info2->pulseClkSenseRfIndex();
|
||||
if (pulse_clk_sense_index1 < pulse_clk_sense_index2)
|
||||
return -1;
|
||||
if (pulse_clk_sense_index1 > pulse_clk_sense_index2)
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public:
|
|||
float latency,
|
||||
ClockUncertainties *uncertainties,
|
||||
PathAPIndex path_ap_index,
|
||||
Path *crpr_clk_path,
|
||||
const Path *crpr_clk_path,
|
||||
const StaState *sta);
|
||||
~ClkInfo();
|
||||
std::string to_string(const StaState *sta) const;
|
||||
|
|
@ -57,7 +57,7 @@ public:
|
|||
const Pin *genClkSrc() const { return gen_clk_src_; }
|
||||
bool isPulseClk() const { return is_pulse_clk_; }
|
||||
const RiseFall *pulseClkSense() const;
|
||||
int pulseClkSenseTrIndex() const { return pulse_clk_sense_; }
|
||||
int pulseClkSenseRfIndex() const { return pulse_clk_sense_; }
|
||||
float latency() const { return latency_; }
|
||||
Arrival &insertion() { return insertion_; }
|
||||
const Arrival &insertion() const { return insertion_; }
|
||||
|
|
@ -69,11 +69,18 @@ public:
|
|||
const Path *crprClkPath(const StaState *sta) const;
|
||||
VertexId crprClkVertexId(const StaState *sta) const;
|
||||
bool hasCrprClkPin() const { return !crpr_clk_path_.isNull(); }
|
||||
bool refsFilter(const StaState *sta) const;
|
||||
// This clk_info/tag is used for a generated clock source path.
|
||||
bool isGenClkSrcPath() const { return is_gen_clk_src_path_; }
|
||||
size_t hash() const { return hash_; }
|
||||
bool crprPathRefsFilter() const { return crpr_path_refs_filter_; }
|
||||
const Path *crprClkPathRaw() const;
|
||||
|
||||
static int cmp(const ClkInfo *clk_info1,
|
||||
const ClkInfo *clk_info2,
|
||||
const StaState *sta);
|
||||
static bool equal(const ClkInfo *clk_info1,
|
||||
const ClkInfo *clk_info2,
|
||||
const StaState *sta);
|
||||
protected:
|
||||
void findHash(const StaState *sta);
|
||||
|
||||
|
|
@ -88,20 +95,14 @@ private:
|
|||
size_t hash_;
|
||||
bool is_propagated_:1;
|
||||
bool is_gen_clk_src_path_:1;
|
||||
// This is used to break a circular dependency in Search::deleteFilteredArrival
|
||||
// between tags and clk infos that reference a filter.
|
||||
bool crpr_path_refs_filter_:1;
|
||||
bool is_pulse_clk_:1;
|
||||
unsigned int pulse_clk_sense_:RiseFall::index_bit_count;
|
||||
unsigned int path_ap_index_:path_ap_index_bit_count;
|
||||
};
|
||||
|
||||
int
|
||||
clkInfoCmp(const ClkInfo *clk_info1,
|
||||
const ClkInfo *clk_info2,
|
||||
const StaState *sta);
|
||||
bool
|
||||
clkInfoEqual(const ClkInfo *clk_info1,
|
||||
const ClkInfo *clk_info2,
|
||||
const StaState *sta);
|
||||
|
||||
class ClkInfoLess
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@ ClkDelays::insertionDelay(Path *clk_path,
|
|||
const ClockEdge *clk_edge = clk_path->clkEdge(sta);
|
||||
const Clock *clk = clk_edge->clock();
|
||||
const RiseFall *clk_rf = clk_edge->transition();
|
||||
ClkInfo *clk_info = clk_path->clkInfo(sta);
|
||||
const ClkInfo *clk_info = clk_path->clkInfo(sta);
|
||||
const Pin *src_pin = clk_info->clkSrc();
|
||||
const PathAnalysisPt *path_ap = clk_path->pathAnalysisPt(sta);
|
||||
const MinMax *min_max = clk_path->minMax(sta);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ CheckCrpr::CheckCrpr(StaState *sta) :
|
|||
// Find the maximum possible crpr (clock min/max delta delay) for a
|
||||
// path from it's ClkInfo.
|
||||
Arrival
|
||||
CheckCrpr::maxCrpr(ClkInfo *clk_info)
|
||||
CheckCrpr::maxCrpr(const ClkInfo *clk_info)
|
||||
{
|
||||
const Path *crpr_clk_path = clk_info->crprClkPath(this);
|
||||
if (crpr_clk_path) {
|
||||
|
|
@ -81,7 +81,7 @@ CheckCrpr::otherMinMaxArrival(const Path *path)
|
|||
other_ap, this);
|
||||
while (other_iter.hasNext()) {
|
||||
Path *other = other_iter.next();
|
||||
if (tagMatchCrpr(other->tag(this), tag))
|
||||
if (Tag::matchCrpr(other->tag(this), tag))
|
||||
return other->arrival();
|
||||
}
|
||||
// No corresponding path found.
|
||||
|
|
@ -126,8 +126,8 @@ CheckCrpr::checkCrpr1(const Path *src_path,
|
|||
crpr = 0.0;
|
||||
crpr_pin = nullptr;
|
||||
const Tag *src_tag = src_path->tag(this);
|
||||
ClkInfo *src_clk_info = src_tag->clkInfo();
|
||||
ClkInfo *tgt_clk_info = tgt_clk_path->tag(this)->clkInfo();
|
||||
const ClkInfo *src_clk_info = src_tag->clkInfo();
|
||||
const ClkInfo *tgt_clk_info = tgt_clk_path->tag(this)->clkInfo();
|
||||
const Clock *src_clk = src_clk_info->clock();
|
||||
const Clock *tgt_clk = tgt_clk_info->clock();
|
||||
const Path *src_clk_path = nullptr;
|
||||
|
|
@ -246,7 +246,7 @@ ConstPathSeq
|
|||
CheckCrpr::genClkSrcPaths(const Path *path)
|
||||
{
|
||||
ConstPathSeq gclk_paths;
|
||||
ClkInfo *clk_info = path->clkInfo(this);
|
||||
const ClkInfo *clk_info = path->clkInfo(this);
|
||||
const ClockEdge *clk_edge = clk_info->clkEdge();
|
||||
const Pin *clk_src = clk_info->clkSrc();
|
||||
PathAnalysisPt *path_ap = path->pathAnalysisPt(this);
|
||||
|
|
@ -350,7 +350,7 @@ CheckCrpr::outputDelayCrpr1(const Path *src_path,
|
|||
{
|
||||
crpr = 0.0;
|
||||
crpr_pin = nullptr;
|
||||
ClkInfo *src_clk_info = src_path->tag(this)->clkInfo();
|
||||
const ClkInfo *src_clk_info = src_path->tag(this)->clkInfo();
|
||||
const Clock *tgt_clk = tgt_clk_edge->clock();
|
||||
const Clock *src_clk = src_path->clock(this);
|
||||
if (src_clk && tgt_clk
|
||||
|
|
@ -361,7 +361,7 @@ CheckCrpr::outputDelayCrpr1(const Path *src_path,
|
|||
Path *tgt_genclk_path = portClkPath(tgt_clk_edge,
|
||||
tgt_clk_edge->clock()->defaultPin(),
|
||||
tgt_path_ap);
|
||||
Path *src_clk_path = src_path->clkInfo(this)->crprClkPath(this);
|
||||
const Path *src_clk_path = src_path->clkInfo(this)->crprClkPath(this);
|
||||
if (src_clk_path)
|
||||
findCrpr(src_clk_path, tgt_genclk_path, same_pin, crpr, crpr_pin);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public:
|
|||
explicit CheckCrpr(StaState *sta);
|
||||
|
||||
// Find the maximum possible crpr (clock min/max delta delay) for path.
|
||||
Arrival maxCrpr(ClkInfo *clk_info);
|
||||
Arrival maxCrpr(const ClkInfo *clk_info);
|
||||
// Timing check CRPR.
|
||||
Crpr checkCrpr(const Path *src_clk_path,
|
||||
const Path *tgt_clk_path);
|
||||
|
|
|
|||
|
|
@ -711,12 +711,12 @@ Genclks::makeTag(const Clock *gclk,
|
|||
state = state->nextState();
|
||||
ExceptionStateSet *states = new ExceptionStateSet();
|
||||
states->insert(state);
|
||||
ClkInfo *clk_info = search_->findClkInfo(master_clk->edge(master_rf),
|
||||
const ClkInfo *clk_info = search_->findClkInfo(master_clk->edge(master_rf),
|
||||
master_pin, true, nullptr, true,
|
||||
nullptr, insert, 0.0, nullptr,
|
||||
path_ap, nullptr);
|
||||
return search_->findTag(master_rf, path_ap, clk_info, false, nullptr, false,
|
||||
states, true);
|
||||
return search_->findTag(master_rf, path_ap, clk_info, false,
|
||||
nullptr, false, states, true);
|
||||
}
|
||||
|
||||
class GenClkArrivalSearchPred : public EvalPred
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ Latches::latchOutArrival(const Path *data_path,
|
|||
tgt_clk_path_ap, this);
|
||||
while (enable_iter.hasNext()) {
|
||||
Path *enable_path = enable_iter.next();
|
||||
ClkInfo *en_clk_info = enable_path->clkInfo(this);
|
||||
const ClkInfo *en_clk_info = enable_path->clkInfo(this);
|
||||
const ClockEdge *en_clk_edge = en_clk_info->clkEdge();
|
||||
if (enable_path->isClock(this)) {
|
||||
ExceptionPath *excpt = exceptionTo(data_path, en_clk_edge);
|
||||
|
|
@ -353,7 +353,7 @@ Latches::latchOutArrival(const Path *data_path,
|
|||
// Tag switcheroo - data passing thru gets latch enable tag.
|
||||
// States and path ap come from Q, everything else from enable.
|
||||
Path *crpr_clk_path = crprActive() ? enable_path : nullptr;
|
||||
ClkInfo *q_clk_info =
|
||||
const ClkInfo *q_clk_info =
|
||||
search_->findClkInfo(en_clk_edge,
|
||||
en_clk_info->clkSrc(),
|
||||
en_clk_info->isPropagated(),
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ Path::Path() :
|
|||
{
|
||||
}
|
||||
|
||||
Path::Path(Path *path) :
|
||||
Path::Path(const Path *path) :
|
||||
prev_path_(path ? path->prev_path_ : nullptr),
|
||||
arrival_(path ? path->arrival_ : 0.0),
|
||||
required_(path ? path->required_ : 0.0),
|
||||
|
|
@ -279,7 +279,7 @@ Path::pathIndex(const StaState *sta) const
|
|||
return this - paths;
|
||||
}
|
||||
|
||||
ClkInfo *
|
||||
const ClkInfo *
|
||||
Path::clkInfo(const StaState *sta) const
|
||||
{
|
||||
return tag(sta)->clkInfo();
|
||||
|
|
@ -608,10 +608,20 @@ Path::cmp(const Path *path1,
|
|||
const Path *path2,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (path1 && path2) {
|
||||
if (path1 == path2)
|
||||
return 0;
|
||||
else if (path1 == nullptr && path2)
|
||||
return 1;
|
||||
else if (path1 && path2 == nullptr)
|
||||
return -1;
|
||||
else {
|
||||
VertexId vertex_id1 = path1->vertexId(sta);
|
||||
VertexId vertex_id2 = path2->vertexId(sta);
|
||||
if (vertex_id1 == vertex_id2) {
|
||||
if (vertex_id1 < vertex_id2)
|
||||
return -1;
|
||||
else if (vertex_id1 > vertex_id2)
|
||||
return 1;
|
||||
else {
|
||||
TagIndex tag_index1 = path1->tagIndex(sta);
|
||||
TagIndex tag_index2 = path2->tagIndex(sta);
|
||||
if (tag_index1 == tag_index2)
|
||||
|
|
@ -621,18 +631,7 @@ Path::cmp(const Path *path1,
|
|||
else
|
||||
return 1;
|
||||
}
|
||||
else if (vertex_id1 < vertex_id2)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
else if (path1 == nullptr
|
||||
&& path2 == nullptr)
|
||||
return 0;
|
||||
else if (path1 == nullptr)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -643,7 +642,7 @@ Path::cmpNoCrpr(const Path *path1,
|
|||
VertexId vertex_id1 = path1->vertexId(sta);
|
||||
VertexId vertex_id2 = path2->vertexId(sta);
|
||||
if (vertex_id1 == vertex_id2)
|
||||
return tagMatchCmp(path1->tag(sta), path2->tag(sta), false, sta);
|
||||
return Tag::matchCmp(path1->tag(sta), path2->tag(sta), false, sta);
|
||||
else if (vertex_id1 < vertex_id2)
|
||||
return -1;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ PathEnd::checkTgtClkDelay(const Path *tgt_clk_path,
|
|||
const MinMax *min_max = tgt_clk_path->minMax(sta);
|
||||
const EarlyLate *early_late = check_role->tgtClkEarlyLate();
|
||||
const PathAnalysisPt *tgt_path_ap = tgt_clk_path->pathAnalysisPt(sta);
|
||||
ClkInfo *clk_info = tgt_clk_path->clkInfo(sta);
|
||||
const ClkInfo *clk_info = tgt_clk_path->clkInfo(sta);
|
||||
const Pin *tgt_src_pin = clk_info->clkSrc();
|
||||
const Clock *tgt_clk = tgt_clk_edge->clock();
|
||||
const RiseFall *tgt_clk_rf = tgt_clk_edge->transition();
|
||||
|
|
@ -560,14 +560,14 @@ PathEndClkConstrained::sourceClkOffset(const ClockEdge *src_clk_edge,
|
|||
Arrival
|
||||
PathEndClkConstrained::sourceClkLatency(const StaState *sta) const
|
||||
{
|
||||
ClkInfo *clk_info = path_->clkInfo(sta);
|
||||
const ClkInfo *clk_info = path_->clkInfo(sta);
|
||||
return clk_info->latency();
|
||||
}
|
||||
|
||||
Arrival
|
||||
PathEndClkConstrained::sourceClkInsertionDelay(const StaState *sta) const
|
||||
{
|
||||
ClkInfo *clk_info = path_->clkInfo(sta);
|
||||
const ClkInfo *clk_info = path_->clkInfo(sta);
|
||||
return clk_info->insertion();
|
||||
}
|
||||
|
||||
|
|
@ -1033,7 +1033,7 @@ PathEndCheck::sourceClkDelay(const StaState *sta) const
|
|||
PathExpanded expanded(path_, sta);
|
||||
const Path *src_clk_path = expanded.clkPath();
|
||||
if (src_clk_path) {
|
||||
ClkInfo *src_clk_info = path_->tag(sta)->clkInfo();
|
||||
const ClkInfo *src_clk_info = path_->tag(sta)->clkInfo();
|
||||
if (src_clk_info->isPropagated()) {
|
||||
// Propagated clock. Propagated arrival is seeded with insertion delay.
|
||||
Arrival clk_arrival = src_clk_path->arrival();
|
||||
|
|
@ -1280,7 +1280,7 @@ PathEndLatchCheck::targetClkWidth(const StaState *sta) const
|
|||
const Search *search = sta->search();
|
||||
Arrival disable_arrival = search->clkPathArrival(disable_path_);
|
||||
Arrival enable_arrival = search->clkPathArrival(clk_path_);
|
||||
ClkInfo *enable_clk_info = clk_path_->clkInfo(sta);
|
||||
const ClkInfo *enable_clk_info = clk_path_->clkInfo(sta);
|
||||
if (enable_clk_info->isPulseClk())
|
||||
return disable_arrival - enable_arrival;
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *,
|
|||
// These paths fanin to before_div_ so we know to_vertex matches.
|
||||
if ((!unique_pins_ || from_vertex != prev_vertex_)
|
||||
&& arc != prev_arc_
|
||||
&& tagMatchNoCrpr(to_tag, before_div_tag_)) {
|
||||
&& Tag::matchNoCrpr(to_tag, before_div_tag_)) {
|
||||
debugPrint(debug_, "path_enum", 3, "visit fanin %s -> %s %s %s",
|
||||
from_path->to_string(this).c_str(),
|
||||
to_vertex->to_string(this).c_str(),
|
||||
|
|
@ -644,7 +644,7 @@ PathEnum::updatePathHeadDelays(PathSeq &paths,
|
|||
Path *after_div)
|
||||
{
|
||||
Tag *prev_tag = after_div->tag(this);
|
||||
ClkInfo *prev_clk_info = prev_tag->clkInfo();
|
||||
const ClkInfo *prev_clk_info = prev_tag->clkInfo();
|
||||
Arrival prev_arrival = search_->clkPathArrival(after_div);
|
||||
int path_idx_max = paths.size() - 1;
|
||||
// paths[0] is the path endpoint
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ PathGroup::enumMinSlackUnderMin(PathEnd *path_end)
|
|||
other_ap, sta_);
|
||||
while (other_iter.hasNext()) {
|
||||
Path *other = other_iter.next();
|
||||
if (tagMatchCrpr(other->tag(sta_), tag)) {
|
||||
if (Tag::matchCrpr(other->tag(sta_), tag)) {
|
||||
PathEnd *end_min = path_end->copy();
|
||||
end_min->setPath(other);
|
||||
float slack = delayAsFloat(end_min->slackNoCrpr(sta_));
|
||||
|
|
|
|||
|
|
@ -1240,8 +1240,14 @@ Properties::getProperty(const Clock *clk,
|
|||
return PropertyValue(clk->isVirtual());
|
||||
else if (property == "is_propagated")
|
||||
return PropertyValue(clk->isPropagated());
|
||||
else {
|
||||
PropertyValue value = registry_clock_.getProperty(clk, property,
|
||||
"clock", sta_);
|
||||
if (value.type() != PropertyValue::Type::type_none)
|
||||
return value;
|
||||
else
|
||||
throw PropertyUnknown("clock", property);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1376,6 +1382,13 @@ Properties::defineProperty(std::string &property,
|
|||
registry_net_.defineProperty(property, handler);
|
||||
}
|
||||
|
||||
void
|
||||
Properties::defineProperty(std::string &property,
|
||||
PropertyRegistry<const Clock *>::PropertyHandler handler)
|
||||
{
|
||||
registry_clock_.defineProperty(property, handler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class TYPE>
|
||||
|
|
|
|||
|
|
@ -2112,7 +2112,7 @@ ReportPath::reportSrcClkAndPath(const Path *path,
|
|||
else if (clk_used_as_data
|
||||
&& pathFromGenPropClk(path, path->minMax(this))) {
|
||||
reportClkLine(clk, clk_name.c_str(), clk_end_rf, clk_time, min_max);
|
||||
ClkInfo *clk_info = path->tag(search_)->clkInfo();
|
||||
const ClkInfo *clk_info = path->tag(search_)->clkInfo();
|
||||
if (clk_info->isPropagated())
|
||||
reportClkSrcLatency(clk_insertion, clk_time, early_late);
|
||||
reportPath1(path, expanded, true, time_offset);
|
||||
|
|
@ -2259,7 +2259,7 @@ ReportPath::tgtClkInsertionOffet(const Path *clk_path,
|
|||
const EarlyLate *early_late,
|
||||
const PathAnalysisPt *path_ap) const
|
||||
{
|
||||
ClkInfo *clk_info = clk_path->clkInfo(this);
|
||||
const ClkInfo *clk_info = clk_path->clkInfo(this);
|
||||
const Pin *src_pin = clk_info->clkSrc();
|
||||
const ClockEdge *clk_edge = clk_info->clkEdge();
|
||||
const Clock *clk = clk_edge->clock();
|
||||
|
|
@ -2278,7 +2278,7 @@ bool
|
|||
ReportPath::pathFromGenPropClk(const Path *clk_path,
|
||||
const EarlyLate *early_late) const
|
||||
{
|
||||
ClkInfo *clk_info = clk_path->tag(search_)->clkInfo();
|
||||
const ClkInfo *clk_info = clk_path->tag(search_)->clkInfo();
|
||||
const ClockEdge *clk_edge = clk_info->clkEdge();
|
||||
if (clk_edge) {
|
||||
const Clock *clk = clk_edge->clock();
|
||||
|
|
@ -2393,7 +2393,7 @@ ReportPath::reportGenClkSrcPath1(const Clock *clk,
|
|||
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 ClkInfo *src_clk_info = src_path->clkInfo(this);
|
||||
const ClockEdge *src_clk_edge = src_clk_info->clkEdge();
|
||||
const Clock *src_clk = src_clk_info->clock();
|
||||
if (src_clk) {
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ Search::init(StaState *sta)
|
|||
arrival_iter_ = new BfsFwdIterator(BfsIndex::arrival, nullptr, sta);
|
||||
required_iter_ = new BfsBkwdIterator(BfsIndex::required, search_adj_, sta);
|
||||
tag_capacity_ = 128;
|
||||
tag_set_ = new TagSet(tag_capacity_);
|
||||
tag_set_ = new TagSet(tag_capacity_, TagHash(sta), TagEqual(sta));
|
||||
clk_info_set_ = new ClkInfoSet(ClkInfoLess(sta));
|
||||
tag_next_ = 0;
|
||||
tags_ = new Tag*[tag_capacity_];
|
||||
|
|
@ -543,8 +543,8 @@ Search::deleteFilteredArrivals()
|
|||
}
|
||||
filtered_arrivals_->clear();
|
||||
deleteFilterTagGroups();
|
||||
deleteFilterClkInfos();
|
||||
deleteFilterTags();
|
||||
deleteFilterClkInfos();
|
||||
}
|
||||
deleteFilter();
|
||||
}
|
||||
|
|
@ -576,7 +576,8 @@ Search::deleteFilterTags()
|
|||
for (TagIndex i = 0; i < tag_next_; i++) {
|
||||
Tag *tag = tags_[i];
|
||||
if (tag
|
||||
&& tag->isFilter()) {
|
||||
&& (tag->isFilter()
|
||||
|| tag->clkInfo()->crprPathRefsFilter())) {
|
||||
tags_[i] = nullptr;
|
||||
tag_set_->erase(tag);
|
||||
delete tag;
|
||||
|
|
@ -589,8 +590,8 @@ void
|
|||
Search::deleteFilterClkInfos()
|
||||
{
|
||||
for (auto itr = clk_info_set_->cbegin(); itr != clk_info_set_->cend(); ) {
|
||||
ClkInfo *clk_info = *itr;
|
||||
if (clk_info->refsFilter(this)) {
|
||||
const ClkInfo *clk_info = *itr;
|
||||
if (clk_info->crprPathRefsFilter()) {
|
||||
itr = clk_info_set_->erase(itr);
|
||||
delete clk_info;
|
||||
}
|
||||
|
|
@ -614,8 +615,7 @@ Search::findFilteredArrivals(bool thru_latches)
|
|||
if (thru_latches)
|
||||
enqueuePendingLatchOutputs();
|
||||
debugPrint(debug_, "search", 1, "find arrivals pass %d", pass);
|
||||
int arrival_count = arrival_iter_->visitParallel(max_level,
|
||||
arrival_visitor_);
|
||||
int arrival_count = arrival_iter_->visitParallel(max_level, arrival_visitor_);
|
||||
deleteTagsPrev();
|
||||
debugPrint(debug_, "search", 1, "found %d arrivals", arrival_count);
|
||||
}
|
||||
|
|
@ -1216,11 +1216,10 @@ ArrivalVisitor::visit(Vertex *vertex)
|
|||
// If vertex is a latch data input arrival that changed from the
|
||||
// previous eval pass enqueue the latch outputs to be re-evaled on the
|
||||
// next pass.
|
||||
if (network_->isLatchData(pin)) {
|
||||
if (arrivals_changed
|
||||
&& network_->isLatchData(pin))
|
||||
search_->enqueueLatchDataOutputs(vertex);
|
||||
}
|
||||
|
||||
if (!search_->arrivalsAtEndpointsExist()
|
||||
|| always_to_endpoints_
|
||||
|| arrivals_changed)
|
||||
|
|
@ -1326,7 +1325,7 @@ ArrivalVisitor::visitFromToPath(const Pin * /* from_pin */,
|
|||
from_tag->to_string(this).c_str());
|
||||
debugPrint(debug_, "search", 3, " to tag : %s",
|
||||
to_tag->to_string(this).c_str());
|
||||
ClkInfo *to_clk_info = to_tag->clkInfo();
|
||||
const ClkInfo *to_clk_info = to_tag->clkInfo();
|
||||
bool to_is_clk = to_tag->isClock();
|
||||
Path *match;
|
||||
size_t path_index;
|
||||
|
|
@ -1363,7 +1362,7 @@ ArrivalVisitor::pruneCrprArrivals()
|
|||
for (auto path_itr = path_index_map.cbegin(); path_itr != path_index_map.cend(); ) {
|
||||
Tag *tag = path_itr->first;
|
||||
size_t path_index = path_itr->second;
|
||||
ClkInfo *clk_info = tag->clkInfo();
|
||||
const ClkInfo *clk_info = tag->clkInfo();
|
||||
bool deleted_tag = false;
|
||||
if (!tag->isClock()
|
||||
&& clk_info->hasCrprClkPin()) {
|
||||
|
|
@ -1372,7 +1371,7 @@ ArrivalVisitor::pruneCrprArrivals()
|
|||
Path *path_no_crpr = tag_bldr_no_crpr_->tagMatchPath(tag);
|
||||
if (path_no_crpr) {
|
||||
Arrival max_arrival = path_no_crpr->arrival();
|
||||
ClkInfo *clk_info_no_crpr = path_no_crpr->clkInfo(this);
|
||||
const ClkInfo *clk_info_no_crpr = path_no_crpr->clkInfo(this);
|
||||
Arrival max_crpr = crpr->maxCrpr(clk_info_no_crpr);
|
||||
Arrival max_arrival_max_crpr = (min_max == MinMax::max())
|
||||
? max_arrival - max_crpr
|
||||
|
|
@ -1610,7 +1609,7 @@ Search::seedClkArrival(const Pin *pin,
|
|||
// Propagate liberty "pulse_clock" transition to transitive fanout.
|
||||
LibertyPort *port = network_->libertyPort(pin);
|
||||
const RiseFall *pulse_clk_sense = (port ? port->pulseClkSense() : nullptr);
|
||||
ClkInfo *clk_info = findClkInfo(clk_edge, pin, is_propagated, nullptr, false,
|
||||
const ClkInfo *clk_info = findClkInfo(clk_edge, pin, is_propagated, nullptr, false,
|
||||
pulse_clk_sense, insertion, latency,
|
||||
uncertainties, path_ap, nullptr);
|
||||
// Only false_paths -from apply to clock tree pins.
|
||||
|
|
@ -1652,7 +1651,7 @@ Search::clkDataTag(const Pin *pin,
|
|||
if (sdc_->exceptionFromStates(pin, rf, clk, rf, min_max, states)) {
|
||||
bool is_propagated = (clk->isPropagated()
|
||||
|| sdc_->isPropagatedClock(pin));
|
||||
ClkInfo *clk_info = findClkInfo(clk_edge, pin, is_propagated,
|
||||
const ClkInfo *clk_info = findClkInfo(clk_edge, pin, is_propagated,
|
||||
insertion, path_ap);
|
||||
return findTag(rf, path_ap, clk_info, false, nullptr, false, states, true);
|
||||
}
|
||||
|
|
@ -1888,7 +1887,7 @@ Search::inputDelayRefPinArrival(Path *ref_path,
|
|||
{
|
||||
Clock *clk = clk_edge->clock();
|
||||
if (clk->isPropagated()) {
|
||||
ClkInfo *clk_info = ref_path->clkInfo(this);
|
||||
const ClkInfo *clk_info = ref_path->clkInfo(this);
|
||||
ref_arrival = delayAsFloat(ref_path->arrival());
|
||||
ref_insertion = delayAsFloat(clk_info->insertion());
|
||||
ref_latency = clk_info->latency();
|
||||
|
|
@ -2011,7 +2010,7 @@ Search::inputDelayTag(const Pin *pin,
|
|||
ExceptionStateSet *states = nullptr;
|
||||
Tag *tag = nullptr;
|
||||
if (sdc_->exceptionFromStates(pin,rf,clk,clk_rf,min_max,states)) {
|
||||
ClkInfo *clk_info = findClkInfo(clk_edge, clk_pin, is_propagated, nullptr,
|
||||
const ClkInfo *clk_info = findClkInfo(clk_edge, clk_pin, is_propagated, nullptr,
|
||||
false, nullptr, clk_insertion, clk_latency,
|
||||
clk_uncertainties, path_ap, nullptr);
|
||||
tag = findTag(rf, path_ap, clk_info, false, input_delay, is_segment_start,
|
||||
|
|
@ -2019,7 +2018,7 @@ Search::inputDelayTag(const Pin *pin,
|
|||
}
|
||||
|
||||
if (tag) {
|
||||
ClkInfo *clk_info = tag->clkInfo();
|
||||
const ClkInfo *clk_info = tag->clkInfo();
|
||||
// Check for state changes on existing tag exceptions (pending -thru pins).
|
||||
tag = mutateTag(tag, pin, rf, false, clk_info,
|
||||
pin, rf, false, false, is_segment_start, clk_info,
|
||||
|
|
@ -2151,7 +2150,7 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
|||
{
|
||||
const TimingRole *role = edge->role();
|
||||
Tag *from_tag = from_path->tag(this);
|
||||
ClkInfo *from_clk_info = from_tag->clkInfo();
|
||||
const ClkInfo *from_clk_info = from_tag->clkInfo();
|
||||
Tag *to_tag = nullptr;
|
||||
const ClockEdge *clk_edge = from_clk_info->clkEdge();
|
||||
const Clock *clk = from_clk_info->clock();
|
||||
|
|
@ -2221,7 +2220,7 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
|||
// passed thru reg/latch D->Q edges.
|
||||
&& from_tag->isClock())) {
|
||||
const RiseFall *clk_rf = clk_edge ? clk_edge->transition() : nullptr;
|
||||
ClkInfo *to_clk_info = from_clk_info;
|
||||
const ClkInfo *to_clk_info = from_clk_info;
|
||||
if (from_clk_info->crprClkPath(this) == nullptr
|
||||
|| network_->direction(to_pin)->isInternal())
|
||||
to_clk_info = search_->clkInfoWithCrprClkPath(from_clk_info,
|
||||
|
|
@ -2304,7 +2303,7 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
|||
Arrival
|
||||
Search::clkPathArrival(const Path *clk_path) const
|
||||
{
|
||||
ClkInfo *clk_info = clk_path->clkInfo(this);
|
||||
const ClkInfo *clk_info = clk_path->clkInfo(this);
|
||||
const ClockEdge *clk_edge = clk_info->clkEdge();
|
||||
const PathAnalysisPt *path_ap = clk_path->pathAnalysisPt(this);
|
||||
const MinMax *min_max = path_ap->pathMinMax();
|
||||
|
|
@ -2313,7 +2312,7 @@ Search::clkPathArrival(const Path *clk_path) const
|
|||
|
||||
Arrival
|
||||
Search::clkPathArrival(const Path *clk_path,
|
||||
ClkInfo *clk_info,
|
||||
const ClkInfo *clk_info,
|
||||
const ClockEdge *clk_edge,
|
||||
const MinMax *min_max,
|
||||
const PathAnalysisPt *path_ap) const
|
||||
|
|
@ -2338,7 +2337,7 @@ Search::clkPathArrival(const Path *clk_path,
|
|||
Arrival
|
||||
Search::pathClkPathArrival(const Path *path) const
|
||||
{
|
||||
ClkInfo *clk_info = path->clkInfo(this);
|
||||
const ClkInfo *clk_info = path->clkInfo(this);
|
||||
if (clk_info->isPropagated()) {
|
||||
const Path *src_clk_path = pathClkPathArrival1(path);
|
||||
if (src_clk_path)
|
||||
|
|
@ -2393,7 +2392,7 @@ Search::fromUnclkedInputTag(const Pin *pin,
|
|||
ExceptionStateSet *states = nullptr;
|
||||
if (sdc_->exceptionFromStates(pin, rf, nullptr, nullptr, min_max, states)
|
||||
&& (!require_exception || states)) {
|
||||
ClkInfo *clk_info = findClkInfo(nullptr, nullptr, false, 0.0, path_ap);
|
||||
const ClkInfo *clk_info = findClkInfo(nullptr, nullptr, false, 0.0, path_ap);
|
||||
return findTag(rf, path_ap, clk_info, false, nullptr,
|
||||
is_segment_start, states, true);
|
||||
}
|
||||
|
|
@ -2405,7 +2404,7 @@ Search::fromRegClkTag(const Pin *from_pin,
|
|||
const RiseFall *from_rf,
|
||||
const Clock *clk,
|
||||
const RiseFall *clk_rf,
|
||||
ClkInfo *clk_info,
|
||||
const ClkInfo *clk_info,
|
||||
const Pin *to_pin,
|
||||
const RiseFall *to_rf,
|
||||
const MinMax *min_max,
|
||||
|
|
@ -2423,8 +2422,8 @@ Search::fromRegClkTag(const Pin *from_pin,
|
|||
}
|
||||
|
||||
// Insert from_path as ClkInfo crpr_clk_path.
|
||||
ClkInfo *
|
||||
Search::clkInfoWithCrprClkPath(ClkInfo *from_clk_info,
|
||||
const ClkInfo *
|
||||
Search::clkInfoWithCrprClkPath(const ClkInfo *from_clk_info,
|
||||
Path *from_path,
|
||||
const PathAnalysisPt *path_ap)
|
||||
{
|
||||
|
|
@ -2456,7 +2455,7 @@ Search::thruTag(Tag *from_tag,
|
|||
Vertex *to_vertex = edge->to(graph_);
|
||||
const Pin *to_pin = to_vertex->pin();
|
||||
const RiseFall *from_rf = from_tag->transition();
|
||||
ClkInfo *from_clk_info = from_tag->clkInfo();
|
||||
const ClkInfo *from_clk_info = from_tag->clkInfo();
|
||||
bool to_is_reg_clk = to_vertex->isRegClk();
|
||||
Tag *to_tag = mutateTag(from_tag, from_pin, from_rf, false, from_clk_info,
|
||||
to_pin, to_rf, false, to_is_reg_clk, false,
|
||||
|
|
@ -2481,7 +2480,7 @@ Search::thruClkTag(Path *from_path,
|
|||
Vertex *to_vertex = edge->to(graph_);
|
||||
const Pin *to_pin = to_vertex->pin();
|
||||
const RiseFall *from_rf = from_tag->transition();
|
||||
ClkInfo *from_clk_info = from_tag->clkInfo();
|
||||
const ClkInfo *from_clk_info = from_tag->clkInfo();
|
||||
bool from_is_clk = from_tag->isClock();
|
||||
bool to_is_reg_clk = to_vertex->isRegClk();
|
||||
const TimingRole *role = edge->role();
|
||||
|
|
@ -2489,7 +2488,8 @@ Search::thruClkTag(Path *from_path,
|
|||
&& to_propagates_clk
|
||||
&& (role->isWire()
|
||||
|| role == TimingRole::combinational()));
|
||||
ClkInfo *to_clk_info = thruClkInfo(from_path, from_vertex, from_clk_info, from_is_clk,
|
||||
const ClkInfo *to_clk_info = thruClkInfo(from_path, from_vertex,
|
||||
from_clk_info, from_is_clk,
|
||||
edge, to_vertex, to_pin, to_is_clk,
|
||||
arc_delay_min_max_eq, min_max, path_ap);
|
||||
Tag *to_tag = mutateTag(from_tag,from_pin,from_rf,from_is_clk,from_clk_info,
|
||||
|
|
@ -2498,10 +2498,10 @@ Search::thruClkTag(Path *from_path,
|
|||
return to_tag;
|
||||
}
|
||||
|
||||
ClkInfo *
|
||||
const ClkInfo *
|
||||
Search::thruClkInfo(Path *from_path,
|
||||
Vertex *from_vertex,
|
||||
ClkInfo *from_clk_info,
|
||||
const ClkInfo *from_clk_info,
|
||||
bool from_is_clk,
|
||||
Edge *edge,
|
||||
Vertex *to_vertex,
|
||||
|
|
@ -2598,11 +2598,13 @@ Search::thruClkInfo(Path *from_path,
|
|||
}
|
||||
|
||||
if (changed) {
|
||||
ClkInfo *to_clk_info = findClkInfo(from_clk_edge, from_clk_info->clkSrc(),
|
||||
const 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);
|
||||
to_uncertainties, path_ap,
|
||||
to_crpr_clk_path);
|
||||
return to_clk_info;
|
||||
}
|
||||
return from_clk_info;
|
||||
|
|
@ -2614,13 +2616,13 @@ Search::mutateTag(Tag *from_tag,
|
|||
const Pin *from_pin,
|
||||
const RiseFall *from_rf,
|
||||
bool from_is_clk,
|
||||
ClkInfo *from_clk_info,
|
||||
const ClkInfo *from_clk_info,
|
||||
const Pin *to_pin,
|
||||
const RiseFall *to_rf,
|
||||
bool to_is_clk,
|
||||
bool to_is_reg_clk,
|
||||
bool to_is_segment_start,
|
||||
ClkInfo *to_clk_info,
|
||||
const ClkInfo *to_clk_info,
|
||||
InputDelay *to_input_delay,
|
||||
const MinMax *min_max,
|
||||
const PathAnalysisPt *path_ap)
|
||||
|
|
@ -2727,7 +2729,7 @@ Search::mutateTag(Tag *from_tag,
|
|||
TagGroup *
|
||||
Search::findTagGroup(TagGroupBldr *tag_bldr)
|
||||
{
|
||||
TagGroup probe(tag_bldr);
|
||||
TagGroup probe(tag_bldr, this);
|
||||
LockGuard lock(tag_group_lock_);
|
||||
TagGroup *tag_group = tag_group_set_->findKey(&probe);
|
||||
if (tag_group == nullptr) {
|
||||
|
|
@ -2828,7 +2830,7 @@ bool
|
|||
ReportPathLess::operator()(const Path *path1,
|
||||
const Path *path2) const
|
||||
{
|
||||
return tagCmp(path1->tag(sta_), path2->tag(sta_), sta_) < 0;
|
||||
return Tag::cmp(path1->tag(sta_), path2->tag(sta_), sta_) < 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2967,7 +2969,7 @@ Search::tagCount() const
|
|||
Tag *
|
||||
Search::findTag(const RiseFall *rf,
|
||||
const PathAnalysisPt *path_ap,
|
||||
ClkInfo *clk_info,
|
||||
const ClkInfo *clk_info,
|
||||
bool is_clk,
|
||||
InputDelay *input_delay,
|
||||
bool is_segment_start,
|
||||
|
|
@ -3037,17 +3039,17 @@ Search::reportTags() const
|
|||
void
|
||||
Search::reportClkInfos() const
|
||||
{
|
||||
Vector<ClkInfo*> clk_infos;
|
||||
Vector<const ClkInfo*> clk_infos;
|
||||
// set -> vector for sorting.
|
||||
for (ClkInfo *clk_info : *clk_info_set_)
|
||||
for (const ClkInfo *clk_info : *clk_info_set_)
|
||||
clk_infos.push_back(clk_info);
|
||||
sort(clk_infos, ClkInfoLess(this));
|
||||
for (ClkInfo *clk_info : clk_infos)
|
||||
for (const ClkInfo *clk_info : clk_infos)
|
||||
report_->reportLine("%s", clk_info->to_string(this).c_str());
|
||||
report_->reportLine("%zu clk infos", clk_info_set_->size());
|
||||
}
|
||||
|
||||
ClkInfo *
|
||||
const ClkInfo *
|
||||
Search::findClkInfo(const ClockEdge *clk_edge,
|
||||
const Pin *clk_src,
|
||||
bool is_propagated,
|
||||
|
|
@ -3064,7 +3066,7 @@ Search::findClkInfo(const ClockEdge *clk_edge,
|
|||
pulse_clk_sense, insertion, latency, uncertainties,
|
||||
path_ap->index(), crpr_clk_path, this);
|
||||
LockGuard lock(clk_info_lock_);
|
||||
ClkInfo *clk_info = clk_info_set_->findKey(&probe);
|
||||
const ClkInfo *clk_info = clk_info_set_->findKey(&probe);
|
||||
if (clk_info == nullptr) {
|
||||
clk_info = new ClkInfo(clk_edge, clk_src,
|
||||
is_propagated, gen_clk_src, gen_clk_src_path,
|
||||
|
|
@ -3075,7 +3077,7 @@ Search::findClkInfo(const ClockEdge *clk_edge,
|
|||
return clk_info;
|
||||
}
|
||||
|
||||
ClkInfo *
|
||||
const ClkInfo *
|
||||
Search::findClkInfo(const ClockEdge *clk_edge,
|
||||
const Pin *clk_src,
|
||||
bool is_propagated,
|
||||
|
|
@ -3612,7 +3614,7 @@ RequiredVisitor::visitFromToPath(const Pin *,
|
|||
while (to_iter.hasNext()) {
|
||||
Path *to_path = to_iter.next();
|
||||
Tag *to_path_tag = to_path->tag(this);
|
||||
if (tagMatchNoCrpr(to_path_tag, to_tag)) {
|
||||
if (Tag::matchNoCrpr(to_path_tag, to_tag)) {
|
||||
Required to_required = to_path->required();
|
||||
Required from_required = to_required - arc_delay;
|
||||
debugPrint(debug_, "search", 3, " to tag %2u: %s",
|
||||
|
|
|
|||
|
|
@ -2881,7 +2881,7 @@ Sta::vertexArrival(Vertex *vertex,
|
|||
while (path_iter.hasNext()) {
|
||||
Path *path = path_iter.next();
|
||||
const Arrival &path_arrival = path->arrival();
|
||||
ClkInfo *clk_info = path->clkInfo(search_);
|
||||
const ClkInfo *clk_info = path->clkInfo(search_);
|
||||
if ((clk_edge == clk_edge_wildcard
|
||||
|| clk_info->clkEdge() == clk_edge)
|
||||
&& !clk_info->isGenClkSrcPath()
|
||||
|
|
|
|||
158
search/Tag.cc
158
search/Tag.cc
|
|
@ -38,20 +38,10 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
static int
|
||||
tagStateCmp(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
static bool
|
||||
tagStateEqual(ExceptionStateSet *states1,
|
||||
ExceptionStateSet *states2);
|
||||
static bool
|
||||
tagStateEqualCrpr(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
|
||||
Tag::Tag(TagIndex index,
|
||||
int rf_index,
|
||||
PathAPIndex path_ap_index,
|
||||
ClkInfo *clk_info,
|
||||
const ClkInfo *clk_info,
|
||||
bool is_clk,
|
||||
InputDelay *input_delay,
|
||||
bool is_segment_start,
|
||||
|
|
@ -262,26 +252,32 @@ Tag::findHash()
|
|||
for (ExceptionState *state : *states_)
|
||||
hashIncr(hash_, state->hash());
|
||||
}
|
||||
hashIncr(hash_, clk_info_->hash());
|
||||
match_hash_ = hash_;
|
||||
|
||||
// Finish hash_.
|
||||
hashIncr(hash_, clk_info_->hash());
|
||||
if (input_delay_)
|
||||
hashIncr(hash_, input_delay_->index());
|
||||
|
||||
// Finish match_hash_.
|
||||
const ClockEdge *clk_edge = clk_info_->clkEdge();
|
||||
if (clk_edge)
|
||||
hashIncr(match_hash_, clk_edge->index());
|
||||
hashIncr(match_hash_, clk_info_->isGenClkSrcPath());
|
||||
}
|
||||
|
||||
size_t
|
||||
Tag::hash(bool match_crpr_clk_pin,
|
||||
const StaState *sta) const
|
||||
{
|
||||
if (match_crpr_clk_pin)
|
||||
return hashSum(hash_, clk_info_->crprClkVertexId(sta));
|
||||
else
|
||||
return hash_;
|
||||
}
|
||||
|
||||
size_t
|
||||
Tag::matchHash(bool match_crpr_clk_pin,
|
||||
const StaState *sta) const
|
||||
{
|
||||
if (match_crpr_clk_pin)
|
||||
// match_hash_ with crpr clk pin thrown in.
|
||||
return hashSum(match_hash_, clk_info_->crprClkVertexId(sta));
|
||||
else
|
||||
return match_hash_;
|
||||
|
|
@ -298,20 +294,20 @@ bool
|
|||
TagLess::operator()(const Tag *tag1,
|
||||
const Tag *tag2) const
|
||||
{
|
||||
return tagCmp(tag1, tag2, sta_) < 0;
|
||||
return Tag::cmp(tag1, tag2, sta_) < 0;
|
||||
}
|
||||
|
||||
int
|
||||
tagCmp(const Tag *tag1,
|
||||
Tag::cmp(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
const StaState *sta)
|
||||
{
|
||||
if (tag1 == tag2)
|
||||
return 0;
|
||||
|
||||
ClkInfo *clk_info1 = tag1->clkInfo();
|
||||
ClkInfo *clk_info2 = tag2->clkInfo();
|
||||
int clk_cmp = clkInfoCmp(clk_info1, clk_info2, sta);
|
||||
const ClkInfo *clk_info1 = tag1->clkInfo();
|
||||
const ClkInfo *clk_info2 = tag2->clkInfo();
|
||||
int clk_cmp = ClkInfo::cmp(clk_info1, clk_info2, sta);
|
||||
if (clk_cmp != 0)
|
||||
return clk_cmp;
|
||||
|
||||
|
|
@ -338,8 +334,8 @@ tagCmp(const Tag *tag1,
|
|||
|
||||
InputDelay *input_delay1 = tag1->inputDelay();
|
||||
InputDelay *input_delay2 = tag2->inputDelay();
|
||||
int input_delay_index1 = input_delay1 ? input_delay1->index() : 0;
|
||||
int input_delay_index2 = input_delay2 ? input_delay2->index() : 0;
|
||||
int input_delay_index1 = input_delay1 ? input_delay1->index() : -1;
|
||||
int input_delay_index2 = input_delay2 ? input_delay2->index() : -1;
|
||||
if (input_delay_index1 < input_delay_index2)
|
||||
return -1;
|
||||
if (input_delay_index1 > input_delay_index2)
|
||||
|
|
@ -352,21 +348,15 @@ tagCmp(const Tag *tag1,
|
|||
if (is_segment_start1 && !is_segment_start2)
|
||||
return 1;
|
||||
|
||||
return tagStateCmp(tag1, tag2);
|
||||
return stateCmp(tag1, tag2);
|
||||
}
|
||||
|
||||
bool
|
||||
tagEqual(const Tag *tag1,
|
||||
const Tag *tag2)
|
||||
Tag::equal(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
const StaState *sta)
|
||||
{
|
||||
return tag1 == tag2
|
||||
|| (tag1->rfIndex() == tag2->rfIndex()
|
||||
&& tag1->pathAPIndex() == tag2->pathAPIndex()
|
||||
&& tag1->clkInfo() == tag2->clkInfo()
|
||||
&& tag1->isClock() == tag2->isClock()
|
||||
&& tag1->inputDelay() == tag2->inputDelay()
|
||||
&& tag1->isSegmentStart() == tag2->isSegmentStart()
|
||||
&& tagStateEqual(tag1, tag2));
|
||||
return cmp(tag1, tag2, sta) == 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -391,42 +381,30 @@ bool
|
|||
TagMatchLess::operator()(const Tag *tag1,
|
||||
const Tag *tag2) const
|
||||
{
|
||||
return tagMatchCmp(tag1, tag2, match_crpr_clk_pin_, sta_) < 0;
|
||||
return Tag::matchCmp(tag1, tag2, match_crpr_clk_pin_, sta_) < 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
bool
|
||||
tagMatch(const Tag *tag1,
|
||||
Tag::match(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
const StaState *sta)
|
||||
{
|
||||
return tagMatch(tag1, tag2, true, sta);
|
||||
return Tag::matchCmp(tag1, tag2, true, sta) == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
tagMatch(const Tag *tag1,
|
||||
Tag::match(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
bool match_crpr_clk_pin,
|
||||
const StaState *sta)
|
||||
{
|
||||
const ClkInfo *clk_info1 = tag1->clkInfo();
|
||||
const ClkInfo *clk_info2 = tag2->clkInfo();
|
||||
return tag1 == tag2
|
||||
|| (clk_info1->clkEdge() == clk_info2->clkEdge()
|
||||
&& tag1->rfIndex() == tag2->rfIndex()
|
||||
&& tag1->pathAPIndex() == tag2->pathAPIndex()
|
||||
&& tag1->isClock() == tag2->isClock()
|
||||
&& tag1->isSegmentStart() == tag2->isSegmentStart()
|
||||
&& clk_info1->isGenClkSrcPath() == clk_info2->isGenClkSrcPath()
|
||||
&& (!match_crpr_clk_pin
|
||||
|| !sta->crprActive()
|
||||
|| clk_info1->crprClkVertexId(sta) == clk_info2->crprClkVertexId(sta))
|
||||
&& tagStateEqual(tag1, tag2));
|
||||
return Tag::matchCmp(tag1, tag2, match_crpr_clk_pin, sta) == 0;
|
||||
}
|
||||
|
||||
int
|
||||
tagMatchCmp(const Tag *tag1,
|
||||
Tag::matchCmp(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
bool match_crpr_clk_pin,
|
||||
const StaState *sta)
|
||||
|
|
@ -490,11 +468,11 @@ tagMatchCmp(const Tag *tag1,
|
|||
return 1;
|
||||
}
|
||||
|
||||
return tagStateCmp(tag1, tag2);
|
||||
return stateCmp(tag1, tag2);
|
||||
}
|
||||
|
||||
bool
|
||||
tagMatchNoCrpr(const Tag *tag1,
|
||||
Tag::matchNoCrpr(const Tag *tag1,
|
||||
const Tag *tag2)
|
||||
{
|
||||
const ClkInfo *clk_info1 = tag1->clkInfo();
|
||||
|
|
@ -505,11 +483,11 @@ tagMatchNoCrpr(const Tag *tag1,
|
|||
&& tag1->pathAPIndex() == tag2->pathAPIndex()
|
||||
&& tag1->isClock() == tag2->isClock()
|
||||
&& clk_info1->isGenClkSrcPath() == clk_info2->isGenClkSrcPath()
|
||||
&& tagStateEqual(tag1, tag2));
|
||||
&& Tag::stateEqual(tag1, tag2));
|
||||
}
|
||||
|
||||
bool
|
||||
tagMatchNoPathAp(const Tag *tag1,
|
||||
Tag::matchNoPathAp(const Tag *tag1,
|
||||
const Tag *tag2)
|
||||
{
|
||||
const ClkInfo *clk_info1 = tag1->clkInfo();
|
||||
|
|
@ -520,11 +498,11 @@ tagMatchNoPathAp(const Tag *tag1,
|
|||
&& tag1->isClock() == tag2->isClock()
|
||||
&& tag1->isSegmentStart() == tag2->isSegmentStart()
|
||||
&& clk_info1->isGenClkSrcPath() == clk_info2->isGenClkSrcPath()
|
||||
&& tagStateEqual(tag1, tag2));
|
||||
&& Tag::stateEqual(tag1, tag2));
|
||||
}
|
||||
|
||||
bool
|
||||
tagMatchCrpr(const Tag *tag1,
|
||||
Tag::matchCrpr(const Tag *tag1,
|
||||
const Tag *tag2)
|
||||
{
|
||||
const ClkInfo *clk_info1 = tag1->clkInfo();
|
||||
|
|
@ -535,13 +513,13 @@ tagMatchCrpr(const Tag *tag1,
|
|||
&& tag1->isClock() == tag2->isClock()
|
||||
&& tag1->isSegmentStart() == tag2->isSegmentStart()
|
||||
&& clk_info1->isGenClkSrcPath() == clk_info2->isGenClkSrcPath()
|
||||
&& tagStateEqualCrpr(tag1, tag2));
|
||||
&& stateEqualCrpr(tag1, tag2));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
static int
|
||||
tagStateCmp(const Tag *tag1,
|
||||
int
|
||||
Tag::stateCmp(const Tag *tag1,
|
||||
const Tag *tag2)
|
||||
{
|
||||
ExceptionStateSet *states1 = tag1->states();
|
||||
|
|
@ -571,53 +549,24 @@ tagStateCmp(const Tag *tag1,
|
|||
&& state_iter2.hasNext()) {
|
||||
ExceptionState *state1 = state_iter1.next();
|
||||
ExceptionState *state2 = state_iter2.next();
|
||||
if (state1 < state2)
|
||||
if (exceptionStateLess(state1, state2))
|
||||
return -1;
|
||||
if (state1 > state2)
|
||||
if (exceptionStateLess(state2, state1))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
tagStateEqual(const Tag *tag1,
|
||||
Tag::stateEqual(const Tag *tag1,
|
||||
const Tag *tag2)
|
||||
{
|
||||
return tagStateEqual(tag1->states(), tag2->states());
|
||||
}
|
||||
|
||||
static bool
|
||||
tagStateEqual(ExceptionStateSet *states1,
|
||||
ExceptionStateSet *states2)
|
||||
{
|
||||
bool states_null1 = (states1 == nullptr || states1->empty());
|
||||
bool states_null2 = (states2 == nullptr || states2->empty());
|
||||
if (states_null1 && states_null2)
|
||||
return true;
|
||||
else if (states_null1 != states_null2)
|
||||
return false;
|
||||
|
||||
size_t state_size1 = states1->size();
|
||||
size_t state_size2 = states2->size();
|
||||
if (state_size1 == state_size2) {
|
||||
ExceptionStateSet::Iterator state_iter1(states1);
|
||||
ExceptionStateSet::Iterator state_iter2(states2);
|
||||
while (state_iter1.hasNext()
|
||||
&& state_iter2.hasNext()) {
|
||||
ExceptionState *state1 = state_iter1.next();
|
||||
ExceptionState *state2 = state_iter2.next();
|
||||
if (state1 != state2)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return stateCmp(tag1, tag2) == 0;
|
||||
}
|
||||
|
||||
// Match loop exception states only for crpr min/max paths.
|
||||
static bool
|
||||
tagStateEqualCrpr(const Tag *tag1,
|
||||
bool
|
||||
Tag::stateEqualCrpr(const Tag *tag1,
|
||||
const Tag *tag2)
|
||||
{
|
||||
ExceptionStateSet *states1 = tag1->states();
|
||||
|
|
@ -653,17 +602,28 @@ tagStateEqualCrpr(const Tag *tag1,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
TagHash::TagHash(const StaState *sta) :
|
||||
sta_(sta)
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
TagHash::operator()(const Tag *tag) const
|
||||
{
|
||||
return tag->hash();
|
||||
bool crpr_on = sta_->crprActive();
|
||||
return tag->matchHash(crpr_on, sta_);
|
||||
}
|
||||
|
||||
TagEqual::TagEqual(const StaState *sta) :
|
||||
sta_(sta)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
TagEqual::operator()(const Tag *tag1,
|
||||
const Tag *tag2) const
|
||||
{
|
||||
return tagEqual(tag1, tag2);
|
||||
return Tag::equal(tag1, tag2, sta_);
|
||||
}
|
||||
|
||||
TagMatchHash::TagMatchHash(bool match_crpr_clk_pin,
|
||||
|
|
@ -690,7 +650,7 @@ bool
|
|||
TagMatchEqual::operator()(const Tag *tag1,
|
||||
const Tag *tag2) const
|
||||
{
|
||||
return tagMatch(tag1, tag2, match_crpr_clk_pin_, sta_);
|
||||
return Tag::match(tag1, tag2, match_crpr_clk_pin_, sta_);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public:
|
|||
Tag(TagIndex index,
|
||||
int rf_index,
|
||||
PathAPIndex path_ap_index,
|
||||
ClkInfo *clk_info,
|
||||
const ClkInfo *clk_info,
|
||||
bool is_clk,
|
||||
InputDelay *input_delay,
|
||||
bool is_segment_start,
|
||||
|
|
@ -66,7 +66,7 @@ public:
|
|||
std::string to_string(bool report_index,
|
||||
bool report_rf_min_max,
|
||||
const StaState *sta) const;
|
||||
ClkInfo *clkInfo() const { return clk_info_; }
|
||||
const ClkInfo *clkInfo() const { return clk_info_; }
|
||||
bool isClock() const { return is_clk_; }
|
||||
const ClockEdge *clkEdge() const;
|
||||
const Clock *clock() const;
|
||||
|
|
@ -85,15 +85,48 @@ public:
|
|||
bool isLoop() const { return is_loop_; }
|
||||
bool isFilter() const { return is_filter_; }
|
||||
bool isSegmentStart() const { return is_segment_start_; }
|
||||
size_t hash() const { return hash_; }
|
||||
size_t hash(bool match_crpr_clk_pin,
|
||||
const StaState *sta) const;
|
||||
size_t matchHash(bool match_crpr_clk_pin,
|
||||
const StaState *sta) const;
|
||||
|
||||
static int cmp(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
const StaState *sta);
|
||||
static int matchCmp(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
bool match_clk_clk_pin,
|
||||
const StaState *sta);
|
||||
static bool match(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
bool match_crpr_clk_pin,
|
||||
const StaState *sta);
|
||||
static bool equal(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
const StaState *sta);
|
||||
static bool matchNoPathAp(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
static bool matchCrpr(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
static bool matchNoCrpr(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
|
||||
protected:
|
||||
void findHash();
|
||||
|
||||
// Match tag clock edge, clock driver and exception states but not clk info.
|
||||
static bool match(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
const StaState *sta);
|
||||
static bool stateEqual(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
static int stateCmp(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
static bool stateEqualCrpr(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
|
||||
private:
|
||||
ClkInfo *clk_info_;
|
||||
const ClkInfo *clk_info_;
|
||||
InputDelay *input_delay_;
|
||||
ExceptionStateSet *states_;
|
||||
size_t hash_;
|
||||
|
|
@ -130,51 +163,22 @@ public:
|
|||
class TagHash
|
||||
{
|
||||
public:
|
||||
TagHash(const StaState *sta);
|
||||
size_t operator()(const Tag *tag) const;
|
||||
|
||||
private:
|
||||
const StaState *sta_;
|
||||
};
|
||||
|
||||
class TagEqual
|
||||
{
|
||||
public:
|
||||
TagEqual(const StaState *sta);
|
||||
bool operator()(const Tag *tag1,
|
||||
const Tag *tag2) const;
|
||||
|
||||
private:
|
||||
const StaState *sta_;
|
||||
};
|
||||
|
||||
bool
|
||||
tagEqual(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
int
|
||||
tagCmp(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
const StaState *sta);
|
||||
|
||||
// Match tag clock edge, clock driver and exception states but not clk info.
|
||||
bool
|
||||
tagMatch(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
const StaState *sta);
|
||||
bool
|
||||
tagMatch(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
bool match_crpr_clk_pin,
|
||||
const StaState *sta);
|
||||
bool
|
||||
tagStateEqual(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
bool
|
||||
tagMatchNoCrpr(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
int
|
||||
tagMatchCmp(const Tag *tag1,
|
||||
const Tag *tag2,
|
||||
bool match_clk_clk_pin,
|
||||
const StaState *sta);
|
||||
|
||||
bool
|
||||
tagMatchNoPathAp(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
bool
|
||||
tagMatchCrpr(const Tag *tag1,
|
||||
const Tag *tag2);
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -41,9 +41,10 @@ TagGroup::TagGroup(TagGroupIndex index,
|
|||
bool has_clk_tag,
|
||||
bool has_genclk_src_tag,
|
||||
bool has_filter_tag,
|
||||
bool has_loop_tag) :
|
||||
bool has_loop_tag,
|
||||
const StaState *sta) :
|
||||
path_index_map_(path_index_map),
|
||||
hash_(pathIndexMapHash(path_index_map)),
|
||||
hash_(hash(path_index_map, sta)),
|
||||
ref_count_(0),
|
||||
index_(index),
|
||||
has_clk_tag_(has_clk_tag),
|
||||
|
|
@ -54,9 +55,10 @@ TagGroup::TagGroup(TagGroupIndex index,
|
|||
{
|
||||
}
|
||||
|
||||
TagGroup::TagGroup(TagGroupBldr *tag_bldr) :
|
||||
TagGroup::TagGroup(TagGroupBldr *tag_bldr,
|
||||
const StaState *sta) :
|
||||
path_index_map_(&tag_bldr->pathIndexMap()),
|
||||
hash_(pathIndexMapHash(path_index_map_)),
|
||||
hash_(hash(path_index_map_, sta)),
|
||||
ref_count_(0),
|
||||
own_path_map_(false)
|
||||
{
|
||||
|
|
@ -81,11 +83,13 @@ TagGroup::decrRefCount()
|
|||
}
|
||||
|
||||
size_t
|
||||
TagGroup::pathIndexMapHash(PathIndexMap *path_index_map)
|
||||
TagGroup::hash(PathIndexMap *path_index_map,
|
||||
const StaState *sta)
|
||||
{
|
||||
bool crpr_on = sta->crprActive();
|
||||
size_t hash = 0;
|
||||
for (auto const [tag, path_index] : *path_index_map)
|
||||
hash += tag->hash();
|
||||
hash += tag->hash(crpr_on, sta);
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
|
@ -268,7 +272,7 @@ TagGroupBldr::insertPath(Tag *tag,
|
|||
if (tag->isGenClkSrcPath())
|
||||
has_genclk_src_tag_ = true;
|
||||
if (tag->isFilter()
|
||||
|| tag->clkInfo()->refsFilter(sta_))
|
||||
|| tag->clkInfo()->crprPathRefsFilter())
|
||||
has_filter_tag_ = true;
|
||||
if (tag->isLoop())
|
||||
has_loop_tag_ = true;
|
||||
|
|
@ -289,7 +293,7 @@ TagGroupBldr::makeTagGroup(TagGroupIndex index,
|
|||
{
|
||||
return new TagGroup(index, makePathIndexMap(sta),
|
||||
has_clk_tag_, has_genclk_src_tag_, has_filter_tag_,
|
||||
has_loop_tag_);
|
||||
has_loop_tag_, sta);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -339,10 +343,7 @@ pathIndexMapEqual(const PathIndexMap *path_index_map1,
|
|||
size_t path_index2;
|
||||
bool exists2;
|
||||
path_index_map2->findKey(tag1, tag2, path_index2, exists2);
|
||||
if (!exists2
|
||||
// ArrivalMap equal function is TagMatchEqual, so make sure
|
||||
// the tag is an exact match.
|
||||
|| tag2 != tag1)
|
||||
if (!exists2)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -47,9 +47,11 @@ public:
|
|||
bool has_clk_tag,
|
||||
bool has_genclk_src_tag,
|
||||
bool has_filter_tag,
|
||||
bool has_loop_tag);
|
||||
bool has_loop_tag,
|
||||
const StaState *sta);
|
||||
// For Search::findTagGroup to probe.
|
||||
TagGroup(TagGroupBldr *tag_bldr);
|
||||
TagGroup(TagGroupBldr *tag_bldr,
|
||||
const StaState *sta);
|
||||
~TagGroup();
|
||||
TagGroupIndex index() const { return index_; }
|
||||
size_t hash() const { return hash_; }
|
||||
|
|
@ -72,7 +74,8 @@ public:
|
|||
int refCount() const { return ref_count_; }
|
||||
|
||||
protected:
|
||||
static size_t pathIndexMapHash(PathIndexMap *path_index_map);
|
||||
static size_t hash(PathIndexMap *path_index_map,
|
||||
const StaState *sta);
|
||||
|
||||
// tag -> path index
|
||||
PathIndexMap *path_index_map_;
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ VisitPathEnds::visitCheckEnd(const Pin *pin,
|
|||
tgt_clk_path_ap, this);
|
||||
while (tgt_clk_path_iter.hasNext()) {
|
||||
Path *tgt_clk_path = tgt_clk_path_iter.next();
|
||||
ClkInfo *tgt_clk_info = tgt_clk_path->clkInfo(this);
|
||||
const ClkInfo *tgt_clk_info = tgt_clk_path->clkInfo(this);
|
||||
const ClockEdge *tgt_clk_edge = tgt_clk_path->clkEdge(this);
|
||||
const Clock *tgt_clk = tgt_clk_path->clock(this);
|
||||
const Pin *tgt_pin = tgt_clk_vertex->pin();
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ PathGroupPathVisitor::visitFromToPath(const Pin *,
|
|||
VertexPathIterator to_iter(to_vertex, to_rf, path_ap, this);
|
||||
while (to_iter.hasNext()) {
|
||||
Path *to_path = to_iter.next();
|
||||
if (tagMatchNoCrpr(to_path->tag(this), to_tag)
|
||||
if (Tag::matchNoCrpr(to_path->tag(this), to_tag)
|
||||
&& matching_paths->hasKey(to_path)) {
|
||||
debugPrint(debug_, "visit_path_group", 2,
|
||||
"match crpr %s %s -> %s %s",
|
||||
|
|
|
|||
Loading…
Reference in New Issue