cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Adventurer
Adventurer
608 Views
Registered: ‎09-25-2007

Using Tcl variable in XDC file

Jump to solution

I'd like to use a Tcl variable to define the edge positions of a generated clock but Vivado is complaining about the syntax. Vivado says that it doesn't know what $CLK_PERIOD_DIV4 is when it tries to parse the create_generated_clock command. I think I might need some escape characters or something? Or perhaps it has something to do with the fact that I'm trying to use a variable within brackets '{ }'. I think $CLK_PERIOD_DIV4 is not actually being substituted for the numeric value and is just being left as text.

set CLK_PERIOD 40.0
set CLK_PERIOD_DIV4 ($CLK_PERIOD/4)
create_generated_clock -name gen_clk -source [get_ports my_port] -edges {1 2 3} -edge_shift {$CLK_PERIOD_DIV4 $CLK_PERIOD_DIV4 $CLK_PERIOD_DIV4} [get_pins my_inst/OUT]

-- Jonathon
0 Kudos
1 Solution

Accepted Solutions
Highlighted
Moderator
Moderator
575 Views
Registered: ‎11-04-2010

{} can be replaced by "" to make $CLK_PERIOD_DIV4 to be handled as a variable.

Example:

set CLK_PERIOD_DIV4 ($CLK_PERIOD/4) => set CLK_PERIOD_DIV4 [expr $CLK_PERIOD / 4]

-edges {1 2 3} -edge_shift {$CLK_PERIOD_DIV4 $CLK_PERIOD_DIV4 $CLK_PERIOD_DIV4} => -edges {1 2 3} -edge_shift "$CLK_PERIOD_DIV4 $CLK_PERIOD_DIV4 $CLK_PERIOD_DIV4"

-------------------------------------------------------------------------
Don't forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------

View solution in original post

9 Replies
Highlighted
Moderator
Moderator
576 Views
Registered: ‎11-04-2010

{} can be replaced by "" to make $CLK_PERIOD_DIV4 to be handled as a variable.

Example:

set CLK_PERIOD_DIV4 ($CLK_PERIOD/4) => set CLK_PERIOD_DIV4 [expr $CLK_PERIOD / 4]

-edges {1 2 3} -edge_shift {$CLK_PERIOD_DIV4 $CLK_PERIOD_DIV4 $CLK_PERIOD_DIV4} => -edges {1 2 3} -edge_shift "$CLK_PERIOD_DIV4 $CLK_PERIOD_DIV4 $CLK_PERIOD_DIV4"

-------------------------------------------------------------------------
Don't forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------

View solution in original post

Highlighted
Adventurer
Adventurer
562 Views
Registered: ‎09-25-2007
That worked! Thanks!
-- Jonathon
0 Kudos
Highlighted
Guide
Guide
413 Views
Registered: ‎01-23-2009

Aside from the syntax issue (which has been solved) what are you trying to do here?

The create_generated_clock is a command for describing the nature of a clock for static timing purposes. It should (really must) match the real clock that is being generated internally in the FPGA. You are describing a clock that is a shifted version of an input clock (which looks like it is coming from a port). How is this clock being shifted? In other words, why is this create_generated_clock valid?

If the clock is being shifted by an MMCM or PLL, then Vivado automatically creates the generated clock (correctly) based on the programming of the MMCM - you should not need to override it. If this isn't being done by a PLL or an MMCM, how are you architecturally implementing this 90 degree clock shift?

Avrum

 

0 Kudos
Highlighted
Adventurer
Adventurer
400 Views
Registered: ‎09-25-2007

It's being shifted by an IDELAY block. The shift amount (i.e. tap value) that I use always ensures that the clock is shifted by 90deg.

I'm definitely open to suggestions if you know a better way to describe the IDELAY shifted clock with XDC. Vivado does not auto-generate XDC constraints for an IDELAY shifted clock.

-- Jonathon
0 Kudos
Highlighted
Guide
Guide
387 Views
Registered: ‎01-23-2009

Is the IDELAY tap value set statically or dynamically?

