VerilogとC:Verilogはハードウェアを記述する


APDahlen Applications Engineer

Verilogはハードウェアを記述するものです。それ以外のものではありません。

すでにマイクロコントローラのプログラミングを知っている場合、これは最も修正が難しい考え方の1つです。Verilogは逐次実行コードのように見えるかもしれませんが、Cプログラミングよりも74シリーズの論理ゲートに近いものです。

Verilogゲートプリミティブを使用したVerilogの並列性を理解する

まず、デジタル論理の授業で扱った積和演算の例から始めます(リスト1および図1)。この例では、Verilogゲートプリミティブを用いて Y = \sum m(2, 4, 5) を実行します。

これらのVerilogゲートプリミティブは、ゲートの種類の後にブール型出力のパラメータ、そして入力が続くC言語の関数のような形式です。例えば、 and (Out, in_1, in_2, in_3)のように記述します。

以下は関数のように見えます。しかし関数ではありません。実行されることはありません。ハードウェアが存在しているだけです。

module sop3_prims (
    input  wire C,       // LSB
    input  wire B,
    input  wire A,
    output wire Y
);

    wire nA, nB, nC;     // inverter wires
    wire m2, m4, m5;     // minterm wires

    not (nA, A);
    not (nB, B);
    not (nC, C);

    and (m2, nA, B, nC); // minterm 2 (010)
    and (m4, A, nB, nC); // minterm 4 (100)
    and (m5, A, nB, C);  // minterm 5 (101)

    or  (Y, m2, m4, m5); // Sum-of-products

endmodule

リスト1: Verilogゲートプリミティブを用いて構成したVerilogの積和演算ハードウェア

