( ESNUG 305 Item 1 ) --------------------------------------------- [11/18/98]

Subject: ( ESNUG 304 #11 )  Paul Zimmer's Mother-Of-All Headaches ESNUG Post
From: "Paul.Zimmer" <paul.zimmer@cerent.com>

John,

You munged my posting!  Compare the attached original to what you just
sent out in esnug 304.  You substituted stdin/stdout for set_input_delay/
set_output_delay!  You also removed some important introductory info.

Could you please do me a favor and just shoot the original posting out
ASAP?  I'm getting emails from confused readers (who think I'm even more
confused than I am).

I know the posting is long and full of gorey details, but that's sometimes
what techinical discussions are like.  Feel free to preface it with a
warning that it may not be appropriate for all audiences.  It's a tough
problem!

Thanks,

    - Paul Zimmer
      Cerent

P.S.  Enclosed is the post:

Hey John,

I've got a couple of related questions to throw out to the ESNUG community.
This is pretty tricky.  I suspect there are less than 10 engineers worldwide
who could understand and/or answer these questions.

Question 1:
-----------

Like a lot of people, I use default scripts to compile most blocks, and
I don't mess with these defaults unless I have to.  This implies setting
appropriate constraints WITHOUT knowing the details of the logic inside,
specifically without knowing what sort of paths exist (seq vs comb).

So, imagine I've got a module that has inputs that go to flops, outputs
that come from flops, and outputs that come from both inputs and
flops (commonly known as a Mealy state machine).

So, I want to budget this thing such that the input-to-clock paths get
0.85 clock period, the clock-to_output paths get 0.15 clock periods,
and the combinational (input-to-output) paths get 0.50 clock periods.

This was easy with the old set_arrival, set_max_delay syntax:

  all_inputs_no_clocks = all_inputs() - find(port,clkname)
  set_arrival 0.15 * clk_per all_inputs_no_clocks  
  set_max_delay 0.15 * clk_per all_outputs()
  set_max_delay clk_per * ( 0.15 + 0.50 ) \
     -from all_inputs_no_clocks -to all_outputs()

Which is why I've kept using the old syntax all this time.

Now, because of question 2 below, I have to move to the "new" syntax
of set_input_delay and set_output_delay.

The input-to-clock and clock-to_output paths are easy enough:

  all_inputs_no_clocks = all_inputs() - find(port,clkname)
  set_input_delay -clock clkname 0.15 * clk_per all_inputs_no_clocks
  set_output_delay -clock clkname 0.85 * clk_per all_outputs()

Unfortunately, this doesn't work for the input-to-output paths.
We've now told dc that all the inputs and outputs are related to the clock,
and that the combined delays take an entire clock cycle.  So, there's
nothing left for the comb budget.

Basically, the sid/sod syntax ASSUMES that a clock cycles is consumed in
the middle.  This isn't true for combinational paths.

The only way that I've found to get around this is to declare the
combinational paths to be multicycle:

  set_multicycle_path 2.0 -setup -from all_inputs_no_clocks \
                          -to all_outputs()
  set_multicycle_path 1.0 -hold -from all_inputs_no_clocks \
                          -to all_outputs()

(The second line is needed to make the hold calculation work correctly.)

Now we have the clock-related constraints out of the way, and we can put
combinational constraints on.  You would think that this could be done by
using set_max_delay.  Unfortunately, I haven't been able to get this to
work.  Instead, I have to create a virtual clock and put output (or input)
delay on it.

  create_clock -name combclk -period 10.0 -waveform {0, 5.0}
  set_input_delay -clock combclk 0.0 all_ins_no_clks -add_delay
  set_output_delay -clock combclk 17.0 all_outputs() -add_delay

All those single-path timing exceptions sound like a potentially serious
performance hit (although I must admit that on 9802 I haven't actually
seen much of a problem).  Besides, this is MESSY.

Has anyone found a better way?

Question 2:
-----------

[ Editor's Note: "sid/sod" == "set_input_delay/set_output_delay" ! - John ]

The reason I have to go to the sid/sod syntax (aside from the fact that
set_arrival has disappeared from the man pages :-) )is because I am now 
dealing with modules that have multiple clocks all mixed in with logic to
be compiled (don't ask).

Now, this is what sid/sod was invented for, so this should be easy, right?
Well, wrong.  The sid/sod approach assumes that the constraint setter 
KNOWNS what inputs and outputs are related to what clocks.  That's fine
at the top of the chip, where I've been using sid/sod for years so that
I can break bidi loops, but my lower-level generic scripts DON'T know that, 
and don't WANT to know that.

If you do the sid/sod for each clock and clk_per in a foreach loop,
you'll get silly things like a path from the slow clock, plus the
input delay of the slow clock, ending at a flop clocked by the
fast clock.

Well, I guess this isn't really silly from dc's point of view.  You've
effectively told dc that there is a source for each input from each
clock domain with a certain delay, and a sync for each output in
each clock domain with a certain delay, and it doesn't know any better.

But, this isn't what you really WANT.  What you want is for the input
and output delays for a clock to only be applied to paths that end/start on
that clock.  So, an input that goes to flops on both the fast and slow
clocks (for example) should have the slow clock's input delay budget on
the path going to the slow clock flop, and the fast clock's input
delay budget on the path going to the fast clock flop.  Likewise for
outputs.

How do you do this?  I'm still trying it out, but the only way I've found 
so far is to do all the same stuff above (Question 1), and then set
false paths across all the clock boundaries.

  foreach(_clock,all_clocks()) { 
    foreach(_other_clock,all_clocks() - {_clock}) { 
      set_false_path -from _clock -to _other_clock 
    } 
  }

That's a shame, since I've already gone to a lot of trouble to define the
clocks using harmonics of the fastest clock, then shrinking them to the
target period using minus clock skew.  So, I shouldn't have to disable
all the cross-clock paths.

Does anybody know of a better way to do this?

    - Paul Zimmer
      Cerent Corporation



 Sign up for the DeepChip newsletter.
Email
 Read what EDA tool users really think.


Feedback About Wiretaps ESNUGs SIGN UP! Downloads Trip Reports Advertise

"Relax. This is a discussion. Anything said here is just one engineer's opinion. Email in your dissenting letter and it'll be published, too."
This Web Site Is Modified Every 2-3 Days
Copyright 1991-2024 John Cooley.  All Rights Reserved.
| Contact John Cooley | Webmaster | Legal | Feedback Form |

   !!!     "It's not a BUG,
  /o o\  /  it's a FEATURE!"
 (  >  )
  \ - / 
  _] [_     (jcooley 1991)