If the IDELAY tap value is set statically, then the tool automatically uses this delay value as part of the calculation of the source clock delay or destination clock delay - it is considered part of the propagation path of the clock. You should not need to (and you should not) override the clock at the output of the IDELAY. Furthermore, the model you have makes the delay exactly 1/4 of a clock period, whereas the real one will be a quantized version of this, based on the capabilities of the IDELAY. By the way, I assume this is 7 series; it is illegal (or "not recommended") to delay a clock in UltraScale/UltraScale+/Versal.

If it is dynamic; i.e. you start out with some tap value and have a state machine adjust the tap setting to 1/4 of a clock period; then this will not be automatically modeled by the tool and would need to be described a different way. However, if the delay is calibrated dynamically, is static timing for the rest of the interface really meaningful?

Avrum

0 Kudos
Highlighted
Adventurer
Adventurer
362 Views
Registered: ‎09-25-2007

@avrumw wrote:

Is the IDELAY tap value set statically or dynamically?

I originally had it set statically, but then changed it to allow it to be set dynamically so that I could play around with it. But my intention is to always have it be shifting by 90deg.


@avrumw wrote:

If the IDELAY tap value is set statically, then the tool automatically uses this delay value as part of the calculation of the source clock delay or destination clock delay - it is considered part of the propagation path of the clock.


Yes, I'm pretty sure that's true. I think I was able to see that in the timing report that it was accounting for the delay but it didn't appear to me to be working right (although I will openly admit that I am not a timing analysis expert even in the slightest degree). The reason I started to mess around with adding my own constraints was to fix the absurd timing failures that I was getting after I inserted the IDELAY block. I was getting ridiculous total negative slack (like close to -900ns) and individual negative hold delays in the multiple tens of ns. None of that made any sense to me and was obviously disinformation - i.e. the timing tool was very confused about what I was doing.

You seem to know your stuff in regards to timing analysis so I am happy to give further information on what I'm trying to do...

