工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> Verilog

Verilogグレイカウンタ:4ビットグレイコード生成モジュール

グレイコードとは

グレイコード(反射2進コード)は、隣り合うコード語のビット差が常に1ビットのみとなる符号化方式です。通常のバイナリカウントでは複数ビットが同時に変化する(例:0111→1000で4ビット変化)ため、非同期クロックドメイン間での値受け渡しや、機械的エンコーダ、カーネルマップ簡略化などでグレイコードが用いられます。

バイナリ→グレイ変換の公式

nビットバイナリ値B[n-1:0]からグレイコードG[n-1:0]への変換:

G[n-1] = B[n-1]
G[i]   = B[i+1] ^ B[i]   (i = n-2 ... 0)

Verilogでは連結演算子で簡潔に記述できます:{B[N-1], B[N-1:1] ^ B[N-2:0]}

設計

内部にバイナリカウンタqを持ち、毎クロックインクリメントしつつグレイ変換した値をoutに出力します。`ifdef FOR_LOOPでforループ版とベクトル演算版を切替可能にしています。

module gray_ctr #(
  parameter N = 4
)(
  input  clk,
  input  rstn,
  output reg [N-1:0] out
);
  reg [N-1:0] q;  // 内部バイナリカウンタ

  always @(posedge clk) begin
    if (!rstn) begin
      q   <= 0;
      out <= 0;
    end else begin
      q <= q + 1;  // バイナリカウント
      
      // グレイ変換:ベクトル演算版(推奨:シンプルで高速)
      `ifdef FOR_LOOP
        for (int i = 0; i < N-1; i = i + 1)
          out[i] <= q[i+1] ^ q[i];
        out[N-1] <= q[N-1];
      `else
        out <= {q[N-1], q[N-1:1] ^ q[N-2:0]};
      `endif
    end
  end
endmodule

テストベンチ

module tb;
  parameter N = 4;
  reg clk;
  reg rstn;
  wire [N-1:0] out;

  gray_ctr u0 (
    .clk(clk),
    .rstn(rstn),
    .out(out)
  );

  always #10 clk = ~clk;  // 20ns周期

  initial begin
    {clk, rstn} <= 0;
    $monitor("T=%0t rstn=%0b out=0x%0h", $time, rstn, out);
    repeat(2) @(posedge clk);
    rstn <= 1;
    repeat(20) @(posedge clk);
    $finish;
  end
endmodule

シミュレーション結果(4ビットグレイコード列)

ncsim> run
T=0   rstn=0 out=0xx
T=10  rstn=0 out=0x0
T=30  rstn=1 out=0x0  // 0000
T=50  rstn=1 out=0x1  // 0001
T=70  rstn=1 out=0x3  // 0011  (1ビット変化: 0001→0011)
T=90  rstn=1 out=0x2  // 0010  (1ビット変化: 0011→0010)
T=110 rstn=1 out=0x6  // 0110
T=130 rstn=1 out=0x7  // 0111
T=150 rstn=1 out=0x5  // 0101
T=170 rstn=1 out=0x4  // 0100
T=190 rstn=1 out=0xc  // 1100
T=210 rstn=1 out=0xd  // 1101
T=230 rstn=1 out=0xf  // 1111
T=250 rstn=1 out=0xe  // 1110
T=270 rstn=1 out=0xa  // 1010
T=290 rstn=1 out=0xb  // 1011
T=310 rstn=1 out=0x9  // 1001
T=330 rstn=1 out=0x8  // 1000
T=350 rstn=1 out=0x0  // 16ステートで巡回完了
...
Simulation complete via $finish(1) at time 430 NS + 0

グレイコード列の確認(4ビット)

10進バイナリグレイ変化ビット
000000000-
100010001bit0
200100011bit1
300110010bit0
401000110bit2
501010111bit0
601100101bit1
701110100bit0
810001100bit3
910011101bit0
1010101111bit1
1110111110bit0
1211001010bit2
1311011011bit0
1411101001bit1
1511111000bit0

グレイカウンタの用途

グレイ→バイナリ逆変換

受信側でグレイコードからバイナリに戻す場合:

function [N-1:0] gray2bin(input [N-1:0] g);
  integer i;
  begin
    gray2bin[N-1] = g[N-1];
    for (i = N-2; i >= 0; i = i - 1)
      gray2bin[i] = gray2bin[i+1] ^ g[i];
  end
endfunction

Verilog

  1. Verilogマスター:デジタル回路設計のための完全チュートリアル
  2. Verilog連結マスター:実践ガイド
  3. Verilog代入文の理解:種類、構文、ベストプラクティス
  4. Verilogブロッキング代入とノンブロッキング代入:違いを徹底解説
  5. Verilog関数のマスター:効率的なRTL設計のために
  6. Verilogタスクの理解:関数との違い、構文、使用法
  7. Verilogクロックジェネレータ:設計と実装ガイド
  8. Verilog数学関数のマスター:効率的なハードウェア設計のために
  9. Verilog $timeformatのマスター:精度と表示制御
  10. Verilog Tフリップフロップ:RTL実装とテストベンチ完全解説
  11. Verilog Mod-Nカウンタ:パラメータ化モジュールとテストベンチ