デジタルICハンドテアリングコード-XX社筆記試験問題(データフローパイプラインの総括)

 序文: 

        このコラムは、デジタル フロントエンドの秋採用者向けに、頻繁に行われるペン インタビューの手引きコード質問を記録することを目的としており、このコラムのすべての記事には原理分析、コードと波形が提供されており、すべてのコードは私自身によって検証されています。

ディレクトリは次のとおりです。

1. デジタルICハンドティアコード分周器(任意の偶数分周)

2. デジタル IC ハンドティアコード分周器 (任意の奇数分周)

3. デジタル IC ハンドティアコード分周器 (任意の 10 進分周)

4.デジタルICハンドティアリングコード - 非同期リセットと同期リリース

5.デジタルICハンドティアコード - エッジ検出(立ち上がりエッジ、立ち下がりエッジ、ダブルエッジ)

6. デジタルICハンドティアリングコード列検出(ステートマシン書き込み方式)

7. デジタルICハンドティアリングコード列検出(シフトレジスタ書き込み方式)

8. デジタルICティアリングコード - 半加算器、全加算器

9. デジタル IC ハンド ティアリング コード - シリアルからパラレル、パラレルからシリアル

10.デジタルICハンドティアリングコード-データビット幅変換器(幅-狭幅、狭幅変換)

11. デジタル IC ハンド ティアリング コード - 有限状態マシン FSM - 飲料マシン

12.デジタルICハンドティアコード - ハンドシェイク信号(READY-VALID)

13. デジタル IC ハンド ティアリング コード - 水ハンドシェイク (ハンドシェイクを使用してパイプラインの中断と背圧の問題を解決します)

14. デジタル IC ハンド テアリング コード - Telink マイクロ筆記試験問題

15. デジタル IC 手引きコード - Pingtouge 技術最終面手引き本当の質問

16.デジタルICマニュアルティアリングコード-Zhaoyiイノベーション筆記試験実際の質問

17. デジタル IC ハンド ティアリング コード - Espressif Technology 筆記試験実際の問題 (4 回の頻度)

18. デジタル IC ティアリング コード - デュアルポート RAM (デュアルポート RAM)

        ...継続的に更新

 ハンドテアリング コードに関するその他の質問については、 デジタル IC ハンドテアリング コード - 質問バンクにアクセスしてください。


目次

トピックの説明

問題解決のアイデア

コード

テストベンチ

出力波形


トピックの説明

        連続データ ストリームを入力して、256 データ ストリームごとの合計値を取得します。タイミング ダイアグラムは次のとおりです。

        入力は i0、i1、i2、…、i253、i254、…であり、1 クロック サイクルに相当し、出力 sum0 は i0 +i2+….+i254 (間隔ごとに加算) の合計値、sum1 は i1+i3+ です。 …. +i255、sum2 は i2+i4+….+i256 など、各出力は 1 クロック サイクルを占有し、Sum0 と i0 の間の相対遅延関係は任意です。入力 i0、i1、i254、... が 8 ビット値であると仮定し、出力合計が精度を失わない適切なビット幅を選択し、最大限のリソースで上記の要件を達成するために Verilog 言語を使用してください。あなたの考え方を保存します。

問題解決のアイデア

        この質問の要約は実際には比較的単純ですが、重要なのは、要件を達成するために最もリソース効率の高い方法を使用することです。入力はすべて 8 ビットで、sum0 と sum1 は i0 から i255 までで、256 個の 8 ビット数値が加算されます。したがって、256 個の 8 ビット数値の加算は 16 ビット数値で表現する必要があるため、合計を 15 ビットに設定します。そして、次のようなルールがあります。

        sum2=sum0-i0+i256、sum3=sum1-i1+i257

        深さ 257*8 ビットの空間 datain_store を使用して i0 ~ i256 を格納すると、値が入力されるたびに、datain_store が 8 ビットシフトして新しい受信数値を格納します。次に 2 つの合計を使用します。1 つの合計は奇数 128 項目の合計を出力し、もう 1 つの合計は偶数 128 項目の合計を出力します。