- I have a clock coming in from a memory device (it's a non-standard memory, not your typical SDR/DDR/QDR/SRAM/whatever).

- That clock is NOT free running (thus the need for IDELAY and not PLL/DCM)

- Clock frequency is 150MHz

- The data coming in from the memory device is source synchronous to the input clock (i.e. the clock that I am IDELAY'ing)

- The input clock and data are edge-aligned

- The data from the memory device is DDR (i.e. clock on both edge of input clock)

- My goal is this: Shift the incoming clock by 90deg and use that shifted clock to sample the incoming data. This will allow me to sample the clock in the very middle of the bit period. NOTE: 90deg phase shift puts me in the middle of the bit period because the data is DDR. So for example if the data was SDR then I would need to shift by 180deg.


@avrumw wrote:

You should not need to (and you should not) override the clock at the output of the IDELAY.


I would love it if that were the case but I'm having insane (non-sensical) timing failures when I provide no constraints to the IDELAY'd clock at all.   I'm open to any suggestions at all that you might have though. It's certainly possible that I'm doing something dumb that is confused the tool...but the IDELAY block is very simple/straightfoward - I don't see how I could be screwing it up. But who knows...


@avrumw wrote:

Furthermore, the model you have makes the delay exactly 1/4 of a clock period, whereas the real one will be a quantized version of this, based on the capabilities of the IDELAY.


Yes, I agree with that statement but I'm not sure what else I can do...? I'm not an XDC expert by any means. I'm mostly guessing as to the correct approach.


@avrumw wrote:

By the way, I assume this is 7 series; it is illegal (or "not recommended") to delay a clock in UltraScale/UltraScale+/Versal.


Correct. Specifically a Zynq 7020 device. However, I am now moving the design to an Artix-7.


@avrumw wrote:

If it is dynamic; i.e. you start out with some tap value and have a state machine adjust the tap setting to 1/4 of a clock period; then this will not be automatically modeled by the tool and would need to be described a different way. However, if the delay is calibrated dynamically, is static timing for the rest of the interface really meaningful?


I agree with all of that but I'm simply not sure what else to do. Again, I'm very happy to receive any advice on a better approach.

-- Jonathon
0 Kudos
Highlighted
Guide
Guide
311 Views
Registered: ‎01-23-2009

My goal is this: Shift the incoming clock by 90deg and use that shifted clock to sample the incoming data.

The problem with this is that you are assuming that 90 degrees is the perfect shift. It is true that if the clock and data are edge aligned then shifting the clock 90 degrees puts the clock in the center of the data eye. However, this is only the "best" place if the setup/hold requirement of the capture mechanism is symmetrical around the clock edge (i.e. it needs a similar amount of setup and hold time). This is not the case...

Depending on the clocking scheme, the setup/hold requirement is very asymmetrical. Take a look at this post on clocking structures for input interfaces; since you are using a gapped clock, you are correct that you can't use the MMCM, so that leaves two clocking schemes; direct using the BUFG or "ChipSync" - using the BUFIO and/or BUFR. The BUFG is significantly slower than ChipSync, and for the IDDR (not the ISERDES) you can consider using the BUFR alone; the BUFR can clock the IDDR and gives slightly better performance than the BUFIO.

The datasheet gives you some rough ideas as to the required setup/hold windows. For ChipSync it is Tpscs/Tphcs - depending on device these are around -0.38/1.76; thus the required data valid window is completely after the clock edge. If your delayed clock is in the middle of the data valid window it is significantly too late. This is why you should be using proper constraints and letting the tool do the timing properly - when done th is way, you can figure out what the optimal tap setting for the IDELAY is.

I was getting ridiculous total negative slack (like close to -900ns) and individual negative hold delays in the multiple tens of ns. None of that made any sense to me and was obviously disinformation

It may not have made sense, but it wasn't "disinformation". I highly suspect that you had the wrong setup and capture edge combinations - if you specified the input constraints "naturally" (which I call the "correct way") , then this would be the default for an interface like this. Take a look at this post on constraining edge aligned source synchronous interfaces. By default, the setup capture edge is the clock edge after the setup launch edge. But in your case, since you are delaying the clock internally, you are trying to capture the data window with the same edge as the one that launched the data (read through the post carefully - it makes this all clear). To do this, you need to change the capture edge with the "set_multicycle_path 0" command and all the other commands to support it that are documented in the referenced post.

If you do all that, then you will be able to choose an IDELAY tap value, run static timing analysis, see the setup/hold margins, then adjust the tap setting to move the clock so that you have the best setup and hold margins. You don't even need to recompile to do this, you can interactively change the tap setting with

set_property IDELAY_VALUE <value> [get_cells <instance_name_of_IDELAY>]

and re-run report_timing. Once you have the best value, you can put the correct value directly in your RTL or in your XDC file to lock it down.

Avrum

0 Kudos
Highlighted
Adventurer
Adventurer
288 Views
Registered: ‎09-25-2007

This is all incredibly useful information! It's going to take me some time to comb through it all so give me a little while.


@avrumw wrote:By default, the setup capture edge is the clock edge after the setup launch edge. But in your case, since you are delaying the clock internally, you are trying to capture the data window with the same edge as the one that launched the data (read through the post carefully - it makes this all clear).

This is particularly interesting. I had never considered and never occurred to me that I was changing the capture edge. I'm guessing this is very likely why the timing tool was giving me such weird analysis results.

Thank you!

-- Jonathon
0 Kudos
Highlighted
Observer
Observer
142 Views
Registered: ‎03-21-2011

Are you sure the clock needs delaying and not the data?  I.e. if you have a clock that stops at zero, say and your waveform is

 

XX XX D0 D1 D2 D3 D4 D5
C0 C0 C0 C1 C0 C1 C0 C1

If you delay the clock then D1 is on the rising edge and D0 is lost, no?  or is the first valid bit AFTER the first edge of the resumed clock?

Also, there's a trick from the old Spartan6 days with a Xilinx ref design.  They were using ISERDES but it may work with IDDR too.  If the data coming in is differential, you effectively are leaving a serdes/iddr per bit unused.  What they did was send the data to BOTH I/O's ISERDES, through dynamic IDELAYs with one IDELAY set to 1/2 bit time extra than the other.  They then waited for data bit transitions. if data[t] != data[t-1] (a transition) then If Data[t] == Data[t-1/2] increment, if != decrement.  Then if the count was too big/small you would dynamically nudge the two IDELAYS by one tap each.  Eventually the Data[t-1/2] would be in the middle of the transition and have a 50/50 chance of being == the real data and the counter would hover in the middle.  The real data[t] was then being sampled dead-nuts-center.

 

 

0 Kudos