cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Contributor
Contributor
2,405 Views
Registered: ‎03-28-2015

Question on set_output_delay with differential output clock and output data

Jump to solution

Hello guys,

My question comes from adding constraints to high speed DAC interface. It's LVDS interface accompany with differential clock. (i.e., the so-called source synchronous design). 

 

Be detailed, the total system block is as below.55.jpg

 

Note: the data is DDR-like, so the clock should be constrained on both rising and falling clock edge. And after double-check with hardware guys, they confirmed me that the clock trace and data trace are almost same copper length in PCB. So, I guess the propagation delay would be zero for my case. And the setup time and hold time of DAC is around ~0.05ns (Tsu) and ~0.5ns (Thd). 

 

So, I attempt to write the set_output_delay constraint for dac_data (Adata_out_p). 

Here's my script. (Note: dac_clk_A is 200Mhz clock, i.e., 5ns period. )

=======================

 

create_generated_clock -name dac_clk_A -source [get_pins i_if/mmcm_clk_0] -divide_by 1 [get_pins i_if/i_serdes_out_clk/dac_clk_out_p]

 

set_output_delay -clock [get_clocks dac_clk_A] -max -0.0500 [get_ports -regexp -filter { NAME =~ ".*Adata_out_p.*" && DIRECTION == "OUT" }]

 

set_output_delay -clock [get_clocks dac_clk_A] -max -0.0500 [get_ports -regexp -filter { NAME =~ ".*Adata_out_p.*" && DIRECTION == "OUT" }] -clock_fall -add_delay

 

=======================

 

The question are how to handle the differential signal for this case.  

Because the output clock is generated by ODDR + OBUFDS, so I think the constraint should be added to OBUFDS. (is it correct? or Output Port?)  And I take dac_clk_out_p as output clock, and Adata_out_p as output data. (I omit those negative signal in differential trace, is that Okay? Or, should I write constraint for them? )

39.jpg

 

And I only write -max delay, and ignore -min. And the most confused things to me is how to handle the falling edge of DDR signal. In UG903, there's example on DDR. But, I really couldn't figure out how to derive delay number for -clock_fall case.

So, I have it same as rising edge. How it works here? 

 

17.jpg

 

That's my question for now.

 

Any idea or reply is high appreciated, thanks advance!

 

Nice day,

Jeff

 

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Guide
Guide
2,615 Views
Registered: ‎01-23-2009

Re: Question on set_output_delay with differential output clock and output data

Jump to solution

So, first.

 

It is better to place the create_generated_clock on with a -source of the C pin of the ODDR or OSERDES and the attachment point as the clock output port itself, as you did in your second post:

 

create_generated_clock -name dac_clk_A -source [get_pins base_microblaze_design_i/axi_ad9122_0/inst/i_i/i_serdes_out_clk/g_data[0].i_oddr/C] -divide_by 1 [get_ports Aclk_out_p]

 

Second, your set_output_delays use (what look like) unnecessarily complex wildcards - wouldn't

 

set_output_delay -clock [get_clocks dac_clk_A] -max <value> [get_ports *Adata_out_p]

 

