デジタル IC ティアリング コード -- Xiaomi テクノロジー (ディバイダー設計)

前書き:
このコラムは、デジタル フロントエンドの秋採用者向けに、高頻度の筆記面接で手で引き裂かれたコードの質問を記録することを目的としています。このコラムのすべての記事には、原理分析、コードと波形が提供されており、すべてのコードは私自身によって検証されています。

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

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)

...継続的に更新

ティアオフ コードに関するその他の質問については、Digital IC ティアオフ コード - 質問バンクにアクセスしてください。


トピックの説明

Verilog RTL による除算器の実装。16ビットA、8ビットB。C=A/B


ソリューション

ハードウェアでは、これらはすべて 2 進数であり、2 進数の除算は 10 進数の除算に似ており、シフトしてサイズを比較するプロセスです。

計算手順:

① 被除数の上位データと除数を比較し、前者>後者であれば、対応するビットの商を1として求め、その差から前者の余りを求めることができます。それ以外の場合、対応する商は 0 となり、前者は剰余として直接使用されます。

② 前ステップの剰余と被除数の残り1ビットデータを新しいデータにつなぎ、除数と比較することで、新たな商と剰余が得られます。

③ 被除数の下位桁も計算に加わるまで、②の処理を繰り返します。

たとえば、375/23 = 16'b0000_0001_0111_0111 / 8'b0001_0111

  1. 被除数の最初の桁を除数と比較すると、8'b0000_0000<8'b0001_0111、商は 0 となり、前者が剰余として使用されます。

  1. 次に、右に 1 ビットシフトした数値を取得して比較を続けます (8'b0000_0000< 8'b0001_0111)。商は 0 で、前者は引き続き剰余として使用されます。

  1. 次に、右に 1 ビットシフトした数値を取得して比較を続けます (8'b0000_0000< 8'b0001_0111)。商は 0 で、前者は引き続き剰余として使用されます。

  1. 次に、右に 1 ビットシフトした数値を取得して比較を続けます (8'b0000_0000< 8'b0001_0111)。商は 0 で、前者は引き続き剰余として使用されます。

  1. 次に、右に 1 ビットシフトした数値を取得して比較を続けます (8'b0000_0000< 8'b0001_0111)。商は 0 で、前者は引き続き剰余として使用されます。

  1. 次に、右に 1 ビットシフトした数値を取得して比較を続けます (8'b0000_0000< 8'b0001_0111)。商は 0 で、前者は引き続き剰余として使用されます。

  1. 次に、右に 1 ビットシフトした数値を取得して比較を続けます (8'b0000_0000< 8'b0001_0111)。商は 0 で、前者は引き続き剰余として使用されます。

  1. 次に、右に 1 ビットシフトした数値を取得して比較を続けます (8'b0000_0001< 8'b0001_0111)。商は 0 で、前者は引き続き剰余として使用されます。

  1. 次に、1 ビット右にシフトした数値を取得して比較を続けます (8'b0000_0010< 8'b0001_0111)。商は 0 で、前者は引き続き剰余として使用されます。

  1. 次に、右に 1 ビットシフトした数値を取得して比較を続けます。8'b0000_0101< 8'b0001_0111、商は 0 となり、前者は引き続き剰余となります。

  1. 次に、1 ビット右にシフトした数値を取得して比較を続けます (8'b0000_1011< 8'b0001_0111)。商は 0 で、前者は引き続き剰余として使用されます。

  1. 次に、1 ビット右にシフトした数値を取得して比較を続けます (8'b0001_0111<=8'b0001_0111)。商は 1 で、2 つの差が剰余として使用されます。

  1. 次に、1 ビット右にシフトした数値を取得して比較を続けます (8'b0000_0000<8'b0001_0111)。商は 0 で、前者が剰余として使用されます。

  1. 次に、1 ビット右にシフトした数値を取得して比較を続けます (8'b0000_0001<8'b0001_0111)。商は 0 で、前者は引き続き剰余として使用されます。

  1. 次に、1 ビット右にシフトした数値を取得して比較を続けます (8'b0000_0011<8'b0001_0111)。商は 0 で、前者は引き続き剰余として使用されます。

  1. 次に、1 ビット右にシフトした数値を取得して比較を続けます。8'b0000_0111<8'b0001_0111、商は 0、前者は引き続き剰余として使用され、比較は最後の桁に達し、出力結果が得られます。 : 商は 1<<4=16、余りは 8'b0000_0111=7 です。

  1. したがって、計算は 375/23=16...7 となります。


コード

module divisor(
    input     [15:0]    A       ,
    input     [7:0]     B       ,
    output    [15:0]    result  ,
    output    [7:0]     remain
    );
    reg [15:0]  a_reg   ;
    reg [7:0]   b_reg   ; 
    reg [31:0]  temp_a  ;  # 其实这里取16+8+1bit就够了,取32位是为了好看。
    reg [31:0]  temp_b  ;

    integer     i;
    always@(*)begin
        a_reg = A;
        b_reg = B;
    end

    always@(*)begin
        temp_a = {16'h0,a_reg};
        temp_b = {b_reg,16'h0};
        
        for(i=0;i<16;i=i+1)begin
            temp_a = temp_a <<1;
            if(temp_a >= temp_b)begin
                temp_a = temp_a-temp_b+1;
            end
            else begin
                temp_a = temp_a;
            end
        end
    end

    assign remain = temp_a[31:16];
    assign result = temp_a[15:0];

endmodule

テストベンチ

module divisor_tb();

reg   [15:0]    A       ;
reg   [7:0]     B       ;
wire  [15:0]    result  ;
wire  [7:0]     remain  ;

initial begin
  #10
  A <=  16'd375;
  B <=  8'd23;
  #10
  A <=  16'd557;
  B <=  8'd57;
end

divisor u_divisor(
  .A      (A)       ,
  .B      (B)       ,
  .result (result)  ,
  .remain (remain)
);

endmodule

波形

式 1: 375/23=16...7

式 2: 557/57=9 …… 44

結果は私たちが検討したことと一致しています。

おすすめ

転載: blog.csdn.net/qq_57502075/article/details/129233750