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: 
1,341 Views
Registered: ‎07-16-2018

Vivado : constraints setup for common clock with multiple SPI interface

Jump to solution

I have been using Vivado 2018 for a system level design and am having trouble with a SPI interface programming. A block diagram of my system is shown below.

vivado_spi_interface_diagram.jpg

 

The Artix-7 FPGA (on the motherboard) sends out a 3-wire SPI interface to 4 daughterboards. Following are the specifications :

FPGA :

  • CLK : input clock to the FPGA
  • SCLK : MMCM generated clock used to generate the SPI clock for the internal modules. These module generate the serial data to program the IC's on the daughterboard.
  • SPI_SCLK : serial clock for the SPI interface common to all daughter-boards.
  • SPI_CS : select lines common to all daughter-boards (using the select line from module #1 on the FPGA)
  • SPI_SDI[1,2,3,4] : serial data specific to each daughter-board generated by the corresponding module on the daughter-board

Daughter-Board(s)

  • CLK_BUF : a clock buffer for the SPI clock, which introduces a 5ns propagation delay.
  • IC #1 --> IC #7 daisy chained on the daughterboard
  • Common select lines to the daughterboards

CONDITIONS

  • Delay on all SPI lines going from FPGA to daughter-boards are equal.
  • delay introduced by BUF IC = 5ns
  • tsetup (IC) = 5ns
  • thold (IC) = 5ns

I have setup my constraint files as follows:

 

create_generated_clock -name sclk [get_pins clock_sources/inst/mmcm_adv_inst/CLKOUT2]

set_output_delay -clock sclk -max 5.000 [get_ports {spi_sdi[*]}]
set_output_delay -clock sclk -min -5.000 [get_ports {spi_sdi[*]}]

set_output_delay -clock sclk -max 5.000 [get_ports {spi_cs]
set_output_delay -clock sclk -min -5.000 [get_ports {spi_cs}]

QUESTIONS

  1. Is this the correct approach to setup the constraint file for the SPI interface? Because of the propagation delay introduced by the CLK BUF IC on the daughter-board, I would like to delay the SPI_CS and SPI_SDI[1,2,34] lines by the amount equal to the propagation delay of the CLK BUF IC.
  2. I believe the Modules 1,2,3,4 will have different net delays for the SPI_SDI[*] paths going out of the FPGA board. How should I ensure that these line see the same delay and hence are output synchronous to each other?
  3. Similarly the SCLK going into each of the modules on the FPGA vs the SPI_SCLK going to the daughter-boards see different delay. Will this affect the serial data put on the bus?

I would like to understand how to tackle these issues. Any help is appreciated.

Thanks

0 Kudos
1 Solution

Accepted Solutions
Historian
Historian
1,256 Views
Registered: ‎01-23-2009

Re: Vivado : constraints setup for common clock with multiple SPI interface

Jump to solution

It is strange that only "spi_cs"  sees this warning and not the "spi_sdi[*]" ports

 

In order for a flip-flop to be packed into an IOB

  - the Q output of the flip-flop must go directly to the I input of the OBUF

  - the flip-flop can drive only one OBUF (you cannot drive multiple OBUFs with the same flip-flop

  - there can be no intervening logic (except for an ODELAY if the IOB is an HP I/O) between the flip-flop and the OBUF

  - the Q output cannot drive anything else (including itself for feedback)

 

If any of those rules are violated, then the flip-flop cannot be packed into the IOB, and you will get this message.

 

Look at the RTL generation of the spi_cs output - presumably it is violating one of the above rules.

 

Avrum

8 Replies
1,298 Views
Registered: ‎01-22-2015

Re: Vivado : constraints setup for common clock with multiple SPI interface

Jump to solution

@antaresmajoris

 

Welcome to the Xilinx Forum!

 

It is rare to receive such a clear and organized explanation with questions. Thank you!

 

Before we tackle your questions, please tell me:

  1. What is the frequency of SPI_CLK?
  2. Are you implementing the Serial Peripheral Interface (SPI) described <here>?
  3. Do you only need to send data to IC#1 - IC#7  (and not receive data from them)?
  4. What is the part number and manufacturer for some (or all) of IC#1 – IC#7

 

Mark

Historian
Historian
1,289 Views
Registered: ‎01-23-2009

Re: Vivado : constraints setup for common clock with multiple SPI interface

Jump to solution

First, for forwarding a clock out of the FPGA you should use an ODDR, rather than just routing the clock to an OBUF. When you route the clock to the OBUF, the clock needs to leave the dedicated clock network and go through general fabric routing. When you use an ODDR (with D1 tied to 1 and D2 tied to 0), this leaves the clock on the dedicated clock network all the way to the clock pin of the ODDR and forwards a "mirror" of the clock out. This has much better skew control and better jitter characteristics.

 

Second, your generated clock is not correct. Assuming you use an ODDR (I will call it my_oddr), then the proper command is

 

create_generated_clock -name sclk -source [get_pins my_oddr/C] -divide_by 1 [get_ports SPI_SCLK]

 

Now you can define the timing of the different outputs with respect to sclk; the -max should be the setup requirement of the device and the -min should be the negative of the hold requirement of the device.

 

One thing that is missing here is your clock buffer; you say it introduces a 5ns delay - presumably this is the MAX, we also need to know the MIN. You would then need to account for it.

 

One way to do this would be by modifying the setup and hold requirements; the hold requirement would increase by the MAX delay of the BUFIC and the setup requirement would decrease by the MIN of the BUFIC.

 

Another way would be to directly describe the latency with the set_clock_latency command. I have never tried to apply a clock latency to an output clock, you can try it and see if it works. Assuming you do it this way, then your set_output_delay commands are correct as you have done them.

 

set_clock_latency -source -max 5 [get_ports SPI_SCLK]

set_clock_latency -source -min 1 [get_ports SPI_CLK]

 

Now for your questions.

 

1) I would like to delay the SPI_CS and SPI_SDI[1,2,34] lines by the amount equal to the propagation delay of the CLK BUF IC.

 

You have to understand what constraints do - they describe the external timing of the system to the FPGA. They do not (necessarily) make the tools meet that timing. When it comes to I/O interfaces, they need to be designed. You may (or may not) be right that the data needs additional delay to match the clock delay. Assuming it does, how is that going to happen?

 

If the flip-flops that drive the data outputs are in the fabric, the tool will attempt to add additional internal routing delays to create any needed delay. However, 5ns is a LOT of delay for the router to add - this will take routing resources inside the FPGA, will be highly process/voltage/temperature (PVT) dependent and will also add jitter to the output signals. Depending on the speed of the interface, this may be acceptable, but it probably isn't the best approach.

 

Generally it is recommended to have output interfaces driven directly from flip-flops and to force those flip-flops into the IOB. This is done with

 

set_property IOB true [get_ports {<the ports in question>}]

 

When done this way, you get more reliable timing with much less variation, but the tools have no ability to modify the output delay - it is what is (which is almost perfectly aligned with the clock that is being driven by the ODDR).

 

So how else can you get delays? There are a couple of other ways:

  - use the ODELAY, which sits between the IOB flip-flop and the OBUF. However, these are only available on high performance (HP) I/O, and they cannot give more than about 2.5ns of delay (depending on how they are configured)

  - use a different edge of the clock. In most SPI interfaces, this is probably the best way - if you (for example) invert the outgoing clock and still use the rising edges of the internal clock to generate the data, you automatically get close to 1/2 clock period of setup time and 1/2 period of hold time. For slow interfaces this is the best approach. To do this, change the connections of the ODDR so that D1 is 0 and D2 is 1. You also need to change the create_generated_clock command to include the -invert flag

  - use the MMCM to generate two different clocks with different phases - one clock is used by the ODDR and the other is used to clock the IOB flip-flops for the data. You can introduce any phase difference you want/need between these two clocks using the attributes of the MMCM

 

In any of these cases, the tools will analyze the interface based on the constraints you gave it, and tell you that the interface you designed either passed the timing requirements or failed the timing requirements...

 

2) How should I ensure that these line see the same delay and hence are output synchronous to each other?

 

Why do you think this is necessary. As long as each of the destinations meets its timing requirements, skew between them should be irrelevant.

 

3) the SCLK going into each of the modules on the FPGA vs the SPI_SCLK going to the daughter-boards see different delay. Will this affect the serial data put on the bus?

 

