Source synchronous interface clocks: "Asynchronous (Timed Unsafe)"
Hi.
I have a FPGA (Cyclone 10 GX, Quartus prime pro 20.4) design which is the sink of 2 independent source synchronous interfaces. The clock edges are center aligned to the data. One of the interfaces is working at single data rate, the other one at double data rate.
The constraints were made according to AN433. Therefore i have a virtual clock and an input clock each. The virtual clock corresponds to the data launch clock of the data source.
The input clock of the DDR-interface is generated by the sourcing device (Cyclone V, LVDS) with a phase offset of +90° (PLL).
For the SDR interface input clock the source (Max10, HSTL 1.8V) just outputs the inverted data clock.
Now my Problem:
These interfaces are not working reliable. Any of them may fail to work after the next compilation and that may be temperature dependent. For me this looks like a timing issue. But there are no timing errors. Instead the Timing Analyzer reports on clock transfers "Asynchronous (Timed Unsafe)" between the virtual clocks and the input clocks.
Is this bad or not? What can i do to fix those interfaces?
What i also noticed is the following. An earlier version of the PCB, which now uses the Cyclone 10, uses a Cyclone V (Quartus prime lite 18.1) and hasn't those interface failure issues. At least after intruducing exactly these timing constraints which i am also using in the Cyclone 10 project now.
Here are the timing constraints of the DDR interface:
set ddr_clock_period 6.667
create_clock -name {clk_ddr_virtual} -period $ddr_clock_period
create_clock -name {clk_ddr_input} -period $ddr_clock_period -waveform "[expr {0.25 * $ddr_clock_period}] [expr {0.75 * $ddr_clock_period}]" [get_ports {<clock input port>}]
set_clock_groups -asynchronous -group [get_clocks {clk_ddr_virtual clk_ddr_input}]
set ddr_inputs {<data input ports>}
set_input_delay -max 0.5 -clock [get_clocks clk_ddr_virtual] [get_ports ${ddr_inputs}]
set_input_delay -max 0.5 -clock [get_clocks clk_ddr_virtual] -clock_fall [get_ports ${ddr_inputs}] -add_delay
set_input_delay -min -0.5 -clock [get_clocks clk_ddr_virtual] [get_ports ${ddr_inputs}] -add_delay
set_input_delay -min -0.5 -clock [get_clocks clk_ddr_virtual] -clock_fall [get_ports ${ddr_inputs}] -add_delay
set_multicycle_path -hold -end -rise_from [get_clocks clk_ddr_virtual] -rise_to [get_clocks clk_ddr_input] 2
set_multicycle_path -hold -end -fall_from [get_clocks clk_ddr_virtual] -fall_to [get_clocks clk_ddr_input] 2
set_false_path -setup -rise_from [get_clocks clk_ddr_virtual] -rise_to [get_clocks clk_ddr_input]
set_false_path -setup -fall_from [get_clocks clk_ddr_virtual] -fall_to [get_clocks clk_ddr_input]
set_false_path -hold -fall_from [get_clocks clk_ddr_virtual] -rise_to [get_clocks clk_ddr_input]
set_false_path -hold -rise_from [get_clocks clk_ddr_virtual] -fall_to [get_clocks clk_ddr_input]