UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
8,051 Views
Registered: ‎06-29-2016

Constraining Source Synchronous SDR interface

Hi All,

I am using a Kintex fpga that has a source-synchronous bus that connects to a SPI peripheral, and I need to properly constrain the bus. My FPGA system clock runs at 100 Mhz, whereas the spi peripheral's clock is limited to 4 Mhz. I am generating a 4 Mhz clock using a simple counter and registers. Attached is a crude schematic of the design with corresponding setup/hold and propagation delays.

* What would be the best way to constraint my fpga inputs and outputs for the bus?

* Should I use set_input_delay and set_output_delay?

* Does it make sense to define a multi-cycle path from the registers of my fpga to the ports?

 

Thank you,

--

Amir

IMG_20160630_101306046.jpg
0 Kudos
2 Replies
Guide avrumw
Guide
8,034 Views
Registered: ‎01-23-2009

Re: Constraining Source Synchronous SDR interface

For systems like this, it is simplest to just ensure that the output and input flip-flops are packed into the IOBs. This limits the skew between the forwarded clock and forwarded data to the couple of hundred picosecond range, and hence becomes irrelevant in a system that is running at 4MHz (250ns period). You can place set_output_delays on this, or even go so far as to constrain the forwarded output with respect to the forwarded clock (using a create_generated_clock on the forwarded clock), but this probably isn't necessary.

 

On the receive side you will have more uncertainty, since the total path is

  clock inside FPGA ->

  Q output of IOB FF generating forwarded clock (<1ns) ->

  IOB output (2-6ns) ->

  board trace delay (1ns) ->

  clock2q of peripheral (12ns-14ns) ->

  board trace delay back (0.6ns) ->

  setup requirement of IOB wrt. internal clock (a little hard to measure)

 

But even being pessimistic on all these times you still have TONS of time on this 250ns bit period...

 

In reality the internal FPGA delays are irrelevant to this interface - the timing is really determined by the choices of 100MHz clock edges that launch the forwarded clock, compared to the internal 100MHz clock edge that captures the data.

 

By forcing all the FFs in the IOBs you limit the range on these internal delays, and you can worst case them - even if you assume the ridiculous values of 10ns for all the internal delays, you still have TONS and TONS of room in a 250ns bit period.

 

So, you can constrain these, and if you really want to, it can be done elegantly and completely in Vivado (using generated clocks and large set_multicycle_path constraints), but its really not necessary...

 

Avrum

7,828 Views
Registered: ‎06-29-2016

Re: Constraining Source Synchronous SDR interface

Hi Avrum,

 

Thanks for your response. There is a good probability that the SPI device will be replaced with a 50Mhz peripheral, and having good constraints becomes very important. I want to have my constraints in a way that does not rely on the room given by the big period (250 ns) of the SPI peripheral, and that as the requirements of the bus get tighter and tighter, the design will be correctly constrained.

 

As of now, all the outputs of the bus are forced into IOBs using ODDR registers. So far I have the following constraints:

#################################################################
# Clock Definitions
################################################################## 
# 4 Mhz Serial Clk Generated at the output of an ODDR
create_generated_clock -name serialClk \
                       -source [get_pins ODDR_inst_serial_clk/C] \
                       -edges {1 26 51} \
                       [get_ports sclk]

# 100 Mhz clock period (10 ns)
set systemClkPeriod [get_property PERIOD [get_clocks sysclk]]

# 4 Mhz clock period (250 ns)
set serialClkPeriod [get_property PERIOD [get_clocks serialClk]] 

#################################################################
# Input and Output Delays
#################################################################

set trace_delay_clock   1.0
set trace_delay_data    0.6

set mosi_setup         [expr {20.0 + $trace_delay_clock - $trace_delay_data}]
set mosi_hold          [expr {2.0 + $trace_delay_clock - $trace_delay_data}]

# Miso propagation delay from clock to data port in the downstream device
set Tpd_Max             14.0
set tpd_Min             12.0

set miso_max_delay     [expr {$Tpd_Max + $trace_delay_clock + $trace_delay_data}]
set miso_min_delay     [expr {$Tpd_Min + $trace_delay_clock + $trace_delay_data}]

# Data is changed on the falling edge of the serial clock and the downstream device will
# pick it up on the rising edge of the serial clock.
set_output_delay -clock [get_clocks serialClk] -clock_fall -max $mosi_setup [get_ports mosi]
set_output_delay -clock [get_clocks serialClk] -clock_fall -min $mosi_hold  [get_ports mosi]

# Downstream device (slave) will change the data on the rising edge of the serial clock and the 
# FPGA (master) will pick it up at the falling edge of the serial clock.
set_input_delay -clock [get_clocks serialClk] -clock_fall -max $miso_max_delay [get_ports miso]
set_input_delay -clock [get_clocks serialClk] -clock_fall -min $miso_min_delay [get_ports miso]

#################################################################
# Multi-Cycle Paths
#################################################################

# Number of Multi-Cycle counts
set multiCycleCount [expr {int(ceil($serialClkPeriod/$systemClkPeriod))}]

set_multicycle_path -from [get_pins ODDR_inst_mosi/C] \
                    -to [get_ports mosi] \
                    -setup -start \
                    $multiCycleCount
set_multicycle_path -from [get_pins ODDR_inst_serial_out/C] \
                    -to [get_ports mosi] \
                    -hold \
                    [expr {$multiCycleCount-1}]

set_multicycle_path -from [get_ports miso] \
                    -setup \
                    $multiCycleCount
set_multicycle_path -from [get_ports miso] \
                    -hold -end \
                    [expr {$multiCycleCount-1}]

My question is, will these constraints adequately represent the system? Will the design function correctly when the requirements are tight?

Thanks,

--

Amir

0 Kudos