5
\$\begingroup\$

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?
\$\endgroup\$
6
  • \$\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\$
    – user154136
    Commented Sep 28, 2017 at 17:30
  • 3
    \$\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\$ Commented Sep 28, 2017 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\$ Commented Sep 29, 2017 at 7:31
  • \$\begingroup\$ The cases are well explained in @user2913869's comment. Shortly it depends on whether the external delay is known. \$\endgroup\$
    – user154136
    Commented Sep 29, 2017 at 8:16
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Nov 29, 2019 at 22:54

1 Answer 1

2
\$\begingroup\$

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

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.