基于FPGA的4位二进制数除法器设计

1. 设计要求:

  设计一个4位二进制数除法器,如下图所示。其中,a[3:0]为被除数,b[3:0]为除数,s[3:0]为商,r[3:0]为余数。

2. 设计原理:

  和十进制除法类似,以计算 27 除以 5 的过程为例:除法运算过程如下:

(1) 取被除数的高几位数据,位宽和除数相同(实例中是 3bit 数据)。

(2) 将被除数高位数据与除数作比较,如果前者不小于后者,则可得到对应位的商为 1,两者做差得到第一步的余数;否则得到对应的商为 0,将前者直接作为余数。

(3) 将上一步中的余数与被除数剩余最高位 1bit 数据拼接成新的数据,然后再和除数做比较。可以得到新的商和余数。

(4) 重复过程 (3),直到被除数最低位数据也参与计算。

需要说明的是,商的位宽应该与被除数保持一致,因为除数有可能为1。所以上述手动计算除法的实例中,第一步做比较时,应该取数字 27 最高位 1 (3’b001) 与 3’b101 做比较。 根据此计算过程,设计位宽可配置的流水线式除法器,流水延迟周期个数与被除数位宽一致。

3. 设计实现

module divider_4bit(
    
    input    wire        [3:0]            a,
    input    wire         [3:0]            b
    
    output    wire         [3:0]            s,
    output    wire        [3:0]            y
);


    wire                    [3:0]            part_0;
    wire                    [3:0]            part_1;
    wire                    [3:0]            part_2;
    wire                    [3:0]            part_3;
    
    assign s[3] = a[3] >= b;                                        //最高位的商s[3]
    assign part_3 = (s[3] == 1'b1 )? a[3] - b : a[3];        
    
    assign s[2] = {part_3, a[2]} >= b;
    assign part_2 = (s[2] == 1'b1) ? {part_3, a[2]} - b : {part_3, a[2]};
    
    assign s[1] = {part_2, a[1]} >= b;
    assign part_1 = (s[1] == 1'b1) ? {part_2, a[1]} - b : {part_2, a[1]};
    
    assign s[0] = {part_1, a[0]} >= b;
    assign part_0 = (s[0] == 1'b1) ? {part_1, a[0]} - b : {part_1, a[0]};
    
    assign y = part_0;

endmodule 

4. 仿真验证

`timescale 1ns/1ps
module divider_4bit_tb();
      
    reg        [3:0]            a;
    reg        [3:0]            b; 
    wire        [3:0]            s;
    wire        [3:0]            y;
    
    wire        [3:0]            tb_s;
    wire        [3:0]            tb_y;
    
    assign tb_s = a / b;
    assign tb_y = a % b;

    divider_4bit divider_4bit_inst (    
        .a                (a),
        .b                (b),        
        .s                (s),
        .y                (y)
    );

   initial begin
        repeat(20)begin
            a = {$random} % 16;
            b = {$random} % 16;
            # 20;
        end    
    end

endmodule 

 

注:0/0=无穷大,任何数除以零(无穷小)得无穷大,而在Veriog中,默认0/0=错误结果,s[3:0]最大值为15。

posted @ 2021-07-19 21:31  豌豆茶  阅读(1072)  评论(0编辑  收藏  举报