BIGFEATURE: Add `set_path_margin` command (#469)

* Implement set_path_margin command

Adds a new set_path_margin SDC command that applies a signed slack
adjustment to the capture-clock side of timing paths. A positive
margin tightens the path (harder to meet) and a negative margin
loosens it. Supports -setup/-hold/-from/-through/-to scoping,
priority/override semantics matching other exceptions, text and
JSON report output, and write_sdc serialisation.

Adapted from Silimate PR #57; uses upstream/master Mode/Scene and
string_view APIs. Test uses unset_path_exceptions in place of the
Silimate-only reset_path alias.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix nested delaySum call indentation to match project style.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Address review: store PathMargin on PathEnd, split tests

Keep the path margin exception on PathEndClkConstrained, add
PathEnd::hasPathMargin for report gating, and split the monolithic
regression into set_path_margin1–6. Rebased onto upstream/master and
document the command in ChangeLog.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Document set_path_margin in OpenSTA.fodt/pdf

Add the command reference, index entry, and note that
unset_path_exceptions also clears path margin exceptions.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Drop [[nodiscard]] from PathEnd::hasPathMargin.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Akash Levy 2026-08-09 09:29:03 -07:00 committed by GitHub
parent 3f4b337e30
commit e9c075ab94
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 1030 additions and 28 deletions

View File

@ -4,6 +4,20 @@ OpenSTA Timing Analyzer Release Notes
This file summarizes user visible changes for each release.
See ApiChangeLog.txt for changes to the STA api.
2026/08/02
----------
The set_path_margin command applies a signed slack adjustment to the
capture-clock side of matching timing paths. A positive margin
tightens the path and a negative margin loosens it.
set_path_margin [-setup] [-hold] [-rise] [-fall]
[-from from_list|-rise_from from_list|-fall_from from_list]
[-through through_list|-rise_through through_list|-fall_through through_list]
[-to to_list|-rise_to to_list|-fall_to to_list]
[-comment comment]
margin
2026/07/20
----------

View File

@ -12579,6 +12579,91 @@
</table:table>
<text:p text:style-name="Body_20_first">The <text:span text:style-name="Command">set_output_delay</text:span> command is used to specify <text:span text:style-name="T280">the external delay to </text:span><text:span text:style-name="T286">a setup/</text:span><text:span text:style-name="T287">hold</text:span><text:span text:style-name="T286"> check on an output port or internal pin </text:span><text:span text:style-name="T288">that is clocked by </text:span><text:span text:style-name="Command_20_Argument"><text:span text:style-name="T288">clock</text:span></text:span><text:span text:style-name="T286">.</text:span> Unless the <text:span text:style-name="Command">-add_delay</text:span> option is specified any existing <text:span text:style-name="T288">output delays are</text:span> replaced.</text:p>
<text:p text:style-name="P276">The <text:span text:style-name="Command">reference_pin</text:span> option is used to specify a <text:span text:style-name="T287">timing check</text:span> with respect to the arrival on a pin in the clock network. For propagated clocks, the <text:span text:style-name="T287">timing check</text:span> is relative to the clock arrival time at the reference pin (the clock source latency and network latency from the clock source to the reference pin). For ideal clocks, <text:span text:style-name="T287">the timing check</text:span> is relative to the reference pin clock source latency. With the <text:span text:style-name="Command">-clock_fall</text:span> flag the <text:span text:style-name="T287">timing check</text:span> is relative to the falling <text:span text:style-name="T280">edge</text:span> <text:span text:style-name="T280">of</text:span> the reference pin. If no clocks arrive at the reference pin the <text:span text:style-name="Command">set_output_delay</text:span> command is ignored. If <text:span text:style-name="Default_20_Paragraph_20_Font">no </text:span><text:span text:style-name="Command">-clock</text:span> is specified the <text:span text:style-name="T287">timing check</text:span> is with respect to all clocks that arrive at the reference pin. The <text:span text:style-name="Command">-source_latency_included</text:span> and <text:span text:style-name="Command">-network_latency_included</text:span> options cannot be used with <text:span text:style-name="Command">-reference_pin</text:span>.</text:p>
<table:table table:name="TablePathMargin" table:style-name="Table114">
<table:table-column table:style-name="Table114.A"/>
<table:table-column table:style-name="Table114.B"/>
<table:table-row table:style-name="Table114.1">
<table:table-cell table:style-name="Table114.A1" office:value-type="string">
<text:p text:style-name="P42"><text:alphabetical-index-mark-start text:id="IMark31489446320"/><text:span text:style-name="Command_20_Heading">set_path_margin</text:span><text:alphabetical-index-mark-end text:id="IMark31489446320"/></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table114.A1" office:value-type="string">
<text:p text:style-name="P42">[-setup]<text:line-break/>[-hold]<text:line-break/>[-rise]<text:line-break/>[-fall]<text:line-break/>[-from <text:span text:style-name="T32">from_list</text:span>]<text:line-break/>[-rise_from <text:span text:style-name="T32">from_list</text:span>]<text:line-break/>[-fall_from <text:span text:style-name="T32">from_list</text:span>]<text:line-break/>[-through <text:span text:style-name="T32">through_list</text:span>]<text:line-break/>[-rise_through <text:span text:style-name="T32">through_list</text:span>]<text:line-break/>[-fall_through <text:span text:style-name="T32">through_list</text:span>]<text:line-break/>[-to <text:span text:style-name="T32">to_list</text:span>]<text:line-break/>[-rise_to <text:span text:style-name="T32">to_list</text:span>]<text:line-break/>[-fall_to <text:span text:style-name="T32">to_list</text:span>]<text:line-break/>[-comment <text:span text:style-name="T32">comment</text:span>]<text:line-break/><text:span text:style-name="T32">margin</text:span></text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table114.1">
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="P42">-setup</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="Example"><text:span text:style-name="Default_20_Paragraph_20_Font">Apply the margin to setup checks.</text:span></text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table114.1">
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="P42">-hold</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="Example"><text:span text:style-name="Default_20_Paragraph_20_Font">Apply the margin to hold checks.</text:span></text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table114.1">
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="P42">-rise</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="Example"><text:span text:style-name="Default_20_Paragraph_20_Font">Apply the margin to rising path edges.</text:span></text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table114.1">
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="P42">-fall</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="Example"><text:span text:style-name="Default_20_Paragraph_20_Font">Apply the margin to falling path edges.</text:span></text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table114.1">
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="P48"><text:span text:style-name="T30">-</text:span><text:span text:style-name="T272">from </text:span>from_list</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="Example"><text:span text:style-name="Default_20_Paragraph_20_Font">A list of clocks, instances, ports or pins.</text:span></text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table114.1">
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="P48"><text:span text:style-name="T30">-</text:span><text:span text:style-name="T272">through </text:span>through_list</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="Example"><text:span text:style-name="Default_20_Paragraph_20_Font">A list of instances, pins or nets.</text:span></text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table114.1">
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="P48"><text:span text:style-name="T30">-</text:span><text:span text:style-name="T272">to </text:span>to_list</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="Example"><text:span text:style-name="Default_20_Paragraph_20_Font">A list of clocks, instances, ports or pins.</text:span></text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table114.1">
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="P48">-comment comment</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="Example"><text:span text:style-name="Default_20_Paragraph_20_Font">Optional comment written by </text:span><text:span text:style-name="Command">write_sdc</text:span><text:span text:style-name="Default_20_Paragraph_20_Font">.</text:span></text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table114.1">
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="P48">margin</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table114.A2" office:value-type="string">
<text:p text:style-name="Example"><text:span text:style-name="Default_20_Paragraph_20_Font">Signed slack adjustment applied on the capture clock. A positive margin tightens the path and a negative margin loosens it.</text:span></text:p>
</table:table-cell>
</table:table-row>
</table:table>
<text:p text:style-name="Body_20_first">The <text:span text:style-name="Command">set_path_margin</text:span> command applies a signed slack adjustment to matching timing paths on the capture-clock side. A positive margin makes the path harder to meet and a negative margin makes it easier. If neither <text:span text:style-name="Command">-setup</text:span> nor <text:span text:style-name="Command">-hold</text:span> is specified the margin applies to both. See <text:span text:style-name="Command">set_false_path</text:span> for a description of allowed <text:span text:style-name="Command_20_Argument">from_list</text:span>, <text:span text:style-name="Command_20_Argument">through_list</text:span> and <text:span text:style-name="Command_20_Argument">to_list</text:span> objects. At least one of <text:span text:style-name="Command">-from</text:span>, <text:span text:style-name="Command">-through</text:span>, or <text:span text:style-name="Command">-to</text:span> is required. Matching exceptions are removed with <text:span text:style-name="Command">unset_path_exceptions</text:span>.</text:p>
<table:table table:name="Table115" table:style-name="Table115">
<table:table-column table:style-name="Table115.A"/>
<table:table-column table:style-name="Table115.B"/>
@ -13724,7 +13809,7 @@
</table:table-cell>
</table:table-row>
</table:table>
<text:p text:style-name="Body_20_first">The unset_path_exceptions command removes any matching set_false_path, set_multicycle_path, set_max_delay, and set_min_delay exceptions.</text:p>
<text:p text:style-name="Body_20_first">The <text:span text:style-name="Command">unset_path_exceptions</text:span> command removes any matching <text:span text:style-name="Command">set_false_path</text:span>, <text:span text:style-name="Command">set_multicycle_path</text:span>, <text:span text:style-name="Command">set_max_delay</text:span>, <text:span text:style-name="Command">set_min_delay</text:span>, and <text:span text:style-name="Command">set_path_margin</text:span> exceptions.</text:p>
<text:p text:style-name="P304"/>
<table:table table:name="Table164" table:style-name="Table164">
<table:table-column table:style-name="Table164.A"/>
@ -14587,6 +14672,7 @@
<text:p text:style-name="P339">set_multicycle_path<text:tab/>67</text:p>
<text:p text:style-name="P339">set_operating_conditions<text:tab/>68</text:p>
<text:p text:style-name="P339">set_output_delay<text:tab/>69</text:p>
<text:p text:style-name="P339">set_path_margin<text:tab/>70</text:p>
<text:p text:style-name="P339">set_port_fanout_number<text:tab/>70</text:p>
<text:p text:style-name="P339">set_power_activity<text:tab/>70</text:p>
<text:p text:style-name="P339">set_propagated_clock<text:tab/>71</text:p>

Binary file not shown.

View File

@ -66,6 +66,7 @@ public:
virtual bool isLoop() const { return false; }
virtual bool isMultiCycle() const { return false; }
virtual bool isPathDelay() const { return false; }
virtual bool isPathMargin() const { return false; }
virtual bool isGroupPath() const { return false; }
virtual bool isFilter() const { return false; }
virtual ExceptionPathType type() const = 0;
@ -101,6 +102,7 @@ public:
static int pathDelayPriority() { return 3000; }
static int multiCyclePathPriority() { return 2000; }
static int filterPathPriority() { return 1000; }
static int pathMarginPriority() { return 500; }
static int groupPathPriority() { return 0; }
// Compare the value (path delay or cycle count) to another exception
// of the same priority. Because the exception "values" are floats,
@ -130,6 +132,7 @@ public:
virtual bool useEndClk() const { return false; }
virtual int pathMultiplier() const { return 0; }
virtual float delay() const { return 0.0; }
virtual float margin() const { return 0.0; }
virtual std::string_view name() const { return {}; }
virtual bool isDefault() const { return false; }
virtual bool ignoreClkLatency() const { return false; }
@ -227,6 +230,35 @@ protected:
float delay_;
};
// set_path_margin
class PathMargin : public ExceptionPath
{
public:
PathMargin(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
float margin,
bool own_pts,
std::string_view comment);
ExceptionPath *clone(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool own_pts) override;
bool isPathMargin() const override { return true; }
ExceptionPathType type() const override
{ return ExceptionPathType::path_margin; }
std::string_view typeString() const override;
bool mergeable(ExceptionPath *exception) const override;
bool overrides(ExceptionPath *exception) const override;
float margin() const override { return margin_; }
int typePriority() const override;
bool tighterThan(ExceptionPath *exception) const override;
protected:
float margin_;
};
// set_multicycle_path
class MultiCyclePath : public ExceptionPath
{

View File

@ -135,6 +135,10 @@ public:
// Target clock uncertainty + inter-clk uncertainty.
virtual float targetClkUncertainty(const StaState *sta) const;
virtual float targetClkMcpAdjustment(const StaState *sta) const;
// Target clock path margin (set_path_margin).
virtual float targetClkPathMargin(const StaState *sta) const;
virtual bool hasPathMargin() const { return false; }
virtual PathMargin *pathMargin() const { return nullptr; }
virtual const TimingRole *checkRole(const StaState *sta) const;
const TimingRole *checkGenericRole(const StaState *sta) const;
virtual bool pathDelayMarginIsExternal() const;
@ -260,6 +264,9 @@ public:
float targetNonInterClkUncertainty(const StaState *sta) const override;
float interClkUncertainty(const StaState *sta) const override;
float targetClkUncertainty(const StaState *sta) const override;
float targetClkPathMargin(const StaState *sta) const override;
bool hasPathMargin() const override { return path_margin_ != nullptr; }
PathMargin *pathMargin() const override { return path_margin_; }
Crpr crpr(const StaState *sta) const override;
Required requiredTime(const StaState *sta) const override;
Slack slack(const StaState *sta) const override;
@ -270,7 +277,8 @@ public:
protected:
PathEndClkConstrained(Path *path,
Path *clk_path);
Path *clk_path,
PathMargin *path_margin);
float sourceClkOffset(const ClockEdge *src_clk_edge,
const ClockEdge *tgt_clk_edge,
const TimingRole *check_role,
@ -280,6 +288,7 @@ protected:
virtual Required requiredTimeNoCrpr(const StaState *sta) const;
Path *clk_path_;
PathMargin *path_margin_;
mutable Crpr crpr_;
mutable bool crpr_valid_{false};
};
@ -295,7 +304,8 @@ public:
protected:
PathEndClkConstrainedMcp(Path *path,
Path *clk_path,
MultiCyclePath *mcp);
MultiCyclePath *mcp,
PathMargin *path_margin);
float checkMcpAdjustment(const Path *path,
const ClockEdge *tgt_clk_edge,
const StaState *sta) const;
@ -316,6 +326,7 @@ public:
Edge *check_edge,
Path *clk_path,
MultiCyclePath *mcp,
PathMargin *path_margin,
const StaState *sta);
PathEnd *copy() const override;
Type type() const override;
@ -348,6 +359,7 @@ public:
Edge *check_edge,
Path *disable_path,
MultiCyclePath *mcp,
PathMargin *path_margin,
PathDelay *path_delay,
const StaState *sta);
Type type() const override;
@ -404,6 +416,7 @@ public:
Path *path,
Path *clk_path,
MultiCyclePath *mcp,
PathMargin *path_margin,
const StaState *sta);
PathEnd *copy() const override;
Type type() const override;
@ -443,6 +456,7 @@ public:
Path *clk_path,
const TimingRole *check_role,
MultiCyclePath *mcp,
PathMargin *path_margin,
ArcDelay margin,
const StaState *sta);
PathEnd *copy() const override;
@ -468,6 +482,7 @@ public:
Path *data_path,
Path *data_clk_path,
MultiCyclePath *mcp,
PathMargin *path_margin,
const StaState *sta);
PathEnd *copy() const override;
Type type() const override;

