Digital IC tearing code--Xiaomi Technology (divider design)

Foreword:
This column aims to record high-frequency written interview hand-torn code questions for the digital front-end autumn tricks. All articles in this column provide principle analysis, codes and waveforms, and all codes have been verified by myself.

The directory is as follows:

1. Digital IC hand-tear code-frequency divider (any even number frequency division)

2. Digital IC hand-tear code-frequency divider (any odd frequency division)

3. Digital IC hand-tear code-frequency divider (any decimal frequency division)

4. Digital IC hand tearing code - asynchronous reset and synchronous release

5. Digital IC hand tear code - edge detection (rising edge, falling edge, double edge)

6. Digital IC hand tearing code-sequence detection (state machine writing method)

7. Digital IC hand tearing code-sequence detection (shift register writing method)

8. Digital IC tearing code - half adder, full adder

9. Digital IC hand tearing code - serial to parallel, parallel to serial

10. Digital IC hand tearing code-data bit width converter (width-narrow, narrow-width conversion)

11. Digital IC hand tearing code - finite state machine FSM - beverage machine

12. Digital IC hand tear code - handshake signal (READY-VALID)

13. Digital IC hand tearing code - water handshake (use handshake to solve the problem of pipeline interruption and back pressure)

14. Digital IC hand tearing code - Telink micro written test questions

15. Digital IC hand tearing code - Pingtouge technology final face hand tearing real question

16. Digital IC manual tearing code-Zhaoyi innovation written test real questions

17. Digital IC hand tearing code - Espressif Technology written test real questions (4 times frequency)

18. Digital IC tearing code - dual-port RAM (dual-port-RAM)

...Continually updated

For more tear-off code questions, you can go to Digital IC tear-off code--question bank .


topic description

Verilog RTL implementation of a divider. 16bitA, 8bitB. C=A/B


Solutions

In hardware, they are all binary numbers. Binary division is similar to decimal division. It is a process of shifting and comparing sizes.

calculation steps:

① Compare the high-order data of the dividend with the divisor. If the former >= the latter, the quotient of the corresponding bit can be obtained as 1, and the difference between the two can be used to obtain the remainder of the first step; otherwise, the corresponding quotient is 0, and the former is directly used as remainder.

② Splicing the remainder in the previous step and the remaining 1-bit data of the dividend into new data, and then comparing it with the divisor, a new quotient and remainder can be obtained.

③ Repeat process ② until the lowest digit of the dividend also participates in the calculation.

For example 375/23 = 16'b0000_0001_0111_0111 / 8'b0001_0111

  1. Take the first digit of the dividend, compared with the divisor, 8'b0000_0000<8'b0001_0111, the quotient is 0, and the former is used as the remainder.

  1. Then take the number shifted one bit to the right and continue to compare, 8'b0000_0000< 8'b0001_0111, the quotient is 0, and the former continues to be used as the remainder.

  1. Then take the number shifted one bit to the right and continue to compare, 8'b0000_0000< 8'b0001_0111, the quotient is 0, and the former continues to be used as the remainder.

  1. Then take the number shifted one bit to the right and continue to compare, 8'b0000_0000< 8'b0001_0111, the quotient is 0, and the former continues to be used as the remainder.

  1. Then take the number shifted one bit to the right and continue to compare, 8'b0000_0000< 8'b0001_0111, the quotient is 0, and the former continues to be used as the remainder.

  1. Then take the number shifted one bit to the right and continue to compare, 8'b0000_0000< 8'b0001_0111, the quotient is 0, and the former continues to be used as the remainder.

  1. Then take the number shifted one bit to the right and continue to compare, 8'b0000_0000< 8'b0001_0111, the quotient is 0, and the former continues to be used as the remainder.

  1. Then take the number shifted one bit to the right and continue to compare, 8'b0000_0001< 8'b0001_0111, the quotient is 0, and the former continues to be used as the remainder.

  1. Then take the number shifted one bit to the right and continue to compare, 8'b0000_0010< 8'b0001_0111, the quotient is 0, and the former continues to be used as the remainder.

  1. Then take the number shifted one bit to the right and continue to compare, 8'b0000_0101< 8'b0001_0111, the quotient is 0, and the former continues to be the remainder.

  1. Then take the number shifted one bit to the right and continue to compare, 8'b0000_1011< 8'b0001_0111, the quotient is 0, and the former continues to be used as the remainder.

  1. Then take the number shifted one bit to the right and continue the comparison, 8'b0001_0111<=8'b0001_0111, the quotient is 1, and the difference between the two is used as the remainder.

  1. Then take the number shifted one bit to the right and continue the comparison, 8'b0000_0000<8'b0001_0111, the quotient is 0, and the former is used as the remainder.

  1. Then take the number shifted one bit to the right and continue the comparison, 8'b0000_0001<8'b0001_0111, the quotient is 0, and the former continues to be used as the remainder.

  1. Then take the number shifted one bit to the right and continue to compare, 8'b0000_0011<8'b0001_0111, the quotient is 0, and the former continues to be used as the remainder.

  1. Then take the number shifted one bit to the right and continue the comparison. 8'b0000_0111<8'b0001_0111, the quotient is 0, and the former continues to be used as the remainder, which has been compared to the last digit. The output result: the quotient is 1<<4=16, and the remainder is: 8'b0000_0111=7.

  1. Therefore, the calculation is 375/23=16...7.


the code

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

Waveform

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

Formula 2: 557/57=9 ...... 44

The results are consistent with what we considered.

Guess you like

Origin blog.csdn.net/qq_57502075/article/details/129233750