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
Visitor pinguin_agya
Visitor
199 Views
Registered: ‎11-20-2018

Bi-directional IOs with DDR - timing issue or design problem?

Hello,

i want to design a SPI-Slave with bi-directional data ports (SIO) and DDR on an Artix7 (xc7a35t). Can you give me a design advise for the SIOs.

Ports:
SCLK : in std_logic;
nCS : in std_logic;
SIO : inout std_logic_vector(7 downto 0);

My suggestion was using IOBUF + ODDR for this IOs. The IOBUF will be automatically created by Vivado using the following assignment:

SIO <= SO when SO_en = '1' else (others => 'Z');


SCLK-Frequency is about 40 MHz. The IO-Timing Constraints are given by a uController. According to the data sheet, i have to set the following IO-Constraints (@40MHz, in ns).

# input timing for FPGA (SPI Slave)
set i_setup_rise 8.5
set i_setup_fall 5.5
set i_hold_rise 3.5
set i_hold_fall 3.5

# output timing for FPGA (SPI Slave)
set o_setup_rise 1.0
set o_setup_fall 1.0
set o_hold_rise 6.0
set o_hold_fall 5.5


Timing constraints:
# 40 MHz serial clock
create_clock -period 25 -name sclk -waveform {0.000 12.5} -add [get_ports SCLK]

# input - rising clock edge
set_input_delay -clock sclk -max 8.5 [get_ports SIO]
set_input_delay -clock sclk -min 3.5 [get_ports SIO] -add_delay


# input - falling clock edge
set_input_delay -clock sclk -clock_fall -max 5.5 [get_ports SIO] -add_delay
set_input_delay -clock sclk -clock_fall -min 3.5 [get_ports SIO] -add_delay

# output - rising clock edge
set_output_delay -clock sclk -reference_pin [get_ports SCLK] -max 1 [get_ports SIO]
set_output_delay -clock sclk -reference_pin [get_ports SCLK] -min -6 [get_ports SIO]

# output - falling clock edge
set_output_delay -clock sclk -clock_fall -reference_pin [get_ports SCLK] -max 1 [get_ports SIO] -add_delay
set_output_delay -clock sclk -clock_fall -reference_pin [get_ports SCLK] -min -5.5 [get_ports SIO] -add_delay


The Timing requirements are not met. The input timing has no error, but the output timing has setup and hold violation (see timing calcuation below).

Can you give me some advice for the design or timing constraints(mabye IOBUF + ODDR is not the best solution)?

Kind Regards,
Pinguin


###################
# SETUP PATH
###################
-------------------------------------------------------------------------------------------------------------------------
| Tool Version : Vivado v.2017.3.1 (lin64) Build 2035080 Fri Oct 20 14:20:00 MDT 2017
| Date : Wed Nov 21 09:16:29 2018
| Command : report_timing -to [get_ports {SIO[0]}]
| Design : SIO_DDR_SPI_example
| Device : 7a35t-ftg256
| Speed File : -1 PRODUCTION 1.19 2017-08-11
-------------------------------------------------------------------------------------------------------------------------

Timing Report

Slack (VIOLATED) : -4.308ns (required time - arrival time)
Source: SO_en_reg/C
(falling edge-triggered cell FDCE clocked by sclk {rise@0.000ns fall@12.500ns period=25.000ns})
Destination: SIO[0]
(output port clocked by sclk {rise@0.000ns fall@12.500ns period=25.000ns})
Path Group: sclk
Path Type: Max at Slow Process Corner
Requirement: 12.500ns (sclk rise@25.000ns - sclk fall@12.500ns)
Data Path Delay: 10.553ns (logic 4.002ns (37.922%) route 6.551ns (62.078%))
Logic Levels: 1 (OBUFT=1)
Output Delay: 1.000ns
Clock Path Skew: -5.220ns (DCD - SCD + CPR)
Destination Clock Delay (DCD): 0.000ns = ( 25.000 - 25.000 )
Source Clock Delay (SCD): 5.220ns = ( 17.720 - 12.500 )
Clock Pessimism Removal (CPR): 0.000ns
Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE
Total System Jitter (TSJ): 0.071ns
Total Input Jitter (TIJ): 0.000ns
Discrete Jitter (DJ): 0.000ns
Phase Error (PE): 0.000ns

