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)
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
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.