天天看點

數字IC手撕代碼--小米科技(除法器設計)題目描述解決思路代碼testbench波形圖

前言:

本專欄旨在記錄高頻筆面試手撕代碼題,以備數字前端秋招,本專欄所有文章提供原理分析、代碼及波形,所有代碼均經過本人驗證。

目錄如下:

1.數字IC手撕代碼-分頻器(任意偶數分頻)

2.數字IC手撕代碼-分頻器(任意奇數分頻)

3.數字IC手撕代碼-分頻器(任意小數分頻)

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手撕代碼-泰淩微筆試真題

15.數字IC手撕代碼-平頭哥技術終面手撕真題

16.數字IC手撕代碼-兆易創新筆試真題

17.數字IC手撕代碼-樂鑫科技筆試真題(4倍頻)

18.數字IC手撕代碼-雙端口RAM(dual-port-RAM)

...持續更新

更多手撕代碼題可以前往 數字IC手撕代碼--題庫。

題目描述

除法器的Verilog RTL實作。16bitA,8bitB。C=A/B

解決思路

在硬體中都是二進制數,二進制除法和十進制除法類似,都是一個移位并比較大小的過程。

計算步驟:

① 将被除數高位資料與除數作比較,如果前者>=後者,則可得到對應位的商為1,兩者做差得到第一步的餘數;否則得到對應的商為0,将前者直接作為餘數。

② 将上一步中的餘數與被除數剩餘最高位1bit資料拼接成新的資料,然後再和除數做比較,可以得到新的商和餘數。

③ 重複過程②,直到被除數最低位資料也參與計算。

舉個例子375/23 = 16'b0000_0001_0111_0111 / 8'b0001_0111

  1. 取被除數的第1位,與除數相比,8'b0000_0000<8'b0001_0111,商為0,前者作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_0000< 8'b0001_0111,商為0,前者繼續作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_0000< 8'b0001_0111,商為0,前者繼續作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_0000< 8'b0001_0111,商為0,前者繼續作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_0000< 8'b0001_0111,商為0,前者繼續作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_0000< 8'b0001_0111,商為0,前者繼續作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_0000< 8'b0001_0111,商為0,前者繼續作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_0001< 8'b0001_0111,商為0,前者繼續作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_0010< 8'b0001_0111,商為0,前者繼續作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_0101< 8'b0001_0111,商為0,前者繼續作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_1011< 8'b0001_0111,商為0,前者繼續作為餘數。
  1. 再取右移一位的數繼續比較,8'b0001_0111<=8'b0001_0111,商為1,兩者之差作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_0000<8'b0001_0111,商為0,前者作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_0001<8'b0001_0111,商為0,前者繼續作為餘數。
  1. 再取右移一位的數繼續比較,8'b0000_0011<8'b0001_0111,商為0,前者繼續作為餘數。
  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
           

testbench

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
           

波形圖

數字IC手撕代碼--小米科技(除法器設計)題目描述解決思路代碼testbench波形圖

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

算式2:557/57=9 ......44

結果與我們考慮的一緻。