Editor's Note: I wish to appologize for some miscommunication in the
 networking section of Post 124.  I've been flooded with phone calls
 from headhunters because I forgot to mention that I was networking
 for consulting work; you know -- short term contracts either doing
 ASIC designs or helping design teams get off on the right foot with
 various EDA tools and design methodologies.  Sorry for the foobar but
 thanks for the good intentions.
                                       - John Cooley, the ESNUG guy


( Post 125 Item 1 ) --------------------------------------------------------

From: Oren Rubinstein <oren@waterloo.hp.com>
Subject: Late Clock Scaling Problem rev 3.0

Hello John.
Here is the description of a bug that I recently found.

The problem is in using "set_timing_ranges".
The code is a flip-flop fed by a multiplexer:

| module timing_range(clk,enable,in,out);
| 
| input	clk,enable,in;
| output out;
| 
| wire d;      // input to the flop
| reg  q;		// flop output
| 
| assign d = enable ? in : q;	// 2->1 multiplexer
| 
| always @(posedge clk) begin
|     q = d;
| end
| 
| assign out = q;
| 
| endmodule


Now assume the clock's rising edge is not at time 0, i.e.:

| create_clock clk -period 20 -waveform {10 20}
| set_clock_skew -plus_uncertainty 0.5 -minus_uncertainty 1.0 clk
| set_drive 0 clk

The library that I'm using has all the timing data for maxdelays,
and has a timing_range section to define the scaling for mindelays:

| timing_range (SETUP_HOLD) {
|     faster_factor : 0.37
|     slower_factor : 1.0
| }

and my script includes:

| set_timing_ranges "SETUP_HOLD"

Here is the result of "report_constraint -all_violators":

| Startpoint: q_reg (rising edge-triggered flip-flop clocked by clk)
| Endpoint: q_reg (rising edge-triggered flip-flop clocked by clk)
| Constraint Group: clk
| Path Type: min
| 
| Point                                    Incr       Path
| -----------------------------------------------------------
| clock clk (rise edge)                   10.00      10.00
| clock network delay (ideal)              0.00      10.00
| q_reg/CLK (DFFF)                         0.00      10.00 r
| q_reg/Q (DFFF)                           1.55      11.55 f
| U11/Q (MUX2F)                            0.60      12.15 f
| q_reg/D (DFFF)                           0.00      12.15 f
| timing range (SETUP_HOLD)                0.37       4.49
| data arrival time                                   4.49
| 
| clock clk (rise edge)                   10.00      10.00
| clock network delay (ideal)              0.00      10.00
| clock uncertainty                        0.50      10.50
| q_reg/CLK (DFFF)                         0.50      10.50 r
| library hold time                        0.65      11.15
| data required time                                 11.15
| -----------------------------------------------------------
| data required time                                 11.15
| data arrival time                                  -4.49
| -----------------------------------------------------------
| slack (VIOLATED)                                   -6.66

Instead of scaling only the delays, Synopsys also scales the clock
rise time for the start point.

I reported this bug to Synopsys two weeks ago, it is under
investigation, but I didn't get any reply yet.

Regards,

 - Oren Rubinstein

   Hewlett-Packard (Canada) Ltd., Panacom Automation Division, CANADA

                           --  --  --  --

 Editor's Note: Oren, I worked on a project using 2.2 that had the
 same problem.  (It took a while to find it because the timing reports
 in 2.2 didn't explictly show the effect of the timing_range which
 Synopsys thankfully improved in 3.0.)  In the design I was working on
 I was trying to compile submodules with realistic clock tree latency
 being taken into consideration for the timing constraints.  The final
 solution using 2.2 was to use a clocks_at 0, 5, 10 in place of the
 orginal clocks_at 3, 8, 10 and to put a set_arrival that was 3 less
 than before.  (i.e. I made the clock tree latency 0.0 so the scaling
 from the timing_range had no effect and kept the rest of my timing
 on the chip relative to this change.)  This process worked well but
 it meant I had to keep a careful eye on timing reports and compiling
 the higher level modules.
                                 - John Cooley, ESNUG Moderator


( Post 125 Item 2 ) --------------------------------------------------------

From: lewis@zycad.protocol.com (Jim LEWIS)
Subject: (Post 120 Item 2) "Seeking Spare Gate Methodologies"

    I see there being a couple of possiblities as to what the 
problem is in trying to create a spare gate methodology.  

    In general if you want an instanciated library cell to 
remain when reading and compiling you may put a dont_touch on
the library cell.  The hazzard of doing this is that wherever
this cell is used (instanciated or mapped by design compiler)
it will be dont_touched (and as a result not removed).  Two passes 
can solve this type of a problem.  The first pass dont_touch the 
library cell.  The second pass remove the dont_touch attribute 
from everything except the cell you want it on.  

    In order to dont_touch a library cell, the library must be 
read in first.  You will need to read it in explicitly if the 
dont_touch is going to be effective at the read.  The following
is similar to a procedure I used in the past.

   /* read the library */
      read -f db { act2_22.db }
       
   /* dont_touch a cell */
     dont_touch find( cell, act2_22.db:act2/INVA ) 

Note: this dont_touch will be removed from the library if it
is read again (2.2b).  The act2_22.db:act2 is the long form
specification for a library.  It is needed only when act2
(the library name) is not a unique name.

    On this previous project, we also used actel.  If you have 
an unused input that is being optimized away there are also 
other ways of solving the problem.  These are more schematic 
based.  The following are a couple ideas:

    1)  Instead of having an unused input cell, use a tristate
	output pad with its tristate output disabled and its 
	input to the pad connected to vcc or gnd.  
	
	We used this as we moved some outputs to unused pads 
	and wanted to minimize the changes to the board to 
	a single jumper.  Since the old pad location would 
	default to an output, we explicitly placed a tristate
	driver there.

    2)  If for some reason 1 does not work, make a dummy circuit
	and connect the input pads through a string of "and" or 
	"or" gates to a pad which can be used as an output.

    
    If you are just trying to get a particular implementation, 
we used the vhdl block statement in conjunction with the 
group -hdl_block frequently.  By isolating small blocks of 
code, we were able to force a particular implementation.  
With the actel library and without the FPGA compiler, we 
used this technique to meet our timing and area constraints
when the Design Compiler needed additional help finding the 
mapping we wanted.  For more details of this process see
Post 109 Item 3.

Hope this helps some,

   - Jim Lewis
     Zycad/Protocol, Design Services


 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)