次のことを意図していると仮定します。
genvar i;
generate
for(i=0; i<45; i=i+1) begin : gen_asrt
bind dut assertion a1( .a(in_bus[i]), .b(out_bus[i]), .* );
end
これは 2 つの理由で機能しません。
インスタンス名a1
は各ループで上書きされています。モジュール内の各インスタンス名は一意である必要があります。IEEE std 1800-2012 § 23.11「スコープまたはインスタンスへの補助コードのバインド」からの引用:
複数のbind
ステートメントがbind_instantiationを同じターゲット スコープにバインドすることは合法です。ただし、bind_instantiation がターゲット スコープのモジュール名前空間で別の名前と衝突するインスタンス名を導入することはエラーになります (3.13 を参照)。これは、既存の名前と、他のbind
ステートメントによって導入されたインスタンス名の両方に適用されます。bind
後者の状況は、ステートメントを含むモジュールの複数のインスタンスが設計に含まれている場合に発生します。
i
bind ステートメントでは、 ではなく のi
スコープ内の変数名を参照しています。繰り返しますが、IEEE std 1800-2012 § 23.11「スコープまたはインスタンスへの補助コードのバインド」から引用します。dut
genvar i
インスタンスがターゲット スコープにバインドされると、そのインスタンスがターゲット スコープの最後に存在するかのようになります。つまり、ターゲット スコープに存在する、またはターゲット スコープにインポートされたすべての宣言は、バインドされたインスタンスに表示されます。スコープにインポートされたワイルドカード インポート候補は表示されますが、bind ステートメントでワイルドカード候補をインポートすることはできません。存在またはインポートされた宣言$unit
は、bind ステートメントでは表示されません。
この種のチェッカーをバインドする方法:
generate ステートメントを処理する 1 つのモジュールを作成し、そのモジュールを bind ステートメントでインスタンス化できます。例:
module bind_assertions #(parameter SIZE=1) ( input clock, input [SIZE-1:0] a,b );
genvar i;
generate
for(i=0; i<SIZE; i=i+1) begin : gen_asrt
assertion a1_even( .a(a[i]), .b(b[i]), .* );
end
endgenerate
endmodule
bind dut bind_assertions#(45) a1( .a(in_bus), .b(out_bus), .* );
技術的には、インスタンスの配列をバインドできます。これは、§ 23.11 の構文 23-9 と付録 A.4.1.1 'モジュールのインスタンス化' に従う正当な構文です。ただし、これは現在アクセスできるすべてのシミュレーターで失敗しているようです。例 (シミュレーターで動作する場合):
bind dut assertion a1[44:0]( .a(in_bus[44:0]), .b(out_bus[44:0]), .* );
ブロックbind
内に存在できますか?generate
IEEE std 1800-2012 § 27.3 'Generate construct syntax' はbind_directive
、構文 27-1 に示されている生成構文の構文内で言及しています。インスタンスの配列をバインドするのと同様に、すべてのシミュレーターがこの機能をまだサポートしているわけではありません。IEEE std 1800-2009 § 27.3 にも言及されていますbind_directive
が、IEEE std 1800-2005 (SystemVerilog の最初の IEEE バージョン) には言及されていません。例 (シミュレーターで動作する場合):
parameter DO_BIND=1;
generate
if(DO_BIND==1) begin
bind dut bind_assertions#(45) a1( .a(in_bus), .b(out_bus), .* );
end
endgenerate