30 |
BSVの設計トライアル (18) |
StmtFSM
前稿ではBSVにより、ステートベースのFSMを設計しました。ステートベースとは、シーケンスを人手でステートに分解し、一つ一つのステートに対してルールを書くもので、基本的にはverilogと同程度の工数がかかります。一方、BSVにはステートマシンを効率的に設計できる、StmtFSMというライブラリが存在します。
検証用FSM
このライブラリの検証用のために検証用FSMを作成します。検証用FSMは2つのコンカレントなFSMを持ち、一方のSenderFSMがFIFOにデータを詰め(エンキュー)、他方のReceiverFSMがFIFOからデータを取り出す(デキュー)ものとします。コンカレントであり、エンキューとデキューは同時に起こります。

package Tb; import StmtFSM::*; import FIFOF::*; (* synthesize *) module mkTb (Empty); FIFOF#(Bit#(8)) fifo <- mkFIFOF; Stmt sender = seq $display("senderFSM %4d FSM started", $time); action $display("senderFSM %4d Enq 10", $time); fifo.enq(10); endaction action $display("senderFSM %4d Enq 20", $time); fifo.enq(20); endaction action $display("senderFSM %4d Enq 30", $time); fifo.enq(30); endaction repeat (8) noAction; endseq; FSM senderFSM <- mkFSM(sender ); Stmt receiver = seq $display("receiverFSM %4d receiver FSM started", $time); while(True) seq action $display("receiverFSM %4d FIFO popped data", $time, fifo.first()); fifo.deq(); endaction repeat (2) noAction; endseq endseq; FSM receiverFSM <- mkFSM(receiver); rule startit; senderFSM.start(); receiverFSM.start(); endrule rule finish (senderFSM.done() && !receiverFSM.done()); $finish; endrule endmodule endpackage
コードに示すように、エンキューはレイテンシ1で実行され、デキューはレイテンシ3で実行されます。各々のFSMは、エンキューデータ、デキューデータをそれぞれ表示します。