論理回路デザイン
ArchiTek home page
パラメータ

算術で圧縮を行うサンプルRTL

Compress Using Easy Operation
  • 2つのFIFOに分けてパラメータ送信制御。
  • データはほとんどの場合+1か+2し、その他はランダムな値をとるものと仮定。
  • ランダムな値をとる割合は10%程度で、FIFOの深さは1:8とする。
  • 初期化は前段からiNew信号で指示(iNewは利用せず、リセット後Validフラグを準備して制御してもよい)。
Latency(CLK)1
    
    module compress(iVld, iStall, iNew, iData, oVld, oStall, oData, reset, clk);
            parameter       W       = 32;
            parameter       NOP     = 2'h0;
            parameter       PLUS1   = 2'h1;
            parameter       PLUS2   = 2'h2;
            parameter       CHANGE  = 2'h3;

            input           iVld;
            output          iStall;
            input           iNew;
            input   [W-1:0] iData;
            output          oVld;
            input           oStall;
            output  [W-1:0] oData;
            input           reset;
            input           clk;
    
            reg     [W-1:0] lData;          // Latched Data
            wire    [W-1:0] lData0;         // Latched Data + 0
            wire    [W-1:0] lData1;         // Latched Data + 1
            wire    [W-1:0] lData2;         // Latched Data + 2
            wire            eq0;
            wire            eq1;
            wire            eq2;
            wire            iOpVld;
            wire            iOpStall;
            reg     [1:0]   iOpData;        // Operation Code
            wire            iItVld;
            wire            iItStall;
            reg     [W-1:0] iItData;        // Initial Data
            wire            oOpVld;
            wire            oOpStall;
            wire    [1:0]   oOpData;        // Operation Code
            wire            oItVld;
            wire            oItStall;
            wire    [W-1:0] oItData;        // Initial Data
            reg     [W-1:0] oData;
    
            wire            iAlloc  = iVld & !iStall;
            wire            oAlloc  = oVld & !oStall;
            wire            oNew    = (oOpData == CHANGE);
    
            reg     [W-1:0] acc;

            // Past Data for Comparison
            always @(posedge clk)
                    if (iAlloc)
                            lData   <= #1 iData;

            assign iStall   = iOpStall | iItStall;
    
            assign lData0   = lData;
            assign lData1   = lData + 'd1;
            assign lData2   = lData + 'd2;
    
            assign eq0      = (iData == lData0);
            assign eq1      = (iData == lData1);
            assign eq2      = (iData == lData2);
    
            assign iOpVld   = iVld & !iItStall;
            assign iItVld   = iVld & !iOpStall;
    
            // Operation Code
            always @(iNew or eq0 or eq1 or eq2)
                    casex ({iNew, eq2, eq1, eq0})
                            4'b1xxx,
                            4'b0000: iOpData = CHANGE;
                            4'b0001: iOpData = NOP;
                            4'b001x: iOpData = PLUS1;
                            4'b01xx: iOpData = PLUS2;
                    endcase
    
            assign iItData  = iData;
    
            // Operation FIFO (Depth 2^4, Data Width W bit)
            fifo #(2, 4) opFifo (
                    .iVld   (iOpVld),
                    .iStall (iOpStall),
                    .iData  (iOpData),
                    .oVld   (oOpVld),
                    .oStall (oOpStall),
                    .oData  (oOpData),
                    .reset  (reset),
                    .clk    (clk)
                    );
    
            // Initial FIFO (Depth 2^1, Data Width W bit)
            fifo #(W, 1) itFifo (
                    .iVld   (iItVld),
                    .iStall (iItStall),
                    .iData  (iItData),
                    .oVld   (oItVld),
                    .oStall (oItStall),
                    .oData  (oItData),
                    .reset  (reset),
                    .clk    (clk)
                    );
    
            // Accumulator
            always @(posedge clk)
                    if (oAlloc)
                            acc     <= #1 oData;
    
            // Operation
            always @(oOpData or oItData or acc)
                    casex (oOpData)
                            NOP:    oData   = acc;
                            PLUS1:  oData   = acc + 'd1;
                            PLUS2:  oData   = acc + 'd2;
                            CHANGE: oData   = oItData;
                    endcase
    
            assign oOpStall = oStall | !oItVld;
            assign oItStall = oStall | !oOpVld & !oNew;
    
            assign oVld     = oOpVld & (!oItStall | !oNew);
    
    endmodule
    
            
iVld → oVld切断
iVld → iStall伝搬
iStall ← oStall切断
Compress Circuit

回路デザイン > パイプライン > パラメータ    このページのTOP ▲

[1]
パラメータの保持は予想以上にコストがかかるので、パイプラインに識別子だけを流しSRAMへの間接参照することもあります。このように、パラメータの引き込みは様々な方法を組み合わせてコストの圧縮に努める必要があります。
[2]
あまり変化しない一時的なテンポラリデータは、パラメータ同様圧縮して使う場合があります。また、一旦メモリに退避して再度使用するような場合もあります。

パラメータのメモリへの出し入れはレジュームにも役に立つので、検討してみる価値があります。レジューム時は、メモリアクセスの負荷を軽減するためランレングス圧縮など真の圧縮方式の導入も考えます。
[3]
オペレーション情報をパイプラインに流す手法はプロセッサのデータパス操作に似ています。レジスタファイル→演算→レジスタファイルのパイプラインに対して、オペレータとオペランドを同期させて送るイメージです。
[4]
外部のSDRAMをアクセスする場合、パラメータはSDRAMでなく内部SRAMにスタックすることがあります。パラメータのアクセスがボトルネックになるのを防ぐとともにSDRAMの帯域増加を抑えるのが目的です。