Hi! I have a doubt regarding clock domain crossing from a fast clock to a slower one. Is it possible to use the two flip flops scheme? If yes, would my code be okay? sinc_in indicates if data in is valid, sinc_out if data out is valid in the secod clock domain and clk1 is faster than clk2, so clk2 is the new domain.
entity clock_sync is port( clk1 : in std_logic; clk2 : in std_logic; sync_in : in std_logic; Data_in : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(7 downto 0); sync_out : out std_logic ); architecture behavioral of clock_sync is constant in: std_logic_vector (7 downto0):=(others=>0); type ff is array(0 to 1) of std_logic_vector(7 downto 0); signal sig_reg : ff:=(others=>in); signal i: integer:=0; begin process(Clock2) begin if rising_edge(Clock2) and sync_in=1 then if i < 2 then i<=i+1; sig_reg(i)<= Data_in; sync_out<=0; else data_out<=sig_reg(i-1); sync_out<=1; end if; end if; end process; end behavioral;
: Edited by User
Stefania M. wrote: > if i < 2 then > i<=i+1; Uiuiuiuiui, looks like a programming language ... Stefania M. wrote: > type ff is array(0 to 1) of std_logic_vector(7 downto 0); > > signal buffer : ff:=(others=>in); Why not: signal buffer: std_logic_vector(15 downto 0):=(others => '0'); Stefania M. wrote: > Is it possible to use the two flip flops scheme? If yes, > would my code be okay? if Data_in is set for only one cycle of the fast clock, you can miss it with the slow clock. So no, this will not work reliable. But Lothar has written a component which takes a short puls and converts it to an full clock cycle of another clock: http://www.lothar-miller.de/s9y/archives/19-Kurzer-Spike-in-Puls-umgewandelt.html Vivado from xilinx also has CDC XPMs which you could use. They are in the language templates XPM_CDC.
-gb- wrote: > buffer Naming a signal 'buffer' is not the best idea, because it is a reserved word in VHDL: https://www.xilinx.com/support/documentation/sw_manuals/xilinx11/ite_r_vhdl_reserved_words.htm Duke
Stefania M. wrote: > sinc_in indicates if data in is valid, sinc_out if data out is valid in > the secod clock domain and clk1 is faster than clk2, so clk2 is the new > domain. Can you sketch this down in a timing diagram? > Is it possible to use the two flip flops scheme? Only when the data rate on the fast clock domain is slower than the clk on the slow clock domain. > If yes, would my code be okay? > if rising_edge(Clock2) and sync_in=1 then Forget this, because sync_in is asynchronus to clk2 and then the usual happens: sync_in acts as an enable for the counter i which consists ofd several flipflops. And so sync_in is routet to each of the flipflops. Finally you will get this: http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html Or, lets simply say the counter i is a FSM (as each counter is). And never ever(!!) use an async input in a FSM
Duke Scarring wrote: > Naming a signal 'buffer' is not the best idea, because it is a reserved > word in VHDL: You are right, sorry ...
Stefania M. wrote: > Is it possible to use the two flip flops scheme? Yes. But as Lothar pointed out, Sync_in is asynchronous to Clk2 so you have to apply the two flip flops to this signal. And you have to validate that Sync_in is stable for enough time with regard to the slow clock. Either this is true due to your application or you make it true with a pulse-stretcher. > If yes, would my code be okay? No. You applied the two flip flops to the parallel data. This can randomly fail due to latency differences in the separate parallel paths. Have a look at the paper "Fourteen ways to fool your synchronizer", you hit number 12 on page 6 :-) Example to do CDR in this case: You synchronize Sync_in and then use this (let's call it Sync_clk2) signal to enable your single output register. Add another flip flop to Sync_clk2 to generate Sync_out so it will be high at the same time the data is valid at the register output.