Verilog モジュール
module
特定の機能を実装する Verilog コードのブロックです。モジュールは他のモジュール内に組み込むことができ、上位レベルのモジュールは、入力ポートと出力ポートを使用して下位レベルのモジュールと通信できます。
構文
モジュール module
で囲む必要があります と endmodule
キーワード。モジュールの名前は module
の直後に指定する必要があります キーワードとオプションのポートのリストも宣言できます。ポート宣言のリストで宣言されたポートは、モジュールの本体内で再宣言できないことに注意してください。
module <name> ([port_list]);
// Contents of the module
endmodule
// A module can have an empty portlist
module name;
// Contents of the module
endmodule
すべての変数宣言、データフロー ステートメント、関数またはタスク、および下位モジュール インスタンス (存在する場合) は、module
内で定義する必要があります。 および endmodule
キーワード。同じファイル内に異なる名前の複数のモジュールが存在する可能性があり、任意の順序で定義できます。
例
モジュール dff は、3 つの入力ポート d、clk、rstn と 1 つの出力ポート q を持つ D フリップフロップを表します。モジュールの内容は、入力のさまざまな組み合わせに対して D フリップフロップがどのように動作するかを説明しています。ここで、rstn がアクティブ ロー リセットであるため、rstn がハイの場合、入力 d は常にクロックのポジティブ エッジで出力 q に割り当てられます。
// Module called "dff" has 3 inputs and 1 output port
module dff ( input d,
input clk,
input rstn,
output reg q);
// Contents of the module
always @ (posedge clk) begin
if (!rstn)
q <= 0;
else
q <= d;
end
endmodule
ハードウェア回路図
このモジュールは、合成中に次のデジタル回路に変換されます。
モジュールの外にコードを書くことはできないことに注意してください!
モジュールの目的は何ですか?
モジュールは、特定の動作特性を実装し、合成中にデジタル回路に変換されるデザイン ユニットを表します。入力の任意の組み合わせをモジュールに与えることができ、対応する出力を提供します。これにより、同じモジュールを使用できます より複雑なハードウェアを実装するより大きなモジュールを形成するために再利用されます。
たとえば、上記の DFF を連鎖させてシフト レジスタを形成することができます。
module shift_reg ( input d,
input clk,
input rstn,
output q);
wire [2:0] q_net;
dff u0 (.d(d), .clk(clk), .rstn(rstn), .q(q_net[0]));
dff u1 (.d(q_net[0]), .clk(clk), .rstn(rstn), .q(q_net[1]));
dff u2 (.d(q_net[1]), .clk(clk), .rstn(rstn), .q(q_net[2]));
dff u3 (.d(q_net[2]), .clk(clk), .rstn(rstn), .q(q));
endmodule
ハードウェア回路図
dff インスタンスは、Verilog RTL モジュールで記述されているようにワイヤで接続されていることに注意してください。
小さなブロックを積み上げて大きな設計ブロックを形成する代わりに、その逆を行うこともできます。単純な GPU エンジンを小さなコンポーネントに分解して、それぞれが特定の機能を実装するモジュールとして表現できるようにすることを検討してください。以下に示す GPU エンジンは、それぞれが特定の機能を実行する 5 つの異なるサブブロックに分けることができます。バス インターフェイス ユニットは、外部からデータをデザインに取り込み、それを別のユニットで処理して命令を抽出します。後続の他のユニットは、前のユニットから提供されたデータを処理します。
各サブブロックは module
として表すことができます 他のモジュールと通信するための入力信号と出力信号の特定のセットを使用し、各サブブロックを必要に応じてより細かいブロックにさらに分割できます。
最上位モジュールとは?
トップレベル モジュールはを含むものです 他のすべてのモジュール。最上位モジュールは、他のモジュール内ではインスタンス化されません。
たとえば、デザイン モジュールは通常、トップ レベルのテストベンチ モジュール内にインスタンス化されるため、入力スティミュラスを提供することでシミュレーションを実行できます。ただし、テストベンチは他のすべてをカプセル化するブロックであり、したがってトップレベル モジュールであるため、他のモジュール内ではインスタンス化されません。 .
トップ レベルの設計
以下に示す設計コードには、design と呼ばれる最上位モジュールがあります。これは、デザインを完成させるために必要な他のすべてのサブモジュールが含まれているためです。サブモジュールは、mod1 内の mod3 や mod2 内の mod4 のように、さらにネストされたサブモジュールを持つことができます。とにかく、mod1 と mod2 がインスタンス化されると、これらはすべて最上位モジュールに含まれます。これでデザインは 完成し、設計の最上位モジュールです。
//---------------------------------
// Design code
//---------------------------------
module mod3 ( [port_list] );
reg c;
// Design code
endmodule
module mod4 ( [port_list] );
wire a;
// Design code
endmodule
module mod1 ( [port_list] ); // This module called "mod1" contains two instances
wire y;
mod3 mod_inst1 ( ... ); // First instance is of module called "mod3" with name "mod_inst1"
mod3 mod_inst2 ( ... ); // Second instance is also of module "mod3" with name "mod_inst2"
endmodule
module mod2 ( [port_list] ); // This module called "mod2" contains two instances
mod4 mod_inst1 ( ... ); // First instance is of module called "mod4" with name "mod_inst1"
mod4 mod_inst2 ( ... ); // Second instance is also of module "mod4" with name "mod_inst2"
endmodule
// Top-level module
module design ( [port_list]); // From design perspective, this is the top-level module
wire _net;
mod1 mod_inst1 ( ... ); // since it contains all other modules and sub-modules
mod2 mod_inst2 ( ... );
endmodule
テストベンチ トップ レベル
テストベンチ モジュールには、デザインの機能をチェックするためのスティミュラスが含まれており、主にシミュレーション ツールを使用した機能検証に使用されます。したがって、デザインはインスタンス化され、テストベンチ モジュール内で d0 と呼ばれます。シミュレーターの観点から見ると、テストベンチは最上位モジュールです。
//-----------------------------------------------------------
// Testbench code
// From simulation perspective, this is the top-level module
// because 'design' is instantiated within this module
//-----------------------------------------------------------
module testbench;
design d0 ( [port_list_connections] );
// Rest of the testbench code
endmodule
階層名
モジュールを相互にインスタンス化できる場合、階層構造が形成されます。したがって、最上位モジュールは root と呼ばれます。 .特定のモジュール内の各下位モジュールのインスタンス化には異なる識別子名が必要であるため、シグナルへのアクセスにあいまいさはありません。階層名は、ドット .
で区切られたこれらの識別子のリストによって構築されます。 階層の各レベル。特定のシグナルへの階層パスを使用して、任意のモジュール内で任意のシグナルにアクセスできます。
// Take the example shown above in top level modules
design.mod_inst1 // Access to module instance mod_inst1
design.mod_inst1.y // Access signal "y" inside mod_inst1
design.mod_inst2.mod_inst2.a // Access signal "a" within mod4 module
testbench.d0._net; // Top level signal _net within design module accessed from testbench
Verilog