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; endendmodulemailboxは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