timing models rm clk tree delay clk->output w/ideal clk conttext
commit 133cd3a33fe37d81a0a8f47c28c245b8de5507b4
Author: James Cherry <cherry@parallaxsw.com>
Date: Sat Dec 7 16:24:38 2024 -0800
timing models rm clk tree delay clk->output w/ideal clk conttext
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 6d17e2e29788ffc5ba65a2d0c34eb840fdd41486
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri Dec 6 16:57:31 2024 -0800
timing models rm clk tree delay from setup/hold w/ideal clk conttext
Signed-off-by: James Cherry <cherry@parallaxsw.com>
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
407ab977a0
commit
a82361ce3d
|
|
@ -52,6 +52,7 @@ public:
|
||||||
int index() const { return index_; }
|
int index() const { return index_; }
|
||||||
bool isPropagated() const { return is_propagated_; }
|
bool isPropagated() const { return is_propagated_; }
|
||||||
void setIsPropagated(bool propagated);
|
void setIsPropagated(bool propagated);
|
||||||
|
bool isIdeal() const { return !is_propagated_; }
|
||||||
// Ideal clock slew.
|
// Ideal clock slew.
|
||||||
void slew(const RiseFall *rf,
|
void slew(const RiseFall *rf,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ public:
|
||||||
// Required time with source clock offset.
|
// Required time with source clock offset.
|
||||||
virtual Required requiredTimeOffset(const StaState *sta) const;
|
virtual Required requiredTimeOffset(const StaState *sta) const;
|
||||||
virtual ArcDelay margin(const StaState *sta) const = 0;
|
virtual ArcDelay margin(const StaState *sta) const = 0;
|
||||||
|
virtual float macroClkTreeDelay(const StaState *) const { return 0.0; }
|
||||||
virtual Slack slack(const StaState *sta) const = 0;
|
virtual Slack slack(const StaState *sta) const = 0;
|
||||||
virtual Slack slackNoCrpr(const StaState *sta) const = 0;
|
virtual Slack slackNoCrpr(const StaState *sta) const = 0;
|
||||||
virtual Arrival borrow(const StaState *sta) const;
|
virtual Arrival borrow(const StaState *sta) const;
|
||||||
|
|
@ -324,6 +325,7 @@ public:
|
||||||
virtual void reportFull(ReportPath *report) const;
|
virtual void reportFull(ReportPath *report) const;
|
||||||
virtual bool isCheck() const { return true; }
|
virtual bool isCheck() const { return true; }
|
||||||
virtual ArcDelay margin(const StaState *sta) const;
|
virtual ArcDelay margin(const StaState *sta) const;
|
||||||
|
virtual float macroClkTreeDelay(const StaState *sta) const;
|
||||||
virtual TimingRole *checkRole(const StaState *sta) const;
|
virtual TimingRole *checkRole(const StaState *sta) const;
|
||||||
virtual TimingArc *checkArc() const { return check_arc_; }
|
virtual TimingArc *checkArc() const { return check_arc_; }
|
||||||
virtual int exceptPathCmp(const PathEnd *path_end,
|
virtual int exceptPathCmp(const PathEnd *path_end,
|
||||||
|
|
@ -339,6 +341,7 @@ protected:
|
||||||
Crpr crpr,
|
Crpr crpr,
|
||||||
bool crpr_valid);
|
bool crpr_valid);
|
||||||
Delay sourceClkDelay(const StaState *sta) const;
|
Delay sourceClkDelay(const StaState *sta) const;
|
||||||
|
virtual Required requiredTimeNoCrpr(const StaState *sta) const;
|
||||||
|
|
||||||
TimingArc *check_arc_;
|
TimingArc *check_arc_;
|
||||||
Edge *check_edge_;
|
Edge *check_edge_;
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,7 @@ LibertyWriter::writeHeader()
|
||||||
if (exists)
|
if (exists)
|
||||||
fprintf(stream_, " default_fanout_load : %.2f;\n", fanout_load);
|
fprintf(stream_, " default_fanout_load : %.2f;\n", fanout_load);
|
||||||
fprintf(stream_, "\n");
|
fprintf(stream_, "\n");
|
||||||
|
|
||||||
fprintf(stream_, " nom_process : %.1f;\n",
|
fprintf(stream_, " nom_process : %.1f;\n",
|
||||||
library_->nominalProcess());
|
library_->nominalProcess());
|
||||||
fprintf(stream_, " nom_temperature : %.1f;\n",
|
fprintf(stream_, " nom_temperature : %.1f;\n",
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ MakeTimingModel::makeTimingModel()
|
||||||
|
|
||||||
findTimingFromInputs();
|
findTimingFromInputs();
|
||||||
findClkedOutputPaths();
|
findClkedOutputPaths();
|
||||||
findClkInsertionDelays();
|
findClkTreeDelays();
|
||||||
|
|
||||||
cell_->finish(false, report_, debug_);
|
cell_->finish(false, report_, debug_);
|
||||||
restoreSdc();
|
restoreSdc();
|
||||||
|
|
@ -525,7 +525,7 @@ MakeTimingModel::findClkedOutputPaths()
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void
|
void
|
||||||
MakeTimingModel::findClkInsertionDelays()
|
MakeTimingModel::findClkTreeDelays()
|
||||||
{
|
{
|
||||||
Instance *top_inst = network_->topInstance();
|
Instance *top_inst = network_->topInstance();
|
||||||
Cell *top_cell = network_->cell(top_inst);
|
Cell *top_cell = network_->cell(top_inst);
|
||||||
|
|
@ -539,8 +539,7 @@ MakeTimingModel::findClkInsertionDelays()
|
||||||
if (pin && sdc_->isClock(pin)) {
|
if (pin && sdc_->isClock(pin)) {
|
||||||
lib_port->setIsClock(true);
|
lib_port->setIsClock(true);
|
||||||
ClockSet *clks = sdc_->findClocks(pin);
|
ClockSet *clks = sdc_->findClocks(pin);
|
||||||
size_t clk_count = clks->size();
|
if (clks->size() == 1) {
|
||||||
if (clk_count == 1) {
|
|
||||||
for (const Clock *clk : *clks) {
|
for (const Clock *clk : *clks) {
|
||||||
ClkDelays delays = sta_->findClkDelays(clk, true);
|
ClkDelays delays = sta_->findClkDelays(clk, true);
|
||||||
for (const MinMax *min_max : MinMax::range()) {
|
for (const MinMax *min_max : MinMax::range()) {
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ private:
|
||||||
void findTimingFromInputs();
|
void findTimingFromInputs();
|
||||||
void findTimingFromInput(Port *input_port);
|
void findTimingFromInput(Port *input_port);
|
||||||
void findClkedOutputPaths();
|
void findClkedOutputPaths();
|
||||||
void findClkInsertionDelays();
|
void findClkTreeDelays();
|
||||||
void makeClkTreePaths(LibertyPort *lib_port,
|
void makeClkTreePaths(LibertyPort *lib_port,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
TimingSense sense,
|
TimingSense sense,
|
||||||
|
|
|
||||||
|
|
@ -1048,6 +1048,40 @@ PathEndCheck::sourceClkDelay(const StaState *sta) const
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Required
|
||||||
|
PathEndCheck::requiredTimeNoCrpr(const StaState *sta) const
|
||||||
|
{
|
||||||
|
Arrival tgt_clk_arrival = targetClkArrivalNoCrpr(sta);
|
||||||
|
ArcDelay check_margin = margin(sta);
|
||||||
|
float macro_clk_tree_delay = macroClkTreeDelay(sta);
|
||||||
|
if (checkGenericRole(sta) == TimingRole::setup())
|
||||||
|
return tgt_clk_arrival - (check_margin + macro_clk_tree_delay);
|
||||||
|
else
|
||||||
|
return tgt_clk_arrival + (check_margin - macro_clk_tree_delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
PathEndCheck::macroClkTreeDelay(const StaState *sta) const
|
||||||
|
{
|
||||||
|
const ClockEdge *tgt_clk_edge = targetClkEdge(sta);
|
||||||
|
const Clock *tgt_clk = tgt_clk_edge->clock();
|
||||||
|
const Network *network = sta->network();
|
||||||
|
const Pin *clk_pin = clk_path_.pin(sta);
|
||||||
|
const Instance *inst = network->instance(clk_pin);
|
||||||
|
const LibertyCell *inst_cell = network->libertyCell(inst);
|
||||||
|
if (tgt_clk->isIdeal()
|
||||||
|
&& inst_cell && inst_cell->isMacro()) {
|
||||||
|
LibertyPort *clk_port = network->libertyPort(clk_pin);
|
||||||
|
if (clk_port) {
|
||||||
|
const MinMax *min_max = clk_path_.minMax(sta);
|
||||||
|
const RiseFall *rf = clk_path_.transition(sta);
|
||||||
|
float slew = delayAsFloat(clk_path_.slew(sta));
|
||||||
|
return clk_port->clkTreeDelay(slew, rf, min_max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PathEndLatchCheck::PathEndLatchCheck(Path *path,
|
PathEndLatchCheck::PathEndLatchCheck(Path *path,
|
||||||
|
|
|
||||||
|
|
@ -2429,10 +2429,16 @@ ReportPath::reportRequired(const PathEnd *end,
|
||||||
{
|
{
|
||||||
Required req_time = end->requiredTimeOffset(this);
|
Required req_time = end->requiredTimeOffset(this);
|
||||||
const EarlyLate *early_late = end->clkEarlyLate(this);
|
const EarlyLate *early_late = end->clkEarlyLate(this);
|
||||||
|
float macro_clk_tree_delay = end->macroClkTreeDelay(this);
|
||||||
ArcDelay margin = end->margin(this);
|
ArcDelay margin = end->margin(this);
|
||||||
if (end->minMax(this) == MinMax::max())
|
if (end->minMax(this) == MinMax::min()) {
|
||||||
margin = -margin;
|
margin = -margin;
|
||||||
reportLine(margin_msg.c_str(), margin, req_time, early_late);
|
macro_clk_tree_delay = -macro_clk_tree_delay;
|
||||||
|
}
|
||||||
|
if (macro_clk_tree_delay != 0.0)
|
||||||
|
reportLine("macro clock tree delay", -macro_clk_tree_delay,
|
||||||
|
req_time + margin, early_late);
|
||||||
|
reportLine(margin_msg.c_str(), -margin, req_time, early_late);
|
||||||
reportLine("data required time", req_time, early_late);
|
reportLine("data required time", req_time, early_late);
|
||||||
reportDashLine();
|
reportDashLine();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2139,6 +2139,18 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
||||||
if (clk == nullptr
|
if (clk == nullptr
|
||||||
|| !sdc_->clkStopPropagation(from_pin, clk)) {
|
|| !sdc_->clkStopPropagation(from_pin, clk)) {
|
||||||
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
||||||
|
|
||||||
|
// Remove clock network delay for macros created with propagated
|
||||||
|
// clocks when used in a context with ideal clocks.
|
||||||
|
if (clk && clk->isIdeal()) {
|
||||||
|
const LibertyPort *clk_port = network_->libertyPort(from_pin);
|
||||||
|
const LibertyCell *inst_cell = clk_port->libertyCell();
|
||||||
|
if (inst_cell->isMacro()) {
|
||||||
|
float slew = delayAsFloat(from_path->slew(this));
|
||||||
|
arc_delay -= clk_port->clkTreeDelay(slew, from_rf, min_max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Propagate from unclocked reg/latch clk pins, which have no
|
// Propagate from unclocked reg/latch clk pins, which have no
|
||||||
// clk but are distinguished with a segment_start flag.
|
// clk but are distinguished with a segment_start flag.
|
||||||
if ((clk_edge == nullptr
|
if ((clk_edge == nullptr
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,7 @@ init_sta()
|
||||||
initSta();
|
initSta();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear all state except network.
|
||||||
void
|
void
|
||||||
clear_sta()
|
clear_sta()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue