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?
  • \$\begingroup\$ 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"]. \$\endgroup\$ – ahmedus Sep 28 '17 at 17:30
  • 2
    \$\begingroup\$ 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. \$\endgroup\$ – user2913869 Sep 28 '17 at 21:57
  • \$\begingroup\$ @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.? \$\endgroup\$ – Vinay Madapura Sep 29 '17 at 7:31
  • \$\begingroup\$ The cases are well explained in @user2913869's comment. Shortly it depends on whether the external delay is known. \$\endgroup\$ – ahmedus Sep 29 '17 at 8:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.