mailbox

mailboxは、SystemVerilogに初めから定義されているclassの1つです。2つの実行task間でデータのやり取りをするときなどに使用しますが、それと同時にハンドシェイクをする役目も果たします。task_Bはmailboxにデータが入るのを待ち、task_Aからmailboxにデータを入れるとtask_Bはmailboxからデータを受け取ることができます。このとき、task_B側でwhile文などでmailboxを監視する必要はありません。

それでは例を見てみましょう。

--- test.sv ---

module test;
  mailbox mbx;
  event go_e;
  int ia;
  task task_a;
    forever begin
      @go_e;
      mbx.put(ia);
    end
  endtask
  task task_b;
    int ib;
    forever begin
      mbx.get(ib);
      $display("[%0d] ib=%0d",$time,ib);
    end
  endtask
  initial begin
    mbx = new();
    fork task_b; join_none
    #100;
    fork task_a; join_none
    #100 ia=10; -> go_e;
    #100 ia=20; -> go_e;
    #100 ia=30; -> go_e;
    #100 $finish;
  end
endmodule

mailboxはclassですので、使うときは必ずnewをします。mailboxへデータを入れるときは、.put()メソッドを使用します。mailboxからデータを取り出すときは、.get()メソッドを使用します。この例では、module階層に定義した変数iaに対し、initial文の中で値を入れてからevent go_eを発行しています。task_Aはevent待ちとなっており、eventが発行されるとmailboxへiaの値を入れる動作をします。task_Bはmailboxにデータが入るのを待っています(.get()メソッドによる動作)。

mailboxにデータが入ると、.get()メソッドで取り出したデータをibに格納し、その値を時間付きで表示しています。

--- 実行結果 ---

# [200] ib=10

# [300] ib=20

# [400] ib=30