論理回路デザイン
お問い合わせ サイトマップ リンク Tips
ArchiTek home page
調停

適正な調停について

調停確定方式のサンプルRTL

Routing
  • 分岐で特定のパイプラインにValidを伝達。同時に、選択変数sSelを別パイプラインに伝達。分岐例として巡回型(sSelがネゴシエーションごとにインクリメント)。
  • 結合で特定のパイプラインのValidを選択。選択は、選択変数sSelに従う。
  • データの記述は省略。
Latency(CLK)0
    
    module split(sVld, sStall, sSel, iVld, iStall, oVld, oStall, reset, clk);
            output          sVld;
            input           sStall;
            output  [R-1:0] sSel;
            input           iVld;
            output          iStall;
            output  [N-1:0] oVld;
            input   [N-1:0] oStall;
            input           reset;
            input           clk;
    
            wire            nasc    = iVld & !iStall;
    
            reg     [R-1:0] sSel;
            wire    [N-1:0] vldVec   = 1'b1 << sSel;
    
            always @(posedge clk)
                    if (reset)
                            sSel    <= #1 {R{1'b0}};
                    else if (!iStall)
                            sSel    <= #1 sSel + 1'b1;

            assign iStall   = oStall[sSel] | sStall;
            assign sVld     = nasc;
            assign oVld     = {N{nasc}} & vldVec;
    endmodule
    
            
iVld → oVld伝搬
iVld → iStall切断
iStall ← oStall伝搬
Separate Circuit
Latency(CLK)1
    
    module unite(sVld, sStall, sSel, iVld, iStall, oVld, oStall);
            input           sVld;
            output          sStall;
            input   [R-1:0] sSel;
            input   [N-1:0] iVld;
            output  [N-1:0] iStall;
            output          oVld;
            input           oStall;
    
            wire    [N-1:0] StallVec   = 1'b1 << sSel;
    
            assign sStall   = !iVld[sSel] | oStall;
            assign iStall   = {N{!sVld | oStall}} | ~StallVec;
            assign oVld     = iVld[sSel] & sVld;
    endmodule
    
            
iVld → oVld伝搬
iVld → iStall伝搬
iStall ← oStall伝搬
Unite Circuit

調停非確定方式のサンプルRTL

Round-Robin Arbiter
  • N個のValidからラウンドロビン方式[5]で1つを選択。
  • データの記述は省略(oArb信号でN個のdataから1つを選択)。
  • ラウンドロビン方式のポインタは、巡回し昇順近傍のものを調停結果とする。
  • ポインタの巡回方式によって性格が異なる。
    • ポインタを毎サイクルインクリメントすれば疑似的なランダム調停(Validを均等に処理)
    • ポインタを調停結果+1に置き換えれば更新型の調停(Validを均等に処理)
    • ポインタを調停結果に置き換えればパーキング型の調停(同一Validの連続を優先)
Latency(CLK)0
    
    module rrArbiter(iVld, iStall, oVld, oStall, oArb, reset, clk);
            parameter       R       = 3;
            parameter       N       = 1<<R;

            input   [N-1:0] iVld;
            output  [N-1:0] iStall;
            output          oVld;
            input           oStall;
            output  [R-1:0] oArb;
            input           reset;
            input           clk;
    
            reg     [R-1:0] oPtr;   // Round-Robin Pointer
            wire    [N-1:0] oVec    = 1'b1 << rrArb;

            // 0: Park, 1: Not Park
            wire            oInc    = 1'b1;
    
            always @(posedge clk)
                    if (reset)
                            oPtr    <= #1 {R{1'b0}};
                    else if (oVld & !oStall)
                            oPtr    <= #1 oArb + oInc;
    
    
            assign iStall   = {N{oStall}} & ~oVec;

            assign oVld     = |iVld;
            assign oArb     = arbFunc(iVld, oPtr);
    
    function [R-1:0] arbFunc;
            input   [N-1:0] vld;
            input   [R-1:0] ptr;
            reg     [R-1:0] idx;
            reg     [R-1:0] num[N-1:0];
            integer         i, j;
            begin
                    for (i=0; i<N; i=i+1) begin
                            num[i]  = {R{1'bx}};
                            for (j=0; j<N; j=j+1) begin
                                    idx     = i[R-1:0] + ~j[R-1:0];
                                    if (vld[idx])
                                            num[i]  = idx;
                            end
                    end
                    arbFunc = num[ptr];
            end
    endfunction
    
    endmodule
    
            
iVld → oVld伝搬
iVld → iStall伝搬
iStall ← oStall伝搬
Round-Robin Arbiter Circuit

回路デザイン > パイプライン > 調停    次のページ(同期)   このページのTOP ▲

[1]
RTLを注意深く見て頂くと分かると思いますが、調停方式ごとに基本型にするかバッファ型にするかが異なります。バッファ型はバッファできるFFが限定されるため、多対1に応用することができないからです。
[2]
サンプルコードにあるsplitとuniteを直接接続するとValidとStallのLoopが生じます。当たり前ですが、この間には任意のステージが存在することが前提です。
[3]
システムLSI内ではパイプラインの役割が比較的に明確なのである程度の予測が出来、順位付けは不特定多数のサービスを行う通信より明確に論じられていないと思われます。
[4]
帯域制御は万能ではありません。あくまでもミクロ的に取得帯域のリミットを設定するイメージだと考えます。また、優先制御と帯域制御を組み合わせてシステム固有の最適な解を見つけるには、ある程度の研究が必要であると思われます。
[5]
Round-Robin Arbiterで使用しているarbFunc()は速度優先(回路規模大)の記述です。予め全てのポインタの可能性で得られる結果をチェックし、最後に指定ポインタでその結果を選択しています。通常は、指定ポインタ分バレルシフトし、優先回路で選択します。前者は1から2割程度の速度アップを確認しています。

なお、調停後の選択子はラッチして使用することが多いのですが、低レイテンシが必要なシステムでは止む無く選択子を直に使うことがあり、このような例を出しました。