Different parts of a digital circuit can run on different clocks. We need to handle these carefully to avoid mistakes when signals move between them.
Clock domain considerations in VHDL
-- Example of synchronizing a signal between clock domains process(clk_dest) is variable sync_1 : std_logic := '0'; variable sync_2 : std_logic := '0'; begin if rising_edge(clk_dest) then sync_1 := signal_from_clk_src; sync_2 := sync_1; end if; end process;
Use a chain of flip-flops (usually two) to safely transfer signals between clock domains.
Always use rising_edge or falling_edge to detect clock edges in VHDL.
-- Simple two-flip-flop synchronizer process(clk_dest) is signal sync_1, sync_2 : std_logic := '0'; begin if rising_edge(clk_dest) then sync_1 <= async_signal; sync_2 <= sync_1; end if; end process;
-- Using handshake signals between clock domains -- Sender domain process(clk_src) is begin if rising_edge(clk_src) then if ready = '1' then data_valid <= '1'; data_out <= data_in; end if; end if; end process; -- Receiver domain process(clk_dest) is begin if rising_edge(clk_dest) then if data_valid = '1' then data_in_dest <= data_out; ack <= '1'; else ack <= '0'; end if; end if; end process;
This VHDL code shows a simple two-stage synchronizer. It safely brings an asynchronous signal into the destination clock domain by passing it through two flip-flops clocked by clk_dest.
library ieee; use ieee.std_logic_1164.all; entity clock_domain_sync is port( clk_src : in std_logic; clk_dest : in std_logic; async_signal : in std_logic; sync_signal : out std_logic ); end entity; architecture rtl of clock_domain_sync is signal sync_1, sync_2 : std_logic := '0'; begin process(clk_dest) is begin if rising_edge(clk_dest) then sync_1 <= async_signal; sync_2 <= sync_1; end if; end process; sync_signal <= sync_2; end architecture;
Never connect signals directly between different clock domains without synchronization.
Using two flip-flops reduces the chance of metastability, which can cause unpredictable behavior.
For complex data, use handshake or FIFO methods instead of simple synchronizers.
Clock domain crossing needs careful handling to avoid errors.
Use two flip-flops to synchronize single-bit signals safely.
For multi-bit data, use handshake or FIFO techniques.
Practice
Solution
Step 1: Understand metastability in clock domain crossing
When a signal changes asynchronously between two clock domains, the receiving flip-flop can enter an unstable state called metastability.Step 2: Role of synchronizers
Synchronizers use multiple flip-flops in series to reduce the chance of metastability affecting the receiving domain, ensuring reliable data transfer.Final Answer:
To prevent metastability and ensure reliable data transfer -> Option CQuick Check:
Synchronizers prevent metastability = C [OK]
- Thinking synchronizers increase clock speed
- Assuming synchronizers reduce power
- Believing synchronizers simplify code syntax
async_sig crossing into clk domain?Solution
Step 1: Identify correct flip-flop sequence
The first flip-flop captures the asynchronous signal, the second flip-flop captures the first flip-flop's output.Step 2: Check clock edge and assignment order
Using rising_edge(clk) is standard, and assignments must be in order: sync1 <= async_sig; sync2 <= sync1;Final Answer:
process(clk) begin if rising_edge(clk) then sync1 <= async_sig; sync2 <= sync1; end if; end process; -> Option AQuick Check:
Correct order and clock edge = A [OK]
- Swapping sync1 and sync2 assignments
- Using falling_edge instead of rising_edge
- Assigning signals in wrong order
sync2 signal after several clock cycles?signal async_sig : std_logic;
signal sync1, sync2 : std_logic;
process(clk) begin
if rising_edge(clk) then
sync1 <= async_sig;
sync2 <= sync1;
end if;
end process;Solution
Step 1: Understand signal propagation through flip-flops
sync1 captures async_sig at rising edge, sync2 captures sync1 at next rising edge, causing a two-cycle delay.Step 2: Resulting behavior of sync2
sync2 becomes a stable, synchronized version of async_sig delayed by two clock cycles, reducing metastability risk.Final Answer:
sync2 will be a stable, synchronized version of async_sig delayed by two clock cycles -> Option BQuick Check:
Two flip-flop delay = stable sync2 = A [OK]
- Expecting no delay in sync2
- Thinking sync2 inverts async_sig
- Assuming runtime errors from this code
async_sig crossing into clk domain:process(clk) begin
if rising_edge(clk) then
sync2 <= async_sig;
sync1 <= sync2;
end if;
end process;Solution
Step 1: Analyze assignment order in process
sync2 is assigned async_sig first, then sync1 is assigned sync2, which reverses the intended synchronizer chain.Step 2: Correct synchronizer order
Proper synchronizer assigns sync1 <= async_sig; then sync2 <= sync1; to ensure correct data flow and metastability reduction.Final Answer:
The assignments are reversed; sync1 should capture async_sig first -> Option DQuick Check:
Assignment order matters = reversed order = D [OK]
- Changing clock edge unnecessarily
- Assuming reset is mandatory here
- Ignoring signal declarations
async_data from an asynchronous clock domain to a clk domain in VHDL. Which method is the safest and most reliable to avoid data corruption?Solution
Step 1: Understand complexity of multi-bit data crossing clock domains
Multi-bit data can change asynchronously, causing partial updates and data corruption if not handled carefully.Step 2: Choose proper synchronization method
Handshake protocols with ready/acknowledge signals ensure data is stable and fully transferred before use, avoiding corruption.Final Answer:
Use a handshake protocol with ready/acknowledge signals between domains -> Option AQuick Check:
Handshake ensures safe multi-bit transfer = B [OK]
- Using single-bit synchronizers on multi-bit buses
- Direct asynchronous assignments causing glitches
- Relying on combinational logic for async crossing
Ready to prove it?
Pass the test and this pattern moves unknown
