Gray code: một bit đổi ở mỗi bước kề nhau

Khoảng 45 phútMức 1/3Bản nháp: một số khẳng định chưa đối chiếu spec

Sau bài này bạn sẽ

  • Encode và decode binary-reflected Gray code
  • Đọc bước chuyển binary và Gray trên VCD thật
  • Phân biệt tính chất mã với điều kiện an toàn CDC

Đếm thứ tự không bắt buộc đổi nhiều bit

Binary từ 7 sang 8 chuyển 0111 → 1000: cả bốn bit đều đổi. Nếu quan sát các bit đổi ở những thời điểm khác nhau, một mẫu trung gian có thể không phải giá trị đầu hay cuối.

Binary-reflected Gray code sắp các từ mã để hai vị trí kề nhau chỉ khác một bit. Nó giúp giảm số bit phải chuyển trong một bước đếm; không tự sửa lỗi điện hay làm biến mất metastability.

Một bảng mã Gray bốn bit

Bài này dùng binary-reflected Gray code, viết tắt BRGC. Gray code là một họ mã; không phải mọi bảng Gray đều dùng đúng thứ tự dưới đây.

Chỉ số binary Binary BRGC
0 0000 0000
1 0001 0001
2 0010 0011
3 0011 0010
4 0100 0110
5 0101 0111
6 0110 0101
7 0111 0100
8 1000 1100
9 1001 1101
10 1010 1111
11 1011 1110
12 1100 1010
13 1101 1011
14 1110 1001
15 1111 1000

Vòng cuối 1000 → 0000 cũng đổi đúng một bit. Tính chất này áp dụng khi đi giữa hai vị trí kề nhau trên vòng, không phải giữa hai chỉ số bất kỳ. Ví dụ chỉ số 0 sang 2 có từ mã 0000 → 0011, đổi hai bit.

Tạo Gray bằng XOR hai bit kề

Với từ binary b rộng W bit, công thức BRGC là g = b XOR (b >> 1), dùng dịch logic và giữ W bit. MSB của g bằng MSB của b; mỗi bit thấp là XOR giữa hai bit binary kề nhau.

Ví dụ b là 1011; b dịch phải một vị trí thành 0101; XOR được 1110. Kết quả khớp hàng chỉ số 11 trong bảng.

Đừng dùng phép cộng thông thường trên g rồi coi đó là “tăng bộ đếm Gray”. Cách dễ kiểm là giữ bộ đếm binary để tính số học, rồi mã hóa giá trị cần truyền hoặc hiển thị.

Giải mã bằng XOR tích lũy từ MSB

MSB của b bằng MSB của g. Mỗi bit binary tiếp theo bằng bit binary ngay phía trên XOR với bit Gray cùng vị trí.

Với g là 1110: MSB b bằng 1; tiếp theo 1 XOR 1 = 0; tiếp 0 XOR 1 = 1; cuối 1 XOR 0 = 1. Khôi phục b là 1011.

Hai hướng encode/decode cần được so với bảng độc lập. Chỉ kiểm “decode(encode(b)) bằng b” có thể bỏ sót việc hai hàm cùng dùng một bảng mã sai so với giao diện đã thỏa thuận.

Nhìn bước 7 sang 8 trên waveform

BRGC bốn bit: binary 0–15 rồi quay về 0

Trích từ mô phỏng Verilator (VCD) của ex.a1.gray, không vẽ tay
012345678910111213141516clkb3b2b1b0g3g2g1g0
  • Cột 8: 7→8: binary đổi 4 bit, BRGC đổi g3
  • Cột 16: 15→0: BRGC chỉ đổi g3; chưa phải bằng chứng CDC vật lý

Các lane b3 tới b0 là binary; g3 tới g0 là Gray. Mỗi cột là một giá trị đã ổn định trong mô phỏng, đi từ 0 tới 15 rồi quay về 0.

Tại cột 8, so với cột 7, b đổi cả bốn bit còn g chỉ đổi g3. Cột 16 cho thấy bước quay vòng. Clock trong hình chỉ là mốc lấy mẫu của testbench; bộ encode/decode trong ví dụ là tổ hợp.