図1: リスト1の2、4および5に応答する一般的な3ビット積和演算(https://circuitverse.org/

技術的なヒント: リスト1および図1は説明目的のものです。このような方法でコードを書く人はいません。時間がかかりすぎますし、誤りが入り込む余地が多いためです。よりよい方法についてはリスト2を参照してください。

これはVerilogによって記述された純粋な組み合わせ回路です。すべては同時に存在しており、クロックはなく、レジスタもありません。これは、74HC04 の6回路インバータ、3入力ANDゲートを3回路内蔵した 74HC11 、そして3入力ORゲートを3回路内蔵した 74HC4075 を使って回路を組むのと、ほとんど同じです。

積和演算ハードウェアの標準的なVerilogの記述

リスト2は、積和演算ハードウェアに適したVerilogコードを示しています。これはリスト1よりも簡潔であり、誤りが発生しにくくなっています。しかしながら、FPGAの合成ツールは、対象となるFPGAに対してほぼ同一のネットリストを生成することが期待されます。いずれの場合でも、合成ツールは論理をFPGAの構造およびタイミング効率のよい構成ビットへと変換し、最小の面積と最小の伝搬遅延になるように最適化します。

技術的なヒント: もしまだFPGAをマイクロコントローラの視点で考えているのであれば、FPGAのビットファイルはペリフェラルを設定するための巨大なテーブルであると考えることができます。

module sop3_standard (
    input  wire C, B, A,   // LSB to MSB
    output wire Y
);

    assign Y = (~A &  B & ~C) |  // minterm 2 (010)
               ( A & ~B & ~C) |  // minterm 4 (100)
               ( A & ~B &  C);   // minterm 5 (101)

endmodule

リスト2: 積和演算回路のための推奨コード

FPGAのLUTに関する誤解とタイミングへの影響

FPGAは論理ゲートの集合ではありません。そうでななく、基本論理ブロックはルックアップテーブル(LUT)です。この記事で示した積和演算の記述は、単一のLUTにマッピングされます。実際には、最近のLUTは3ビットよりも入力数が多いため、まだ余裕があります。例えば、Terasicの DE23-Lite に搭載されている Alteraの Agilex 3 A3CZ135BB18AE7S では、図2に示すように8入力LUTを備えています。

図1に戻ると、インバータの伝搬遅延が長いために、典型的なグリッチハザードが発生することが分かります。LUTでは積和演算全体が単一のLUTに集約されるため、これが最小化されます。これはタイミンググリッチが完全に排除されることを意味するものではありません。しかし、この場合には大幅に低減されます。複数のLUTを含む大規模な設計では、レジスタを使用した実装の方が適しています。

図2: Agilex 3 FPGAにおける適応型ロジックモジュールのブロック図

レジスタとクロック信号によるFPGAハードウェアの制御

ここまでは、FPGA内部のすべてが同時に動作すると仮定してきました。ここからは、クロックおよびフリップフロップ(レジスタ、あるいは単に同期メモリとも呼ばれます)を導入することで、組み合わせ論理から順序回路へ移行します。

この違いは図2に示されています。簡単な例として、最上部の出力信号はLUTから直接取り出されていますが、その次の出力信号は上側のフリップフロップ(レジスタ)から取り出されています。これらは組み合わせ出力と同期出力(それぞれ)を表しています。

  • 組み合わせ出力は継続的に更新されます。

  • レジスタはクロック信号の立ち上がりエッジで更新されます。

例えば、Terasicのボードでは、プログラム可能なTexas Instrumentsの LMK3C0105A05RERR を使用して、FPGAに3つのクロック信号を供給しています。
リスト3は同期式のVerilogコードを示しています。最も重要な変更点は、ノンブロッキング代入演算子「<=」と、posedge clkに対する感度指定です。図2との関係で言えば、SOP演算には引き続きLUTが使用されますが、新たにregが追加されます。regに格納される値はクロック信号に同期します。

module sop3_registered (
    input  wire clk, C, B, A,
    output reg Y
);

    always @(posedge clk) begin
        Y <= (~A &  B & ~C) | 
             ( A & ~B & ~C) | 
             ( A & ~B &  C);
    end

endmodule

リスト3: レジスタ付き積和演算ハードウェアの記述

シミュレーションに慣れることの落とし穴:Verilogがハードウェアでなくなるとき

ここまでは、FPGAを構成するビットファイルへ変換される合成された論理のみに焦点を当ててきました。Verilogの用途はこれだけではありません。まもなくVerilogベースのテストベンチが登場します。テストベンチはFPGA上で動作するものではなく、PC上で動作します。そのため、コンパイルされたVerilogテストベンチは、FPGAでは実現できない動作を実行できます。主な違いは時間制御とループ処理が可能である点です。例えば、Nクロックサイクルを生成するVerilogテストベンチを作成することができます。

もしVerilogがプログラミングのように見え始めた場合、それは合成されません。

ハードウェアとテストベンチとの区別

リスト4には、その典型的な兆候のいくつかを見ることができます。これにはシミュレーションのtimescale指定、tb(testbench)プレフィックス、そして5タイムユニットの遅延を示す#が含まれます。

THIS WILL NOT SYNTHESIZE INTO AN FPGA BITFILE.

`timescale 1ns/1ps

initial begin
    clk = 0;
    {A, B, C} = 3'b010; // Apply minterm 2

    for (i = 0; i < 10; i = i + 1) begin
        #5 clk = ~clk; // Rising edge - Y updates here!
        #5 clk = ~clk; // Falling edge
    end

    // Add code to test all minterms.

    $stop;
end

リスト4: Verilogテストベンチの一部です。このコードは合成されません。

技術的なヒント: 別の機会にVerilogジェネレータについて説明できます。これはプログラミングのように見えますが、実際には反復的にハードウェアを生成する仕組みです。N個のモジュールをインスタンス化するための便利な方法を提供します。

ご健闘をお祈りします。

APDahlen

著者による関連記事

この記事が気に入った場合は、以下の関連記事も役立つかもしれません。

著者について

Aaron Dahlen氏、LCDR USCG(退役)は、DigiKeyでアプリケーションエンジニアを務めています。彼は、技術者およびエンジニアとしての27年間の軍役を通じて構築されたユニークなエレクトロニクスおよびオートメーションのベースを持っており、これは12年間教壇に立ったことによってさらに強化されました(経験と知識の融合)。ミネソタ州立大学Mankato校でMSEEの学位を取得したDahlen氏は、ABET認定EEプログラムで教鞭をとり、EETプログラムのプログラムコーディネーターを務め、軍の電子技術者にコンポーネントレベルの修理を教えてきました。

Dahlen氏は、ミネソタ州北部の故郷に戻り、コンデンサ探しから始まった数十年にわたる旅を終えました。彼の物語はこちらからお読みください。




オリジナル・ソース(English)