27 |
RISC-Vプロセッサの設計 (25) |
次にパイプラインウェイトをテストします。具体的にはテストベンチにのwait信号を設け、途中でアサートします。
Tb.bsv
Tbにはその記述を追加します。
import StmtFSM::*; import Processor::*; (* synthesize *) module mkTb(); Empty proc <- mkProcessor(); Stmt main = seq proc.if_wait_load(False); delay(10); proc.if_wait_load(True); delay(1); // ここでif_waitを2サイクルアサート proc.if_wait_load(False); delay(10); $finish; endseq; mkAutoFSM(main); endmodule
if_wait信号を1サイクルアサートをさせようとしてdelay(1);を挟みましたが、その前のload(True);により1サイクルアサートされるようです。そのため、1サイクルアサートさせるには以下の表のように、何も挟まないかdelay(0);と記述するようです。
BSV構文 | waitアサート期間 |
---|---|
proc.if_wait_load(True); proc.if_wait_load(False); |
1サイクル |
proc.if_wait_load(True); delay(0); proc.if_wait_load(False); |
1サイクル |
proc.if_wait_load(True); repeat(0) noAction; proc.if_wait_load(False); |
1サイクル |
proc.if_wait_load(True); noAction; proc.if_wait_load(False); |
2サイクル |
proc.if_wait_load(True); delay(1); proc.if_wait_load(False); |
2サイクル |
proc.if_wait_load(True); repeat(1) noAction; proc.if_wait_load(False); |
2サイクル |
Processor.bsv
PCパイプラインにインタフェースを設け、そこにif_wait入力を設けます。
Import FIFO::*; interface Processor_ifc; (* prefix="" *) method Action if_wait_load(Bool in_if_wait); endinterface (* synthesize, always_ready *) module mkProcessor(Processor_ifc);
if_waitはレジスタで宣言します。
Reg#(Bool) if_wait <- mkReg(False);
<IF>において、waitが来たら上位のdeqと下位のenqを停止します。
// <IF> rule if_stage; let pc_if = ifs.first; if (!if_wait) begin ifs.deq; $display (" pc_if = %04h", pc_if); ids.enq (pc_if); end endrule
コンパイルと起動コマンドは以下のとおりです。gtkwaveはここ。
\$ bsc -u -sim Tb.bsv; bsc -sim -e mkTb -o mkTb.exe; ./mkTb.exe -V; gtkwave -A dump.vcd
以下はbsimシミュレーション波形です。if_waitを1サイクルアサートしようとして、delay(1);とすると2サイクルアサートされるので、1サイクルアサートするにはdelay(0);とするようです。
if_waitにより一旦はinvalidになりますが、そのデータを転送するとvalidになってしまうようです。

以下はverilogシミュレーション波形です。if_waitによりinvalidになることはありません。

Leave a Comment