Location Delay type Incr(ns) Path(ns) Netlist Resource(s)
------------------------------------------------------------------- -------------------
(clock sclk fall edge) 12.500 12.500 f
C11 0.000 12.500 f SCLK (IN)
net (fo=0) 0.000 12.500 SCLK
C11 IBUF (Prop_ibuf_I_O) 1.527 14.027 f SCLK_IBUF_inst/O
net (fo=1, routed) 1.972 15.999 SCLK_IBUF
BUFGCTRL_X0Y16 BUFG (Prop_bufg_I_O) 0.096 16.095 f SCLK_IBUF_BUFG_inst/O
net (fo=30, routed) 1.625 17.720 SCLK_IBUF_BUFG
SLICE_X1Y52 FDCE r SO_en_reg/C (IS_INVERTED)
------------------------------------------------------------------- -------------------
SLICE_X1Y52 FDCE (Prop_fdce_C_Q) 0.459 18.179 f SO_en_reg/Q
net (fo=4, routed) 6.551 24.730 genSerialOut[0].IOBUF_SCLK/T
G11 OBUFT (TriStatE_obuft_T_O)
3.543 28.273 r genSerialOut[0].IOBUF_SCLK/OBUFT/O
net (fo=1, unset) 0.000 28.273 SIO[0]
G11 r SIO[0] (INOUT)
------------------------------------------------------------------- -------------------

(clock sclk rise edge) 25.000 25.000 r
C11 0.000 25.000 r SCLK (IN)
clock pessimism 0.000 25.000
clock uncertainty -0.035 24.965
output delay -1.000 23.965
-------------------------------------------------------------------
required time 23.965
arrival time -28.273
-------------------------------------------------------------------
slack -4.308

 

###################
# HOLD Path
###################
-------------------------------------------------------------------------------------------------------------------------
| Tool Version : Vivado v.2017.3.1 (lin64) Build 2035080 Fri Oct 20 14:20:00 MDT 2017
| Date : Wed Nov 21 09:17:44 2018
| Command : report_timing -to [get_ports {SIO[0]}] -hold
| Design : SIO_DDR_SPI_example
| Device : 7a35t-ftg256
| Speed File : -1 PRODUCTION 1.19 2017-08-11
-------------------------------------------------------------------------------------------------------------------------

Timing Report

Slack (VIOLATED) : -3.089ns (arrival time - required time)
Source: genSerialOut[0].ODDR_1/C
(rising edge-triggered cell ODDR clocked by sclk {rise@0.000ns fall@12.500ns period=25.000ns})
Destination: SIO[0]
(output port clocked by sclk {rise@0.000ns fall@12.500ns period=25.000ns})
Path Group: sclk
Path Type: Min at Fast Process Corner
Requirement: 0.000ns (sclk rise@0.000ns - sclk rise@0.000ns)
Data Path Delay: 1.407ns (logic 1.406ns (99.929%) route 0.001ns (0.071%))
Logic Levels: 1 (OBUFT=1)
Output Delay: -6.000ns
Clock Path Skew: -1.540ns (DCD - SCD - CPR)
Destination Clock Delay (DCD): 0.000ns
Source Clock Delay (SCD): 1.540ns
Clock Pessimism Removal (CPR): -0.000ns
Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE
Total System Jitter (TSJ): 0.071ns
Total Input Jitter (TIJ): 0.000ns
Discrete Jitter (DJ): 0.000ns
Phase Error (PE): 0.000ns

Location Delay type Incr(ns) Path(ns) Netlist Resource(s)
------------------------------------------------------------------- -------------------
(clock sclk rise edge) 0.000 0.000 r
C11 0.000 0.000 r SCLK (IN)
net (fo=0) 0.000 0.000 SCLK
C11 IBUF (Prop_ibuf_I_O) 0.295 0.295 r SCLK_IBUF_inst/O
net (fo=1, routed) 0.634 0.929 SCLK_IBUF
BUFGCTRL_X0Y16 BUFG (Prop_bufg_I_O) 0.026 0.955 r SCLK_IBUF_BUFG_inst/O
net (fo=30, routed) 0.585 1.540 SCLK_IBUF_BUFG
OLOGIC_X0Y50 ODDR r genSerialOut[0].ODDR_1/C
------------------------------------------------------------------- -------------------
OLOGIC_X0Y50 ODDR (Prop_oddr_C_Q) 0.177 1.717 r genSerialOut[0].ODDR_1/Q
net (fo=1, routed) 0.001 1.718 genSerialOut[0].IOBUF_SCLK/I
G11 OBUFT (Prop_obuft_I_O) 1.229 2.946 r genSerialOut[0].IOBUF_SCLK/OBUFT/O
net (fo=1, unset) 0.000 2.946 SIO[0]
G11 r SIO[0] (INOUT)
------------------------------------------------------------------- -------------------

(clock sclk rise edge) 0.000 0.000 r
C11 0.000 0.000 r SCLK (IN)
clock pessimism 0.000 0.000
clock uncertainty 0.035 0.035
output delay 6.000 6.035
-------------------------------------------------------------------
required time -6.035
arrival time 2.946
-------------------------------------------------------------------
slack -3.089

0 Kudos
4 Replies
Xilinx Employee
Xilinx Employee
94 Views
Registered: ‎01-05-2017

Re: Bi-directional IOs with DDR - timing issue or design problem?

Hi,

Could you please show a timing diagram of the required setup/hold times and how the data and clock are aligned? Thanks.

David

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
Visitor pinguin_agya
Visitor
65 Views
Registered: ‎11-20-2018

Re: Bi-directional IOs with DDR - timing issue or design problem?

Hello David,

thanks for your response!

I hope the timing diagram and block diagram gives you a good overview about the timing. 

 

Block diagram:

Blockschaltbild.png

 

Timing diagram from uC (values - see block diagram):

Timing_diagram_uC.png

 

Typical SPI transmission:

SPI-Interface.png

 

 

 

 

Blue SIO data: Request from Master (used for Input delay arrows)

Yellow SIO data: response to Master (from Slave - used for Output delay arrows)

Z:= High impedance (switch direction of SIO)

Data driven with falling clock edge, will first be latched with rising edge at receiver (and vice versa). 

 

According to the Xilinx Templates I used for input delays the template Source synchronous DDR example and for output delays the source synchronous DDR Example (see below). The clock is defined with 40Mhz. 

 

# 40 MHz serial clock
create_clock -period 25 -name sclk -waveform {0.000 12.5} -add [get_ports SCLK]

 

# Edge-Aligned Double Data Rate Source Synchronous Inputs
# (Using a direct FF connection)
#

# input             _________________________________
# clock   _________|                                 |___________________________
#                  |                                 |
#          skew_bre|skew_are                 skew_bfe|skew_afe
#          <------>|<------>                 <------>|<------>
#        _         |       _________________         |       _________________
# data   _XXXXXXXXXXXXXXXXX____Rise_Data____XXXXXXXXXXXXXXXXX____Fall_Data____XX

# input - rising clock edge
set_input_delay -clock sclk -max 8.5 [get_ports SIO]
set_input_delay -clock sclk -min 3.5 [get_ports SIO] -add_delay


# input - falling clock edge
set_input_delay -clock sclk -clock_fall -max 5.5 [get_ports SIO] -add_delay
set_input_delay -clock sclk -clock_fall -min 3.5 [get_ports SIO] -add_delay

 

# Double Data Rate Source Synchronous Outputs
#
# forwarded                      ________________________________
# clock               __________|                                |______________
#                               |                                |
#                         tsu_r | thd_r                    tsu_f | thd_f
#                       <------>|<------->               <------>|<----->
#                       ________|_________               ________|_______
# data @ destination XXX__________________XXXXXXXXXXXXXXX________________XXXXX

# output - rising clock edge
set_output_delay -clock sclk -reference_pin [get_ports SCLK] -max 1 [get_ports SIO]
set_output_delay -clock sclk -reference_pin [get_ports SCLK] -min -6 [get_ports SIO]

# output - falling clock edge
set_output_delay -clock sclk -clock_fall -reference_pin [get_ports SCLK] -max 1 [get_ports SIO] -add_delay
set_output_delay -clock sclk -clock_fall -reference_pin [get_ports SCLK] -min -5.5 [get_ports SIO] -add_delay

Note: For output timing i've used the -reference_pin because the timing is related to SCLK Pin.

 

Kind Regards,

Martin

0 Kudos
Historian
Historian
53 Views
Registered: ‎01-23-2009

Re: Bi-directional IOs with DDR - timing issue or design problem?

It looks like you have a couple of problems...

First, it's very hard to read the timing report you posted - the format is all messed up. Maybe you can repost it with better formatting - either a screen shot of the graphic report, or a pure (formatted) text report - you may need to put it in an "Insert Code" box to preserve the formatting (with the new Forum format I don't know exactly what the interface does with formatted reports).

But the big problem is your output hold time. The device needs 6ns of output hold time, but you have not described an architecture that has the ability to generate this. The 6ns requirement is from the SCLK input - you have it going through a BUFG and directly to an ODDR flip-flop and OBUF (for the "data output" part of your output). With this architecture, the only hold time you get is the "natural" hold time from the propagation of these components, which is not enough to satisfy the 6ns requirement. So you get a hold time failure from the ODDR.

However, for the tristate enable part of your output, the tristate enable control is not packed in the IOB - it is using a fabric flip-flop. It probably shouldn't - you should get it packed into the IOB - you may need to set the IOB property on the output or even directly on the tristate flip-flop (you may have to play with it a bit to get this done). With it in the IOB flip-flop, whatever solution you do to get the output data path to pass will also work for the tristate path. But, as it is, since the tristate FF is in the fabric, the tool can add additional routing delay to get it to meet the 6ns hold time requirement. In doing so, it is adding TONS of additional routing to this path (and may even get this path to meet the required hold time). But because of all this additional routing, the path is now violating the setup requirement.

The solution is to come up with an architecture that allows you to meet this hold time requirement. If the I/O is a High Performance (HP) I/O then you can consider using the ODELAY to give you the delay you need. The advantage of the ODELAY (over routing) is that it is Process/Voltage/Temperature compensated - with routing delay, for every 1ns the tool adds at "FAST" process, this results in around 3ns at "SLOW" process - with the ODELAY the value is almost identical at both process corners.

If this is not an option, then things become more complicated. Is your SCLK always running, or is it gapped? If it is always running then you can use an MMCM. With the MMCM, you can specify a phase delay between the input clock and the output clock. By adding an MMCM delay to the clock, you can push the clocking of the IOB flip-flops (and DDR flip-flops) forward to satisfy the hold time requirement of the external device. However, if the SCLK is gapped (not running when there are no accesses  on the serial bus) then you cannot use an MMCM.

If neither of these cases are available (the SCLK is gapped and the IO is in a High Range I/O), you may be in trouble - even though this interface is slow-ish (40MHz DDR), it is probably too fast to oversample, and has timing requirements that you cannot meet with the resources you have available.

Finally, a quick note. The -reference_pin option is not useful here - you have already specified the timing with respect to the clock you defined on the SCLK pin, so the tool understands that relationship. The "reference_pin" option is used only when you want to relate one output to a clock that is also an output of the FPGA. Even then, this only gives you a report, which was all the old tool - ISE - could do. With Vivado, even in this case, you can properly define the timing relationship of this system with a generated clock - so the -reference_pin is basically a useless option (it's merely to give ISE users an option to get the kind of analysis they used to have).

Avrum

0 Kudos
Visitor pinguin_agya
Visitor
19 Views
Registered: ‎11-20-2018

Re: Bi-directional IOs with DDR - timing issue or design problem?

Hello avrumw,

thanks for your detailed answer!

Using the IOB attribute for the tristate input of the IOBUFT works and improves the setup timing! Using the IOB-attribute on the tristate-buffer the timing problems are reduced to some hold Pathes (from SIO and to SIO). So, I add some IDELAYs into the input pathes and fix the hold times "from SIO".

Now, i got only hold violations on the output data path (to SIO). This pathes has a worst hold slack of -3ns (Path from ODDR/C to SIO[*] ).

 

In Artix7 there are NO ODELAY primitives available (only HR IOs)! Can I use other primitives to apply some additional delay on the clock-path of the SIO output? (OSERDES, BUFG/BUFR, ...)

Do you have any ideas?

Kind regards

Pinguin

0 Kudos