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サイクル遅れます。