4 |
BSVの設計トライアル (20) |
実行結果
次は、ファンクションの中にシーケンスを組み込み、ゲームFSMの設計トライアルを行います。 シーケンスを人手で分解することは、なるべくしたくありません。ファンクションでシーケンスが定義できれば、インベーダ動作、自機動作等のファンクションを作成し、順番にそれらを呼び出せば良いはずです。
import StmtFSM::*; interface TestFSM_ifc; method Action inp(UInt#(8) inx); endinterface (* synthesize *) module mkTestFSM(TestFSM_ifc); Reg#(UInt#(8)) i <- mkRegU; Reg#(UInt#(8)) x <- mkRegU; function Stmt test1; return (seq $display("%3d 1-1", $time); delay(5); $display("%3d 1-2", $time); endseq); endfunction function Stmt test2(UInt#(8) xx); return (seq $display("%3d 2-1", $time); for (i <= 0; i < xx; i <= i + 1) $display("%3d 2-loop-%1d", $time, i); $display("%3d 2-2", $time); endseq); endfunction Stmt main = seq $display("%3d fsm1.start", $time); test1; $display("%3d fsm2.start", $time); test2(x); endseq; mkAutoFSM(main); method Action inp(UInt#(8) inx); x <= inx; endmethod endmodule: mkTestFSM
このためのテストベンチを示します。あえてモジュール外部からループ回数を入れているのは、ループ回数がダイナミックに(実行時に)決定できるかを確認するためです。ファンクションのループを8回呼び出してみます。
import StmtFSM::*; import TestFSM::*; (* synthesize, always_ready, always_enabled *) module mkTb (Empty); TestFSM_ifc test <- mkTestFSM(); Reg#(UInt#(8)) count <- mkReg(8); Stmt main = seq test.inp(count); repeat(40) noAction; endseq; mkAutoFSM(main); endmodule
実行結果を示します。test1の次にtest2が呼び出され、ループが8回回ったことを示しています。
20 fsm1.start 30 1-1 90 1-2 100 fsm2.start 110 2-1 130 2-loop-0 150 2-loop-1 170 2-loop-2 190 2-loop-3 210 2-loop-4 230 2-loop-5 250 2-loop-6 270 2-loop-7 290 2-2