Electronic – Interfacing FPGA to an external chip and timing constraints

designfpgaxdc

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?

Best Answer

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.)