論理回路デザイン
ArchiTek home page
スループット制御

カウント量可変のサンプルRTL[2]

入力制御タイプ?
  • iStallをiVldで直ちに制御し入力をHoldして処理する形式。
  • oVldとoDataは入力から直接出力する。
  • 終了時にiStallをデアサートし、次のiVldを受け付ける。
  • iCntはiVldごとのカウント量-1を設定する。iData同様、iStallがアサートされている場合Holdする。
  • iStallはiVldに接続するため、パイプライン結合時、組み合わせ回路のループに注意。
  • xxxFunc()はデータの任意の加工を示す。加工なしなら、iDataに置き代わる。
Latency(CLK)0
    
    module gearIT(iData, iCnt, iVld, iStall, oData, oVld, oStall, reset, clk);
            parameter       W       = 32;
            parameter       D       = 4;

            input   [W-1:0] iData;
            input   [D-1:0] iCnt;   // Count Number - 1
            input           iVld;
            output          iStall;
            output  [W-1:0] oData;
            output          oVld;
            input           oStall;
            input           reset;
            input           clk;
    
            wire            oAlloc  = oVld & !oStall;
            reg     [D-1:0] cnt;    // Incrementer
            wire            fin     = oAlloc & (cnt == iCnt);
    
            always @(posedge clk)
                    if (reset | fin)
                            cnt     <= #1 {D{1'b0}};
                    else
                            cnt     <= #1 cnt + oAlloc;
    
            assign iStall   = iVld & !fin;
    
            assign oData    = xxxFunc(iData);
            assign oVld     = iVld;

    function [W-1:0] xxxFunc;
            input   [W-1:0] data;
            xxxFunc = data;
    endfunction
    endmodule
    
            
iVld → oVld伝搬
iVld → iStall伝搬
iStall ← oStall伝搬
Direct Input Gearing 1

入力制御タイプ?
  • iStallをiVldで直ちに制御し入力をHoldして処理する形式。
  • oVldとoDataは一旦ラッチする。
  • 終了時にiStallをデアサートし、次のiVldを受け付ける。
  • iStallはiVldに接続するため、パイプライン結合時、組み合わせ回路のループに注意。
  • xxxFunc()はデータの任意の加工を示す。加工なしなら、iDataに置き代わる。
Latency(CLK)0
    
    module gearIL(iData, iCnt, iVld, iStall, oData, oVld, oStall, reset, clk);
            parameter       W       = 32;
            parameter       D       = 4;

            input   [W-1:0] iData;
            input   [D-1:0] iCnt;   // Count Number - 1
            input           iVld;
            output          iStall;
            output  [W-1:0] oData;
            output          oVld;
            input           oStall;
            input           reset;
            input           clk;
    
            reg             oVld;
            reg     [W-1:0] oData;
            wire            iAlloc  = ~|cntD & iVld;
            wire            oAlloc  = oVld & !oStall;
            reg     [D-1:0] cnt;    // Incrementer
            wire    [D-1:0] cntD;   // Incrementer(Next)
            reg     [D-1:0] num;    // Latched Count Number
            wire    [D-1:0] numD    = iAlloc ? iCnt : num;;
            wire            fin     = oAlloc & (cnt == num);
    
            always @(posedge clk)
                    if (reset) begin
                            oVld    <= #1 1'b0;
                            cnt     <= #1 {D{1'b0}};
                    end
                    else begin
                            oVld    <= #1 |cntD | iVld;
                            cnt     <= #1 cntD;
                    end
    
            always @(posedge clk)
                    num     <= #1 numD;
    
            always @(posedge clk)
                    if (!oStall)
                            oData   <= #1 xxxFunc(iData);
    
            assign cntD     = fin ? {D{1'b0}} : cnt + oAlloc;
    
            assign iStall   = iVld & (cntD != numD) | oStall;

    function [W-1:0] xxxFunc;
            input   [W-1:0] data;
            xxxFunc = data;
    endfunction
    endmodule
    
            
iVld → oVld切断
iVld → iStall伝搬
iStall ← oStall伝搬
Direct Input Gearing 2

出力制御タイプ
  • iData, iVldを一旦ラッチし制御する形式。
  • 終了時のiStallの値によって、さらに2つのタイプに分かれる。
    • iStall=1: iVldを受け付けない。タイミングアークは基本型(S?と等価(RTLの赤字部分をカット)。無駄なバブルサイクルが1つ発生。
    • iStall=0: iVldを受け付ける。タイミングアークはバッファ型(S?と等価。
  • xxxFunc()はデータの任意の逐次加工を示す。加工なしなら、iDataもしくはoDataに置き代わる。
Latency(CLK)1
    
    module gearO(iData, iCnt, iVld, iStall, oData, oVld, oStall, reset, clk);
            parameter       W       = 32;
            parameter       D       = 4;

            input   [W-1:0] iData;
            input   [D-1:0] iCnt;   // Count Number - 1
            input           iVld;
            output          iStall;
            output  [W-1:0] oData;
            output          oVld;
            input           oStall;
            input           reset;
            input           clk;
    
            reg     [W-1:0] oData;
            reg             oVld;
            wire            iAlloc  = iVld & !iStall;
            wire            oAlloc  = oVld & !oStall;
            reg     [D-1:0] cnt;    // Decrementer
            wire            fin     = ~|cnt & oAlloc;
    
            always @(posedge clk)
                    if (reset)
                            cnt     <= #1 {D{1'b0}};
                    else
                            cnt     <= #1 iAlloc ? iCnt : cnt - oAlloc;
    
            always @(posedge clk)
                    if (iAlloc)
                            oData   <= #1 xxxFunc(iData);
                    else if (!oStall)
                            oData   <= #1 xxxFunc(oData);
    
            always @(posedge clk)
                    if (reset)
                            oVld    <= #1 1'b0;
                    else if (!oVld | !oStall)
                            oVld    <= #1 |cnt | iVld;
    
            assign iStall   = oVld & !fin;

    function [W-1:0] xxxFunc;
            input   [W-1:0] data;
            xxxFunc = data;
    endfunction
    endmodule
    
            
iVld → oVld遮断
iStall ← oStall遮断
(S?
iStall ← oStall伝搬
(S?
Latched Gearing

回路デザイン > パイプライン > スループット制御    次のページ(調停)   このページのTOP ▲

[1]
状態遷移により数サイクルに1回程度だけパイプラインを駆動する場合、そのままでは毎サイクル動作するパイプラインが無駄になります。

従って、パイプラインを駆動する部分にスループットを増加させるステージを組み込んでバランスを取ったりします。
[2]
スループット制御には他にもいろんなバリエーションが考えられます。例はあくまでも一例として参照して下さい。