22 |
GameFSMの改良 (6) |
元は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を起動し、終了を待つだけの関数です。