Digital IC front-end study notes: Gray code (including binary Gray code converter implemented by Verilog)

related articles

Digital IC front-end study notes: LSFR (Linear Feedback Shift Register)

Digital IC front-end study notes: cross-clock domain signal synchronization

Digital IC front-end study notes: signal synchronization and edge detection

Digital IC front-end study notes: synthesis of latch Latch

Digital IC front-end study notes: Verilog implementation of FIFO (1)

Digital IC front-end study notes: Verilog implementation of FIFO (2)

Digital IC front-end study notes: arbitration polling (1)

Digital IC front-end study notes: arbitration polling (2)

Digital IC front-end study notes: arbitration polling (3)

Digital IC front-end study notes: arbitration polling (4)

Digital IC front-end study notes: arbitration polling (5)

Digital IC front-end study notes: arbitration polling (6)

Digital IC front-end study notes: least recently used (LRU) algorithm


Table of contents

1. Gray code encoding/decoding

2. Binary code to Gray code Verilog implementation

3. Gray code to binary code Verilog implementation


1. Gray code encoding/decoding

        Gray coding appeared in the patent published by Frank Gray in 1953. The main feature is that only one bit of the adjacent coding value changes. The following table shows the three-bit and four-bit binary codes and the corresponding Gray codes. From the figure This feature can be clearly seen in , and this feature also makes Gray codes have a very wide range of applications.

three-bit gray code

decimal code binary code gray coding
0 000 000
1 001 001
2 010 011
3 011 010
4 100 110
5 101 111
6 110 101
7 111 100

four-bit gray code

decimal code binary code gray coding decimal code binary code gray coding
0 0000 0000 8 1000 1100
1 0001 0001 9 1001 1101
2 0010 0011 10 1010 1111
3 0011 0010 11 1011 1110
4 0100 0110 12 1100 1010
5 0101 0111 13 1101 1011
6 0110 0101 14 1110 1001
7 0111 0100 15 1111 1000

        Gray coding is widely used in asynchronous FIFOs (First In First Out) using two different clocks. Generally speaking, when multiple bits of data cross the clock domain boundary, traditional synchronizers cannot be used to directly synchronize each bit of data, because there is no guarantee that these data will be synchronized at the same time, and a high error rate may occur. However, if the multi-bit data is gray-coded and only one bit of data may change at a time, it can be directly synchronized.

        In an asynchronous FIFO, the write address and read address pointers are stored in different clock domains, and in order to indicate the FIFO status, we need to generate the FIFO_full signal in the write clock domain and the FIFO_rmpty signal in the read clock domain to judge the FIFO status When , it is necessary to compare the values ​​of the read and write pointers, and the values ​​in two different clock domains cannot be directly compared. Therefore, we need to convert the binary-coded pointer to Gray code first, and make the Gray code traverse from one clock domain to another clock domain, and then use the conversion formula to convert the Gray code back to binary code, and the target clock domain Pointer comparison. The entire synchronization process is shown in the figure below.

       

         We analyze this process in depth with some real-world examples, and then look at the problems that exist when using this conversion method. In the following example, in the CLKA clock domain, a value changes from a decimal value of 5 to 6. Let's analyze the transmission process of multi-bit data. 

decimal value binary value Gray code value Synchronized binary value Synchronized decimal value
5 101 111 111 5
6 110 101 111 or 101 5 or 6

         In CLKA, when the decimal number changes from 5 to 6, after passing through the synchronizer, it becomes 101 in the target clock domain or temporarily becomes the original 111 (after one or two clock cycles, it will still become 101). It can be seen that whether it is 101 or 111, the final result is a legal value that appears in sequence.

        What happens if you use the synchronizer directly in the CLKB clock domain without using the above binary-gray code conversion circuit? The table below gives the possible results.

decimal value binary value Synchronized binary value Synchronized decimal value
5 101 101 5
6 110 101 or 110 or 100 or 111 5 or 6 or 4 or 7

        It can be seen that the value after synchronization may be the old value 101, the new value, but it may also become 100 or 111. Because multiple bits of data are synchronized separately, there is no guarantee that multiple bits of signals will be sampled on the same clock edge, and the effective values ​​of these independently synchronized signals may appear on different clock edges.

        Although the correct value can be obtained in the end, that is, the final output becomes . But values ​​that violate the rules may appear during this time. In this example, there are two illegal values, if there are more bit data transitions at the same time, a large number of illegal values ​​may be generated, and the output will retain these values ​​for one to two cycles.

        For FIFO, the empty/full signal is obtained by comparing the pointers. When these illegal values ​​appear, the FIFO may have wrong empty/full signals, which will cause system work errors or even crash.

2. Binary code to Gray code Verilog implementation

module binary_to_gray #(parameter PTR = 8)
                       (input [PTR:0]binary_value,
                        output [PTR:0]gray_value);
genvar i;
generate
    for(i = 0;i < PTR;i = i+1) begin
        assign gray_value[i] = binary_value[i] ^ binary_value[i+1];
    end
endgenerate

assign gray_value[PTR] = binary_value[PTR];

endmodule

3. Gray code to binary code Verilog implementation

module gray_to_binary #(parameter PTR = 8)
                       (output [PTR:0]binary_value,
                        input [PTR:0]gray_value);
genvar i;
generate
    for(i = 0;i < PTR;i = i+1) begin
        assign binary_value[i] = binary_value[i+1] ^ gray_value[i];
    end
endgenerate

assign binary_value[PTR] = gray_value[PTR];

endmodule

 The above content comes from "Verilog Advanced Digital System Design Technology and Example Analysis"

Guess you like

Origin blog.csdn.net/weixin_45791458/article/details/130084594