赞
踩
前言:
本专栏旨在记录高频笔面试手撕代码题,以备数字前端秋招,本专栏所有文章提供原理分析、代码及波形,所有代码均经过本人验证。
目录如下:
10.数字IC手撕代码-数据位宽转换器(宽-窄,窄-宽转换)
13.数字IC手撕代码-流水握手(利用握手解决流水线断流、反压问题)
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位,与除数相比,8'b0000_0000<8'b0001_0111,商为0,前者作为余数。
再取右移一位的数继续比较,8'b0000_0000< 8'b0001_0111,商为0,前者继续作为余数。
再取右移一位的数继续比较,8'b0000_0000< 8'b0001_0111,商为0,前者继续作为余数。
再取右移一位的数继续比较,8'b0000_0000< 8'b0001_0111,商为0,前者继续作为余数。
再取右移一位的数继续比较,8'b0000_0000< 8'b0001_0111,商为0,前者继续作为余数。
再取右移一位的数继续比较,8'b0000_0000< 8'b0001_0111,商为0,前者继续作为余数。
再取右移一位的数继续比较,8'b0000_0000< 8'b0001_0111,商为0,前者继续作为余数。
再取右移一位的数继续比较,8'b0000_0001< 8'b0001_0111,商为0,前者继续作为余数。
再取右移一位的数继续比较,8'b0000_0010< 8'b0001_0111,商为0,前者继续作为余数。
再取右移一位的数继续比较,8'b0000_0101< 8'b0001_0111,商为0,前者继续作为余数。
再取右移一位的数继续比较,8'b0000_1011< 8'b0001_0111,商为0,前者继续作为余数。
再取右移一位的数继续比较,8'b0001_0111<=8'b0001_0111,商为1,两者之差作为余数。
再取右移一位的数继续比较,8'b0000_0000<8'b0001_0111,商为0,前者作为余数。
再取右移一位的数继续比较,8'b0000_0001<8'b0001_0111,商为0,前者继续作为余数。
再取右移一位的数继续比较,8'b0000_0011<8'b0001_0111,商为0,前者继续作为余数。
再取右移一位的数继续比较,8'b0000_0111<8'b0001_0111,商为0,前者继续作为余数,已经比到最后一位,输出结果:商为1<<4=16,余数为:8'b0000_0111=7。
故计算得到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
结果与我们考虑的一致。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。