Waveform được lấy mẫu không cho biết các glitch ngắn giữa hai mẫu. Không dùng hình này để kết luận encoder tổ hợp luôn không glitch trong phần cứng.

Một bit đổi chưa đủ để bảo đảm CDC

Gray thường xuất hiện trong việc chuyển con trỏ FIFO giữa hai miền clock. Mục đích là tránh truyền một bộ đếm binary có nhiều bit đang chuyển đồng thời ở mỗi bước kề nhau.

Thiết kế thực còn cần quy tắc tạo và đăng ký con trỏ, synchronizer, ràng buộc timing/skew và phân tích CDC phù hợp. Mã Gray không phát hiện hoặc sửa metastability. Nếu nguồn nhảy nhiều vị trí, nhiều bit có thể đổi; một bit lỗi vẫn có thể tạo ra từ mã Gray hợp lệ khác.

Clock đích có thể bỏ qua vài giá trị nguồn khi hai miền chạy khác tốc độ. Tính đơn bit của các bước nguồn, điều kiện quan sát ở đích và độ trễ đồng bộ là các vấn đề riêng cần kiểm; ví dụ mã hóa ở bài này chưa xác nhận FIFO bất đồng bộ an toàn.

Đặt đúng phạm vi của tính chất đơn bit

  • Nhầm “hai vị trí kề nhau” với “mọi cặp giá trị”.
  • Dùng Gray như số binary để cộng, so lớn nhỏ trực tiếp.
  • Cho rằng bảng mã là mã sửa lỗi chỉ vì mỗi bước đổi một bit.
  • Suy tính không glitch từ vài cột waveform.
  • Bỏ synchronizer vì đã mã hóa Gray.

Trong review RTL, hãy yêu cầu người viết chỉ rõ chuỗi chuyển trạng thái hợp lệ và nơi đăng ký tín hiệu. Đây là thông tin cần trước khi bàn đến CDC.

Tự dựng và phản biện bảng mã

  1. Encode binary 0110 rồi decode kết quả để kiểm.
  2. Đếm số bit đổi của bước chỉ số 3 sang 4 ở binary và BRGC.
  3. Tìm hai vị trí không kề nhau có từ Gray khác ít nhất hai bit.
  4. Vì sao kiểm round-trip thôi chưa chứng minh encoder khớp một giao diện bên ngoài?
  5. Một con trỏ có thể nhảy tăng 2 mỗi chu kỳ. Có thể dùng nguyên kết luận “chỉ một bit đổi” của bộ đếm tăng 1 không?

Kiểm tra

Tự kiểm tra: Gray code: một bit đổi ở mỗi bước kề nhau

  1. Binary 1011 mã hóa BRGC thành gì?
  2. Tính một bit đổi được bảo đảm cho cặp nào trong bảng BRGC đã nêu?
  3. Từ chỉ số 7 sang 8 trong bảng, binary và Gray đổi bao nhiêu bit?
  4. Chỉ mã hóa Gray đã đủ chứng minh CDC an toàn chưa?
  5. Chỉ kiểm decode(encode(b)) bằng b có xác nhận encoder khớp bảng giao diện chưa?

Bằng chứng kiểm chứng

Expected tính trước chạy: GRAY CHECK samples=17 unique=16 transitions=16 seen=65535 wrap=0 time_ns=180.

Binary-reflected Gray code: bảng chuẩn và chuyển vòng

Kỳ vọng tính trước chạy: GRAY CHECK samples=17 unique=16 transitions=16 seen=65535 wrap=0 time_ns=180

