11 |
BSVでのデータの受け取り方2例 |
モジュール内でデータを受け取るにはRegisterを設置する方法とWireを設置する方法があります。パイプラインプロセッサのwait信号を例にして、2つの違いを見てみます。
まず、Test-benchにおいてRegisterを設置するのは共通とします。例えば、
Tb.bsv:
import StmtFSM::*; import Processor::*; (* synthesize *) module mkTb(); Processor_ifc proc <- mkProcessor(); Reg#(Bool) if_wait <- mkReg(True); Reg#(Bool) mc_wait <- mkReg(True); Reg#(Bool) ex_wait <- mkReg(True); Reg#(Bool) ma_wait <- mkReg(True); rule load_wait_values; proc.if_wait_load(if_wait); proc.mc_wait_load(mc_wait); proc.ex_wait_load(ex_wait); proc.ma_wait_load(ma_wait); endrule Stmt main = seq action if_wait <= False; mc_wait <= False; ex_wait <= False; ma_wait <= False; endaction delay(4); if_wait <= True; delay(0); if_wait <= False; delay(4);
(中略)
$finish; endseq; mkAutoFSM(main); endmodule
であり、下位のモジュールが、
Processor.bsv:
import FIFO::*; interface Processor_ifc; (* prefix="" *) method Action if_wait_load(Bool in_if_wait); method Action mc_wait_load(Bool in_mc_wait); method Action ex_wait_load(Bool in_ex_wait); method Action ma_wait_load(Bool in_ma_wait); endinterface (* synthesize, always_ready *) module mkProcessor(Processor_ifc); Reg#(int) pc <- mkReg(0); FIFO#(Maybe#(int)) ifs <- mkLFIFO; FIFO#(Maybe#(int)) ids <- mkLFIFO; FIFO#(Maybe#(int)) exs <- mkLFIFO; FIFO#(Maybe#(int)) mas <- mkLFIFO; FIFO#(Maybe#(int)) wbs <- mkLFIFO; Reg#(Bool) if_wait <- mkReg(False); Reg#(Bool) mc_wait <- mkReg(False); Reg#(Bool) ex_wait <- mkReg(False); Reg#(Bool) ma_wait <- mkReg(False); // <PC> rule pc_stage; if (pc > 100) $finish(0); $display("------"); ifs.enq(tagged Valid pc); pc <= pc + 4; endrule // <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 else begin ids.enq (tagged Invalid); end endrule // <ID> rule id_stage; let pc_id = ids.first; if (!mc_wait) begin ids.deq; $display (" pc_id = %04h", pc_id); exs.enq (pc_id); end else begin exs.enq (tagged Invalid); end endrule // <EX> rule ex_stage; let pc_ex = exs.first; if (!ex_wait) begin exs.deq; $display (" pc_ex = %04h", pc_ex); mas.enq (pc_ex); end else begin mas.enq (tagged Invalid); end endrule // <MA> rule ma_stage; let pc_ma = mas.first; if (!ma_wait) begin mas.deq; $display (" pc_ma = %04h", pc_ma); wbs.enq (pc_ma); end else begin wbs.enq (tagged Invalid); end endrule // <WB> rule wb_stage; let pc_wb = wbs.first; wbs.deq; $display (" pc_wb = %04h", pc_wb); endrule method Action if_wait_load(Bool in_if_wait); if_wait <= in_if_wait; endmethod method Action mc_wait_load(Bool in_mc_wait); mc_wait <= in_mc_wait; endmethod method Action ex_wait_load(Bool in_ex_wait); ex_wait <= in_ex_wait; endmethod method Action ma_wait_load(Bool in_ma_wait); ma_wait <= in_ma_wait; endmethod endmodule: mkProcessor
この場合は上位がレジスタであり、下位もレジスタであるため、信号の伝播が1サイクル遅れます。