be sufficient (although if there is more than one bit, wouldn't it be Adata_out_p[*] ?)

 

Next, the "correct" value for the output delay comes from the device you are trying to interface to - presumably a DAC - they come from the datasheet of the DAC. It would help if you told us the bit rate you are using and the mode of the DAC.

 

A setup time of -0.05 isn't inherently incorrect - in fact looking at the datasheet of an AD9122, it appears to be correct - the data must be valid between 0.05ns after the clock edge and 0.65ns after the clock edge; this is an edge aligned output interface (which is actually the best case for an FPGA). The constraints would be

  -max: the value of the setup requirement - the setup requirement is -0.05

  - min: the NEGATIVE value of the hold requirement - the hold requirement is 0.65

 

set_output_delay -clock dac_clk_a -max -0.05 [get_ports *_Adata_out_p]

set_output_delay -clock dac_clk_a -min -0.65 [get_ports *_Adata_out_p]

set_output_delay -clock dac_clk_a -max -0.05 -clock_fall -add_delay [get_ports *_Adata_out_p]

set_output_delay -clock dac_clk_a -min -0.65 -clock_fall -add_delay [get_ports *_Adata_out_p]

 

Now the question is - which edges is the tool going to use for capture. By default, it is the "next edge". So the window at time 0.05 to 0.65, which is "launched" by the edge at time 0 will be captured by the first falling edge (we don't know where that is since we don't know the period), and will try and meet the setup and hold requirement for that edge. But this isn't what we want for this ingerface - we want the capture to be done with the same edge. To do that, we need to use a set_multicycle_path command to change the clock edges and fix the other relationships.

 

Take a look at this post - it describes the process for source synchronous input interfaces, but the process is similar for output interfaces. The good news here is that you already have two clocks (so you don't need, and don't want, a virtual clock)

  - the internal flip-flop data is launched by your base clock (the clock that drives the ODDR)

  - the external device is captured by the generated clock (dac_clk_A)

 

In fact, take a look at this post on constraining an edge aligned source synchronous output interface - it even appears to be using the same DAC you are using... It has the constraints, including the set_multicycle_path and set_false_path commands, and also discusses the pessimism of the tools on this kind of interface.

 

Avrum

View solution in original post

5 Replies
Highlighted
Contributor
Contributor
2,352 Views
Registered: ‎03-28-2015

Re: Question on set_output_delay with differential output clock and output data

Jump to solution

Hello, 

I have more experiment today, improve the constraint script, but still couldn't get what I want. 

 

First, I modify the crate_generated_clock command, the get_pins (yesterday) actually pick up a network, which leads to parse error during synthesis. Now, I fix that, and place it directly on oddr/C pin. See below in bold.

 

create_generated_clock -name dac_clk_A -source [get_pins base_microblaze_design_i/axi_ad9122_0/inst/i_if/i_serdes_out_clk/g_data[0].i_oddr/C] -divide_by 1 [get_ports Aclk_out_p]

Then, I change to spec to of -max to something around 0.2 than negative 0.05 yesterday. (I suppose the negative value is incorrect, this value should be positive, and equals to setup time if trace delay is zero. And I made more marginal setup time to 0.2ns. And I also add a bit margin to hold time, it's 0.6ns now.)

 

Based on AN 433 (from Altera),   I duplicate constraint for falling clock edge.  

 

 

See below for complete constraint script. 

==========================

create_generated_clock -name dac_clk_A -source [get_pins base_microblaze_design_i/axi_ad9122_0/inst/i_if/i_serdes_out_clk/g_data[0].i_oddr/C] -divide_by 1 [get_ports Aclk_out_p]

 

set_output_delay -clock [get_clocks dac_clk_A] -max 0.200 [get_ports -regexp -filter { NAME =~ ".*Adata_out_p.*" && DIRECTION == "OUT" }]

 

set_output_delay -clock [get_clocks dac_clk_A] -max 0.200 [get_ports -regexp -filter { NAME =~ ".*Adata_out_p.*" && DIRECTION == "OUT" }] -clock_fall -add_delay

 

set_output_delay -clock [get_clocks dac_clk_A] -min -0.600 [get_ports -regexp -filter { NAME =~ ".*Adata_out_p.*" && DIRECTION == "OUT" }]

 

set_output_delay -clock [get_clocks dac_clk_A] -min -0.600 [get_ports -regexp -filter { NAME =~ ".*Adata_out_p.*" && DIRECTION == "OUT" }] -clock_fall -add_delay

 

============================================

But, the problem now is the hold violation, which is very confused to me. 

11.jpg

 

I couldn't understand why there will be inter-clock path hold error here. the mmcm_clk_0_s is the clock driving the clock and data ODDR, which generates differential dac_data_p and dac_clk_A.

 

Because set_output_delay -min will translate to hold time requirement. I am wondering if my constraint with -min option is incorrect. I browsed some threads in this forum and confirmed my usage. it's just trace_delay - hold_time (trace_delay is zero for this design), and I really couldn't figure out why this make hold time fails. 

 

Could someone lend a hand? And give me some clue to move forward. Thanks a lot!

 

Jeff

 

 

0 Kudos
Highlighted
Contributor
Contributor
2,367 Views
Registered: ‎03-28-2015

Re: Question on set_output_delay with differential output clock and output data

Jump to solution

Hello, 

I have more experiment today, improve the constraint script, but still couldn't get what I want. 

 

First, I modify the crate_generated_clock command, the get_pins (yesterday) actually pick up a network, which leads to parse error during synthesis. Now, I fix that, and place it directly on oddr/C pin. See below in bold.

 

create_generated_clock -name dac_clk_A -source [get_pins base_microblaze_design_i/axi_ad9122_0/inst/i_if/i_serdes_out_clk/g_data[0].i_oddr/C] -divide_by 1 [get_ports Aclk_out_p]

Then, I change to spec to of -max to something around 0.2 than negative 0.05 yesterday. (I suppose the negative value is incorrect, this value should be positive, and equals to setup time if trace delay is zero. And I made more marginal setup time to 0.2ns. And I also add a bit margin to hold time, it's 0.6ns now.)

 

Based on AN 433,   I duplicate constraint for falling clock edge.  

 

 

See below for complete constraint script. 

==========================

create_generated_clock -name dac_clk_A -source [get_pins base_microblaze_design_i/axi_ad9122_0/inst/i_if/i_serdes_out_clk/g_data[0].i_oddr/C] -divide_by 1 [get_ports Aclk_out_p]

 

set_output_delay -clock [get_clocks dac_clk_A] -max 0.200 [get_ports -regexp -filter { NAME =~ ".*Adata_out_p.*" && DIRECTION == "OUT" }]

 

set_output_delay -clock [get_clocks dac_clk_A] -max 0.200 [get_ports -regexp -filter { NAME =~ ".*Adata_out_p.*" && DIRECTION == "OUT" }] -clock_fall -add_delay

 

set_output_delay -clock [get_clocks dac_clk_A] -min -0.600 [get_ports -regexp -filter { NAME =~ ".*Adata_out_p.*" && DIRECTION == "OUT" }]

 

set_output_delay -clock [get_clocks dac_clk_A] -min -0.600 [get_ports -regexp -filter { NAME =~ ".*Adata_out_p.*" && DIRECTION == "OUT" }] -clock_fall -add_delay

 

============================================

But, the problem now is the hold violation, which is very confused to me. 

11.jpg

 

I couldn't understand why there will be inter-clock path hold error here. the mmcm_clk_0_s is the clock driving the clock and data ODDR, which generates differential dac_data_p and dac_clk_A.

 

Because set_output_delay -min will translate to hold time requirement. I am wondering if my constraint with -min option is incorrect. I browsed some threads in this forum and confirmed my usage. it's just trace_delay - hold_time (trace_delay is zero for this design), and I really couldn't figure out why this make hold time fails. 

 

Could someone lend a hand? And give me some clue to move forward. Thanks a lot!

 

Jeff

 

 

0 Kudos
Highlighted
Guide
Guide
2,616 Views
Registered: ‎01-23-2009

Re: Question on set_output_delay with differential output clock and output data

Jump to solution

So, first.

 

It is better to place the create_generated_clock on with a -source of the C pin of the ODDR or OSERDES and the attachment point as the clock output port itself, as you did in your second post:

 

create_generated_clock -name dac_clk_A -source [get_pins base_microblaze_design_i/axi_ad9122_0/inst/i_i/i_serdes_out_clk/g_data[0].i_oddr/C] -divide_by 1 [get_ports Aclk_out_p]

 

Second, your set_output_delays use (what look like) unnecessarily complex wildcards - wouldn't

 

set_output_delay -clock [get_clocks dac_clk_A] -max <value> [get_ports *Adata_out_p]

 

be sufficient (although if there is more than one bit, wouldn't it be Adata_out_p[*] ?)

 

Next, the "correct" value for the output delay comes from the device you are trying to interface to - presumably a DAC - they come from the datasheet of the DAC. It would help if you told us the bit rate you are using and the mode of the DAC.

 

A setup time of -0.05 isn't inherently incorrect - in fact looking at the datasheet of an AD9122, it appears to be correct - the data must be valid between 0.05ns after the clock edge and 0.65ns after the clock edge; this is an edge aligned output interface (which is actually the best case for an FPGA). The constraints would be

  -max: the value of the setup requirement - the setup requirement is -0.05

  - min: the NEGATIVE value of the hold requirement - the hold requirement is 0.65

 

set_output_delay -clock dac_clk_a -max -0.05 [get_ports *_Adata_out_p]

set_output_delay -clock dac_clk_a -min -0.65 [get_ports *_Adata_out_p]

set_output_delay -clock dac_clk_a -max -0.05 -clock_fall -add_delay [get_ports *_Adata_out_p]

set_output_delay -clock dac_clk_a -min -0.65 -clock_fall -add_delay [get_ports *_Adata_out_p]

 

Now the question is - which edges is the tool going to use for capture. By default, it is the "next edge". So the window at time 0.05 to 0.65, which is "launched" by the edge at time 0 will be captured by the first falling edge (we don't know where that is since we don't know the period), and will try and meet the setup and hold requirement for that edge. But this isn't what we want for this ingerface - we want the capture to be done with the same edge. To do that, we need to use a set_multicycle_path command to change the clock edges and fix the other relationships.

 

Take a look at this post - it describes the process for source synchronous input interfaces, but the process is similar for output interfaces. The good news here is that you already have two clocks (so you don't need, and don't want, a virtual clock)

  - the internal flip-flop data is launched by your base clock (the clock that drives the ODDR)

  - the external device is captured by the generated clock (dac_clk_A)

 

In fact, take a look at this post on constraining an edge aligned source synchronous output interface - it even appears to be using the same DAC you are using... It has the constraints, including the set_multicycle_path and set_false_path commands, and also discusses the pessimism of the tools on this kind of interface.

 

Avrum

View solution in original post

Highlighted
Contributor
Contributor
2,282 Views
Registered: ‎03-28-2015

Re: Question on set_output_delay with differential output clock and output data

Jump to solution

Hello, Avrumw,

 

Glad to see your reply! The DAC interface DDR clock is 200Mhz. So, the total period is 5ns, and half period is 2.5ns!

 

The thread (source synchronous input interfaces) you suggested do give me much insight on the concept and procedure to do this kind of constraint. THANKS A LOT!!!

 

I try to use similar set_multicycle_path script like in constraining an edge aligned source synchronous output interface

  

Moreover, I changed the fpga design to provide a more flexible clock output (phase shifted output of mmcm). The design now seems to be as follows. Note: in current design, I set the phase shift of dac_clk_A to be zero, i.e., the phase aligned with data_clk_A. (I believe the multicycle analysis above still be valid under this case, i.e., phase shift zero. And I know if the phase shift is not zero, may the multicycle path is absolutely changed. )

236.jpg

 

The XDC file now looks like below. (Note: I have a bit over-constraint for setup time and hold time here. But, I believe these number is not key point now.)

=============

# phase shifted clock for clock output port, but phase shift is zero!

create_generated_clock -name dac_clk_A -source [get_pins base_microblaze_design_i/axi_ad9122_0/inst/i_if/i_serdes_out_clk/g_data[0].i_oddr/C] -divide_by 1 [get_ports Aclk_out_p]

 

# clock for internal FPGA logic, also phase shift zero.

create_generated_clock -name data_clk_A [get_pins base_microblaze_design_i/axi_ad9122_0/inst/i_if/i_serdes_clk/i_mmcm_drp/i_mmcm/CLKOUT0]

 

# *_p pins
set_output_delay -clock [get_clocks dac_clk_A] -max 0.100 [get_ports {Adata_out_p[*]}] 
set_output_delay -clock [get_clocks dac_clk_A] -max 0.100 [get_ports {Adata_out_p[*]}] -clock_fall -add_delay

set_output_delay -clock [get_clocks dac_clk_A] -min -0.700 [get_ports {Adata_out_p[*]}] 
set_output_delay -clock [get_clocks dac_clk_A] -min -0.700 [get_ports {Adata_out_p[*]}] -clock_fall -add_delay

set_multicycle_path 0 -from [get_clocks data_clk_A] -to [get_clocks dac_clk_A]
set_false_path -setup -rise_from [get_clocks data_clk_A] -fall_to [get_clocks dac_clk_A]
set_false_path -setup -fall_from [get_clocks data_clk_A] -rise_to [get_clocks dac_clk_A]

set_multicycle_path -1 -hold -end -from [get_clocks data_clk_A] -to [get_clocks dac_clk_A]
set_false_path -hold -rise_from [get_clocks data_clk_A] -rise_to [get_clocks dac_clk_A]
set_false_path -hold -fall_from [get_clocks data_clk_A] -fall_to [get_clocks dac_clk_A]
=======================

 

The implement timing result fails for setup. I pick up one pin as example. See below. 

 

12.jpg

13.jpg

 

My confusion to the result now are below. I couldn't understand why the same data path have different delay between source clock path and destination clock path.  (from IBUFDS to MMCM output BUFG, the path delay  differs for two paths. for example, BUFG to MMCM has 0.971 ns net delay for source clock while it's 0.696 ns for destination clock.)  It's very confused for me, I assumes the same path should be of same delay.

 

After some trial and error, I could add some positive phase shift to dac_clk_A (~ 67 degree) to make final implementation result good now. All of multicycle constraint above has been commented out for this positive case. 

 

241.jpg242.jpg

 

Finally, I try tofigure out the whole dac data bus timing alignment with its output clock. (Edge aligned)

Based on How to calculate the output bus skew, it seems that report_datasheet is the tcl to check final time alignment. 

I use following command. 

===========

report_datasheet -file dac_busA.txt -group {{Aclk_out_p} {Adata_out_p[*]} {Adata_out_n[*]}}

 

================

Here's the result.

 

350.jpg

 

I wonder how to interpreter report_datasheet result.  How to interpreter the Max/Min delay for Adac_clk_p? Is my method correct ? That's all for today.

 

So, expect to hear from you, and again, much thanks for your time and effort!!

 

Jeff 

 

 

 

 

0 Kudos
Highlighted
Guide
Guide
2,262 Views
Registered: ‎01-23-2009

Re: Question on set_output_delay with differential output clock and output data

Jump to solution

My confusion to the result now are below. I couldn't understand why the same data path have different delay between source clock path and destination clock path.  (from IBUFDS to MMCM output BUFG, the path delay  differs for two paths. for example, BUFG to MMCM has 0.971 ns net delay for source clock while it's 0.696 ns for destination clock.)  It's very confused for me, I assumes the same path should be of same delay.

 

Take a look at this post on clock pessimism.

 

And now think about your two clock system.

 

With a one clock system (all the way to both ODDRs), the clock path to the forwarded clock ODDR and the clock path to the forwarded data ODDR are the same up to the final net, where there is some difference in routing. This difference in routing contributes both to "real" skew (the paths may not be of identical lengths) and also on-chip variation (OCV) skew; the nets involved are different nets, and hence will be timed at different processes (i.e. [SLOW_MIN] vs. [SLOW_MAX]).

 

With a two clock system, a huge chunk of your clock paths are no longer the same. First, the MMCM has some phase error between outputs (+/-120ps in most families). Then, you are going through different BUFGs, and entirely different clock networks. Since none of this is common, none of this is "clock pessimism" - the full OCV penalty applies.

 

For this reason, the timing is "bad". You say you want the signals to be within 100ps max, and the tools say it violates by an additional 766ps (for a total skew of 866ps). This is in line with what the tool reports on this kind of interface...

 

So, with 866ps of uncertainty (presumably pretty  close to symmetrical, so +/-866ps - a total of 1733ps), and your device seems to only allow 800ps of uncertainty (+100/-700), the tools are telling you that they can't meet timing on this interface...

 

A requirement of 800ps is tight. The tools may be pessimistic, but they typically report around +/-600ps. Your problem is made worse due to the fact that the uncertainty tolerated by your device is asymmetric, requiring some mechanism of shifting the clock/data relationship. When you add things like different clocks internally (like you are doing), or ODELAYs (which will also degrade timing, assuming they are available, since they only exist in HP I/O banks), the timing gets worse.

 

Avrum

0 Kudos