コード

module pip_sum(
    input           clk         ,
    input           rstn        ,
    input  [7:0]    datain      ,
    input           datain_ena  ,
    
    output [14:0]   sum         ,
    output          dataout_ena 
);

reg [8*257-1:0] datain_store;  //DEPTH = 2056

reg [7:0] count;
reg [14:0] sum_odd,sum_even;

reg datain_ena_onebeat;

reg flag;

always @(posedge clk)begin
    if(datain_ena)begin
        datain_store <= {datain_store[8*256-1:0],datain}; //left shift 8bit, store datain in low 8bit
    end
end

always @(posedge clk)begin
    if(!rstn)begin
        count <= 8'd0;
    end
    else if(datain_ena_onebeat == 1'b1 && count < 8'd255)begin
        count <= count + 1'b1;
    end
    else if(datain_ena_onebeat == 1'b1 && count == 8'd255)begin
        count <= 8'd0;
    end
end

always @(posedge clk)begin
    if(!rstn)
        flag <= 1'b0;
    else if(count == 8'd255) 
        flag <= 1'b1;  //
end
wire [7:0] look;
assign look = datain_store[7:0];
always @(posedge clk)begin
    if(!rstn)begin
        sum_odd  <= 15'd0;
        sum_even <= 15'd0;
    end
    else begin
        datain_ena_onebeat <= datain_ena;
        if(datain_ena_onebeat) 
            case(count[0])
                0:begin 
                    if(flag==0)
                        sum_even <= sum_even + datain_store[7:0];
                    else 
                        sum_even <= sum_even - datain_store[8*257-1:8*256] + datain_store[7:0];
                end
                1:begin
                    if(flag==0)
                        sum_odd  <= sum_odd  + datain_store[7:0];
                    else 
                        sum_odd  <= sum_odd - datain_store[8*257-1:8*256] + datain_store[7:0];
                end
            endcase
    end
end

reg [14:0] sum_odd_onebeat,sum_even_onebeat;
always @(posedge clk)begin
    sum_odd_onebeat  <= sum_odd;
    sum_even_onebeat <= sum_even;
end

assign sum = (count[0]) ? sum_odd_onebeat: sum_even_onebeat;
assign dataout_ena = flag;

endmodule

テストベンチ

module pip_sum_tb();

reg clk,rstn;
reg [15:0] count;
reg [7:0] datain;
reg datain_ena;

wire [14:0] sum;
wire dataout_ena;

always #5 clk <= ~clk;
initial begin
    clk <= 1'b0;
    rstn <= 1'b0;
    #16
    rstn <= 1'b1;
    #20
    datain_ena <= 1'b1;

    #10000
    $finish();
end

initial begin
    datain <= 8'd0;
    count <= 1'b0;
    forever begin
        @(posedge clk)begin
            if(datain_ena == 1)begin
                if(count < 255)begin
                    datain <= 1'b0;
                end
                else
                    datain <= datain + 1'b1;
                    count <= count + 1'b1;
            end
        end
    end
end

//dump fsdb
initial begin
    $fsdbDumpfile("pip_sum.fsdb");
    $fsdbDumpvars(0);
end

pip_sum u_pip_sum(
    .clk            (clk)       ,
    .rstn           (rstn)      ,
    .datain         (datain)    ,
    .datain_ena     (datain_ena),

    .sum            (sum)       ,
    .dataout_ena    (dataout_ena)
);

endmodule

出力波形

        結果の正確さを容易にするために、datain の最初の 256 サイクルを 0 にして、出力 sum0 と sum1 が両方とも 0 になるようにし、その後 datain を正の整数シーケンスとしてインクリメントします。出力結果からわかるように、sum0=sum1=0、sum2=sum0-i0+i256=0-0+1=1; sum3=sum1-i1+i257=0-0+ という予想と一致しています。 2=2 などです。


 ハンドテアリング コードに関するその他の質問については、 デジタル IC ハンドテアリング コード - 質問バンクにアクセスしてください。

おすすめ

転載: blog.csdn.net/qq_57502075/article/details/127836194
おすすめ