Article #1015

既に発行済みのブログであっても適宜修正・追加することがあります。
We may make changes and additions to blogs already published.
posted by sakurai on September 4, 2025 #1015

ChatGPTのコードがあまり良くないので、次の考え方で整理してコードを修正します。

元の処理はbusyを内部演奏状態に使用すると同時に外部にbusyを見せていたので、プリエンプティブではなかった。この2つを分離し、playを内部演奏状態とし、外部には受取りの1サイクルのみbusyを立てるようにしてください。

以下に変更したコードを示します。

package Consumer4;

interface Consumer4Ifc;
   method Action consume(UInt#(4) x);
endinterface

module mkConsumer4 (Consumer4Ifc);

   Reg#(UInt#(4)) cnt      <- mkReg(0);     // 0-14 を数える 4bit で十分
   Reg#(Bool)     busy     <- mkReg(False); // ハンドシェーク停止用 1 サイクル
   Reg#(Bool)     play     <- mkReg(False); // 15 サイクル演奏フラグ
   Reg#(UInt#(4)) lastVal  <- mkRegU;       // 取り込んだコード
   
   /* 15 サイクル演奏タイマ */
   rule timer (play);
      if (cnt == 14) begin
         cnt  <= 0;
         play <= False;          // 演奏終了
      end
      else
         cnt <= cnt + 1;
   endrule
   
   /* busy は 1 サイクル後に自動クリア */
   rule clear_busy (busy);
      busy <= False;
   endrule

  /* 受信メソッド
      ガード if (!busy) を付けることで
      can_fire = !busy が自動生成される */
   method Action consume(UInt#(4) x) if (!busy);
      lastVal <= x;                   // EN=1 サイクルでラッチ
      $display("%0t: consume = %h", $time, x);
      busy <= True;              // 1 サイクルだけbusyを上げる
      play <= True;              // 演奏開始
      cnt  <= 0;
   endmethod
endmodule
endpackage

左矢前のブログ 次のブログ右矢

Leave a Comment

Your email address will not be published.

You may use Markdown syntax. If you include an ad such as http://, it will be invalidated by our AI system.

Please enter the numbers as they are shown in the image above.