当前位置:   article > 正文

Verilog 定点除法器设计

verilog 定点除法

原理参考

  • top
module div_top #(  
        parameter M = 5,
        parameter N = 3
)
(         
        input                  clk,
        input                  rst,
        input                  en,
        input         [M-1:0]      divided,
        input         [N-1:0]      divisor,
        output        [M-1:0]    quotient,
        output        [N-1:0]      remainder
);
//save quotient and remainder lever by lever
wire [M-1:0] quotient_co [M-1:0];
wire [N-1:0] remainder_co [M-1:0];
//tansfer divided and divisor
wire [M-1:0] divided_kp [M-1:0];
wire [N-1:0] divisor_kp [M-1:0];
//the first level 
div_initial #(   .M(5),
                 .N(3)
            )
        u1  (
              .clk(clk),
              .rst(rst),
              .en(en),
              .divided_fir({{(N-1){1'b0}},divided[M-1]}),
              .divided(divided),
              .divisor(divisor),
              .divided_kp(divided_kp[0]),
              .divisor_kp(divisor_kp[0]),
              .quotient_co(quotient_co[0]),
              .remainder_co(remainder_co[0])
            );
//use loop to generate next level
genvar i;
generate
for (i=1; i <= M-1; i=i+1) begin:div_bit
        div_cell #(   .M(5),
                      .N(3)
            )
        u2  (
              .clk(clk),
              .rst(rst),
              .en(en),
              .divided_bit(divided_kp[i-1][M-i-1]),
              .divided(divided_kp[i-1]),
              .divisor(divisor_kp[i-1]),
              .divided_kp(divided_kp[i]),
              .divisor_kp(divisor_kp[i]),
              .quotient_ci(quotient_co[i-1]),
              .remainder_ci(remainder_co[i-1]),
              .quotient_co(quotient_co[i]),
              .remainder_co(remainder_co[i])
            );
   end
 endgenerate
 assign quotient = quotient_co[M-1];
 assign remainder = remainder_co[M-1];
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

.divided_bit(divided_kp[i-1][M-i-1])//可实现二维下标访问

  • div_initial
module div_initial #(
        parameter M = 5,
        parameter N = 3
)
(         
        input                  clk,
        input                  rst,
        input                  en,
        input     [M-1:0]      divided,
        input     [N-1:0]      divisor,
        input     [N-1:0]      divided_fir,
        output reg   [M-1:0]      divided_kp,
        output reg   [N-1:0]      divisor_kp,
        output reg   [M-1:0]      quotient_co,
        output reg   [N-1:0]      remainder_co
);

always@(posedge clk or negedge rst) begin
  if (!rst) begin
    quotient_co <= 'b0;
    remainder_co <= 'b0;
  end
  else if (en) begin
//tansfer divided and divisor
    divided_kp <= divided;
    divisor_kp <= divisor;
    if (divided_fir>= divisor) begin  
      quotient_co <= 'b1;
      remainder_co <= divided_fir - divisor;
    end
    else begin 
    quotient_co <= 'b0;
    remainder_co <= divided_fir;
    end
  end
  else begin
    quotient_co <= 'b0;
    remainder_co <= 'b0;
  end
end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • div_cell
module div_cell #(
        parameter M = 5,
        parameter N = 3
)
(         
        input                  clk,
        input                  rst,
        input                  en,
        input                  divided_bit,
        input     [M-1:0]      divided,
        input     [N-1:0]      divisor,
        input     [M-1:0]    quotient_ci,
        input     [N-1:0]      remainder_ci,
        output reg   [M-1:0]      divided_kp,
        output reg   [N-1:0]      divisor_kp,
        output reg   [M-1:0]      quotient_co,
        output reg   [N-1:0]      remainder_co
);

always@(posedge clk or negedge rst) begin
  if (!rst) begin
    quotient_co <= 'b0;
    remainder_co <= 'b0;
  end
  else if (en) begin
//tansfer divided and divisor
    divided_kp <= divided;
    divisor_kp <= divisor;
    if ({remainder_ci,divided_bit} >= divisor) begin
      quotient_co <= (quotient_ci<<1) + 1'b1;               //quotient plu 1
      remainder_co <= {remainder_ci,divided_bit} - divisor; //calculate remainder
    end
    else begin 
    quotient_co <= quotient_ci<<1;
    remainder_co <= {remainder_ci,divided_bit};
    end
  end
  else begin
    quotient_co <= 'b0;
    remainder_co <= 'b0;
  end
end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

quotient_co <= (quotient_ci<<1) + 1’b1; //注意优先级()标注

  • test
module test ;
    parameter    M = 5 ;
    parameter    N = 3 ;
    reg          clk;
    reg          rst ;
    reg          en;
    reg [M-1:0]  divided ;
    reg [N-1:0]  divisor ;

    wire [M-1:0] quotient ;
    wire [N-1:0] remainder ;


div_top #(      .M(5),
                .N(3)
            )
        u1  (
              .clk(clk),
              .rst(rst),
              .en(en),
              .divided(divided),
              .divisor(divisor),
              .quotient(quotient),
              .remainder(remainder)
            );


    //clock
    always begin
        clk = 0 ; #5 ;
        clk = 1 ; #5 ;
    end

    //driver
    initial begin
        rst      = 1'b0 ;
        #8 ;
        rst      = 1'b1 ;

        #55 ;
        @(negedge clk ) ;
        en = 1'b1 ;
                divided  = 27;      divisor      = 5;
        #10 ;   divided  = 20;      divisor      = 3;
        #10 ;   divided  = 30;      divisor      = 4;
        #10 ;   divided  = 19;      divisor      = 4;
        #10 ;   divided  = 14;      divisor      = 1;
        repeat(32)    #10   divided   = divided + 1 ;
        divisor      = 7;
        repeat(32)    #10   divided   = divided + 1 ;
        divisor      = 5;
        repeat(32)    #10   divided   = divided + 1 ;
        divisor      = 4;
        repeat(32)    #10   divided   = divided + 1 ;
        divisor      = 6;
        repeat(32)    #10   divided   = divided + 1 ;
    end

  initial begin
  $fsdbDumpfile("div_top.fsdb");
  $fsdbDumpvars;
  #40000 $finish;
 end
 endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 结果
  • 在这里插入图片描述
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/522354
推荐阅读
相关标签
  

闽ICP备14008679号