Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

Constraining Complex Design in SDC

Hi,

I've been working on a fairly complex design which has several external devices (two ADCs, a DAC, and four voltage pulsers) which each have have clock and data lines that need constraining to check that they will meet the required setup/hold specs.

What gets a bit complex is that each IC will have its clock sourced from the FPGA to avoid the need for external LVDS clock buffers, but each clock within a group must remain as closely aligned as possible (no more than around 200ps out - ballpark figure), so for example the four pulser clocks must be aligned to each other, the two ADC clocks must be aligned.

With the ADCs the clock that is fed out is a sample clock which goes in to the ADC and then is returned shifted by anywhere between 10.3ns and 12ns internally after which it comes out as an LVDS frame clock. This frame clock feeds back into the FPGA to deserialise LVDS two groups of 8 data channels which may also need constraining.

The two frame clocks are shifted by 165 degrees during the deserialisation resulting in a parallel clock. Data is simply clocked back onto the original sample clock source to return it to the the sample clock domain so that the data from both ADCs is synchronised.

I've attached a drawing of an overview of the system.

I was wondering if someone could guide me through constraining this design as although I have read through several documents on timequest and source-synchronous signals, its not really sinking in and so I don't really know what I am doing (and the effect the commands are having) to put it bluntly.

Any advice would be greatly appreciated.

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    For an ADC (at high speeds) it is not safe to use fpga generated clock due to jitter. Anyway you will need to define it as a clock to timequest.

    For inputs from ADC you need to use set_input_delay to define offset of data from its clk (the one coming from ADC). Apart from that your post and diagram are not clear.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Again,

    I back looking at this after a working on a different bit of the project for a while.

    I understand that the diagram may not be entirely clear, so hopefully the following will clarify the situation.

    New Diagram for a simplified case:

    http://www.alteraforum.com/forum/attachment.php?attachmentid=10147&stc=1

    Basically inside the FPGA we have a clock and a data path - lets call them "Clock A" and "Data A". Lets first look at the clock path.

    Clock A is an 80MHz 50% duty cycle clock. The actual source is a PLL internall, but for simplicity, lets say:

    create_clock -name {clock_a} -period 12.500 -waveform { 0.000 6.250 } [get_ports { source_a }]

    The clock drives a DDR output block (ALTDDIO_OUT). On a rising edge of the clock a 1 is clocked out and on the falling edge a zero is clocked out. This essentially produces an 80MHz clock "Clock Out", which is synchronous to "Clock A", but with some delay as a result of clock routing and the I/O block. So we have the following generated clock (the source being the output pin of the DDIO block and the target is the LVDS output port)

    create_generated_clock -name {clock_out} -master_clock {clock_a} -source [get_pins {*|ddio_outa[0]|muxsel}] [get_ports { clock_out }]

    This clock is routed externally through some device which feeds a synchronous clock back out again - "Clock Return", but with some delay. The total delay for all of the external routing and the device is: 10.4ns < Tdelay < 12.0ns.

    The clock is then fed into the FPGA through a dedicated LVDS clock input. The following commands are how I have tried to describe this, but it could be wrong:

    create_generated_clock -name {clock_b} -source [get_ports {clock_b}] -offset 11.4 -divide_by 1 [get_ports { clock_b }]

    set_clock_uncertainty -from {clock_out} -to { clock_b } -setup 0.6

    set_clock_uncertainty -from {clock_out} -to { clock_b } -hold 1.1

    ----

    Right, so now we have "Clock A" and "Clock B". Internally Clock A is used to drive the register for "Data A". Clock B is used to drive the register for "Data B".

    What I need timequest to tell me is whether or not the setup and hold times for the "Data B" register can be met.

    What I am unsure about is how to correctly define "Clock B". I've been trying to understand the timequest guide and Altera wiki and help pages, but can't get my head around how to translate their examples to my problem.

    Using the constraints that I have put above, everything meets timing, but from looking at the timing report of the path from "Data A" to "Data B" I can't see the delays from the "Clock A" to "Clock Out" being included (though maybe I am misinterpreting it).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    clock return is a base clock and not generated so your constraint is wrong.

    clock B is not needed to be defined separately from clock return before buffer.

    input to register B: Timequest checks all internal paths for slack. That includes input path to register B.

    output from register B:TimeQuest reports io TCO from datasheet report if you set output delay i.e. required data offset from refrrred clock

    you need to treat clkout as data with set output delay as well (not sure what generate statement do here)