SystemVerilog:mailbox

SystemVerilogの「mailbox」を書いてみました。
FIFOの拡張版(やり取り制御込み)といったところでしょうか。

ちなみに、キッカケはこちらのブログです。
Is my SystemVerilog mailbox half-full or half-empty? An engineer’s hunger now served!

  • サンプルコード1
module testbench;

  mailbox mbx;

  task task_put(input int in);
    mbx.put(in);
  endtask

  task task_get;
    int data;
    forever begin
      mbx.get(data);
      $display("@%0d data=%0d", $time, data);
    end
  endtask

  initial begin
    mbx = new();
    fork task_get; join_none

    for(int i=0; i<10; i++) begin
      #10; task_put(10*i);
    end

    #100 $finish;
  end

endmodule
  • 出力結果
# run -all
# @10 data=0
# @20 data=10
# @30 data=20
# @40 data=30
# @50 data=40
# @60 data=50
# @70 data=60
# @80 data=70
# @90 data=80
# @100 data=90              

確かに、emptyなど確認せずに使えるので便利♪

ブログのように boundを指定

  • サンプルコード(bound=8)
module testbench;

  mailbox mbx;

  task task_put(input int in);
    mbx.put(in);
    $display("@%0d mbx.num() = %0d", $time, mbx.num());
  endtask

  task task_get;
    int data;
    forever begin
      #100 mbx.get(data);
      $display("@%0d data=%0d", $time, data);
    end
  endtask

  initial begin
    mbx = new(8);
    fork task_get; join_none
    
    for(int i=0; i<10; i++) begin
      #10; task_put(10*i);
    end

    #1000 $finish;
  end

endmodule
  • 出力結果
# run -all
# @10 mbx.num() = 1
# @20 mbx.num() = 2
# @30 mbx.num() = 3
# @40 mbx.num() = 4
# @50 mbx.num() = 5
# @60 mbx.num() = 6
# @70 mbx.num() = 7
# @80 mbx.num() = 8
# @100 data=0
# @100 mbx.num() = 8
# @200 data=10
# @200 mbx.num() = 8
# @300 data=20
# @400 data=30
# @500 data=40
# @600 data=50
# @700 data=60
# @800 data=70
# @900 data=80
# @1000 data=90   

なるほど!
put する方もちゃんと待っているんですね。

その他のメンバ関数

この他にもメンバ関数として、

  • Try to place a message in a mailbox without blocking: try_put()
  • Retrieve a message from a mailbox: peek()
  • Try to retrieve a message from a mailbox without blocking: try_get() or try_peek()

があります。

参考サイト