1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

moduleおよびinterfaceのbindと信号の参照方法

Last updated at Posted at 2022-05-28

主にAssertion等の用途でmoduleやinterfaceを他のmoduleにbindする事がある。その際に必要な信号を参照する方法を紹介する。

bindのポート接続で参照

bindされるmoduleにinput portを定義し、bind時に参照する信号を接続する。その際に.*による暗黙的ポート接続が使える。いちいち手で繋ぐのも面倒なので.*で繋ぐことをお勧めする。
下位モジュールの信号はポート接続の所で階層参照で接続する。

checker.sv
bind tb.i_dut checker i_checker( .*, .signal_b(i_sub.signal_b) );

module checker ( input clk, rst_n, signal_a, signal_b );

  a_AB : assert property (@(posedge clk) disable iff(!rst_n) signal_a |=> signal_b);

endmodule 

絶対パスで指定

ポートで接続せずとも当然絶対パスで信号を参照する事ができる。しかし、絶対パスは階層が変わったりすると使えなくなり、再利用性が悪いのでお勧めしない。そもそも絶対パスで参照するならbindなんてする必要はない。

checker.sv
bind tb.i_dut checker i_checker( .*);

module checker ( input clk, rst_n);

  // Absolute signal path referencing
  wire aignal_a = $root.tb.i_dut.signal_a;
  wire aignal_b = $root.tb.i_dut.i_sub.signal_b;
//wire aignal_a =       tb.i_dut.signal_a;
//wire aignal_b =       tb.i_dut.i_sub.signal_b;

  a_AB : assert property (@(posedge clk) disable iff(!rst_n) signal_a |=> signal_b);

endmodule 

相対パスで指定

あまり知られてはいない様だがbindしたmoduleからの相対パスで信号を参照できる。相対パスでの信号の参照方法にも2種類あり、bindしたmoduleのインスタンス名から含める方法と含めない方法がある。
bindしたmodule以下のサブモジュール以下の信号への参照であればどちらの方法でも良いが、bindしたmodule内の直下の信号を参照する場合には必ずそのmoduleのインスタンス名から指定する必要がある。

checker.sv
bind tb.i_dut checker i_checker( .*);

module checker ( input clk, rst_n);

  //-- 1. Relative signal path referencing with bound module instance name
  wire signal_a = i_dut.signal_a;
  wire signal_b = i_dut.i_sub.signal_b;

  //-- 2. Relative signal path referencing without bound module instance name
//wire signal_a2 = signal_a;        // NG !
  wire signal_b2 = i_sub.signal_b;  // OK 

  a_AB  : assert property (@(posedge clk) disable iff(!rst_n) signal_a |=> signal_b );
  a_AB2 : assert property (@(posedge clk) disable iff(!rst_n) signal_a |=> signal_b2);

endmodule 

interfaceのbind

interfaceもmoduleと同様なので全く同様にbindが可能。

dut_if.sv
bind tb.i_dut dut_if i_if( .*);

interface dut_if ( input clk, rst_n, signal_a);

  wire signal_b = i_sub.signal_b; 

  a_AB : assert property (@(posedge clk) disable iff(!rst_n) signal_a |=> signal_b);

endinterface 

interfaceをbindすると何が良いのかと言うとvirtual interfaceとしてそのinterfaceのハンドル(?)をcalssの様なダイナミックオブジェクトにも渡す事ができる。

tb.sv
module tb;

  class aaa;
    virtual dut_if v_if;
    
    virtual task run();
      wait(v_if.signal_a);
      ...
    endtask

  endclass

  initial begin
    aaa a = new(); 
    a.v_if = i_dut.i_if;  // <==== Passing the handle to a class
    a.run();
    ...
  end

  dut i_dut(.*);

endmodule 

これはmoduleではできず、interfaceにしかする事ができない。なので特に理由が無ければmoduleではなくinterfaceをbindする事をお勧めする。

moduleは完全にstaticな世界の住人なのだが、interfaceはvirtual interfaceによりstaticな世界をdynamicな世界に結ぶ事ができる存在なのである。

UVMではSequenceとかでDUTの内部信号を参照したい場合に、このinterfaceのbindを使う事でそれが可能となる。(あるいはbindせずともテストベンチでinterfaceをinstance化して階層参照で信号を参照してinterface内の信号にassignしてもできる。)
以下のWhitebox verificationをご参考

Paper in PDF

以下、Virtual Interfaceを使ってDUTのstaticな世界をUVMのdyamicな世界を繋げるQiita内の記事。ただしこれではbindは使っていない。

この記事では既存のBFMのfunction/taskにアクセスする方法としてVirtual Class(Abstract Class)を紹介しているが、必ずしもVirtual Classを使う必要はなくVirtual Interfaceでやる事も可能。その場合にはinterfaceをBFM moduleにbindしてinterfaceからBFM内にアクセス可能にするとか、あるいはテストベンチトップにbindしてBFM module instanceにアクセスするとか考えられる。もしくはbindせずとも絶対パス参照でBFMにアクセスするようにしても良い。


参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?