Crossing Clock Domains - Gray Codes

September 29, 2015


To continue our discussion on clock domain crossing, I would say one of the most important designs that a hardware engineer should know, is the asynchronous FIFO. A RTL design engineer should never feel embarrassed to write the complete dual-clock FIFO within 3 minutes. I will not repeat how the Verilog codes should look like, but I will put emphasis on how the Gray codes should be written here.


For example, depending on the writer's clock wclk, the reader's pointer rd_ptr should be double-sampled. We denote the first sample as rd_ptr_s and the second sample as rd_ptr_ss. We also know that the samples should use Gray representation (a hardware engineer should always know and really understand the reason!). To write the code concisely, we have the binary-to-Gray translation as:


always@ (posedge wclk)

begin

rd_ptr_s <= rd_ptr ^ (rd_ptr >> 1);

rd_ptr_ss <= rd_ptr_s;

end


From the reader's side, vice versa, the writer's pointer has to be double-sampled into Gray codes first, then recovered from Gray codes back into binary. I will ignore it here since the code is very similar to the above codes.


The Gray-to-binary translation, can be written as (r_rd_ptr_ss and r_wt_ptr_ss denote the recovered binary representations of the read pointer and the write pointer, respectively):


genvar i

generate

for (i=0;i<ADDR_WIDTH+1;i=i+1) begin

always@(*)

begin

r_rd_ptr_ss[i]=^(rd_ptr_ss>>i);

r_wt_ptr_ss[i]=^(wt_ptr_ss>>i);

end

end

endgenerate


The above code completes the translation for both read and write pointers. Notice that I followed a parameterized design style. During interviews, it is very hard to come up with the above codes immediately; so my suggestion is to remember these translation techniques. By the way, the FIFO also contains other components such as RESET, full and empty signals, etc. Yes, that is part of the challenges a hardware engineer has to face!


I was constantly being asked to give an asynchronous FIFO with 7 slots. An qualified engineer should always be able to say this is not possible, since it is impossible to construct a Gray code with an odd number of codewords. However, we should know that, although difficult, it is possible to construct a Gray code consisting of any even number (not necessarily only power of 2) of codewords. For example, theoretically, it is possible to construct an asynchronous FIFO with 6 slots (see the two websites I recommended).