Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions include/sta/ExceptionPath.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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; }
Expand Down Expand Up @@ -227,6 +230,34 @@ 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);
virtual ExceptionPath *clone(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool own_pts);
virtual bool isPathMargin() const { return true; }
virtual ExceptionPathType type() const { return ExceptionPathType::path_margin; }
virtual std::string_view typeString() const;
virtual bool mergeable(ExceptionPath *exception) const;
virtual bool overrides(ExceptionPath *exception) const;
virtual float margin() const { return margin_; }
virtual int typePriority() const;
virtual bool tighterThan(ExceptionPath *exception) const;

protected:
float margin_;
};

// set_multicycle_path
class MultiCyclePath : public ExceptionPath
{
Expand Down
3 changes: 3 additions & 0 deletions include/sta/PathEnd.hh
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ 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.
virtual float targetClkPathMargin(const StaState *sta) const;
virtual const TimingRole *checkRole(const StaState *sta) const;
const TimingRole *checkGenericRole(const StaState *sta) const;
virtual bool pathDelayMarginIsExternal() const;
Expand Down Expand Up @@ -260,6 +262,7 @@ 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;
Crpr crpr(const StaState *sta) const override;
Required requiredTime(const StaState *sta) const override;
Slack slack(const StaState *sta) const override;
Expand Down
6 changes: 6 additions & 0 deletions include/sta/Sdc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,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).
Expand Down
1 change: 1 addition & 0 deletions include/sta/SdcClass.hh
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,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 };
Expand Down
7 changes: 7 additions & 0 deletions include/sta/Sta.hh
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,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,
Expand Down
58 changes: 58 additions & 0 deletions sdc/ExceptionPath.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Comment thread
stanminlee marked this conversation as resolved.

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,
Expand Down
17 changes: 16 additions & 1 deletion sdc/Sdc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4103,6 +4103,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)
{
Expand Down Expand Up @@ -4510,7 +4524,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);
Expand Down
13 changes: 13 additions & 0 deletions sdc/Sdc.i
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,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,
Expand Down
55 changes: 55 additions & 0 deletions sdc/Sdc.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -2475,6 +2475,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 } {
Expand Down
8 changes: 8 additions & 0 deletions sdc/WriteSdc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,10 @@ WriteSdc::writeExceptionCmd(ExceptionPath *exception) const
if (exception->ignoreClkLatency())
sta::print(stream_, " -ignore_clock_latency");
}
else if (exception->isPathMargin()) {
gzprintf(stream_, "set_path_margin");
writeSetupHoldFlag(exception->minMax());
}
else if (exception->isGroupPath()) {
if (exception->isDefault())
sta::print(stream_, "group_path -default");
Expand All @@ -1293,6 +1297,10 @@ WriteSdc::writeExceptionValue(ExceptionPath *exception) const
sta::print(stream_, " ");
writeTime(exception->delay());
}
else if (exception->isPathMargin()) {
gzprintf(stream_, " ");
writeTime(exception->margin());
}
}

void
Expand Down
38 changes: 32 additions & 6 deletions search/PathEnd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -630,8 +636,8 @@ 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
Expand Down Expand Up @@ -692,6 +698,25 @@ PathEndClkConstrained::targetClkUncertainty(const StaState *sta) const
targetClkPath(), checkRole(sta), sdc);
}

float
PathEndClkConstrained::targetClkPathMargin(const StaState *sta) const
{
Sdc *sdc = path_->sdc(sta);
ExceptionPath *exception =
sta->search()->exceptionTo(ExceptionPathType::path_margin,
path_, path_->pin(sta),
path_->transition(sta),
targetClkEdge(sta),
checkRole(sta)->pathMinMax(),
false, false, sdc);
if (!exception)
return 0.0;
float margin = exception->margin();
if (checkRole(sta)->genericRole() == TimingRole::setup())
margin = -margin;
return margin;
}
Comment thread
stanminlee marked this conversation as resolved.
Comment thread
stanminlee marked this conversation as resolved.

Crpr
PathEndClkConstrained::crpr(const StaState *sta) const
{
Expand Down Expand Up @@ -1386,11 +1411,12 @@ PathEndOutputDelay::targetClkArrivalNoCrpr(const StaState *sta) const
Arrival base = delaySum(targetClkTime(sta),
tgtClkDelay(tgt_clk_edge, check_role, sta),
sta);
return delaySum(delaySum(base,
return delaySum(delaySum(delaySum(base,
targetClkUncertainty(sta),
sta),
checkMcpAdjustment(path_, tgt_clk_edge, sta),
sta);
sta),
targetClkPathMargin(sta), sta);
}
}

Expand Down Expand Up @@ -1881,9 +1907,9 @@ PathEndPathDelay::targetClkArrivalNoCrpr(const StaState *sta) const
{
const ClockEdge *tgt_clk_edge = targetClkEdge(sta);
if (tgt_clk_edge)
return delaySum(targetClkDelay(sta),
return delaySum(delaySum(targetClkDelay(sta),
targetClkUncertainty(sta),
sta);
sta), targetClkPathMargin(sta), sta);
else if (clk_path_)
return clk_path_->arrival();
else
Expand Down
Loading
Loading