論理回路デザイン
ArchiTek home page
リソースシェアリング

リソースシェアリングサンプルRTL

ステートマシン制御
  • 4変数の積を1つの乗算器で算出するため、S1からS3の3状態[3]ステートマシン[4]を使用。
  • 状態S3まで入力データをHoldさせるためStallを発生。
  • 状態S3で出力データのハンドシェークを実施。出力データは32bitまるめ。
  • iStallのタイミングを切断するには1サイクル追加してS0(IDLE)状態を新たに作り、入力データをラッチ。
Latency(CLK)3
    
    module product(
            iData0, iData1, iData2, iData3,
            iVld, iStall,
            oData, oVld, oStall,
            reset, clk);
    
            parameter       W       = 32;

            parameter       S1      = 2'h1,
                            S2      = 2'h2,
                            S3      = 2'h3;
    
            input   [W-1:0] iData0, iData1, iData2, iData3;
            input           iVld;
            output          iStall;
            output  [W-1:0] oData;          // Result
            output          oVld;
            input           oStall;
            input           reset;
            input           clk;
    
            reg     [1:0]   state, stateD;
            wire            Stall   = oVld & oStall;
            reg     [W-1:0] aIn, bIn;
            wire    [W-1:0] yOut;
    
            reg             oVld;
            reg     [W-1:0] oData, oDataD;

            wire            iAlloc  = iVld & !iStall;
            wire            oAlloc  = oVld & !oStall;
    
            assign yOut     = aIn * bIn;  // Mul Resource (32bit clip)
    
            always @(state or Stall or
                    oData or yOut or
                    iVld or iData0 or iData1 or iData2 or iData3) begin

                    stateD  = state;        // Default
                    oDataD  = oData;
                    aIn     = {W{1'bx}};
                    bIn     = {W{1'bx}};

                    if (!Stall)
                            case (state)
                                    S1: if (iVld) begin
                                            stateD             = S2;
                                            {aIn, bIn, oDataD} = {iData0, iData1, yOut};
                                    end
                                    S2: begin
                                            stateD             = S3;
                                            {aIn, bIn, oDataD} = {oData,  iData2, yOut};
                                    end
                                    S3: begin
                                            stateD             = S1;
                                            {aIn, bIn, oDataD} = {oData,  iData3, yOut};
                                    end
                            endcase
            end
    
            always @(posedge clk)
                    if (reset)
                            state   <= #1 S1;
                    else
                            state   <= #1 stateD;
    
            always @(posedge clk)
                    if (reset)
                            oVld    <= #1 1'b0;
                    else
                            oVld    <= #1 (stateD == S3);
    
            always @(posedge clk)
                    oData   <= #1 oDataD;
    
            assign iStall   = iVld & (state != S3) | oStall;
    endmodule
    
            
iVld → oVld切断
iVld → iStall伝搬
iStall ← oStall切断
State Machine

回路デザイン > パイプライン > リソースシェアリング    次のページ(パラメータ)   このページのTOP ▲

[1]
優先方式で生じる僅かな傾向の差は、シミュレーション時間を増やしても変わらないので、構造上の差としか言えません。とは言え、Stallのゆらぎで性能の良し悪しが反転するのは少し不思議な気がしており、改めてチェックする必要性を感じています。
[2]
パイプラインの性質上、同一リソースのメモリユニットに対して、Read→加工→Writeの手順を踏むのが大半です。このReadとWriteを束ねてアクセスした方が効率的です。ただし、論理帯域を必要とするものは、ReadとWriteを分けた方が得策な場合があります。
[3]
実際のステートの定義は、具体的で何をしているのか分かりやすい名前を付けます。
[4]
oAllocと(state==S2)の条件は重ならないのでこの書き方ですが、将来シュリンクなどを行って状態が1つだけになると整合しなくなります。なるべく、重なることを想定した書き方の方が好ましいと言えます。