Vengineerの妄想(準備期間)

人生は短いけど、長いです。人生を楽しみましょう!

Bluespec SystemVerilog : HELLO WORLDを学ぶ(その5)

Verification Engineerの戯言


(その4)のカウント値の比較を別のルールに記述することも可能です。
すべてのルールは並列に動作するので、end_runルールではctrは5と比較しています。
say_helloルールは、ctrが5未満のときのみ実行されるようにします。
このようにルールが実行される条件を()内に指定することができます。

    package FirstAttempt;

        // My first design in the cool Bluespec language

        String s = "Hello world";

        (* synthesize *)
        module mkAttempt(Empty);

            Reg#(UInt#(3)) ctr <- mkReg(0);

            rule end_run (ctr==5);
                $finish(0);
            end
 
            rule say_hello (ctr<5);
                ctr <= ctr + 1;
                $display(s);
            endrule
        endmodule
    endpackage 

次は、カウントアップ部分も別のルールにしてみます。
これで3つのルール(end_run, say_hello, inc_ctr)が並列に動作します。

    package FirstAttempt;

        // My first design in the cool Bluespec language

        String s = "Hello world";

        (* synthesize *)
        module mkAttempt(Empty);

            Reg#(UInt#(3)) ctr <- mkReg(0);

            rule end_run (ctr==5);
                $finish(0);
            end
 
            rule say_hello (ctr<5);
                $display(s);
            endrule

            rule inc_ctr;
                ctr <= ctr + 1;
            endrule

        endmodule
    endpackage 

ここでもし、say_helloルールに(ctr<5)という条件が無い場合はどうなるでしょう!
そうです。ここでRace Conditionが発生する可能性があります。
それは、前のsay_helloルールでは、$displayの実行後、カウントアップされましたが、
この例では、say_helloルールとinc_ctrルールの順番がどうなるかは分かりません。
say_helloルールが実行された後に、inc_ctrルールが実行しなければいけません。
そのためにも、say_helloルールには(ctr<5)という条件が必要です。

試しに、say_helloルールから(ctr<5)という条件を削除し、シミュレーションしてみると、


7回も"Hello World"が表示されます。

Verilog HDLファイルを生成してみました。

    % bsc -verilog FirstAttempt.bsv

生成されたファイルは次のようになっています。

    `ifdef BSV_ASSIGNMENT_DELAY
    `else
    `define BSV_ASSIGNMENT_DELAY
    `endif

    module mkAttempt(CLK,
	             RST_N);
      input  CLK;
      input  RST_N;

      // register ctr
      reg [2 : 0] ctr;
      wire [2 : 0] ctr$D_IN;
      wire ctr$EN;

      // register ctr
      assign ctr$D_IN = ctr + 3'd1 ;
      assign ctr$EN = 1'd1 ;

      // handling of inlined registers

      always@(posedge CLK)
      begin
        if (!RST_N)
        begin
          ctr <= `BSV_ASSIGNMENT_DELAY 3'd0;
        end
        else
        begin
          if (ctr$EN) ctr <= `BSV_ASSIGNMENT_DELAY ctr$D_IN;
        end
      end

      // synopsys translate_off
    `ifdef BSV_NO_INITIAL_BLOCKS
    `else // not BSV_NO_INITIAL_BLOCKS
      initial
      begin
        ctr = 3'h2;
      end
    `endif // BSV_NO_INITIAL_BLOCKS
      // synopsys translate_on

      // handling of system tasks

      // synopsys translate_off
      always@(negedge CLK)
      begin
        #0;
        if (RST_N) if (ctr < 3'd5) $display("Hello world");
        if (RST_N) if (ctr == 3'd5) $finish(32'd0);
      end
      // synopsys translate_on
    endmodule  // mkAttempt

say_helloルールの(ctr<5)の条件がないと、

        if (RST_N) if (ctr < 3'd5) $display("Hello world");

    のところが、

        $display("Hello world");    

になりますので、RST_Nが"0"のときにも"Hello World"が表示されます。。

検証、Verification、Bluespec SystemVerilog