ダブルバッファをはさんだパイプライン

[] [] []


前項ではステージ間のバッファが1個であったので、あるステージで処理が長引くとそれ以前のステージはすべて待ち状態になる。そこでステージ間のバッファを2(バンク0,バンク1)に増やした場合を考える。

このバッファはFIFOと見なせるので、ステージ間の制御もFIFOと同様にすればよい (非同期FIFOの作り方)

k番目のステージの動作は次のようになる。

(1) 初期状態ではステージはアイドル(idle_reg =1)でバッファは空。

(2) 前段のバッファが空でなく(ibuf_bank!=bankr_reg)、かつ自ステージが処理中でなく(idle_reg=1)かつ後段のバッファがフルでなければ(obuf_bank!=(bankw_reg^2'b10))、データを入力レジスタにロード(load =1パルス)してステージは処理中(idle_reg=0)になる。ここでidleに対してセットとクリアが同時に来ることはない。

/* ステージの開始条件 */

assign load = (ibuf_bank!=bankr_reg) & (obuf_bank!=(bankw_reg^2'b10)) & idle_reg;

 

/* ステージの処理有無 */

always @(posedge clk or negedge rst_n)

    begin

    if(~rst_n)

        idle_reg <= 1'b1;

    else if(done)

        idle_reg <= 1'b1;

    else if(load)

        idle_reg <= 1'b0;

    end

(3) nLATクロック後に完了する(done=1パルス)ので、idleをクリアし、出力データを後段のバッファに書き込む。

/* バッファのリード側バンク */

always @(posedge clk or negedge rst_n)

    begin

    if(~rst_n)

        bankr_reg <= 2'd0;

    else if(load)

        bankr_reg <= bankr_reg + 1'b1;

    end

 

/* バッファのライト側バンク */

always @(posedge clk or negedge rst_n)

    begin

    if(~rst_n)

        bankw_reg <= 2'd0;

    else if(done)

        bankw_reg <= bankw_reg + 1'b1;

    end

シミュレーションで確認してみると、シングルバッファの場合に比べてダブルバッファの場合は待ち時間が少なくなっている様子が見れる。

(i) ダブルバッファをはさんだパイプライン

(ii) シングルバッファをはさんだパイプライン


[] [] []