4 |
BSVにおけるコマンドバッファ制御 (3) |
それでは実際のソース、GameFSM.bsv, OneStage.bsv, SoundFSM.bsvを提供します。これらはそれぞれゲームFSM、中間バッファ、サウンドFSMのソースです。両FSMを直結できるかどうか調査して、できるのであれば、ソースを修正してください。
目的
現在の設計では、GameFSMとSoundFSMの間にOneStageという中間モジュールが存在しています。これはFIFOではなく、コマンド受け渡しのbusyフラグを持つ調停回路です。 これを 完全に排除し、BSV の Ready/Enable による自動ハンドシェークだけで同期をとる構成に書き換えます。
Before / After 構成
現在(Before)
GameFSM ──► OneStage ──► SoundFSM
- 実データは GameFSM 側の inscode レジスタに保持
- OneStage は empty/wr_en/rd_en による制御信号だけを調停している
変更後(After)
GameFSM ──► SoundFSM × 4ch
- 余計な 1 cycle が削減
- BSC が各
sound()
呼び出しに Ready/Enable を自動合成
修正方針(概要)
修正対象ファイル | 修正内容 |
---|---|
OneStage.bsv | 完全に削除 (または mkTop から除外) |
GameFSM.bsv | OneStage 接続を削除し、Vector#(4, FSM_ifc) を受けるよう改修 |
SoundFSM.bsv | 変更不要(既にmethod sound(Code_t) をエクスポート) |
mkTop.bsv | Vector を生成し、そのまま GameFSM へ 1引数で渡す |
修正内容の詳細
1. OneStage.bsv を削除
このファイルは完全に不要になるため
2. GameFSM.bsv の修正
(A) インターフェースを Vector 版へ
interface GameFSM_ifc;
method Action step();
interface Vector#(4, FSM_ifc#(Code_t)) soundCh; // ★ 追加
endinterface
-module invader_move(GameFSM_ifc /*AUTOARG*/);
+module invader_move #(Vector#(4, FSM_ifc#(Code_t)) ch) (GameFSM_ifc);
(B) 不要レジスタ削除
- Wire#(Bool) fempty <- mkWire;
- Reg#(Bool) fwen <- mkReg(False);
- Reg#(UInt#(4)) inscode<- mkRegU;
(C) sound() ではなく 1 行呼び出し
rule send_sound;
UInt#(2) idx = truncate(nextCode); // ch[0]~[3] を選択
ch[idx].sound(nextCode); // BSC が ready/enable を自動合成
nextCode <= nextCode + 1;
endrule
3. SoundFSM.bsv の変更は不要
既に以下のようにインターフェースが定義されています:
interface FSM_ifc;
method Action sound(Code_t code);
endinterface
module mkSoundFSM0(FSM_ifc);
4. トップモジュール(mkTop.bsv)の修正
module mkTop ();
Vector#(4, FSM_ifc#(Code_t)) sc <- replicateM(mkSoundFSM0); // または個別生成
sc[1] <- mkSoundFSM1();
sc[2] <- mkSoundFSM2();
sc[3] <- mkSoundFSM3();
GameFSM_ifc gfsm <- mkGameFSM(sc); // ← 1 引数で OK
endmodule
メリット
- OneStage 削除 → 余計な 1 cycle 遅延を解消
- 自前ハンドシェーク (fempty, fwen) ロジック消失 → 記述量削減
- 音チャンネルが Vector に集約 → 拡張時もTopと呼び出し構文は不変
- Ready/Enable は BSC が自動生成 → 衝突・競合を静的解析で保証
Leave a Comment