Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
15465 Discussions

Crossing Clock Domain Problems | Timing Analyser ignores set_max_skew assignment

Christian_Woznik
391 Views

Hello everyone,

I have a problem with quartus 20.1 while trying to cross a clock domain. I have followed the Intel video regarding the crossing https://www.youtube.com/watch?v=RTcZOl2e8PI and the Intel Help https://www.intel.com/content/www/us/en/programmable/support/support-resources/knowledge-base/tools/... .

I also have attached the code for the synchroniser at the bottom. However Timing Analyser always reports that it ignores the set_max_skew assignments with the following message:

 

 

No path is found satisfying assignment "set_max_skew -from [get_registers {neuralNetwork|InputSync|clk1_Buffer[*][*]}] -to [get_registers {neuralNetwork|InputSync|clk2_Buffer[0][*][*]}] 2.693 ". This assignment will be ignored.

 

 

It does not matter if i use from_clock or from with the registers. I get the same error.

However I do not get any warning during analysis as I would if I would have a wrong path in there (had  typos in there and got the warning).

The problem is that I can not use the max_skew report and thus see if the timings are actually held. Does anyone have any idea?

Best regards
Christian

Edit: I have just checked in the TA. I can find the registers when setting up new assignments. I also tried setting just the individual register connections, which I can definitively find the Technology Map Viewer. It also gets ignored.

 

Edit 2: I have now looked through the output for the timing analyser during compilation. There it says it detects all of the synchronizer chains, calculates a MTBF, settling time, etc.
Afterwards I went ahead and tested the design on the FPGA and all output look good. I really do not understand why TA is not able to create the report. Any ideas?

SDC constrains:

 

 

**************************************************************
# Create Clock
#**************************************************************
create_clock -name {input_clk} -period 13.468 -waveform { 0.000 6.734 } [get_ports {clk}]

#**************************************************************
# Create Generated Clock
#**************************************************************

create_generated_clock -name output_clk -source [get_ports {clk}] -master_clock input_clk -add [get_ports {clk_o}]
create_generated_clock -name {pllBaseClock} -source [get_pins {neuralNetwork|PLL|nnfpga_pll_inst|altera_pll_i|general[0].gpll~FRACTIONAL_PLL|refclkin}] -duty_cycle 50/1 -multiply_by 16 -divide_by 2 -master_clock {input_clk} [get_pins {neuralNetwork|PLL|nnfpga_pll_inst|altera_pll_i|general[0].gpll~FRACTIONAL_PLL|vcoph[0]}] 
create_generated_clock -name {neuralNetworkClock} -source [get_pins {neuralNetwork|PLL|nnfpga_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|vco0ph[0]}] -duty_cycle 50/1 -multiply_by 1 -divide_by 2 -master_clock {pllBaseClock} [get_pins {neuralNetwork|PLL|nnfpga_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}]  

#**************************************************************
# Set Clock Groups
#**************************************************************

set_clock_groups -asynchronous -group [get_clocks {neuralNetworkClock}] -group [get_clocks {input_clk}] 


#**************************************************************
# Set Net Delay
#**************************************************************

set_net_delay -max 2.693 -from [get_pins {neuralNetwork|InputSync|clk1_Buffer[*][*]|q}]
set_net_delay -max 2.693 -from [get_pins {neuralNetwork|OutputSync|clk1_Buffer[*][*]|q}]


#**************************************************************
# Set Max Skew
#**************************************************************

set_max_skew -from [get_registers {neuralNetwork|InputSync|clk1_Buffer[*][*]}] -to [get_registers {neuralNetwork|InputSync|clk2_Buffer[0][*][*]}] 2.693
set_max_skew -from [get_registers {neuralNetwork|OutputSync|clk1_Buffer[*][*]}] -to [get_registers {neuralNetwork|OutputSync|clk2_Buffer[0][*][*]}] 2.693

 

 

 

synchronizer:

 

 

-- Synchorniser for array of std_logic_vector of variable size
-- Requires VHDL 2008 support! 
--
-- (c) Christian Woznik

library IEEE;
use ieee.std_logic_1164.all;

USE ieee.math_real.log2;
USE ieee.math_real.ceil;

library work;
use work.types.all;

entity synchroniserArrayStdLogicVector is
	generic (arraySize 		: integer;
				stages			: integer;
				inputdataWidth : integer);
				
	port (clk1        : in 	std_logic;
			clk2 			: in 	std_logic; 			
			
			dataIn		: in variableSizeLogicVectorArray (0 to (arraySize) -1)(inputdataWidth-1 downto 0);
			
			dataOut 		: out variableSizeLogicVectorArray (0 to (arraySize) -1)(inputdataWidth-1 downto 0));
			
end synchroniserArrayStdLogicVector ;


architecture behave of synchroniserArrayStdLogicVector is	
	signal clk1_Buffer : variableSizeLogicVectorArray (0 to (arraySize) -1)(inputdataWidth-1 downto 0);
	
	type t_BufferArray is array (0 to stages-1) of variableSizeLogicVectorArray(0 to (arraySize) -1)(inputdataWidth-1 downto 0);
	signal clk2_Buffer : t_BufferArray;
begin
	process(clk1)
	begin	
		if rising_edge(clk1) then
			clk1_Buffer <= dataIn;
		end if;
	end process;
	
	process(clk2)
		variable i : integer;
	begin
		if rising_edge(clk2) then
			clk2_Buffer(0) <= clk1_Buffer;
			for i in 0 to stages-2 loop
				clk2_Buffer(i+1) <= clk2_Buffer(i);
			end loop;
		end if;
	end process;
	
	dataOut <= clk2_Buffer(stages-1);
end behave;

 

 

0 Kudos
3 Replies
SyafieqS
Moderator
350 Views

Christian,


What version of Quartus are you using? If you are using Pro, there is feature like DA DRC for CDC and CDC Viewer report in Timing Analyzer which will tell you there is CDC still occur in your design easily.


Since you mentioned during compilation the PnR works and the output is correct, no meta. furthermore no hardware failure during testing and error during compilation, this could be a bug as well for TA. Is it possible to attach you qar here to reproduce the issue. 


SyafieqS
Moderator
290 Views

Christian,


May I know if there is any update?


IRohl1
Beginner
245 Views

The answer is easy: Quartus has a bug since at least Quartus 16.1, which means you cannot use "set_max_skew" to constrain "Clock Domain Crossing" paths (CDCs); which is unfortunate, because this is the correct constraint for these kind of paths.

Note that even if you would be able to use "set_max_skew" it wouldn't help, because the fitter ignores these constraints.

Additionally you can only use "set_net_delay" for CDC paths, which do not contain ANY combinational logic in between; so you can only use "set_net_delay" for pure register to register paths.

 

The only way to get reliable CDC logic is to put it into an own entity and then use "logic lock" regions to make sure the fitter puts all the registers as close together as possible.

 

To get some notion about timings for CDC logic, you then need an extra "SDC" file, where you remove all "set_false_path" and "set_clock_group" constraints, because then the timing analyzer will be at least able to give you numbers for the "set_max_skew" constraints.

 

Welcome to the world of unreliable tools and "community" support, which does not even understand what you are talking about.

Reply