Cross Two Clock Domains

Send Signal from a Faster to a Slower Clock Domain

circuit4u
3 min readJun 25

--

1. Slower to Faster Clock Domain

It’s pretty straightforward to send signal from a slower clock domain to a faster clock domain. The basic assumption is that the faster clock can always capture the signal changes, i.e. the edge from low to high or high to low in the slower clock domain, provided that the metastability is taken care of. By shifting that signal into a three-bit shift register, the faster clock can capture that rising/falling edge signal to produce a single clock cycle flag signal.

    reg [2:0] edge_detect;

always @(posedge fast_clk) begin
edge_detect <= {edge_detect[1:0], slow_signal};
end

wire fast_clk_flag = edge_detect[1] ^ edge_detect[2];

The XOR operator would capture both the rising and falling edges of the slow_signal. On the other hand, if you only need to capture the rising edge:

wire fast_clk_flag = edge_detect[2:1] == 2'b01;

Now comes the question: how do we pass a one clock cycle flag signal from a faster clock domain into the slower clock domain.

2. Faster to Slower Clock Domain

For a flag signal that lasts only one faster clock cycle, the slower clock won’t be able to capture it. The trick is to turn that flag into a single-shot long lasting pulse, so that the slower clock can sample it into a shift register, and the rest is the same as before.

To make that single-shot long pulse, XOR comes to help again.

always @(posedge fast_clk) begin            
fast_long_pulse <= fast_long_pulse ^ fast_flag;
end

After the single-shot (fast_long_pulse) is popped up, the fast_flag is no longer high on the next clock cycle to cancel itself out.

The next time fast_flag comes again, it will drop fast_long_pulse to low. And that falling edge can be picked up by the slower clock as well, as long as it uses the XOR operator.

3. Faster to Slower Clock Domain with Back Pressure

--

--

circuit4u

memento of electronics and fun exploration for my future self