- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I know there is a lot of discussion on this board regarding timing constraints, but I couldn't find this topic well addressed.
I have a system where my FPGA interfaces to an ADC using a SPI like master interface. I am struggling a bit with how to properly constrain this IO. For the purposes of this discussion assume the interface contains SCLK (out), CS(out), MOSI(out), MISO(in). I think that I understand that the CS and MOSI signals should be treated as source synchronous signals with respect to SCLK for setup and hold analysis. However I am struggling a bit with how the MISO input should be treated. I know that I need to create a virtual clock to launch this signal with my latch clock being the internal SCLK. To further complicate things, my setup contains several buffer stages for reasons I won't go into here that have potential for introducing skew between signals. I have attached a diagram of my basic setup. https://www.alteraforum.com/forum/attachment.php?attachmentid=6628 This is what I have so far in my SDC: # base clocks create_clock -name data_clk -period "32.768Mhz";# main clock create_clock -name data_io_clk -period "32.768Mhz";# latch clock for MOSI and CS create_clock -name data_io_clk_ext -period "32.768Mhz";# virtual clock for launch of MISO derive_pll_clocks derive_clock_uncertainty# ------------------------------------------------------------------------------# Component timing parameters# ------------------------------------------------------------------------------# ISO_BUF set iso_buf_tsk 6.5 # CLK_BUF set clk_buf_tsk 0.05 set clk_buf_tpd_min 0.8 set clk_buf_tpd_max 2.0 # DAT_BUF set dat_buf_tsk 1.0 set dat_buf_tpd_min 1.5 set dat_buf1_tpd_max 5.1 # ADC set adc_tsu 5.0 set adc_th 5.0 set adc_cto_min 10.0 set adc_cto_max 25.0# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------# FPGA <-> ADC SPI Interface Constraints# ------------------------------------------------------------------------------ set adc_in_min [expr $adc_cto_min] set adc_in_max [expr $adc_cto_max] set adc_out_min [expr -($clk_buf_tsk + $iso_buf_tsk + ($clk_buf_tpd_max - $dat_buf_tpd_min) + $adc_th)] set adc_out_max [expr $clk_buf_tsk + $iso_buf_tsk + ($dat_buf_tpd_max - $clk_buf_tpd_min) + $adc_tsu] set_input_delay -min -clock { data_io_clk_ext } $adc_in_min [get_ports adc_miso\[*\]] set_input_delay -max -clock { data_io_clk_ext } $adc_in_max [get_ports adc_miso\[*\]] set_output_delay -min -clock { data_io_clk } $adc_out_min [get_ports { adc_cs adc_mosi\[*\]}] set_output_delay -min -clock { data_io_clk } $adc_out_min [get_ports { adc_cs adc_mosi\[*\]}]# ------------------------------------------------------------------------------ My basic strategy here was to analyze these signals for skew only as board delays will be basically negligible due to the fact that these signals begin routed together as a group. So my main concern is that I meet tsu and thd of the adc and that the miso meets tsu and thd of the FPGA. The overall tpd will be more then one clock cycle, but I can handle that in logic using delay states. I am assuming I need to somehow account for the skew that would occur on the clock signal for the MISO signal, but I am having trouble understanding what this might look like. Also for my outputs, when I compile this code and look at it in timequest, the tco of the FPGA is ~10ns, but when I actually run this configuration on hardware, the tco looks more like 5ns. In order to adjust for the potential skew introduced by the system my minimum tco needs to be greater then 12.05ns (adc_out_min) and my maximum tco must be less then 15.85ns. Anyone have any idea what I am doing wrong here and what I should change to achieve this? Thanks in advance!Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your clock constraints look incorrect; you're just creating 3 identical virtual clocks.
Instead, you should do it like this: create_clock -name clk -period $mainClockPeriod [get_ports clk# Constrain the clock that actually goes into the FPGA derive_pll_clocks# Constrain PLL generated clocks create_generated_clock -name data_io_clk -source $pllOutput [get_ports $sclkOutputPortName]# Create a derived clock on the SCLK output pin You don't need a virtual clock for this case, because the clock is provided by the FPGA. So the CS, MOSI and MISO signals should all be constrained in relation to data_io_clk. What you need to do for MISO is the same thing you did CS/MOSI: take into account all your clock/signal buffers and the ADC's MISO tCO and figure out what's the minimum and maximum delay between a SCLK rising edge and a MISO transition, seen at the FPGA pins. In case of doubt, drawing the timing diagram always helps. Your output delay calculations look a bit more complicated than they should, but I didn't examine it carefully so they may be all right. It should be something like max output delay = adc tSU + sum of all max buffer delays on data path - sum of all min buffer delays on clock path min output delay = -adc tH + sum of all min buffer delays on data path - sum of all max buffer delays on clock path For the input delay, it should be max input delay = max adc tCO + sum of all max buffer delays on data path + sum of all max buffer delays on clock path min input delay = min adc tCO + sum of all min buffer delays on data path + sum of all min buffer delays on clock path You mention that your delays are > 1 clock and you'll use delay states to handle this. This is OK, but you may need to add multi-cycle exceptions to adjust the constrains, or TimeQuest may never give you a "pass" (even if your design might actually work). That said, I'm not sure you'll be able to achieve timing closure for 32 MHz operation, given all those delays.. you may have to run with a slower SCLK. I'll leave your last question to when you've fixed these issues. :)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much, this was very helpful. I too am very concerned about closing timing.
After going through the exercise I think I have found that while I can close timing on the output signals interface, it will not be possible to close timing on the MISO using the current hardware approach. However, I do need to run at these speeds. I think I have come up with a method to allow this. If I loop back the SCLK and the CSn, that should set up a source synchronous interface for the MISO. If I then feed that SCLK into a PLL and phase shift as needed to center in the valid data window I should be able to both run at my desired speed and meet timing. Then for timing purposes, I only need to be concerned with the possible skew between signals similar to the what I was able to do for the output signals. Any thoughts on this approach?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't see anything wrong with nor do I have a better idea now. :)
You might not need a PLL though, just using the falling edge of the received SCLK might work. Note that you'll have to treat the incoming SCLK as an asynchronous clock, in regard to SCLK and others. What are the values you got for min and max input delay?
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page