View File

@ -757,6 +757,12 @@ public:
bool break_path,
float delay,
std::string_view comment);
void makePathMargin(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
float margin,
std::string_view comment);
bool pathDelaysWithoutTo() const { return path_delays_without_to_; }
// Delete matching false/multicycle/path_delay exceptions.
// Caller owns from, thrus, to exception points (and must delete them).

View File

@ -44,6 +44,7 @@ class InputDelay;
class OutputDelay;
class FalsePath;
class PathDelay;
class PathMargin;
class MultiCyclePath;
class FilterPath;
class GroupPath;
@ -69,6 +70,7 @@ class PortDelay;
enum class AnalysisType { single, bc_wc, ocv };
enum class ExceptionPathType { false_path, loop, multi_cycle, path_delay,
path_margin,
group_path, filter, any};
enum class ClockSense { positive, negative, stop };

View File

@ -654,6 +654,13 @@ public:
float delay,
std::string_view comment,
Sdc *sdc);
void makePathMargin(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
float margin,
std::string_view comment,
Sdc *sdc);
void makeGroupPath(std::string_view name,
bool is_default,
ExceptionFrom *from,

View File

@ -131,6 +131,11 @@ protected:
const Pin *pin,
const RiseFall *rf,
const MinMax *min_max);
PathMargin *pathMarginTo(const Path *path,
const Pin *pin,
const RiseFall *rf,
const ClockEdge *clk_edge,
const MinMax *min_max) const;
ExceptionPath *exceptionTo(const Path *path,
const Pin *pin,
const RiseFall *rf,

View File

@ -559,6 +559,64 @@ PathDelay::overrides(ExceptionPath *exception) const
////////////////////////////////////////////////////////////////
PathMargin::PathMargin(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
float margin,
bool own_pts,
std::string_view comment) :
ExceptionPath(from, thrus, to, min_max, own_pts,
pathMarginPriority() + fromThruToPriority(from, thrus, to),
comment),
margin_(margin)
{
}
ExceptionPath *
PathMargin::clone(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool own_pts)
{
return new PathMargin(from, thrus, to, min_max_, margin_, own_pts, comment_);
}
int
PathMargin::typePriority() const
{
return pathMarginPriority();
}
bool
PathMargin::tighterThan(ExceptionPath *) const
{
return false;
}
std::string_view
PathMargin::typeString() const
{
return "Margin";
}
bool
PathMargin::mergeable(ExceptionPath *) const
{
return false;
}
bool
PathMargin::overrides(ExceptionPath *exception) const
{
// A later set_path_margin with the same scope replaces the earlier one.
return exception->isPathMargin()
&& exception->priority() == priority_
&& exception->minMax() == min_max_;
}
////////////////////////////////////////////////////////////////
FalsePath::FalsePath(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,

View File

@ -3958,6 +3958,20 @@ Sdc::makePathDelay(ExceptionFrom *from,
addException(exception);
}
void
Sdc::makePathMargin(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
float margin,
std::string_view comment)
{
checkFromThrusTo(from, thrus, to);
PathMargin *exception = new PathMargin(from, thrus, to, min_max,
margin, true, comment);
addException(exception);
}
void
Sdc::recordPathDelayInternalFrom(ExceptionPath *exception)
{
@ -4365,7 +4379,8 @@ Sdc::addException1(ExceptionPath *exception)
void
Sdc::addException2(ExceptionPath *exception)
{
if (exception->isMultiCycle() || exception->isPathDelay())
if (exception->isMultiCycle() || exception->isPathDelay()
|| exception->isPathMargin())
deleteMatchingExceptions(exception);
recordException(exception);
mergeException(exception);

View File

@ -838,6 +838,19 @@ make_path_delay(ExceptionFrom *from,
delay, std::move(comment), sdc);
}
void
make_path_margin(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
float margin,
std::string_view comment)
{
Sta *sta = Sta::sta();
Sdc *sdc = sta->cmdSdc();
sta->makePathMargin(from, thrus, to, min_max, margin, comment, sdc);
}
void
reset_path_cmd(ExceptionFrom *
from, ExceptionThruSeq *thrus,

View File

@ -2430,6 +2430,61 @@ proc set_min_delay { args } {
################################################################
define_cmd_args "set_path_margin" \
{[-setup] [-hold] [-rise] [-fall] [-comment comment]\
[-from from_list] [-rise_from from_list] [-fall_from from_list]\
[-through|-thr|-th through_list] [-rise_through|-rise_thr|-rise_th through_list]\
[-fall_through|-fall_thr|-fall_th through_list]\
[-to to_list] [-rise_to to_list] [-fall_to to_list] margin}
proc set_path_margin { args } {
parse_key_args "set_path_margin" args \
keys {-from -rise_from -fall_from -to -rise_to -fall_to -comment} \
flags {-rise -fall -setup -hold} 0
# Applies to setup, hold, or both.
set min_max "min_max"
if { [info exists flags(-setup)] && ![info exists flags(-hold)] } {
set min_max "max"
} elseif { [info exists flags(-hold)] && ![info exists flags(-setup)] } {
set min_max "min"
}
# Validate arguments.
set cmd "set_path_margin"
set arg_error 0
set from [parse_from_arg keys arg_error]
set thrus [parse_thrus_arg args arg_error]
set to [parse_to_arg keys flags arg_error]
check_exception_pins $from $to
if { $arg_error } {
delete_from_thrus_to $from $thrus $to
return
}
# Validate margin value count and argument type.
check_for_key_args $cmd args
if { [llength $args] == 0 } {
delete_from_thrus_to $from $thrus $to
sta_error 1800 "missing margin argument."
} elseif { [llength $args] > 1 } {
sta_warn 1801 "'$args' ignored."
}
if { $from == "NULL" && $thrus == "" && $to == "NULL" } {
delete_from_thrus_to $from $thrus $to
sta_error 1802 "-from, -through or -to required."
}
# Parse margin value.
set margin [lindex $args 0]
check_float "set_path_margin margin" $margin
set margin [time_ui_sta $margin]
set comment [parse_comment_key keys]
make_path_margin $from $thrus $to $min_max $margin $comment
}
################################################################
define_cmd_args "set_min_pulse_width" {[-low] [-high] value [objects]}
proc set_min_pulse_width { args } {

View File

@ -1231,6 +1231,10 @@ WriteSdc::writeExceptionCmd(ExceptionPath *exception) const
if (exception->ignoreClkLatency())
sta::print(stream_, " -ignore_clock_latency");
}
else if (exception->isPathMargin()) {
sta::print(stream_, "set_path_margin");
writeSetupHoldFlag(exception->minMax());
}
else if (exception->isGroupPath()) {
if (exception->isDefault())
sta::print(stream_, "group_path -default");
@ -1251,6 +1255,10 @@ WriteSdc::writeExceptionValue(ExceptionPath *exception) const
sta::print(stream_, " ");
writeTime(exception->delay());
}
else if (exception->isPathMargin()) {
sta::print(stream_, " ");
writeTime(exception->margin());
}
}
void

View File

@ -222,6 +222,12 @@ PathEnd::targetClkMcpAdjustment(const StaState *) const
return 0.0;
}
float
PathEnd::targetClkPathMargin(const StaState *) const
{
return 0.0;
}
const TimingRole *
PathEnd::checkRole(const StaState *) const
{
@ -511,9 +517,11 @@ PathEndUnconstrained::typeName() const
////////////////////////////////////////////////////////////////
PathEndClkConstrained::PathEndClkConstrained(Path *path,
Path *clk_path) :
Path *clk_path,
PathMargin *path_margin) :
PathEnd(path),
clk_path_(clk_path),
path_margin_(path_margin),
crpr_(0.0)
{
}
@ -630,8 +638,9 @@ PathEndClkConstrained::targetClkArrivalNoCrpr(const StaState *sta) const
targetClkPath(),
checkRole(sta),
sdc);
return delaySum(delaySum(clk_arrival, uncertainty, sta),
targetClkMcpAdjustment(sta), sta);
return delaySum(delaySum(delaySum(clk_arrival, uncertainty, sta),
targetClkMcpAdjustment(sta), sta),
targetClkPathMargin(sta), sta);
}
Delay
@ -692,6 +701,17 @@ PathEndClkConstrained::targetClkUncertainty(const StaState *sta) const
targetClkPath(), checkRole(sta), sdc);
}
float
PathEndClkConstrained::targetClkPathMargin(const StaState *sta) const
{
if (!path_margin_)
return 0.0;
float margin = path_margin_->margin();
if (checkRole(sta)->genericRole() == TimingRole::setup())
margin = -margin;
return margin;
}
Crpr
PathEndClkConstrained::crpr(const StaState *sta) const
{
@ -752,8 +772,9 @@ PathEndClkConstrained::exceptPathCmp(const PathEnd *path_end,
PathEndClkConstrainedMcp::PathEndClkConstrainedMcp(Path *path,
Path *clk_path,
MultiCyclePath *mcp) :
PathEndClkConstrained(path, clk_path),
MultiCyclePath *mcp,
PathMargin *path_margin) :
PathEndClkConstrained(path, clk_path, path_margin),
mcp_(mcp)
{
}
@ -921,8 +942,9 @@ PathEndCheck::PathEndCheck(Path *path,
Edge *check_edge,
Path *clk_path,
MultiCyclePath *mcp,
PathMargin *path_margin,
const StaState *) :
PathEndClkConstrainedMcp(path, clk_path, mcp),
PathEndClkConstrainedMcp(path, clk_path, mcp, path_margin),
check_arc_(check_arc),
check_edge_(check_edge)
{
@ -1082,9 +1104,10 @@ PathEndLatchCheck::PathEndLatchCheck(Path *path,
Edge *check_edge,
Path *disable_path,
MultiCyclePath *mcp,
PathMargin *path_margin,
PathDelay *path_delay,
const StaState *sta) :
PathEndCheck(path, check_arc, check_edge, nullptr, mcp, sta),
PathEndCheck(path, check_arc, check_edge, nullptr, mcp, path_margin, sta),
disable_path_(disable_path),
path_delay_(path_delay),
src_clk_arrival_(0.0)
@ -1300,9 +1323,10 @@ PathEndOutputDelay::PathEndOutputDelay(OutputDelay *output_delay,
Path *path,
Path *clk_path,
MultiCyclePath *mcp,
PathMargin *path_margin,
const StaState *) :
// No target clk_path_ for output delays.
PathEndClkConstrainedMcp(path, clk_path, mcp),
PathEndClkConstrainedMcp(path, clk_path, mcp, path_margin),
output_delay_(output_delay)
{
}
@ -1494,9 +1518,10 @@ PathEndGatedClock::PathEndGatedClock(Path *gating_ref,
Path *clk_path,
const TimingRole *check_role,
MultiCyclePath *mcp,
PathMargin *path_margin,
ArcDelay margin,
const StaState *) :
PathEndClkConstrainedMcp(gating_ref, clk_path, mcp),
PathEndClkConstrainedMcp(gating_ref, clk_path, mcp, path_margin),
check_role_(check_role),
margin_(margin)
{
@ -1564,8 +1589,9 @@ PathEndDataCheck::PathEndDataCheck(DataCheck *check,
Path *data_path,
Path *data_clk_path,
MultiCyclePath *mcp,
PathMargin *path_margin,
const StaState *sta) :
PathEndClkConstrainedMcp(data_path, nullptr, mcp),
PathEndClkConstrainedMcp(data_path, nullptr, mcp, path_margin),
data_clk_path_(data_clk_path),
check_(check)
{
@ -1711,7 +1737,7 @@ PathEndDataCheck::exceptPathCmp(const PathEnd *path_end,
PathEndPathDelay::PathEndPathDelay(PathDelay *path_delay,
Path *path,
const StaState *sta):
PathEndClkConstrained(path, nullptr),
PathEndClkConstrained(path, nullptr, nullptr),
path_delay_(path_delay),
check_arc_(nullptr),
check_edge_(nullptr),
@ -1724,7 +1750,7 @@ PathEndPathDelay::PathEndPathDelay(PathDelay *path_delay,
Path *path,
OutputDelay *output_delay,
const StaState *sta):
PathEndClkConstrained(path, nullptr),
PathEndClkConstrained(path, nullptr, nullptr),
path_delay_(path_delay),
check_arc_(nullptr),
check_edge_(nullptr),
@ -1739,7 +1765,7 @@ PathEndPathDelay::PathEndPathDelay(PathDelay *path_delay,
TimingArc *check_arc,
Edge *check_edge,
const StaState *sta) :
PathEndClkConstrained(path, clk_path),
PathEndClkConstrained(path, clk_path, nullptr),
path_delay_(path_delay),
check_arc_(check_arc),
check_edge_(check_edge),

View File

@ -1134,6 +1134,9 @@ ReportPath::reportJson(const PathEnd *end,
delayAsFloat(end->checkCrpr(this)));
result += sta::format(" \"margin\": {:.3e},\n",
delayAsFloat(end->margin(this)));
if (end->hasPathMargin())
result += sta::format(" \"path_margin\": {:.3e},\n",
end->targetClkPathMargin(this));
result += sta::format(" \"required_time\": {:.3e},\n",
delayAsFloat(end->requiredTimeOffset(this)));
result += sta::format(" \"slack\": {:.3e}\n",
@ -2569,6 +2572,11 @@ ReportPath::reportClkUncertainty(const PathEnd *end,
if (inter_uncertainty != 0.0)
reportLine("inter-clock uncertainty", inter_uncertainty,
clk_arrival, early_late);
if (end->hasPathMargin()) {
float margin = end->targetClkPathMargin(this);
clk_arrival = delaySum(clk_arrival, margin, this);
reportLine("path margin", margin, clk_arrival, early_late);
}
}
////////////////////////////////////////////////////////////////

View File

@ -2070,6 +2070,19 @@ Sta::makePathDelay(ExceptionFrom *from,
search_->arrivalsInvalid();
}
void
Sta::makePathMargin(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
float margin,
std::string_view comment,
Sdc *sdc)
{
sdc->makePathMargin(from, thrus, to, min_max, margin, comment);
search_->arrivalsInvalid();
}
void
Sta::resetPath(ExceptionFrom *from,
ExceptionThruSeq *thrus,

View File

@ -185,19 +185,22 @@ VisitPathEnds::visitCheckEnd(const Pin *pin,
&& (exception == nullptr
|| exception->isFilter()
|| exception->isGroupPath()
|| exception->isMultiCycle())) {
|| exception->isMultiCycle()
|| exception->isPathMargin())) {
MultiCyclePath *mcp=dynamic_cast<MultiCyclePath*>(exception);
PathMargin *path_margin = pathMarginTo(path, pin, end_rf,
tgt_clk_edge, min_max);
if (network_->isLatchData(pin)
&& check_role == TimingRole::setup()) {
PathEndLatchCheck path_end(path, check_arc, edge,
tgt_clk_path, mcp, nullptr,
this);
tgt_clk_path, mcp, path_margin,
nullptr, this);
visitor->visit(&path_end);
is_constrained = true;
}
else {
PathEndCheck path_end(path, check_arc, edge,
tgt_clk_path, mcp, this);
tgt_clk_path, mcp, path_margin, this);
visitor->visit(&path_end);
is_constrained = true;
}
@ -210,7 +213,7 @@ VisitPathEnds::visitCheckEnd(const Pin *pin,
if (network_->isLatchData(pin)
&& check_role == TimingRole::setup()) {
PathEndLatchCheck path_end(path, check_arc, edge,
tgt_clk_path, nullptr,
tgt_clk_path, nullptr, nullptr,
path_delay, this);
visitor->visit(&path_end);
}
@ -369,9 +372,13 @@ VisitPathEnds::visitOutputDelayEnd1(OutputDelay *output_delay,
&& (exception == nullptr
|| exception->isFilter()
|| exception->isGroupPath()
|| exception->isMultiCycle())) {
|| exception->isMultiCycle()
|| exception->isPathMargin())) {
MultiCyclePath *mcp = dynamic_cast<MultiCyclePath*>(exception);
PathEndOutputDelay path_end(output_delay, path, ref_path, mcp, this);
PathMargin *path_margin = pathMarginTo(path, pin, end_rf,
tgt_clk_edge, min_max);
PathEndOutputDelay path_end(output_delay, path, ref_path, mcp,
path_margin, this);
visitor->visit(&path_end);
is_constrained = true;
}
@ -442,13 +449,16 @@ VisitPathEnds::visitGatedClkEnd(const Pin *pin,
&& (exception == nullptr
|| exception->isFilter()
|| exception->isGroupPath()
|| exception->isMultiCycle())
|| exception->isMultiCycle()
|| exception->isPathMargin())
&& (!filtered
|| search_->matchesFilter(path, clk_edge))) {
MultiCyclePath *mcp =
dynamic_cast<MultiCyclePath *>(exception);
PathMargin *path_margin = pathMarginTo(path, pin, end_rf,
clk_edge, min_max);
PathEndGatedClock path_end(path, clk_path, check_role,
mcp, margin, this);
mcp, path_margin, margin, this);
visitor->visit(&path_end);
is_constrained = true;
}
@ -565,11 +575,15 @@ VisitPathEnds::visitDataCheckEnd1(DataCheck *check,
&& (exception == nullptr
|| exception->isFilter()
|| exception->isGroupPath()
|| exception->isMultiCycle())
|| exception->isMultiCycle()
|| exception->isPathMargin())
&& (!filtered
|| search_->matchesFilter(path, tgt_clk_edge))) {
MultiCyclePath *mcp=dynamic_cast<MultiCyclePath*>(exception);
PathEndDataCheck path_end(check, path, tgt_clk_path, mcp, this);
PathMargin *path_margin = pathMarginTo(path, pin, end_rf,
tgt_clk_edge, min_max);
PathEndDataCheck path_end(check, path, tgt_clk_path, mcp,
path_margin, this);
visitor->visit(&path_end);
is_constrained = true;
}
@ -639,6 +653,19 @@ VisitPathEnds::pathDelayTo(Path *path,
return dynamic_cast<PathDelay*>(exception);
}
PathMargin *
VisitPathEnds::pathMarginTo(const Path *path,
const Pin *pin,
const RiseFall *rf,
const ClockEdge *clk_edge,
const MinMax *min_max) const
{
ExceptionPath *exception =
search_->exceptionTo(ExceptionPathType::path_margin, path, pin, rf,
clk_edge, min_max, false, false, path->sdc(this));
return dynamic_cast<PathMargin*>(exception);
}
ExceptionPath *
VisitPathEnds::exceptionTo(const Path *path,
const Pin *pin,

View File

@ -168,6 +168,12 @@ record_public_tests {
report_checks_src_attr
report_json1
report_json2
set_path_margin1
set_path_margin2
set_path_margin3
set_path_margin4
set_path_margin5
set_path_margin6
slash_port_test
suppress_msg
user_properties

122
test/set_path_margin1.ok Normal file
View File

@ -0,0 +1,122 @@
Startpoint: r2 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r2/CK (DFF_X1)
0.0772 0.0772 v r2/Q (DFF_X1)
0.0233 0.1006 v u1/Z (BUF_X1)
0.0273 0.1278 v u2/ZN (AND2_X1)
0.0000 0.1278 v r3/D (DFF_X1)
0.1278 data arrival time
10.0000 10.0000 clock clk (rise edge)
0.0000 10.0000 clock network delay (ideal)
-0.5000 9.5000 path margin
0.0000 9.5000 clock reconvergence pessimism
9.5000 ^ r3/CK (DFF_X1)
-0.0390 9.4610 library setup time
9.4610 data required time
-------------------------------------------------------------
9.4610 data required time
-0.1278 data arrival time
-------------------------------------------------------------
9.3332 slack (MET)
setup_to_tighten -5.000e-10
Startpoint: r1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: min
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r1/CK (DFF_X1)
0.0772 0.0772 v r1/Q (DFF_X1)
0.0254 0.1026 v u2/ZN (AND2_X1)
0.0000 0.1026 v r3/D (DFF_X1)
0.1026 data arrival time
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.5000 0.5000 path margin
0.0000 0.5000 clock reconvergence pessimism
0.5000 ^ r3/CK (DFF_X1)
0.0016 0.5016 library hold time
0.5016 data required time
-------------------------------------------------------------
0.5016 data required time
-0.1026 data arrival time
-------------------------------------------------------------
-0.3990 slack (VIOLATED)
hold_to_tighten 5.000e-10
Startpoint: r2 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r2/CK (DFF_X1)
0.0772 0.0772 v r2/Q (DFF_X1)
0.0233 0.1006 v u1/Z (BUF_X1)
0.0273 0.1278 v u2/ZN (AND2_X1)
0.0000 0.1278 v r3/D (DFF_X1)
0.1278 data arrival time
10.0000 10.0000 clock clk (rise edge)
0.0000 10.0000 clock network delay (ideal)
67.0000 77.0000 path margin
0.0000 77.0000 clock reconvergence pessimism
77.0000 ^ r3/CK (DFF_X1)
-0.0390 76.9610 library setup time
76.9610 data required time
-------------------------------------------------------------
76.9610 data required time
-0.1278 data arrival time
-------------------------------------------------------------
76.8332 slack (MET)
setup_to_loosen 6.700e-08
Startpoint: r1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: min
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r1/CK (DFF_X1)
0.0772 0.0772 v r1/Q (DFF_X1)
0.0254 0.1026 v u2/ZN (AND2_X1)
0.0000 0.1026 v r3/D (DFF_X1)
0.1026 data arrival time
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
-0.5000 -0.5000 path margin
0.0000 -0.5000 clock reconvergence pessimism
-0.5000 ^ r3/CK (DFF_X1)
0.0016 -0.4984 library hold time
-0.4984 data required time
-------------------------------------------------------------
-0.4984 data required time
-0.1026 data arrival time
-------------------------------------------------------------
0.6010 slack (MET)
hold_to_loosen -5.000e-10

37
test/set_path_margin1.tcl Normal file
View File

@ -0,0 +1,37 @@
# set_path_margin -to with -setup/-hold
read_liberty ../examples/nangate45_typ.lib.gz
read_verilog ../examples/example1.v
link_design top
create_clock -name clk -period 10 {clk1 clk2 clk3}
set_input_delay -clock clk 0 {in1 in2}
proc setup_at { args } {
report_checks {*}$args -path_delay max -digits 4 -fields {} -group_path_count 1
}
proc hold_at { args } {
report_checks {*}$args -path_delay min -digits 4 -fields {} -group_path_count 1
}
proc report_json_path_margin { label path_delay args } {
set cmd [concat [list report_checks] $args \
[list -path_delay $path_delay -format json -group_path_count 1]]
with_output_to_variable json $cmd
if { [regexp {"path_margin": ([^,\n]+)} $json match margin] } {
puts "$label $margin"
} else {
puts "$label none"
}
}
set_path_margin -setup 0.50 -comment {tighten setup time} -to [get_pins r3/D]
setup_at -to [get_pins r3/D]
report_json_path_margin setup_to_tighten max -to [get_pins r3/D]
set_path_margin -hold 0.50 -comment {tighten hold time} -to [get_pins r3/D]
hold_at -to [get_pins r3/D]
report_json_path_margin hold_to_tighten min -to [get_pins r3/D]
set_path_margin -setup -67 -comment {loosen setup time} -to [get_pins r3/D]
setup_at -to [get_pins r3/D]
report_json_path_margin setup_to_loosen max -to [get_pins r3/D]
set_path_margin -hold -0.50 -comment {loosen hold time} -to [get_pins r3/D]
hold_at -to [get_pins r3/D]
report_json_path_margin hold_to_loosen min -to [get_pins r3/D]

60
test/set_path_margin2.ok Normal file
View File

@ -0,0 +1,60 @@
Startpoint: r1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r1/CK (DFF_X1)
0.0836 0.0836 ^ r1/Q (DFF_X1)
0.0277 0.1113 ^ u2/ZN (AND2_X1)
0.0000 0.1113 ^ r3/D (DFF_X1)
0.1113 data arrival time
10.0000 10.0000 clock clk (rise edge)
0.0000 10.0000 clock network delay (ideal)
-2.0000 8.0000 path margin
0.0000 8.0000 clock reconvergence pessimism
8.0000 ^ r3/CK (DFF_X1)
-0.0311 7.9689 library setup time
7.9689 data required time
-------------------------------------------------------------
7.9689 data required time
-0.1113 data arrival time
-------------------------------------------------------------
7.8576 slack (MET)
setup_from_r1 -2.000e-09
Startpoint: r2 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r2/CK (DFF_X1)
0.0772 0.0772 v r2/Q (DFF_X1)
0.0233 0.1006 v u1/Z (BUF_X1)
0.0273 0.1278 v u2/ZN (AND2_X1)
0.0000 0.1278 v r3/D (DFF_X1)
0.1278 data arrival time
10.0000 10.0000 clock clk (rise edge)
0.0000 10.0000 clock network delay (ideal)
0.0000 10.0000 clock reconvergence pessimism
10.0000 ^ r3/CK (DFF_X1)
-0.0390 9.9610 library setup time
9.9610 data required time
-------------------------------------------------------------
9.9610 data required time
-0.1278 data arrival time
-------------------------------------------------------------
9.8332 slack (MET)
setup_from_r2 none

29
test/set_path_margin2.tcl Normal file
View File

@ -0,0 +1,29 @@
# set_path_margin -from
read_liberty ../examples/nangate45_typ.lib.gz
read_verilog ../examples/example1.v
link_design top
create_clock -name clk -period 10 {clk1 clk2 clk3}
set_input_delay -clock clk 0 {in1 in2}
proc setup_at { args } {
report_checks {*}$args -path_delay max -digits 4 -fields {} -group_path_count 1
}
proc report_json_path_margin { label path_delay args } {
set cmd [concat [list report_checks] $args \
[list -path_delay $path_delay -format json -group_path_count 1]]
with_output_to_variable json $cmd
if { [regexp {"path_margin": ([^,\n]+)} $json match margin] } {
puts "$label $margin"
} else {
puts "$label none"
}
}
set_path_margin -setup 2.0 -from [get_pins r1/CK]
# Should see path margin.
setup_at -from [get_pins r1/CK] -to [get_pins r3/D]
report_json_path_margin setup_from_r1 max -from [get_pins r1/CK] -to [get_pins r3/D]
# Should not see path margin.
setup_at -from [get_pins r2/CK] -to [get_pins r3/D]
report_json_path_margin setup_from_r2 max -from [get_pins r2/CK] -to [get_pins r3/D]

60
test/set_path_margin3.ok Normal file
View File

@ -0,0 +1,60 @@
Startpoint: r1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r1/CK (DFF_X1)
0.0836 0.0836 ^ r1/Q (DFF_X1)
0.0277 0.1113 ^ u2/ZN (AND2_X1)
0.0000 0.1113 ^ r3/D (DFF_X1)
0.1113 data arrival time
10.0000 10.0000 clock clk (rise edge)
0.0000 10.0000 clock network delay (ideal)
-5.0000 5.0000 path margin
0.0000 5.0000 clock reconvergence pessimism
5.0000 ^ r3/CK (DFF_X1)
-0.0311 4.9689 library setup time
4.9689 data required time
-------------------------------------------------------------
4.9689 data required time
-0.1113 data arrival time
-------------------------------------------------------------
4.8576 slack (MET)
setup_from_to_r1 -5.000e-09
Startpoint: r2 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r2/CK (DFF_X1)
0.0772 0.0772 v r2/Q (DFF_X1)
0.0233 0.1006 v u1/Z (BUF_X1)
0.0273 0.1278 v u2/ZN (AND2_X1)
0.0000 0.1278 v r3/D (DFF_X1)
0.1278 data arrival time
10.0000 10.0000 clock clk (rise edge)
0.0000 10.0000 clock network delay (ideal)
0.0000 10.0000 clock reconvergence pessimism
10.0000 ^ r3/CK (DFF_X1)
-0.0390 9.9610 library setup time
9.9610 data required time
-------------------------------------------------------------
9.9610 data required time
-0.1278 data arrival time
-------------------------------------------------------------
9.8332 slack (MET)
setup_from_to_r2 none

29
test/set_path_margin3.tcl Normal file
View File

@ -0,0 +1,29 @@
# set_path_margin -from and -to
read_liberty ../examples/nangate45_typ.lib.gz
read_verilog ../examples/example1.v
link_design top
create_clock -name clk -period 10 {clk1 clk2 clk3}
set_input_delay -clock clk 0 {in1 in2}
proc setup_at { args } {
report_checks {*}$args -path_delay max -digits 4 -fields {} -group_path_count 1
}
proc report_json_path_margin { label path_delay args } {
set cmd [concat [list report_checks] $args \
[list -path_delay $path_delay -format json -group_path_count 1]]
with_output_to_variable json $cmd
if { [regexp {"path_margin": ([^,\n]+)} $json match margin] } {
puts "$label $margin"
} else {
puts "$label none"
}
}
set_path_margin -setup 5.0 -from [get_pins r1/CK] -to [get_pins r3/D]
# Should see path margin.
setup_at -from [get_pins r1/CK] -to [get_pins r3/D]
report_json_path_margin setup_from_to_r1 max -from [get_pins r1/CK] -to [get_pins r3/D]
# Should not see path margin.
setup_at -from [get_pins r2/CK] -to [get_pins r3/D]
report_json_path_margin setup_from_to_r2 max -from [get_pins r2/CK] -to [get_pins r3/D]

60
test/set_path_margin4.ok Normal file
View File

@ -0,0 +1,60 @@
Startpoint: r1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r1/CK (DFF_X1)
0.0836 0.0836 ^ r1/Q (DFF_X1)
0.0277 0.1113 ^ u2/ZN (AND2_X1)
0.0000 0.1113 ^ r3/D (DFF_X1)
0.1113 data arrival time
10.0000 10.0000 clock clk (rise edge)
0.0000 10.0000 clock network delay (ideal)
0.0000 10.0000 clock reconvergence pessimism
10.0000 ^ r3/CK (DFF_X1)
-0.0311 9.9689 library setup time
9.9689 data required time
-------------------------------------------------------------
9.9689 data required time
-0.1113 data arrival time
-------------------------------------------------------------
9.8576 slack (MET)
setup_through_r1 none
Startpoint: r2 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r2/CK (DFF_X1)
0.0772 0.0772 v r2/Q (DFF_X1)
0.0233 0.1006 v u1/Z (BUF_X1)
0.0273 0.1278 v u2/ZN (AND2_X1)
0.0000 0.1278 v r3/D (DFF_X1)
0.1278 data arrival time
10.0000 10.0000 clock clk (rise edge)
0.0000 10.0000 clock network delay (ideal)
-3.0000 7.0000 path margin
0.0000 7.0000 clock reconvergence pessimism
7.0000 ^ r3/CK (DFF_X1)
-0.0390 6.9610 library setup time
6.9610 data required time
-------------------------------------------------------------
6.9610 data required time
-0.1278 data arrival time
-------------------------------------------------------------
6.8332 slack (MET)
setup_through_r2 -3.000e-09

29
test/set_path_margin4.tcl Normal file
View File

@ -0,0 +1,29 @@
# set_path_margin -through
read_liberty ../examples/nangate45_typ.lib.gz
read_verilog ../examples/example1.v
link_design top
create_clock -name clk -period 10 {clk1 clk2 clk3}
set_input_delay -clock clk 0 {in1 in2}
proc setup_at { args } {
report_checks {*}$args -path_delay max -digits 4 -fields {} -group_path_count 1
}
proc report_json_path_margin { label path_delay args } {
set cmd [concat [list report_checks] $args \
[list -path_delay $path_delay -format json -group_path_count 1]]
with_output_to_variable json $cmd
if { [regexp {"path_margin": ([^,\n]+)} $json match margin] } {
puts "$label $margin"
} else {
puts "$label none"
}
}
set_path_margin -setup 3.0 -through [get_pins u1/Z]
# Should not see path margin.
setup_at -from [get_pins r1/CK] -to [get_pins r3/D]
report_json_path_margin setup_through_r1 max -from [get_pins r1/CK] -to [get_pins r3/D]
# Should see path margin.
setup_at -from [get_pins r2/CK] -to [get_pins r3/D]
report_json_path_margin setup_through_r2 max -from [get_pins r2/CK] -to [get_pins r3/D]

61
test/set_path_margin5.ok Normal file
View File

@ -0,0 +1,61 @@
Startpoint: r1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r1/CK (DFF_X1)
0.0836 0.0836 ^ r1/Q (DFF_X1)
0.0277 0.1113 ^ u2/ZN (AND2_X1)
0.0000 0.1113 ^ r3/D (DFF_X1)
0.1113 data arrival time
10.0000 10.0000 clock clk (rise edge)
0.0000 10.0000 clock network delay (ideal)
-4.0000 6.0000 path margin
0.0000 6.0000 clock reconvergence pessimism
6.0000 ^ r3/CK (DFF_X1)
-0.0311 5.9689 library setup time
5.9689 data required time
-------------------------------------------------------------
5.9689 data required time
-0.1113 data arrival time
-------------------------------------------------------------
5.8576 slack (MET)
setup_from_clk_r1 -4.000e-09
Startpoint: r2 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r2/CK (DFF_X1)
0.0772 0.0772 v r2/Q (DFF_X1)
0.0233 0.1006 v u1/Z (BUF_X1)
0.0273 0.1278 v u2/ZN (AND2_X1)
0.0000 0.1278 v r3/D (DFF_X1)
0.1278 data arrival time
10.0000 10.0000 clock clk (rise edge)
0.0000 10.0000 clock network delay (ideal)
-4.0000 6.0000 path margin
0.0000 6.0000 clock reconvergence pessimism
6.0000 ^ r3/CK (DFF_X1)
-0.0390 5.9610 library setup time
5.9610 data required time
-------------------------------------------------------------
5.9610 data required time
-0.1278 data arrival time
-------------------------------------------------------------
5.8332 slack (MET)
setup_from_clk_r2 -4.000e-09

28
test/set_path_margin5.tcl Normal file
View File

@ -0,0 +1,28 @@
# set_path_margin -from clock
read_liberty ../examples/nangate45_typ.lib.gz
read_verilog ../examples/example1.v
link_design top
create_clock -name clk -period 10 {clk1 clk2 clk3}
set_input_delay -clock clk 0 {in1 in2}
proc setup_at { args } {
report_checks {*}$args -path_delay max -digits 4 -fields {} -group_path_count 1
}
proc report_json_path_margin { label path_delay args } {
set cmd [concat [list report_checks] $args \
[list -path_delay $path_delay -format json -group_path_count 1]]
with_output_to_variable json $cmd
if { [regexp {"path_margin": ([^,\n]+)} $json match margin] } {
puts "$label $margin"
} else {
puts "$label none"
}
}
set_path_margin -setup 4.0 -from [get_clocks clk]
# Should see path margin on the clock.
setup_at -from [get_pins r1/CK] -to [get_pins r3/D]
report_json_path_margin setup_from_clk_r1 max -from [get_pins r1/CK] -to [get_pins r3/D]
setup_at -from [get_pins r2/CK] -to [get_pins r3/D]
report_json_path_margin setup_from_clk_r2 max -from [get_pins r2/CK] -to [get_pins r3/D]

60
test/set_path_margin6.ok Normal file
View File

@ -0,0 +1,60 @@
Startpoint: r1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r1/CK (DFF_X1)
0.0836 0.0836 ^ r1/Q (DFF_X1)
0.0277 0.1113 ^ u2/ZN (AND2_X1)
0.0000 0.1113 ^ r3/D (DFF_X1)
0.1113 data arrival time
10.0000 10.0000 clock clk (rise edge)
0.0000 10.0000 clock network delay (ideal)
-6.0000 4.0000 path margin
0.0000 4.0000 clock reconvergence pessimism
4.0000 ^ r3/CK (DFF_X1)
-0.0311 3.9689 library setup time
3.9689 data required time
-------------------------------------------------------------
3.9689 data required time
-0.1113 data arrival time
-------------------------------------------------------------
3.8576 slack (MET)
setup_combo_r1 -6.000e-09
Startpoint: r2 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-------------------------------------------------------------
0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 ^ r2/CK (DFF_X1)
0.0772 0.0772 v r2/Q (DFF_X1)
0.0233 0.1006 v u1/Z (BUF_X1)
0.0273 0.1278 v u2/ZN (AND2_X1)
0.0000 0.1278 v r3/D (DFF_X1)
0.1278 data arrival time
10.0000 10.0000 clock clk (rise edge)
0.0000 10.0000 clock network delay (ideal)
0.0000 10.0000 clock reconvergence pessimism
10.0000 ^ r3/CK (DFF_X1)
-0.0390 9.9610 library setup time
9.9610 data required time
-------------------------------------------------------------
9.9610 data required time
-0.1278 data arrival time
-------------------------------------------------------------
9.8332 slack (MET)
setup_combo_r2 none

31
test/set_path_margin6.tcl Normal file
View File

@ -0,0 +1,31 @@
# set_path_margin -from/-through/-to
read_liberty ../examples/nangate45_typ.lib.gz
read_verilog ../examples/example1.v
link_design top
create_clock -name clk -period 10 {clk1 clk2 clk3}
set_input_delay -clock clk 0 {in1 in2}
proc setup_at { args } {
report_checks {*}$args -path_delay max -digits 4 -fields {} -group_path_count 1
}
proc report_json_path_margin { label path_delay args } {
set cmd [concat [list report_checks] $args \
[list -path_delay $path_delay -format json -group_path_count 1]]
with_output_to_variable json $cmd
if { [regexp {"path_margin": ([^,\n]+)} $json match margin] } {
puts "$label $margin"
} else {
puts "$label none"
}
}
set_path_margin -setup 6.0 -from [get_pins r1/CK] \
-through [get_pins u2/A1] \
-to [get_pins r3/D]
# Should see path margin.
setup_at -from [get_pins r1/CK] -to [get_pins r3/D]
report_json_path_margin setup_combo_r1 max -from [get_pins r1/CK] -to [get_pins r3/D]
# Should not see path margin.
setup_at -from [get_pins r2/CK] -to [get_pins r3/D]
report_json_path_margin setup_combo_r2 max -from [get_pins r2/CK] -to [get_pins r3/D]