# Cross Two Clock Domains

--

## 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

--

--

memento of electronics and fun exploration for my future self