This commit is contained in:
James Cherry 2020-06-27 16:24:54 -07:00
commit cc35414dcf
4 changed files with 47 additions and 25 deletions

View File

@ -425,6 +425,7 @@ private:
// Path constrained by an output delay.
// If there is a reference pin, clk_path_ is the reference pin clock.
// If there is a path delay PathEndPathDelay is used instead of this.
class PathEndOutputDelay : public PathEndClkConstrainedMcp
{
public:
@ -555,6 +556,7 @@ private:
// Path constrained by set_min/max_delay.
// "Clocked" when path delay ends at timing check pin.
// May end at output with set_output_delay.
class PathEndPathDelay : public PathEndClkConstrained
{
public:
@ -587,6 +589,7 @@ public:
virtual PathDelay *pathDelay() const { return path_delay_; }
virtual ArcDelay margin(const StaState *sta) const;
virtual float sourceClkOffset(const StaState *sta) const;
virtual ClockEdge *targetClkEdge(const StaState *sta) const;
virtual float targetClkTime(const StaState *sta) const;
virtual Arrival targetClkArrivalNoCrpr(const StaState *sta) const;
virtual float targetClkOffset(const StaState *sta) const;
@ -594,6 +597,7 @@ public:
virtual Required requiredTime(const StaState *sta) const;
virtual int exceptPathCmp(const PathEnd *path_end,
const StaState *sta) const;
bool hasOutputDelay() const { return output_delay_ != nullptr; }
protected:
PathEndPathDelay(PathDelay *path_delay,
@ -610,8 +614,7 @@ protected:
PathDelay *path_delay_;
TimingArc *check_arc_;
Edge *check_edge_;
// Output delay is nullptr when there is no timing check or output
// delay at the endpoint.
// Output delay is nullptr when there is no output delay at the endpoint.
OutputDelay *output_delay_;
// Source clk arrival for set_min/max_delay -ignore_clk_latency.
Arrival src_clk_arrival_;

View File

@ -1845,6 +1845,17 @@ PathEnd::pathDelaySrcClkOffset(const PathRef &path,
return offset;
}
ClockEdge *
PathEndPathDelay::targetClkEdge(const StaState *sta) const
{
if (!clk_path_.isNull())
return clk_path_.clkEdge(sta);
else if (output_delay_)
return output_delay_->clkEdge();
else
return nullptr;
}
float
PathEndPathDelay::targetClkTime(const StaState *sta) const
{
@ -1858,14 +1869,12 @@ PathEndPathDelay::targetClkTime(const StaState *sta) const
Arrival
PathEndPathDelay::targetClkArrivalNoCrpr(const StaState *sta) const
{
if (!clk_path_.isNull()) {
ClockEdge *tgt_clk_edge = targetClkEdge(sta);
if (tgt_clk_edge)
return targetClkDelay(sta)
+ targetClkUncertainty(sta);
else
return clk_path_.arrival(sta);
}
ClockEdge *tgt_clk_edge = targetClkEdge(sta);
if (tgt_clk_edge)
return targetClkDelay(sta)
+ targetClkUncertainty(sta);
else if (!clk_path_.isNull())
return clk_path_.arrival(sta);
else
return 0.0;
}
@ -1887,9 +1896,7 @@ PathEndPathDelay::requiredTime(const StaState *sta) const
return src_clk_arrival_ + delay + margin(sta);
}
else {
Arrival tgt_clk_arrival = 0.0;
if (!clk_path_.isNull())
tgt_clk_arrival = targetClkArrival(sta);
Arrival tgt_clk_arrival = targetClkArrival(sta);
float src_clk_offset = sourceClkOffset(sta);
// Path delay includes target clk latency and timing check setup/hold
// margin or external departure at target.

View File

@ -705,12 +705,16 @@ void
ReportPath::reportEndpoint(const PathEndPathDelay *end,
string &result)
{
Instance *inst = network_->instance(end->vertex(this)->pin());
const char *inst_name = cmd_network_->pathName(inst);
string clk_name = tgtClkName(end);
const char *reg_desc = clkRegLatchDesc(end);
auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str());
reportEndpoint(inst_name, reason, result);
if (end->hasOutputDelay())
reportEndpointOutputDelay(end, result);
else {
Instance *inst = network_->instance(end->vertex(this)->pin());
const char *inst_name = cmd_network_->pathName(inst);
string clk_name = tgtClkName(end);
const char *reg_desc = clkRegLatchDesc(end);
auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str());
reportEndpoint(inst_name, reason, result);
}
}
void
@ -746,13 +750,11 @@ ReportPath::reportFull(const PathEndPathDelay *end,
float delay = path_delay->delay();
reportLine(delay_msg.c_str(), delay, delay, early_late, result);
if (!path_delay->ignoreClkLatency()) {
const Path *tgt_clk_path = end->targetClkPath();
if (tgt_clk_path) {
float delay = 0.0;
if (path_delay)
delay = path_delay->delay();
Clock *tgt_clk = end->targetClk(this);
if (tgt_clk) {
const Path *tgt_clk_path = end->targetClkPath();
if (reportClkPath()
&& isPropagated(tgt_clk_path))
&& isPropagated(tgt_clk_path, tgt_clk))
reportTgtClk(end, delay, result);
else {
Arrival tgt_clk_delay = end->targetClkDelay(this);
@ -832,6 +834,13 @@ ReportPath::reportFull(const PathEndOutputDelay *end,
void
ReportPath::reportEndpoint(const PathEndOutputDelay *end,
string &result)
{
reportEndpointOutputDelay(end, result);
}
void
ReportPath::reportEndpointOutputDelay(const PathEndClkConstrained *end,
string &result)
{
Vertex *vertex = end->vertex(this);
Pin *pin = vertex->pin();
@ -851,6 +860,7 @@ ReportPath::reportEndpoint(const PathEndOutputDelay *end,
if (tgt_clk) {
string clk_name = tgtClkName(end);
auto reason = stdstrPrint("internal path endpoint clocked by %s", clk_name.c_str());
reportEndpoint(pin_name, reason, result);
}
else

View File

@ -203,6 +203,8 @@ protected:
string &result);
void reportEndpoint(const PathEndOutputDelay *end,
string &result);
void reportEndpointOutputDelay(const PathEndClkConstrained *end,
string &result);
void reportEndpoint(const PathEndPathDelay *end,
string &result);
void reportEndpoint(const PathEndGatedClock *end,