Article #676

既に発行済みのブログであっても適宜修正・追加することがあります。
We may make changes and additions to blogs already published.
posted by sakurai on October 11, 2023 #676

モジュール内でデータを受け取るには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サイクル遅れます。

図%%.1
図676.1 ウエイト伝播

左矢前のブログ 次のブログ右矢

Leave a Comment

Your email address will not be published.

You may use Markdown syntax. If you include an ad such as http://, it will be invalidated by our AI system.

Please enter the numbers as they are shown in the image above.