Verilogモジュール「top」とverilogモジュール「subcomponent」がある場合、最上位にsubcomponentをインスタンス化するにはどうすればよいですか?
上:
module top(
input clk,
input rst_n,
input enable,
input [9:0] data_rx_1,
input [9:0] data_rx_2,
output [9:0] data_tx_2
);
サブコンポーネント:
module subcomponent(
input clk,
input rst_n,
input [9:0] data_rx,
output [9:0] data_tx
);
注
これは一般的な質問として書かれたもので、何度も何度も現れ続けます。 self-answer の形式に従っています。追加の回答と更新が推奨されます。
これは一般的に SystemVerilog IEEE Std 1800-2012 のセクション23.3.2でカバーされています。
最も簡単な方法は、topのメインセクションでインスタンス化して、名前付きインスタンスを作成し、ポートを順番に接続することです。
module top(
input clk,
input rst_n,
input enable,
input [9:0] data_rx_1,
input [9:0] data_rx_2,
output [9:0] data_tx_2
);
subcomponent subcomponent_instance_name (
clk, rst_n, data_rx_1, data_tx );
endmodule
これは SystemVerilog IEEE Std 1800-2012 のセクション23.3.2.1で説明されています。
これには、特にサブコンポーネントコードのポート順序に関していくつかの欠点があります。ここでの単純なリファクタリングは、接続を切断したり、動作を変更したりする可能性があります。たとえば、誰かがバグを修正し、何らかの理由でポートを並べ替え、clkを切り替えて順序をリセットした場合などです。コンパイラからの接続の問題はありませんが、意図したとおりに機能しません。
module subcomponent(
input rst_n,
input clk,
...
したがって、名前付きポートを使用して接続することをお勧めします。これは、コード内のワイヤの接続のトレースにも役立ちます。
module top(
input clk,
input rst_n,
input enable,
input [9:0] data_rx_1,
input [9:0] data_rx_2,
output [9:0] data_tx_2
);
subcomponent subcomponent_instance_name (
.clk(clk), .rst_n(rst_n), .data_rx(data_rx_1), .data_tx(data_tx) );
endmodule
これは SystemVerilog IEEE Std 1800-2012 のセクション23.3.2.2で説明されています。
各ポートに独自の行を与え、正しくインデントすると、読みやすさとコード品質が向上します。
subcomponent subcomponent_instance_name (
.clk ( clk ), // input
.rst_n ( rst_n ), // input
.data_rx ( data_rx_1 ), // input [9:0]
.data_tx ( data_tx ) // output [9:0]
);
これまでに行われたすべての接続は、サブモジュールへの入力と出力を再利用しており、接続ワイヤは作成されていません。あるコンポーネントから別のコンポーネントに出力を取得する場合はどうなりますか:
clk_gen(
.clk ( clk_sub ), // output
.en ( enable ) // input
subcomponent subcomponent_instance_name (
.clk ( clk_sub ), // input
.rst_n ( rst_n ), // input
.data_rx ( data_rx_1 ), // input [9:0]
.data_tx ( data_tx ) // output [9:0]
);
Clk_subのワイヤが自動的に作成されるため、これは名目上機能します。これに依存する危険があります。デフォルトでは1ビットのワイヤのみが作成されます。これが問題となる例は、データの場合です。
2番目のコンポーネントのインスタンス名が変更されていることに注意してください
subcomponent subcomponent_instance_name (
.clk ( clk_sub ), // input
.rst_n ( rst_n ), // input
.data_rx ( data_rx_1 ), // input [9:0]
.data_tx ( data_temp ) // output [9:0]
);
subcomponent subcomponent_instance_name2 (
.clk ( clk_sub ), // input
.rst_n ( rst_n ), // input
.data_rx ( data_temp ), // input [9:0]
.data_tx ( data_tx ) // output [9:0]
);
上記のコードの問題は、data_tempの幅が1ビットしかないため、ポート幅の不一致に関するコンパイル警告が表示されることです。接続ワイヤを作成し、幅を指定する必要があります。すべての接続ワイヤを明示的に書き出すことをお勧めします。
wire [9:0] data_temp
subcomponent subcomponent_instance_name (
.clk ( clk_sub ), // input
.rst_n ( rst_n ), // input
.data_rx ( data_rx_1 ), // input [9:0]
.data_tx ( data_temp ) // output [9:0]
);
subcomponent subcomponent_instance_name2 (
.clk ( clk_sub ), // input
.rst_n ( rst_n ), // input
.data_rx ( data_temp ), // input [9:0]
.data_tx ( data_tx ) // output [9:0]
);
SystemVerilogに移行すると、少数の文字を入力する手間を省くことができるいくつかのトリックがあります。それらはコードの可読性を妨げ、バグを見つけにくくすることができると信じています。
つかいます .port
同じ名前のワイヤ/レジスタに接続するためのブラケットなし。これは特にたくさんのclkとリセットできれいに見えることがありますが、いくつかのレベルでは異なるクロックやリセットを生成するか、実際には同じ名前の信号に変更したいのに接続したくないため、配線のバグにつながる可能性があります目には明らかではありません。
module top(
input clk,
input rst_n,
input enable,
input [9:0] data_rx_1,
input [9:0] data_rx_2,
output [9:0] data_tx_2
);
subcomponent subcomponent_instance_name (
.clk, // input **Auto connect**
.rst_n, // input **Auto connect**
.data_rx ( data_rx_1 ), // input [9:0]
.data_tx ( data_tx ) // output [9:0]
);
endmodule
これは SystemVerilog IEEE Std 1800-2012 のセクション23.3.2.3で説明されています。
上記よりもさらに悪いと思う別のトリックは.*
言及されていないポートを同じワイヤの信号に接続します。これは、実稼働コードでは非常に危険だと思います。新しいポートが追加されて欠落している場合、または新しいポート名のインスタンスレベルにカウンターパーツがある場合、誤って接続され、自動接続され、警告が生成されないことは明らかではありません。
subcomponent subcomponent_instance_name (
.*, // **Auto connect**
.data_rx ( data_rx_1 ), // input [9:0]
.data_tx ( data_tx ) // output [9:0]
);
これは SystemVerilog IEEE Std 1800-2012 のセクション23.3.2.4で説明されています。
必ずverilog-mode、特にverilog-autoを確認してください。 http://www.veripool.org/wiki/verilog-mode/ これはemacsのverilogモードですが、たとえばvi(m?)にはプラグインが存在します。
インスタンス化は、AUTOINSTを使用して自動化できます。コメントはM-x verilog-auto
で展開され、後で手動で編集できます。
subcomponent subcomponent_instance_name(/*AUTOINST*/);
拡大
subcomponent subcomponent_instance_name (/*AUTOINST*/
//Inputs
.clk, (clk)
.rst_n, (rst_n)
.data_rx (data_rx_1[9:0]),
//Outputs
.data_tx (data_tx[9:0])
);
暗黙のワイヤは/*AUTOWIRE*/
で自動化できます。詳細については、リンクを確認してください。