If the clock and data signals have different propagation paths to the destination device, then you need to modify the set_output_delay commands accordingly (in a way similar to what I did for the BUFIC). You need to specify the set_output_delay commands so that they accurately reflect the requirements of the system - in this case the system includes the devices and the trace lengths of both the clock and the data.

 

Avrum

0 Kudos
1,277 Views
Registered: ‎07-16-2018

Re: Vivado : constraints setup for common clock with multiple SPI interface

Jump to solution
markg@prosensing.com
Thanks for our response. Please see my responses below:

markg@prosensing.com wrote:

@antaresmajoris

 

Welcome to the Xilinx Forum!

 

It is rare to receive such a clear and organized explanation with questions. Thank you!

 

Before we tackle your questions, please tell me:

  1. What is the frequency of SPI_CLK?
    • The SPI clock is running at 10 MHz
  2. Are you implementing the Serial Peripheral Interface (SPI) described <here>?
    • Yes, I am implementing a 3-wire  SPI interface (Master --> Slave)
  3. Do you only need to send data to IC#1 - IC#7  (and not receive data from them)?
    • Yes I am only sending data, and not receiving any from the IC's
  4. What is the part number and manufacturer for some (or all) of IC#1 – IC#7
    • Its MAX14662 : setup and hold times for a 10 MHz clock are 15ns (datasheet attached)

 

Mark


 

0 Kudos
1,270 Views
Registered: ‎07-16-2018

Re: Vivado : constraints setup for common clock with multiple SPI interface

Jump to solution

@avrumw

 

Thank you for your detailed explanation.

 

I have now modified my constraints file as below :

# CONFIGURING THE OUTPUT SPI PORTS TO BE PLACED IN IOB
set_property IOB TRUE [get_ports spi_sdi[*]]
set_property IOB TRUE [get_ports spi_cs]

# CREATE FORWARDED CLOCK FROM ODDR INSTANTIATION
#create_generated_clock -name clk_s -divide_by 1 -source [get_pins ODDR_inst_spi/C] [get_ports spi_sclk]
create_generated_clock -name clk_s -source [get_pins ODDR_inst_spi/C] -divide_by 1 -invert [get_ports spi_sclk] 
set_output_delay -clock clk_s -max 15.000 [get_ports {spi_sdi[*]}]
set_output_delay -clock clk_s -max 15.000 [get_ports {spi_cs}]
set_output_delay -clock clk_s -min -15.000 [get_ports {spi_sdi[*]}]
set_output_delay -clock clk_s -min -15.000 [get_ports {spi_cs}]

set_clock_latency -source -max 6.5 [get_ports spi_sclk]
set_clock_latency -source -min 1.5 [get_ports spi_sclk]

The ODDR instantiation in my code is as follows :

-- ODDR: Output Double Data Rate Output Register with Set, Reset
-- and Clock Enable.
-- 7 Series
-- Xilinx HDL Libraries Guide, version 2012.2
    ODDR_inst_spi : ODDR
      generic map(
          DDR_CLK_EDGE => "SAME_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
          INIT => '0', -- Initial value for Q port ('1' or '0')
          SRTYPE => "SYNC") -- Reset Type ("ASYNC" or "SYNC")
          port map (
          Q => spi_sclk, -- 1-bit DDR output
          C => sclk, -- from MMCM
          CE => '1', -- 1-bit clock enable input
          D1 => '0', -- 1-bit data input (positive edge)
          D2 => '1', -- 1-bit data input (negative edge)
          R => '0', -- 1-bit reset input
          S => '0' -- 1-bit set input
      );
-- End of ODDR_inst instantiation

 

The 6.5 ns, and 1.5 ns are the max and min propagation delay times from the datasheet (attached)

 

However, I see a critical warning  after implementation

[Place 30-722] Terminal 'spi_cs' has IOB constraint set to TRUE, but it is either not connected to a FLOP element or the connected FLOP element could not be brought into the I/O

It is strange that only "spi_cs"  sees this warning and not the "spi_sdi[*]" ports

 

Any inputs for this is appreciated!

 

Thanks

0 Kudos
Historian
Historian
1,257 Views
Registered: ‎01-23-2009

Re: Vivado : constraints setup for common clock with multiple SPI interface

Jump to solution

It is strange that only "spi_cs"  sees this warning and not the "spi_sdi[*]" ports

 

In order for a flip-flop to be packed into an IOB

  - the Q output of the flip-flop must go directly to the I input of the OBUF

  - the flip-flop can drive only one OBUF (you cannot drive multiple OBUFs with the same flip-flop

  - there can be no intervening logic (except for an ODELAY if the IOB is an HP I/O) between the flip-flop and the OBUF

  - the Q output cannot drive anything else (including itself for feedback)

 

If any of those rules are violated, then the flip-flop cannot be packed into the IOB, and you will get this message.

 

Look at the RTL generation of the spi_cs output - presumably it is violating one of the above rules.

 

Avrum

1,231 Views
Registered: ‎01-22-2015

Re: Vivado : constraints setup for common clock with multiple SPI interface

Jump to solution

@antaresmajoris

 

You’ll get no better answer to your questions than Avrum’s.

 

However, I thought you may be interested in an alternative way to do SPI.  It is called “bit banging” and is a method that ensures the interface passes timing analysis by design.  So, in theory, you need not write timing constraints.  Bit-banging the SPI goes roughly as follows…

 

Use the MMCM to produce a 100MHz clock, CLK100, that will clock FPGA Modules#1-#4 in your design.  Create a new Module#5 inside the FPGA that supervises Modules #1-#4 and controls SPI_CS.  Module#5 also creates the SPI_SCLK by sending a signal (not a real clock) to an IOB register that feeds the SPI_SCLK output pin of the FPGA.  Per Fig 10 of the MAX14662 datasheet, Module#5 will operate roughly as follows for SPI_SCLK=10MHz:

 

  1. Place SPI in rest state (SPI_CS=1, SPI_SCLK=1)

  2. To begin data transmission, set SPI_SCLK=0

  3. Wait 5 cycles of CLK100 (50ns) and set SPI_CS=0.  Modules#1-#4 see SPI_CS falling-edge and put first bit of data on SPI_SDI[.].

  4. Wait 50ns and set SPI_SCLK=1.  Note that 55ns=50ns+5ns(for PI49FCT buffer) satisfies tCSS=15ns and tDS=15ns specs of MAX14662.

  5. Wait 50ns and set SPI_SCLK=0.  Modules#1-#4 put next bit of data on SPI_SDI[.]  Note that 45ns=50ns-5ns(for PI49FCT buffer) satisfies tDH=15ns spec of MAX14662.

  6. Steps 4. and 5. are repeated until all data bits have been sent.  This could be quite a few bits since you are daisy-chaining IC #1-#7 (see MAX14662 datasheet for details)

  7. Wait tCSH=60ns, set SPI_CS=1 followed by SPI_SCLK=1, and return to rest state 1.

 

Bit-banging can be implemented nicely using the HDL "state machine" coding technique.

 

Mark

0 Kudos
1,178 Views
Registered: ‎07-16-2018

Re: Vivado : constraints setup for common clock with multiple SPI interface

Jump to solution

@avrumw

 

Thank you so much for your response.

This seems to do the trick!

I have my clock using the ODDR module and the CS, SDI in the IOB buffers.

I have some other issues with the hardware, but for now the output constraints behave as they should.

 

Thanks a ton!

0 Kudos
Highlighted
1,175 Views
Registered: ‎07-16-2018

Re: Vivado : constraints setup for common clock with multiple SPI interface

Jump to solution

markg@prosensing.com

 

Hi Mark

Thanks for introducing me to this alternate method. I will surely try this at some point to see if I get similar results. However at this point the constraints seemed to help me.

 

Thanks for helping me out on my queries.

 

0 Kudos