Merge pull request #401 from The-OpenROAD-Project-staging/sta_fix_const_net_ptr
dcalc: no slew merge for constant disabled arcs
This commit is contained in:
commit
b6a817bab8
|
|
@ -47,6 +47,7 @@
|
||||||
#include "Sdc.hh"
|
#include "Sdc.hh"
|
||||||
#include "Scene.hh"
|
#include "Scene.hh"
|
||||||
#include "SearchPred.hh"
|
#include "SearchPred.hh"
|
||||||
|
#include "search/Sim.hh"
|
||||||
#include "Stats.hh"
|
#include "Stats.hh"
|
||||||
#include "TimingArc.hh"
|
#include "TimingArc.hh"
|
||||||
#include "TimingRole.hh"
|
#include "TimingRole.hh"
|
||||||
|
|
@ -88,8 +89,10 @@ DcalcPred::searchFrom(const Vertex *from_vertex,
|
||||||
const Pin *from_pin = from_vertex->pin();
|
const Pin *from_pin = from_vertex->pin();
|
||||||
const Sdc *sdc = mode->sdc();
|
const Sdc *sdc = mode->sdc();
|
||||||
const Network *network = sta_->network();
|
const Network *network = sta_->network();
|
||||||
|
const Sim *sim = mode->sim();
|
||||||
Net *net = network->net(from_pin);
|
Net *net = network->net(from_pin);
|
||||||
return !(sdc->isDisabledConstraint(from_pin)
|
return !(sdc->isDisabledConstraint(from_pin)
|
||||||
|
|| sim->isConstant(from_vertex)
|
||||||
|| (net && (network->isPower(net)
|
|| (net && (network->isPower(net)
|
||||||
|| network->isGround(net))));
|
|| network->isGround(net))));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
sta_module_tests("dcalc"
|
sta_module_tests("dcalc"
|
||||||
TESTS
|
TESTS
|
||||||
|
case_analysis_leak
|
||||||
prima_report
|
prima_report
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
load on constant net cn (ff) arrival at z (ps)
|
||||||
|
0 158.79
|
||||||
|
50 158.79
|
||||||
|
200 158.79
|
||||||
|
500 158.79
|
||||||
|
1000 158.79
|
||||||
|
|
||||||
|
arrival spread across the sweep: 0.00 ps (expected 0.00)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
# Delay calculation must not merge slew from set_case_analysis constants.
|
||||||
|
#
|
||||||
|
# Regression guard for "dcalc no slew merge for constant disabled arcs".
|
||||||
|
#
|
||||||
|
# GraphDelayCalc uses DcalcPred (dcalc/GraphDelayCalc.cc). Its searchFrom
|
||||||
|
# used to stop only at power/ground nets:
|
||||||
|
#
|
||||||
|
# return !(sdc->isDisabledConstraint(from_pin)
|
||||||
|
# || (net && (network->isPower(net) || network->isGround(net))));
|
||||||
|
#
|
||||||
|
# SearchPred0::searchFrom (search/SearchPred.cc) stops at
|
||||||
|
# sim->isConstant(from_vertex); DcalcPred did not, so in
|
||||||
|
# findDriverEdgeDelays an arc whose source pin is an SDC constant still
|
||||||
|
# passed searchFrom/searchThru and had its delay and slew merged into the
|
||||||
|
# driver vertex -- including when that driver is a live, non-constant pin.
|
||||||
|
#
|
||||||
|
# The fix adds sim->isConstant(from_vertex) to DcalcPred::searchFrom, and
|
||||||
|
# makes Sta::delayCalcPreamble propagate constants before delay calculation
|
||||||
|
# so the predicate sees them.
|
||||||
|
#
|
||||||
|
# Circuit (dcalc_case_analysis_leak.v):
|
||||||
|
#
|
||||||
|
# c --BUF u0--> cn ---A2\
|
||||||
|
# AND2 u1 --> n1 --BUF u2--> z
|
||||||
|
# a -------------------A1/
|
||||||
|
#
|
||||||
|
# set_case_analysis 1 c makes net cn constant. 1 is non-controlling for an
|
||||||
|
# AND, so n1 and z stay live and the A2->ZN arc is dead. The reported path is
|
||||||
|
# a -> u1 -> u2 -> z, which never traverses cn.
|
||||||
|
#
|
||||||
|
# Sweeping the wire load on cn must not change anything on that path. Before
|
||||||
|
# the fix it did: cn's slew rode the dead A2->ZN arc into n1, and n1's slew
|
||||||
|
# set u2's delay, so the arrival spread was 46.38 ps. The arrival column
|
||||||
|
# below must now be flat.
|
||||||
|
|
||||||
|
read_liberty ../../examples/nangate45_slow.lib.gz
|
||||||
|
read_verilog dcalc_case_analysis_leak.v
|
||||||
|
link_design top
|
||||||
|
|
||||||
|
create_clock -name clk -period 10
|
||||||
|
set_input_delay 0 -clock clk [get_ports {a c}]
|
||||||
|
set_output_delay 0 -clock clk [get_ports z]
|
||||||
|
set_input_transition 0.010 [get_ports {a c}]
|
||||||
|
|
||||||
|
set_case_analysis 1 [get_ports c]
|
||||||
|
|
||||||
|
puts ""
|
||||||
|
puts "load on constant net cn (ff) arrival at z (ps)"
|
||||||
|
set arrivals {}
|
||||||
|
foreach load {0 50 200 500 1000} {
|
||||||
|
set_load $load [get_nets cn]
|
||||||
|
set path [lindex [find_timing_paths -path_delay max] 0]
|
||||||
|
set arrival [format %.2f [expr [$path data_arrival_time] * 1e12]]
|
||||||
|
lappend arrivals $arrival
|
||||||
|
puts [format "%-32s%s" $load $arrival]
|
||||||
|
}
|
||||||
|
|
||||||
|
set delta [expr [lindex $arrivals end] - [lindex $arrivals 0]]
|
||||||
|
puts ""
|
||||||
|
puts "arrival spread across the sweep: [format %.2f $delta] ps (expected 0.00)"
|
||||||
|
puts ""
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
module top (a, c, z);
|
||||||
|
input a, c;
|
||||||
|
output z;
|
||||||
|
wire cn, n1;
|
||||||
|
|
||||||
|
// set_case_analysis 1 on port c makes net cn constant.
|
||||||
|
BUF_X1 u0 (.A(c), .Z(cn));
|
||||||
|
// 1 is non-controlling for AND2, so n1 is NOT constant.
|
||||||
|
AND2_X1 u1 (.A1(a), .A2(cn), .ZN(n1));
|
||||||
|
// Consumes n1's slew, so slew corruption becomes a delay change.
|
||||||
|
BUF_X1 u2 (.A(n1), .Z(z));
|
||||||
|
endmodule
|
||||||
|
|
@ -2415,7 +2415,7 @@ Corner: slow
|
||||||
0.14 1.14 v buf1/Z (BUF_X1)
|
0.14 1.14 v buf1/Z (BUF_X1)
|
||||||
0.09 1.23 v and1/ZN (AND2_X1)
|
0.09 1.23 v and1/ZN (AND2_X1)
|
||||||
0.09 1.32 ^ nand1/ZN (NAND2_X1)
|
0.09 1.32 ^ nand1/ZN (NAND2_X1)
|
||||||
0.07 1.38 ^ buf4/Z (BUF_X4)
|
0.06 1.38 ^ buf4/Z (BUF_X4)
|
||||||
0.00 1.38 ^ q3 (out)
|
0.00 1.38 ^ q3 (out)
|
||||||
1.38 data arrival time
|
1.38 data arrival time
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ max slew
|
||||||
|
|
||||||
Pin Limit Slew Slack
|
Pin Limit Slew Slack
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
nor1/ZN 0.20 0.01 0.18 (MET)
|
reg1/QN 0.20 0.01 0.19 (MET)
|
||||||
|
|
||||||
max fanout
|
max fanout
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -191,6 +191,7 @@ StaSimObserver::StaSimObserver(StaState *sta) :
|
||||||
void
|
void
|
||||||
StaSimObserver::valueChangeAfter(const Pin *pin)
|
StaSimObserver::valueChangeAfter(const Pin *pin)
|
||||||
{
|
{
|
||||||
|
graph_delay_calc_->delayInvalid(pin);
|
||||||
Vertex *vertex = graph_->pinDrvrVertex(pin);
|
Vertex *vertex = graph_->pinDrvrVertex(pin);
|
||||||
if (vertex) {
|
if (vertex) {
|
||||||
search_->arrivalInvalid(vertex);
|
search_->arrivalInvalid(vertex);
|
||||||
|
|
@ -3655,9 +3656,11 @@ void
|
||||||
Sta::delayCalcPreamble()
|
Sta::delayCalcPreamble()
|
||||||
{
|
{
|
||||||
ensureLevelized();
|
ensureLevelized();
|
||||||
for (Mode *mode : modes_)
|
for (Mode *mode : modes_) {
|
||||||
|
mode->sim()->ensureConstantsPropagated();
|
||||||
mode->clkNetwork()->ensureClkNetwork();
|
mode->clkNetwork()->ensureClkNetwork();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setIncrementalDelayTolerance(float tol)
|
Sta::setIncrementalDelayTolerance(float tol)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue