cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Anonymous
Not applicable
14,135 Views

Timing constraint clock and data related DDR outputs

Jump to solution

Hello,

 

I'm using a Spartan6 FPGA to design a LVDS deserializer.

On the parallel output port, I use DDR signal with ODDR2 instance. I have to check using STA the setup and hold time between both edge of the clock and all data on the outputs pads of the FPGA.

 

For that, basically, I use the constraint below (RGB_Tx is the group of all outputs data and clock.):

 

TIMEGRP "RGB_Tx" OFFSET = OUT AFTER "LVDS_Rx_Even_Clock_p" REFERENCE_PIN "RGB_Tx_Clock" RISING;
TIMEGRP "RGB_Tx" OFFSET = OUT AFTER "LVDS_Rx_Even_Clock_p" REFERENCE_PIN "RGB_Tx_Clock" FALLING;

 

With this constraint, I have this warning:

 

WARNING:Timing:3224 - The clock LVDS_Rx_Even_Clock_p associated with TIMEGRP
   "RGB_Tx" OFFSET = OUT AFTER COMP "LVDS_Rx_Even_Clock_p" REFERENCE_PIN       
   BEL "RGB_Tx_Clock" "FALLING"; does not clock any registered output
   components.

 

I read AR# 34634 and AR# 12819, so this error seems known but I'm not able to get any working solution.

I also attached the schematic for this part.

 

Can eveyone help me on this issue, I really need to check it by STA.

 

Thanks

Regards

Matthieu

DDR_output.jpg
0 Kudos
1 Solution

Accepted Solutions
blasm
Xilinx Employee
Xilinx Employee
22,104 Views
Registered: ‎08-17-2011

Hello Matthieu,

 

This is Blas from Xilinx Technical Support.

I was contacted by Dries to look at in this problem also and I think we might have an asnwer:

 

In ODDR within S6, there are some differences wether the parameter DDR_ALIGNMENT = NONE, or if DDR_ALIGNMENT = C0/C1.

 

For DDR_ALIGNMENT = NONE, the TA will be able to find output paths clocked with the RISING and FALING edge of the clock. WHereas if DDR_ALIGNMENT = C0/C1 , then only one clock edge is analyzed, either RISING with C0 or FALLING with C1.

 

Basically , this is a silicon limitation due to the internal configuration of the ODDR and the way the data is clocked IN (fetch) by the ODDR. There is more detailed information in the UG381.

 

As a quick summary, when NONE is selected, the ODDR capture the data in the RISING & FALING edges of the clock so the tool analyses the 2 situations whereas with C0/C1, the ODDR capture both input data at the same time so only one edge, either RISING for C0 or FAILING for C1 is considered.
 
"DDR_ALIGNMENT = C0" means "Accept Input Alignment to Clock C0. The C0 mode outputs both data bits from the ODDR2 primitive on the rising edge of clock C0" 
"DDR_ALIGNMENT = C1" means "Accept Input Alignment to Clock C1. The C1 mode outputs both data bits from the ODDR2 primitive on the rising edge of clock C1"


So depending on which configuration you are applying to the ODDR parameter, the tool will analyze the RISING, FALING or the RISING and FALING of the ODDR

 

 

View solution in original post

23 Replies
htsvn
Xilinx Employee
Xilinx Employee
14,106 Views
Registered: ‎08-02-2007

Hi,

 

Did you get a chance to look at this AR? http://www.xilinx.com/support/answers/29362.htm

 

--Hem

----------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
----------------------------------------------------------------------------------------------
0 Kudos
Anonymous
Not applicable
14,104 Views

Hi,

 

I took a look but not help me in my case. After reading all AR, it seems normal that the FALLING keywords isn't take into account with ODDR2 registers.

Nevertheless, I'm pretty sure that there is a way to analyse that but I really don't knwo how.

 

Thanks

Matthieu

0 Kudos
driesd
Xilinx Employee
Xilinx Employee
14,102 Views
Registered: ‎11-28-2007

Hi Matthieu,

 

why do you draw this conclusion?

Have you taken a look at AR12819?

 

Would it be possible to supply a small testcase?

This would also help you to debug/experiment as runtimes are then significantly shorter.

 

 

Best regards,

Dries

--------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if the information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented by clicking the star next to the post.
0 Kudos
Anonymous
Not applicable
14,090 Views

Hi Dries,

 

My conclusion is based on AR# 34634.

About your AR12819, I'm not able to see it

 

 
An Unexpected Error has occurred.

Sorry, your request failed. A notification has been sent to the development team for investigation.

Exception ID: 5FB5FC6C

 

I'll provide small code, no problem.

 

Thanks

Best Regards

Matthieu

0 Kudos
driesd
Xilinx Employee
Xilinx Employee
14,083 Views
Registered: ‎11-28-2007

Hi Matthieu,

 

apologies, either something went wrong copy-pasting, either the forum corrupted my link.

Can you retry?

 

Thanks in advance for the testcase!

 

 

Best regards

Dries

--------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if the information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented by clicking the star next to the post.
0 Kudos
Anonymous
Not applicable
14,079 Views

About the AR12819, yes I already look into. I'm in the first case but on Step3, I need to create subgroup of the falling edge FF. But in my case ODDR2 is driving pads so I don't knwo how I can create this kind of sub group.

 

Best Regards

Matthieu

0 Kudos
driesd
Xilinx Employee
Xilinx Employee
14,075 Views
Registered: ‎11-28-2007

Hi Mathieu,

 

mmm, not sure why you struggle.

In your case, this should be:

NET "main_clk" TNM_NET = "main_clk_grp";
TIMESPEC "TS_main_clk" = PERIOD "main_clk_grp" 16 ns HIGH 50%;
TIMEGRP "falling_reg" = FALLING "main_clk_grp"; # Falling _reg includes synchronous elements # OR INST "g_RGB_Tx_Data_DDR[*].i_ODDR2_Data" TNM = "falling_reg"; # Falling_reg includes synchronous elements

 

 

Best regards,

Dries

--------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if the information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented by clicking the star next to the post.
0 Kudos
Anonymous
Not applicable
14,073 Views

I attached the VHDL code with UCF file.

 

I already tried all method that I know adn method describer on the AR12819 but always have warnings and I'm noat able to check setup/hold time with rising and falling edge.

 

Maybe I wrote wrong constraint, I'm really lost on this issue.

 

Thanks again

Best Regards

Matthieu

0 Kudos
Anonymous
Not applicable
14,072 Views

Sorry, you just need to open the project ant implement it...no more

 

Regards

Matthieu

0 Kudos
driesd
Xilinx Employee
Xilinx Employee
13,941 Views
Registered: ‎11-28-2007

Hi Matthieu,

 

here are cleaned up constraints that I verified work:

 # Step 1. Create a PERIOD constraint on the original clock, grouping the DDR flip-flops.
NET "LVDS_Rx_Even_Clock_p" TNM_NET = "pixelclk_rgb";
TIMESPEC "TS_pclk_rgb"    = PERIOD "pixelclk_rgb"   15.385 ns HIGH 50%;

 # Step 2. Group the I/O pads.
INST "RGB_Tx_Clock"                         TNM = "RGB_Tx";
INST "RGB_Tx_Data<*>"                       TNM = "RGB_Tx";
INST "RGB_Tx_Hsync"                         TNM = "RGB_Tx";
INST "RGB_Tx_Vsync"                         TNM = "RGB_Tx";
INST "RGB_Tx_Den"                           TNM = "RGB_Tx";

 # Step 3. Create a sub-group of the falling edge flip-flops.
INST "g_RGB_Tx_Data_DDR[*].i_ODDR2_Data" TNM = "falling_reg";

 # Step 4. Create an OFFSET constraint for the DDR group.
TIMEGRP "RGB_Tx" OFFSET = OUT AFTER "LVDS_Rx_Even_Clock_p";
#TIMEGRP "RGB_Tx" OFFSET = OUT AFTER "LVDS_Rx_Even_Clock_p" REFERENCE_PIN "RGB_Tx_Clock" RISING;

 # Step 5. Create an adjusted OFFSET constraint for the falling edge flip-flops.
TIMEGRP "RGB_Tx" OFFSET = OUT AFTER "LVDS_Rx_Even_Clock_p" TIMEGRP "falling_reg";
#TIMEGRP "RGB_Tx" OFFSET = OUT AFTER "LVDS_Rx_Even_Clock_p" REFERENCE_PIN "RGB_Tx_Clock" FALLING;

 

These are the problems with your constraints:

First, you get these warnings during Translate that need to be resolved:

WARNING:ConstraintSystem - TNM : pixelclk_rgb was distributed to a DCM but new
   TNM constraints were not derived. The requirement for derived TNM constraints
   is that the distributed TNM is referenced by no more than a single PERIOD
   constraint. Non-PERIOD referencers are also not allowed. This TNM is used in
   the following user groups or specifications:
   <TIMESPEC "TS_pclk_rgb"    = PERIOD "pixelclk_rgb"   15.385 ns HIGH 50%;>
   [Top.ucf(2)]
   <TIMEGRP "falling_reg" = FALLING "pixelclk_rgb";> [Top.ucf(3)]

WARNING:ConstraintSystem:190 - The TNM 'pixelclk_rgb', does not directly or
   indirectly drive any flip-flops, latches and/or RAMS and cannot be actively
   used by the referencing Period constraint 'TS_pclk_rgb'. If clock manager
   blocks are directly or indirectly driven, a new TNM and PERIOD are derived
   only if the PERIOD constraint is the only referencing constraint and if an
   output of the clock manager block drives flip-flops, latches or RAMs.  
   This TNM is used in the following user groups and/or specifications:
   <TIMESPEC "TS_pclk_rgb"    = PERIOD "pixelclk_rgb"   15.385 ns HIGH 50%;>
   [Top.ucf(2)]
   <TIMEGRP "falling_reg" = FALLING "pixelclk_rgb";> [Top.ucf(3)]

WARNING:ConstraintSystem:197 - The following specification is invalid because
   the referenced TNM constraint was removed:
   <TIMESPEC "TS_pclk_rgb"    = PERIOD "pixelclk_rgb"   15.385 ns HIGH 50%;>
   [Top.ucf(2)]

 

Using your falling DDR instance constraint instead to resolve these warnings:

INST "RGB_Tx_Data_DDR[*].i_ODDR2_Data" TNM = "falling_reg";

 causes the following error message:

ERROR:ConstraintSystem:58 - Constraint <INST "RGB_Tx_Data_DDR[*].i_ODDR2_Data"
   TNM = "falling_reg";> [Top.ucf(5)]: INST "RGB_Tx_Data_DDR[*].i_ODDR2_Data"
   does not match any design objects.

 

Indeed the correct hierarchical name for these DDR-FFs is, as I suggested earlier:

INST "g_RGB_Tx_Data_DDR[*].i_ODDR2_Data" TNM = "falling_reg";

 After this fix, timing is correctly analyzed for your DDR interface.

 

By the way, since you didn't specify any constraint value for the OFFSET OUT, you just as well could have used the datasheet table numbers in the timing report (.twr)

 

 

Best regards,

Dries

--------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if the information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented by clicking the star next to the post.
0 Kudos
Anonymous
Not applicable
13,938 Views

Oops, I forgot the g_ using INST "g_RGB_Tx_Data_DDR[*].i_ODDR2_Data" TNM = "falling_reg"; sorry.

 

So indeed, I don't have any errors yet. It's a big step for me, thanks a lot.

 

I didn't specified any constraint because I want just analyse setup and hold time.

 

But, on the datasheet report I can see the bus skew but how can I check the setup and hold time between the clock (RGB_Tx_Clock) and data (RGB_Tx_Data*)?

Untitled.jpg

 

What I search, it's the value tsu and th for the rising and falling edges, could you just help me on the last step.

 

Thanks again

Best Regards

Matthieu

 

 

0 Kudos
driesd
Xilinx Employee
Xilinx Employee
13,924 Views
Registered: ‎11-28-2007

Hi Matthieu,

 

setup is shown in the timing report by default

hold time is shown when you select the "show fastest paths" option.

 

You can also check the switches of the trace command (trce) in the ISE command line user-guide.

 

 

Best regards,

Dries

--------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if the information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented by clicking the star next to the post.
0 Kudos
Anonymous
Not applicable
13,918 Views

Hi driesd,

 

Is it possible to show me, the timing report with these value of the example I provided to you because it's not clear for me?

I'm able to see the setup and hold time requierements for the DDR inputs but not for the outputs.

 

I can attach my report if needed.

 

Also how the timing analyser know that it must report the setup and hold time for the falling edge with the line

INST "g_RGB_Tx_Data_DDR[*].i_ODDR2_Data" TNM = "falling_reg"; ?

 

Sorry for insistence but I'm not usual with this analysis and it's very important for me.

 

Thanks

Best Regards

Matthieu

0 Kudos
driesd
Xilinx Employee
Xilinx Employee
13,913 Views
Registered: ‎11-28-2007

Matthieu,

 

actually the data you are requesting is in the datasheet table of the timing report (.twr):

Data Sheet report:
-----------------
All values displayed in nanoseconds (ns)

Clock LVDS_Rx_Even_Clock_p to Pad
---------------+-----------------+------------+-----------------+------------+-------------------+--------+
               |Max (slowest) clk|  Process   |Min (fastest) clk|  Process   |                   | Clock  |
Destination    |  (edge) to PAD  |   Corner   |  (edge) to PAD  |   Corner   |Internal Clock(s)  | Phase  |
---------------+-----------------+------------+-----------------+------------+-------------------+--------+
RGB_Tx_Clock   |        14.168(R)|      SLOW  |         7.043(R)|      FAST  |RGB_Tx_SDR_Clock_90|   3.846|
RGB_Tx_Data<0> |        10.230(R)|      SLOW  |         3.095(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<1> |        10.230(R)|      SLOW  |         3.095(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<2> |        10.227(R)|      SLOW  |         3.092(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<3> |        10.227(R)|      SLOW  |         3.092(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<4> |        10.225(R)|      SLOW  |         3.090(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<5> |        10.225(R)|      SLOW  |         3.090(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<6> |        10.235(R)|      SLOW  |         3.100(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<7> |        10.235(R)|      SLOW  |         3.100(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<8> |        10.232(R)|      SLOW  |         3.097(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<9> |        10.232(R)|      SLOW  |         3.097(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<10>|        10.229(R)|      SLOW  |         3.094(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<11>|        10.229(R)|      SLOW  |         3.094(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<12>|        10.227(R)|      SLOW  |         3.092(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<13>|        10.227(R)|      SLOW  |         3.092(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<14>|        10.227(R)|      SLOW  |         3.092(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<15>|        10.227(R)|      SLOW  |         3.092(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<16>|        10.232(R)|      SLOW  |         3.097(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<17>|        10.232(R)|      SLOW  |         3.097(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<18>|        10.237(R)|      SLOW  |         3.102(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<19>|        10.237(R)|      SLOW  |         3.102(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<20>|        10.237(R)|      SLOW  |         3.102(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<21>|        10.237(R)|      SLOW  |         3.102(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<22>|        10.237(R)|      SLOW  |         3.102(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Data<23>|        10.237(R)|      SLOW  |         3.102(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Den     |        10.152(R)|      SLOW  |         3.012(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Hsync   |        10.145(R)|      SLOW  |         3.005(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
RGB_Tx_Vsync   |        10.145(R)|      SLOW  |         3.005(R)|      FAST  |RGB_Tx_SDR_Clock   |   0.000|
---------------+-----------------+------------+-----------------+------------+-------------------+--------+

the skew between the clock and data is about 4ns

 

 

Best regards:

Dries

--------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if the information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented by clicking the star next to the post.
0 Kudos
Anonymous
Not applicable
13,909 Views

Ok,

 

It was my first assumption but is this skew based on the rising edge or on both edge. I know that it would be the same but just to be sure.

 

Thanks again

Best regards

Matthieu

0 Kudos
driesd
Xilinx Employee
Xilinx Employee
13,902 Views
Registered: ‎11-28-2007

Hi Matthieu,

 

I thought this would be easy, but I gave it a few tries and I'm afraid I must agree that I cannot check timing on both rising and falling edge.

This is very odd, I'll open an internal case, have this investigated, create an answer record and post back to you.

 

Personally, I would change the design and instead of inverting the clock locally, use additional PLL outputs to generated the 180 degree shifted clocks.

This will guarantee best 50-50 duty cycle and lowest skew.

 

 

Best regards,

Dries

--------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if the information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented by clicking the star next to the post.
Anonymous
Not applicable
13,900 Views

Driesd,

 

Thank again for your support. I'll check to change my design with your advise.

I'll wait your AR for the timing analysis part.

 

About this post, do you prefer I close it or wait the AR?

 

Best Regards,

Matthieu

 

0 Kudos
driesd
Xilinx Employee
Xilinx Employee
13,897 Views
Registered: ‎11-28-2007

Hi Matthieu,

 

as long as you think it's not resolved, I would not marked it at "solved".

 

 

Best regards,

Dries

--------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if the information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented by clicking the star next to the post.
0 Kudos
blasm
Xilinx Employee
Xilinx Employee
22,105 Views
Registered: ‎08-17-2011

Hello Matthieu,

 

This is Blas from Xilinx Technical Support.

I was contacted by Dries to look at in this problem also and I think we might have an asnwer:

 

In ODDR within S6, there are some differences wether the parameter DDR_ALIGNMENT = NONE, or if DDR_ALIGNMENT = C0/C1.

 

For DDR_ALIGNMENT = NONE, the TA will be able to find output paths clocked with the RISING and FALING edge of the clock. WHereas if DDR_ALIGNMENT = C0/C1 , then only one clock edge is analyzed, either RISING with C0 or FALLING with C1.

 

Basically , this is a silicon limitation due to the internal configuration of the ODDR and the way the data is clocked IN (fetch) by the ODDR. There is more detailed information in the UG381.

 

As a quick summary, when NONE is selected, the ODDR capture the data in the RISING & FALING edges of the clock so the tool analyses the 2 situations whereas with C0/C1, the ODDR capture both input data at the same time so only one edge, either RISING for C0 or FAILING for C1 is considered.
 
"DDR_ALIGNMENT = C0" means "Accept Input Alignment to Clock C0. The C0 mode outputs both data bits from the ODDR2 primitive on the rising edge of clock C0" 
"DDR_ALIGNMENT = C1" means "Accept Input Alignment to Clock C1. The C1 mode outputs both data bits from the ODDR2 primitive on the rising edge of clock C1"


So depending on which configuration you are applying to the ODDR parameter, the tool will analyze the RISING, FALING or the RISING and FALING of the ODDR

 

 

View solution in original post

Anonymous
Not applicable
10,504 Views

Hello Blas,

 

Ok, so in my case, I will use the NONE parameter to have an idea of the timings based on both edges but I'll keep the C0 parameter for the final design because it is the way that the data are incoming in the ODDR. I tested that and saw that I can calculate all my setup and hold times by changing the parameter.

 

For my final STA, I'll take a margin from the one running with NONE parameter.

I would have preferred to analyse all my timings based on the final design but I well understood that it is not possible.

 

Thanks for your support

Matthieu Baque

0 Kudos
driesd
Xilinx Employee
Xilinx Employee
10,501 Views
Registered: ‎11-28-2007

Hi Matthieu,

 

just to be clear, this is not a bug but actually this is how timing is correctly analyzed.

 

Can you mark Blas his answer as the solution if you are satisfied?

 

 

Thanks!

Dries

--------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if the information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented by clicking the star next to the post.
0 Kudos
Anonymous
Not applicable
10,492 Views

Hello Dries,

 

Yes I agree this is how the timing analysis is working and not a bug, no problem.

 

Thanks

Matthieu Baque

0 Kudos
driesd
Xilinx Employee
Xilinx Employee
10,488 Views
Registered: ‎11-28-2007

Hi Matthieu,

 

good to hear that.

 

Can you then mark Blas his post with "accept as solution"

screenshot_001.jpg


Thanks

Dries

--------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if the information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented by clicking the star next to the post.
0 Kudos