set_data_check support mcp, 1/2 cycle path reporting
This commit is contained in:
parent
f60b82fee5
commit
f3a50663d8
|
|
@ -142,6 +142,7 @@ public:
|
|||
virtual TimingArc *checkArc() const { return nullptr; }
|
||||
// PathEndDataCheck data clock path.
|
||||
virtual const PathVertex *dataClkPath() const { return nullptr; }
|
||||
virtual int setupDefaultCycles() const { return 1; }
|
||||
|
||||
static bool less(const PathEnd *path_end1,
|
||||
const PathEnd *path_end2,
|
||||
|
|
@ -181,6 +182,7 @@ public:
|
|||
static float checkSetupMcpAdjustment(const ClockEdge *src_clk_edge,
|
||||
const ClockEdge *tgt_clk_edge,
|
||||
const MultiCyclePath *mcp,
|
||||
int default_cycles,
|
||||
Sdc *sdc);
|
||||
|
||||
protected:
|
||||
|
|
@ -545,6 +547,8 @@ protected:
|
|||
Crpr crpr,
|
||||
bool crpr_valid);
|
||||
Arrival requiredTimeNoCrpr(const StaState *sta) const;
|
||||
// setup uses zero cycle default
|
||||
virtual int setupDefaultCycles() const { return 0; }
|
||||
|
||||
private:
|
||||
PathVertex data_clk_path_;
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ Latches::latchRequired(const Path *data_path,
|
|||
+ open_latency
|
||||
+ open_uncertainty
|
||||
+ PathEnd::checkSetupMcpAdjustment(data_clk_edge, enable_clk_edge, mcp,
|
||||
sdc_)
|
||||
1, sdc_)
|
||||
+ open_crpr;
|
||||
debugPrint3(debug_, "latch", 1, "latch data %s %s enable %s\n",
|
||||
network_->pathName(data_path->pin(this)),
|
||||
|
|
|
|||
|
|
@ -358,7 +358,9 @@ PathEnd::checkTgtClkDelay(const PathVertex *tgt_clk_path,
|
|||
const RiseFall *tgt_clk_rf = tgt_clk_edge->transition();
|
||||
insertion = search->clockInsertion(tgt_clk, tgt_src_pin, tgt_clk_rf,
|
||||
min_max, early_late, tgt_path_ap);
|
||||
if (clk_info->isPropagated()) {
|
||||
if (clk_info->isPropagated()
|
||||
// Data check target clock is always propagated.
|
||||
|| check_role->isDataCheck()) {
|
||||
// Propagated clock. Propagated arrival is seeded with
|
||||
// early_late==path_min_max insertion delay.
|
||||
Arrival clk_arrival = tgt_clk_path->arrival(sta);
|
||||
|
|
@ -824,7 +826,7 @@ PathEndClkConstrainedMcp::checkMcpAdjustment(const Path *path,
|
|||
Sdc *sdc = sta->sdc();
|
||||
if (min_max == MinMax::max())
|
||||
return PathEnd::checkSetupMcpAdjustment(src_clk_edge, tgt_clk_edge,
|
||||
mcp_, sdc);
|
||||
mcp_, setupDefaultCycles(), sdc);
|
||||
else {
|
||||
// Hold check.
|
||||
// Default arrival clock is a proxy for the target clock.
|
||||
|
|
@ -874,6 +876,7 @@ float
|
|||
PathEnd::checkSetupMcpAdjustment(const ClockEdge *src_clk_edge,
|
||||
const ClockEdge *tgt_clk_edge,
|
||||
const MultiCyclePath *mcp,
|
||||
int default_cycles,
|
||||
Sdc *sdc)
|
||||
{
|
||||
if (mcp) {
|
||||
|
|
@ -887,7 +890,7 @@ PathEnd::checkSetupMcpAdjustment(const ClockEdge *src_clk_edge,
|
|||
const ClockEdge *clk_edge =
|
||||
mcp->useEndClk() ? tgt_clk_edge : src_clk_edge;
|
||||
float period = clk_edge->clock()->period();
|
||||
return (mult - 1) * period;
|
||||
return (mult - default_cycles) * period;
|
||||
}
|
||||
else
|
||||
return 0.0;
|
||||
|
|
|
|||
|
|
@ -947,8 +947,8 @@ ReportPath::reportFull(const PathEndDataCheck *end,
|
|||
reportShort(end, expanded, result);
|
||||
reportSrcPathArrival(end, expanded, result);
|
||||
|
||||
// Capture/target clock path reporting resembles both source (reportSrcPath)
|
||||
// and target (reportTgtClk) clocks.
|
||||
// Data check target clock path reporting resembles
|
||||
// both source (reportSrcPath) and target (reportTgtClk) clocks.
|
||||
// It is like a source because it can be a non-clock path.
|
||||
// It is like a target because crpr and uncertainty are reported.
|
||||
// It is always propagated, even if the clock is ideal.
|
||||
|
|
@ -960,12 +960,14 @@ ReportPath::reportFull(const PathEndDataCheck *end,
|
|||
float src_offset = end->sourceClkOffset(this);
|
||||
Delay clk_delay = end->targetClkDelay(this);
|
||||
Arrival clk_arrival = end->targetClkArrival(this);
|
||||
float offset = delayAsFloat(clk_arrival - clk_delay + src_offset);
|
||||
ClockEdge *tgt_clk_edge = end->targetClkEdge(this);
|
||||
float prev = delayAsFloat(clk_arrival) + src_offset;
|
||||
float offset = prev - delayAsFloat(clk_delay) - tgt_clk_edge->time();
|
||||
reportPath5(data_clk_path, clk_expanded, clk_expanded.startIndex(),
|
||||
clk_expanded.size() - 1,
|
||||
data_clk_path->clkInfo(search_)->isPropagated(), false,
|
||||
// Delay to startpoint is already included.
|
||||
clk_arrival + src_offset, offset, result);
|
||||
prev, offset, result);
|
||||
}
|
||||
reportRequired(end, checkRoleReason(end), result);
|
||||
reportSlack(end, result);
|
||||
|
|
|
|||
|
|
@ -556,8 +556,8 @@ VisitPathEnds::visitDataCheckEnd1(DataCheck *check,
|
|||
|| exception->isMultiCycle())
|
||||
&& (!filtered
|
||||
|| search_->matchesFilter(path, tgt_clk_edge))) {
|
||||
// No mcp for data checks.
|
||||
PathEndDataCheck path_end(check, path, tgt_clk_path, nullptr, this);
|
||||
MultiCyclePath *mcp=dynamic_cast<MultiCyclePath*>(exception);
|
||||
PathEndDataCheck path_end(check, path, tgt_clk_path, mcp, this);
|
||||
visitor->visit(&path_end);
|
||||
is_constrained = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue