5

I have designed a system using Artix-7 FPGA on a custom board. The goal is to transfer 32-bit data to an external onboard chip whose data bus is an inout port. First, a little background:

The external chip is driven by a 100MHz clock which is generated by the FPGA, let's call it o_clk. The FPGA generates this clock through an MMCM in the Memory Interface Generator (MIG IP) using the 200MHz differential system clock. The o_clk is looped back from the FPGA's output and is given to another ball as an input clock, let's call it i_clk.

The external chip receives the o_clk and sees data on this clock's rising edge. However, when the external chip sends data back to FPGA, the FPGA sees this data on the looped back i_clk. The idea behind doing so is that we can treat communications as source synchronous, in both the directions (remember, it is an inout port). Something like below:

FPGA --> EC is synchronous to FPGA because FPGA generates a clock
EC   --> FPGA is synchronous to EC because FPGA gets an external clock (virtually from EC)

To constrain this design, I have used the i_clk to set input delays on the io_data and have used the o_clk to constrain output on the same io_data bus. I have made sure I am using a forwarded clock (create_generated_clock)(using the ODDR2) for the set_output_delay constraint.

Here are my constraints:

create_clock -period 10.000 -name i_clk -waveform {0.000 5.000} [get_ports i_clk]
set_clock_groups -name loopback_grp -asynchronous -group [get_clocks i_clk] -group [get_clocks o_clk]

set_input_delay -clock i_fx3_pclk -max 8.000 [get_ports io_fx3_fdata]
set_input_delay -clock i_clk -min 2.000 [get_ports io_data]

set_output_delay -clock o_clk -max 2.000 [get_ports io_data]
set_output_delay -clock o_clk -min -0.500 [get_ports io_data]

The system seems to work properly when I run it on hardware, but I still have some doubts because I am still an amateur FPGA developer and this is my first big FPGA design.

My questions are:

  1. Have I designed a good system?
  2. Is it correct to treat the communication from EC --> FPGA as source synchronous? (The other direction is source sync because FPGA is providing clock if I am not wrong.!)
  3. Are my constraints correct?
Niteesh Shanbog
  • 711
  • 7
  • 21
  • By these constraints, `i_clk` is asynchronous to `o_clk`. Did you intend this? If you want to make them synchronous, you must define them in the same clock group. For example, `-group [get_clocks "i_clk o_clk"]`. –  Sep 28 '17 at 17:30
  • 3
    If you know the clock/data trace distances between the FPGA and the external device, you should be able to treat the system as a system-synchronous interface. That is, the data returned will have a predictable timing pattern relative to o_clk. In that case, there would be no reason to use i_clk, just constrain relative input data relative to o_clk and clock in with o_clk, and maybe use IDELAYs to meet timing. If the trace length is unknown (the clock/data travel through a cable length that is not known at design time), you will have to treat i_clk as asynchronous. – user2913869 Sep 28 '17 at 21:57
  • @ahmedus, yes, I did that on purpose, because the `i_clk` is looped back in hardware and it doesn't know that both the clocks are related. Should I make them synchronous in a design point of view.? – Vinay Madapura Sep 29 '17 at 07:31
  • The cases are well explained in @user2913869's comment. Shortly it depends on whether the external delay is known. –  Sep 29 '17 at 08:16
  • Do you have more information about your target device? Some devices natively support source-synchronous operation. Also, you will definitely want to set the clocks as related because they obviously have no frequency error between them. – user2943160 Nov 29 '19 at 22:54
  • Looping the clock back on the board doesn't accomplish much if it's just a ball to ball connection. Ideally you would serpentine the trace back to i_clk so that it's length is 2x the length of the data traces to the other chip. This mimics the delay of the clock/data to the other chip and the delay of the data back to the FPGA. – BrianB May 13 '20 at 18:02

1 Answers1

2

Basically what you're trying to do is create a delayed clock to capture your input, and thus allow more setup time for the return signals. While treating the return signals as 'source sync' with a clock that flies with them seems logical, it's not so well controlled: the return clock signal integrity adds another variable to your timing.

You could instead use a phase-shifted clock that captures your input. This is much better controlled and totally dealt with inside the FPGA.

A safe amount of phase shift is at least the output hold time of your far-end device, plus your best-case (fastest) calculated round-trip flight time, entered as your set_output_delay -min value (entered as a negative number for hold time.)

hacktastical
  • 49,832
  • 2
  • 47
  • 138