gray_codec.sv RTL
`timescale 1ns/1psmodule gray_codec(input logic [3:0] binary,output wire [3:0] gray,roundtrip);  assign gray=binary^(binary>>1);  assign roundtrip[3]=gray[3];  for(genvar k=0;k<3;k++)begin:prefix_decode    assign roundtrip[k]=roundtrip[k+1]^gray[k];  endendmodule
tb.sv testbench
`timescale 1ns/1ps// Expected BEFORE execution: canonical BRGC table, 17 samples of 0..15 then0.// 16 cyclic transitions are single-bit; all16 raw values seen, mask65535.// 18th rising edge bounds the last VCD column; finish180ns.module tb_a1_gray;  bit clk=0;logic [3:0] binary=0;  wire [3:0] gray,roundtrip;  wire b3=binary[3],b2=binary[2],b1=binary[1],b0=binary[0];  wire g3=gray[3],g2=gray[2],g1=gray[1],g0=gray[0];  logic [3:0] expected_gray[16]='{4'h0,4'h1,4'h3,4'h2,4'h6,4'h7,4'h5,4'h4,4'hc,4'hd,4'hf,4'he,4'ha,4'hb,4'h9,4'h8};  logic [3:0] previous_gray;  int samples=0,transitions=0,seen=0;  gray_codec dut(.binary(binary),.gray(gray),.roundtrip(roundtrip));  always #5 clk=~clk;  initial begin    $dumpfile("trace.vcd");$dumpvars(0,tb_a1_gray);    for(int i=0;i<17;i++)begin      if(i>0)@(negedge clk);      binary=4'(i);@(posedge clk);#1;samples++;seen|=1<<binary;      if(gray!==expected_gray[i%16]||roundtrip!==binary)$fatal(1,"Gray table/roundtrip mismatch sample=%0d",i);      if(i>0)begin        if($countones(gray^previous_gray)!=1)$fatal(1,"Gray adjacent transition mismatch sample=%0d",i);        transitions++;      end      previous_gray=gray;    end    @(negedge clk);@(posedge clk);@(negedge clk);    if(samples!=17||transitions!=16||seen!=65535||binary!=0||gray!=0||$time!=180)      $fatal(1,"Gray experiment contract");    $display("GRAY CHECK samples=17 unique=16 transitions=16 seen=65535 wrap=0 time_ns=%0d",$time);    $finish;  endendmodule

Đã kiểm chứng thế nào

  • Phân tích và elaborate theo LRM (pyslang 12.1.0)
  • Lint -Wall (Verilator 5.050)
  • Mô phỏng, exit 0 và output khớp kỳ vọng tính tay (Verilator 5.050, 2-state)
  • Waveform trích từ VCD của lần mô phỏng
  • Tổng hợp, số cell khớp kỳ vọng (Yosys 0.70)

Output phải khớp: GRAY CHECK samples=17 unique=16 transitions=16 seen=65535 wrap=0 time_ns=180

Kỳ vọng sau tổng hợp: gray_codec: $_*DFF* = 0gray_codec: $_*LATCH* = 0

Verilator 5.050 two-state; finite known input domains only. No X/Z or all-width language-conformance claim.

Testbench sampling clock only; DUT is combinational. This sampled functional trace is not glitch-free, metastability or CDC physical proof.

Các kiểm tra chạy lúc xây dựng nội dung (2026-11-07), không chạy trong trình duyệt. Kỳ vọng được tính tay trước khi chạy.

Tham chiếu là bảng 16 từ BRGC viết trước chạy, tách khỏi công thức XOR của DUT. Kiểm từng encode/decode, đủ 16 mã khác nhau và 16 bước kề gồm quay vòng. Giữ cạnh lấy mẫu thứ 18 để chặn cột VCD cuối; kết thúc tại 180 ns.

Parser, lint, simulation, VCD và synthesis generic đều đạt. Wave có 17 cột khớp trace thật. Yosys không suy flip-flop/latch trong DUT tổ hợp. Không claim timing vật lý, glitch-free, xác suất metastability hay CDC sign-off.

[1] [2] [3]

Nguồn và mức độ đối chiếu

  1. Gray Code — bản chụp resources.zip, What is Gray Code?; Binary vs. Gray Code Transition Comparison; Gray Code Table (0-15); Binary to Gray Code Conversion; Mathematical Formula; Common Beginner Mistakes. Trích dẫn; nguồn đã đọc các mục liên quan.
  2. Thí nghiệm nguyên bản A1.gray, Sixteen BRGC lookup words, round-trip, cyclic one-bit transitions and sampled VCD. Trích dẫn; nguồn đã đọc toàn văn.
  3. IEEE 1800-2023 SystemVerilog LRM, Bitwise XOR, logical shifts and integral widths — chưa đối chiếu LRM. Chưa đối chiếu với văn bản nguồn (chưa mở).