15-03-2017, 10:26 AM
(This post was last modified: 15-03-2017, 10:27 AM by ppppenguin.)
Another useful little trick. This time about crossing between clock domains. You will inevitably have to take signals between different and async clock domains. If the domains are synchronous then you shoudl have used clock enables so no problem can arise.
For async signals you can simply reclock a signal with the receiving clock and this often works OK. Obviously there will be a jitter equal to 1 period of the receiving clock. As you raise the frequencies and/or narrow the pulses this starts to become unreliable or even impossible.
The whole subject is actually quite complex(see here for example https://filebox.ece.vt.edu/~athanas/4514...l_cdc.html ) but there is one trick you need to know. The 2 flipflop synchroniser. It's pretty much bomb proof. The first FF is clocked by the input signal while its D input is held at logic 1. Its Q output feeds the 2nd FF's D input. The second FF is clocked by the receveing clock. The important bit is the feedback. The first FF's async clear input is fed by the 2nd FF's Q output. This example uses booleans but it's fine with std_logic.
For async signals you can simply reclock a signal with the receiving clock and this often works OK. Obviously there will be a jitter equal to 1 period of the receiving clock. As you raise the frequencies and/or narrow the pulses this starts to become unreliable or even impossible.
The whole subject is actually quite complex(see here for example https://filebox.ece.vt.edu/~athanas/4514...l_cdc.html ) but there is one trick you need to know. The 2 flipflop synchroniser. It's pretty much bomb proof. The first FF is clocked by the input signal while its D input is held at logic 1. Its Q output feeds the 2nd FF's D input. The second FF is clocked by the receveing clock. The important bit is the feedback. The first FF's async clear input is fed by the 2nd FF's Q output. This example uses booleans but it's fine with std_logic.
Code:
-- First FF
process (OUTPUT, INPUT) begin -- First stage of synchroniser
if OUTPUT then PRE_OUTPUT <= false; -- Async clear
elsif rising_edge(INPUT) then PRE_OUTPUT <= true; -- Set
end if;
end process;
-- 2nd FF
process (CK) begin
if rising_edge(CK) then
OUTPUT <= PRE_OUTPUT; -- Just a simple FF
end if; --CK
end process;
www.borinsky.co.uk Jeffrey Borinsky www.becg.tv







