数字IC除法器结构

在数字电路中,如何可以实现除法器呢?

我们先以二进制除法的运算过程为例:

在这里插入图片描述

上图中,蓝色表示被除数,红色表示商,紫色表示余数。

如1011(十进制11)除以0011(十进制3)的运算过程,首先从最高位开始,第一位是1,显然不够除以0011,因此本位的商为0,然后扩展下一位变为10依然不够,商继续为0,再扩展一位变为101,此时大于0011,因此将商置1,得到余数010;然后扩展下一位,变为0101,得到商为1,余数为010,因为到了最低位,因此计算完毕,最终结果商为011(十进制3),余数为010(十进制2)。

因此,我们可以通过将上述的算法过程用verilog实现,得到一个除法器。

核心要素如下:

  • 移位

    移位表示要从最高位开始和除数进行比较,每比较一次,就需要将下一bit扩展进来

  • 比较器

    判断扩展后的数是否大于除数,如果是则商置1

  • 加法器/减法器

    用于计算余数以及商

给出如下算法步骤:

①判断最高位temp是否大于除数,是则商加1,余数=temp-除数;否则temp={temp,被除数左移一位后的最高bit};

②循环判断n次。

Verilog如下:

module division(
    input clk,
    input rst,
    input [3:0]a,
    input [3:0]b,
    input valid,
    output reg [3:0]quotient,
    output reg [3:0]remainder,
    output reg  result_valid
    );


reg start;
reg start_dl;
reg start_dl2;
reg [1:0]cnt;
reg [3:0]temp;
reg [3:0]quotient_tmp;
always@(posedge clk or posedge rst)
begin
    if(rst)
        start<=0;
    else if(cnt==3'd3)
        start<=0;
    else if(valid)
        start<=1'b1;
    else
        start<=start;
end

always @(posedge clk or posedge rst)
begin
    if(rst)
    begin
        start_dl   <= 0 ;   
        start_dl2   <= 0 ;   
    end
  else
      begin
          start_dl   <= start ;  
           start_dl2   <= start_dl ; 
      end
end

reg [3:0]a_reg;
reg [3:0]b_reg;
always@(posedge clk or posedge rst)
begin
    if(rst)
    begin
        a_reg<=0;
        b_reg<=0;
    end
    else if(start)
        a_reg<=a_reg<<1;
    else if(valid)
      begin
        a_reg<=a;
        b_reg<=b;
    end
    else
      begin
        a_reg<=0;
        b_reg<=0;
    end
end

always@(posedge clk or posedge rst)
begin
    if(rst)
        cnt<=0;
    else if(start)
        cnt<=cnt+1'b1;
    else
        cnt<=0;
end

always@(posedge clk or posedge rst)
begin
    if(rst)
    begin
        temp<=0;
        quotient_tmp<=0;
    end
    else if((start|start_dl)&&temp>=b_reg)
    begin
        temp<={temp-b_reg,a_reg[3]};
        quotient_tmp<=(quotient_tmp<<1)+1'b1;
    end
    else if((start|start_dl))
    begin
        temp<={temp,a_reg[3]};
        quotient_tmp<=quotient_tmp<<1;
    end
    else
    begin
        temp<=0;
        quotient_tmp<=0;
    end
end

always@(posedge clk or posedge rst)
begin
    if(rst)
        begin
            quotient<=0;
            remainder<=0;
            result_valid<=0;
        end 
    else if(start_dl2&&(!start_dl))
    begin
        quotient<=quotient_tmp;
        remainder<=temp>>1;
        result_valid<=1;
    end
    else
     begin
            quotient<=0;
            remainder<=0;
            result_valid<=0;
        end 
end
endmodule

tb如下:

module tb();
reg clk=1;
reg rst=1;
reg [3:0]a;
reg [3:0]b;
reg valid;

always #5 clk=~clk;
initial begin
    #100 rst=0;
    #100
    a=4'b1011;
    b=4'b0011;
    valid=1'b1;
    #10
    valid=0;
end
    division inst_division
        (
            .clk          (clk),
            .rst          (rst),
            .a            (a),
            .b            (b),
            .valid        (valid),
            .quotient     (quotient),
            .remainder    (remainder),
            .result_valid (result_valid)
        );
endmodule

仿真结果如下:

在这里插入图片描述

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值