Posts Issued on September 22, 2025

GameFSMの改良 (6)

posted by sakurai on September 22, 2025 #1026

元はcopyArea()等の4種の関数でしたが、それを統合して内部で振り分けます。これはVRAMへのsingle writer化が目的です。single writer化すると警告が消えるだけでなく、競合条件の数が減るため競合チェック時間も短くなります。

またこれら4種の関数とは別にVRAMアクセスのためのコードも含めています。これもsingle writer化のためです。

  // 元の Stmt を呼び分ける統合 blit(本文は従来の関数をそのまま呼ぶだけ)
  function Stmt blit(Blit b);
    return (seq
      if (b.op == BLIT_COPY)
        copyArea_org(b.sx, b.sy, b.dx, b.dy, b.w, b.h);
      else if (b.op == BLIT_OR)
        orArea_org(b.sx, b.sy, b.dx, b.dy, b.w, b.h);
      else if (b.op == BLIT_ERASE)
        eraseArea_org(b.dx, b.dy, b.w, b.h);
      else if (b.op == BLIT_ANDN)
        eraseAreaSP_org(b.sx, b.sy, b.dx, b.dy, b.w, b.h);
      else if (b.op == BLIT_VDOTS)
        getVdots_org(b.dx, b.dy);
      else // BLIT_HDOTS
        getHdots_org(b.dx, b.dy);
    endseq);
  endfunction

次にコマンド変数とともにFSMを作成します。

  // mkFSM
  Reg#(Blit) blitArg <- mkRegU;
  FSM gfx <- mkFSM( blit(blitArg) ); // FSMの作成

このFSMを起動するRUN_FSMコマンドは汎用に作成されています。fsmを渡すと起動、終了待ちを実行します。

  // FSM起動コマンドの定義
  `define RUN_FSM(F)  seq \
    action F.start(); endaction \
    await(F.done); \
  endseq

  // 起動・完了待ちの薄ラッパ
  function Stmt _BLIT(Blit b);
    return (seq
//      noAction; // read/write競合警告を止めるため
      action blitArg <= b; endaction
      `RUN_FSM(gfx_fsm) // gfx_fsmの起動
    endseq);
  endfunction

_BLIT()はFSMを起動し、終了を待つだけの関数です。


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