( ESNUG 300 Item 5 ) ---------------------------------------------- [10/7/98]
From: sgolson@trilobyte.com (Steve Golson)
Subject: Experiences, New Scripts, & Benchmarks with DC'98
John,
Here are some notes on my early experiences with DC'98 (1998.02-2).
Compared to DC 3.4b, with *no* changes to scripts and constraints, I'm
getting cycle time reductions of about 12%, from 13.46ns to 11.80ns.
The area increases about 9% overall. Total run time reduced 22%, from
25.5 hours to 20 hours. (Some modules ran much faster.)
This design has
35717 lines of Verilog
197 Verilog source files
193 dc_shell scripts, conventional bottom-up module compilation
273 'compile' commands
~450k gates
set_input_delay on clocks
-------------------------
DC'98 supports applying set_input_delay on clock inputs. In previous
versions this input delay was ignored. Now, the delay is added to the
clock network delay, but only when you propagate your clocks (using
set_clock_skew -propagated).
So be careful if you do something like
create_clock -period 10 find(pin,CLK)
set_input_delay 4 -clock CLK all_inputs()
because you will inadvertently set an input delay on port CLK. You
will get some informational TIM-112 and TIM-113 messages when you do
this, but only if you propagate your clocks.
You will get some UID-402 warnings if you try to set the input delay
relative to another clock (or no clock).
This feature is very useful when you have a skew-control PLL and you
are trying to back-annotate onto your clock network. You have to
propagate your clocks to correctly model clock skew, but how do you
account for the PLL insertion delay compensation? The PLL is
effectively acting as a *negative* delay. So we can model this
as follows:
create_clock -period 10 find(port,CLK)
set_clock_skew -propagated find(clock,CLK)
set_input_delay -3.82 -clock CLK find(port,CLK)
In this case 3.82 is the delay from PLL clock input, through the clock
buffer tree, to the PLL reference input. This is the delay that will
be removed by the skew-control PLL. You have to get this number via
timing analysis, and it will be different for min/typ/max conditions.
Generally you try to have your PLL reference delay be near the
midpoint of your clock buffer tree skew distribution. This means that
some flops will be clocked *before* the external clock edge, in effect
an overall negative clock insertion delay for that flop. The timing
report for such a flop shows a negative clock network delay:
Startpoint: q_reg (rising edge-triggered flip-flop clocked by clk)
Endpoint: q (output port clocked by clk)
Path Group: clk
Path Type: max
Point Incr Path
-----------------------------------------------------------
clock clk (rise edge) 0.00 0.00
clock network delay (propagated) -0.82 -0.82
q_reg/CK (DFF) 0.00 -0.82 r
q_reg/D (DFF) 1.29 0.47 r
U9/Y (BUFX1) 0.08 0.55 f
q (out) 0.00 0.55 f
data arrival time 0.55
clock clk (rise edge) 10.00 10.00
clock network delay (propagated) 0.00 10.00
output external delay -8.00 2.00
data required time 2.00
-----------------------------------------------------------
data required time 2.00
data arrival time -0.55
-----------------------------------------------------------
slack (MET) 1.45
Back-annotation with SDF
------------------------
SDF files specify delays with triplets that give the min, typ, and max
values for a particular delay. For example
(23:34:45)
would represent a minimum delay of 23, typical of 34, and a maximum of 45.
In previous versions of Design Compiler, when you back-annotate the
delays from an SDF file using the read_timing command, you could
control which values of the triplet were annotated using four dc_shell
variables:
sdfin_fall_cell_delay_type
sdfin_fall_net_delay_type
sdfin_rise_cell_delay_type
sdfin_rise_net_delay_type
Setting these to "minimum", "typical", or "maximum" (the default)
would select the particular triplet element.
DC'98 has a nifty new command 'set_min_library' which allows compile
to optimize for max delays and min delays simultaneously. You can also
specify different wire loads and operating conditions to be used for
min and max delays. This is great for compile, but how does it affect
back-annotation?
'read_timing' no longer uses these variables. Instead there are two
new options for read_timing. Here is what the man page says:
-min_triplet min_triplet_name
Specifies which value from the SDF delay
triplet should be annotated for minimum
delay analysis. By default, no delays
are annotated for minimum delay analysis
and as a result, the same delay values
that were annotated for maximum delay
analysis are also used for minimum
delays. The legal values for
min_triplet_name are "none" (the
default), "minimum" (use the leftmost
delay triplet), or "typical" (use the
middle delay triplet).
-max_triplet max_triplet_name
Specifies which value from the SDF delay
triplet to annotate for maximum delay
analysis. By default, the rightmost
delay value in each triplet is annotated
for maximum delay analysis. The legal
values for max_triplet_name are
"maximum" (the default), "typical" (use
the middle delay triplet), or "none"
(don't annotate delays for maximum delay
analysis).
It also understands the names "max", "typ", and "min".
Here's how to get both max and min timing to use the typical triplet:
read_timing -min_triplet "typical" -max_triplet "typical" your_sdf_file
and how to get both max and min timing to use the maximum triplet:
read_timing -min_triplet "none" -max_triplet "maximum" your_sdf_file
But you cannot get both max and min timing to use the minimum triplet!
This is a bug (or a misfeature, take your pick).
My silicon vendor sends me an SDF file that has three values per
triplet, corresponding to best case, typical, and worst case timing
(over voltage, temperature, and process). So I need to do max and min
timing analysis using *each* element in the triplet. The new
read_timing syntax doesn't allow it. The -min_triplet and -max_triplet
options should *each* allow "minimum", "typical", "maximum".
If you try and use a pre-DC'98 script that has these variables,
read_timing will automatically assume the appropriate values for
-min_triplet and -max_triplet. Here is a snippet from a DC log file
that back-annotates maximum (worst-case) delays:
sdfin_fall_cell_delay_type = "maximum"
"maximum"
sdfin_fall_net_delay_type = "maximum"
"maximum"
sdfin_rise_cell_delay_type = "maximum"
"maximum"
sdfin_rise_net_delay_type = "maximum"
"maximum"
read_timing -load_delay cell -context verilog file.sdf
Information: Reading 'maximum' values for 'maximum delay analysis'.
(SDFN-16)
1
You get similar results from "typical". But if you try "minimum":
sdfin_fall_cell_delay_type = "minimum"
"minimum"
sdfin_fall_net_delay_type = "minimum"
"minimum"
sdfin_rise_cell_delay_type = "minimum"
"minimum"
sdfin_rise_net_delay_type = "minimum"
"minimum"
read_timing -load_delay cell -context verilog file.sdf
Error: 'minimum' is not a valid triplet name for max. (SDFN-20)
0
Wonderful. My old scripts are now broken.
So how do I annotate minimum triplet values onto maximum delays?
Write a perl script!
Here is a perl script that modifies an SDF file to copy the leftmost
triplet element onto the other two elements. This allows me to do what
I want, which is to get the minimum triplet annotated onto both min
and max delays.
#! /usr/local/bin/perl
#
# min_only
#
# When run on an SDF file, this script
# copies the min (leftmost) delay triplet value to
# the typ (middle) and max (rightmost) values
#
# If you have an empty line in the middle of a triplet,
# this script won't work! So go write your own perl.
$/ = "" ; # paragraph mode for multi-line matches
$rnum = '[e\-\+\.0-9]+' ; # real number
while (<>) {
s?
(\(\s*) # $1 (
($rnum) # $2 min value
(\s*:\s*) # $3 :
($rnum) # $4 typ value
(\s*:\s*) # $5 :
($rnum) # $6 max value
(\s*\)) # $7 )
?$1$2$3$2$5$2$7?gsx ;
}continue{
print $_;
}
###### end of perl script min_only
So now my dc_shell script looks like:
sh min_only original.sdf > /tmp/hacked.sdf
read_timing -min_triplet "min" -max_triplet "max" /tmp/hacked.sdf
sh /bin/rm /tmp/hacked.sdf
and this gets the min triplet value annotated onto both the min and
max delays.
More back-annotation with SDF
-----------------------------
Be especially careful when you propagate your clocks! Because of the
new simultaneous min/max timing capability, when running a setup
check, the source clock is propagated with max conditions and delays,
while the destination clock is propagated with min conditions and
delays!
Conversely, if you are running a hold check, the source clock is
propagated with min conditions and delays, and the destination clock
is propagated with max conditions and delays.
This is almost certainly *not* what you want. So:
1. If you are using the min/max timing feature, do *not* propagate
your clocks
or
2. When you back-annotate timing and propagate your clocks, make sure
the same values are annotated onto max and min delays. Use the
read_timing examples I gave earlier, and use the perl script if
necessary.
I haven't tried it, but there is a hidden variable to workaround this
problem:
remove_min_max_pessimism = "true"
Be sure and do an update_timing after you set this variable. See
Solvit article Synthesis-304 for more information.
- Steve Golson
Trilobyte
|
|