Verilog 除法器设计

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

除法运算过程如下:

(1) 取被除数的高几位数据,位宽和除数相同(实例中是 3bit 数据)。
(2) 将除数高位数据与除数作比较,如果前者不小于后者,则可得到对应位的商为 1,两者做差得到第一步的余数;否则得到对应为的商为0,将前者直接作为余数。
(3) 将上一步中的余数与被除数剩余最高位 1bit 数据拼接成新的数据,然后再和除数做比较。可以得到新的商和余数。
(4) 重复过程 (3),直到被除数最低位数据也参与计算。
需要说明的是,商的位宽应该与被除数保持一致,因为除数有可能为1。所以上述手动计算除法的实例中,第一步做比较时,应该取数字 27 最高位 1 (3’b001) 与 3’b101 做比较。 根据此计算过程,设计位宽可配置的流水线式除法器,流水延迟周期个数与被除数位宽一致。

除法器设计
单步运算设计

单步除法计算时,单步被除数位宽(信号 dividend)需比原始除数(信号 divisor)位宽多1bit 才不至于溢出。

为了便于流水,输出端需要有寄存器来存储原始的除数(信号 divisor 和 divisor_kp)和被除数信息(信号 dividend_ci 和 dividend_kp)。

单步的运算结果就是得到新的 1bit 商数据(信号 merchant)和余数(信号 remainder)。

为了得到最后的除法结果,新的 1bit 商数据(信号 merchant)还需要与上一周期的商结果(merchant_ci)进行移位累加。

单步运算单元设计如下(文件名 divider_cell.v):

实例
// parameter M means the actual width of divisor
module divider_cell
#(parameter N=5,
parameter M=3)
(
input clk,
input rstn,
input en,

  input [M:0]               dividend,
  input [M-1:0]             divisor,
  input [N-M:0]             merchant_ci , //上一级输出的商
  input [N-M-1:0]           dividend_ci , //原始除数

  output reg [N-M-1:0]      dividend_kp,  //原始被除数信息
  output reg [M-1:0]        divisor_kp,   //原始除数信息
  output reg                rdy ,
  output reg [N-M:0]        merchant ,  //运算单元输出商
  output reg [M-1:0]        remainder   //运算单元输出余数
);

always @(posedge clk or negedge rstn) begin
    if (!rstn) begin
        rdy            <= 'b0 ;
        merchant       <= 'b0 ;
        remainder      <= 'b0 ;
        divisor_kp     <= 'b0 ;
        dividend_kp    <= 'b0 ;
    end
    else if (en) begin
        rdy            <= 1'b1 ;
        divisor_kp     <= divisor ;  //原始除数保持不变
        dividend_kp    <= dividend_ci ;  //原始被除数传递
        if (dividend >= {1'b0, divisor}) begin
            merchant    <= (merchant_ci<<1) + 1'b1 ; //商为1
            remainder   <= dividend - {1'b0, divisor} ; //求余
        end
        else begin
            merchant    <= merchant_ci<<1 ;  //商为0
            remainder   <= dividend ;        //余数不变
        end
    end // if (en)
    else begin
        rdy            <= 'b0 ;
        merchant       <= 'b0 ;
        remainder      <= 'b0 ;
        divisor_kp     <= 'b0 ;
        dividend_kp    <= 'b0 ;
    end
end

endmodule
流水级例化

单步计算的余数(信号 remainder)和原始被除数(信号dividend)对应位的 1bit 数据重新拼接作为新的单步被除数输入到下一级单步除法计算单元。

其中,被除数、除数、及商的数据信息也要往下一级运算单元中传递。

流水级模块例化完成除法的设计如下(文件名 divider_man.v):

实例
//parameter N means the actual width of dividend
//using 29/5=5…4
module divider_man
#(parameter N=5,
parameter M=3,
parameter N_ACT = M+N-1)
(
input clk,
input rstn,

  input                     data_rdy ,  //数据使能
  input [N-1:0]             dividend,   //被除数
  input [M-1:0]             divisor,    //除数

  output                    res_rdy ,
  output [N_ACT-M:0]        merchant ,  //商位宽:N
  output [M-1:0]            remainder ); //最终余数

wire [N_ACT-M-1:0]   dividend_t [N_ACT-M:0] ;
wire [M-1:0]         divisor_t [N_ACT-M:0] ;
wire [M-1:0]         remainder_t [N_ACT-M:0];
wire [N_ACT-M:0]     rdy_t ;
wire [N_ACT-M:0]     merchant_t [N_ACT-M:0] ;

//初始化首个运算单元
divider_cell      #(.N(N_ACT), .M(M))
   u_divider_step0
( .clk              (clk),
  .rstn             (rstn),
  .en               (data_rdy),
  //用被除数最高位 1bit 数据做第一次单步运算的被除数,高位补0
  .dividend         ({
  {(M){1'b0}}, dividend[N-1]}),
  .divisor          (divisor),                  
  .merchant_ci      ({(N_ACT-M+1){1'b0}}),   //商初始为0
  .dividend_ci      (dividend[N_ACT-M-1:0]), //原始被除数
  //output
  .dividend_kp      (dividend_t[N_ACT-M]),   //原始被除数信息传递
  .divisor_kp       (divisor_t[N_ACT-M]),    //原始除数信息传递
  .rdy              (rdy_t[N_ACT-M]),
  .merchant         (merchant_t[N_ACT-M]),   //第一次商结果
  .remainder        (remainder_t[N_ACT-M])   //第一次余数
  );

genvar               i ;
generate
    for(i=1; i<=N_ACT-M; i=i+1) begin: sqrt_stepx
        divider_cell      #(.N(N_ACT), .M(M))
          u_divider_step
          (.clk              (clk),
           .rstn             (rstn),
           .en               (rdy_t[N_ACT-M-i+1]),
           .dividend         ({remainder_t[N_ACT-M-i+1], dividend_t[N_ACT-M-i+1][N_ACT-M-i]}),   //余数与原始被除数单bit数据拼接
           .divisor          (divisor_t[N_ACT-M-i+1]),
           .merchant_ci      (merchant_t[N_ACT-M-i+1]),
           .dividend_ci      (dividend_t[N_ACT-M-i+1]),
           //output
           .divisor_kp       (divisor_t[N_ACT-M-i]),
           .dividend_kp      (dividend_t[N_ACT-M-i]),
           .rdy              (rdy_t[N_ACT-M-i]),
           .merchant         (merchant_t[N_ACT-M-i]),
           .remainder        (remainder_t[N_ACT-M-i])
          );
    end // block: sqrt_stepx
endgenerate

assign res_rdy       = rdy_t[0];
assign merchant      = merchant_t[0];  //最后一次商结果作为最终的商
assign remainder     = remainder_t[0]; //最后一次余数作为最终的余数

endmodule
取被除数位宽为 5,除数位宽为 3,testbench 中加入自校验,描述如下:

实例
`timescale 1ns/1ns

module test ;
parameter N = 5 ;
parameter M = 3 ;
reg clk;
reg rstn ;
reg data_rdy ;
reg [N-1:0] dividend ;
reg [M-1:0] divisor ;

wire         res_rdy ;
wire [N-1:0] merchant ;
wire [M-1:0] remainder ;

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

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

    #55 ;
    @(negedge clk ) ;
    data_rdy  = 1'b1 ;
            dividend  = 25;      divisor      = 5;
    #10 ;   dividend  = 16;      divisor      = 3;
    #10 ;   dividend  = 10;      divisor      = 4;
    #10 ;   dividend  = 15;      divisor      = 1;
    repeat(32)    #10   dividend   = dividend + 1 ;
    divisor      = 7;
    repeat(32)    #10   dividend   = dividend + 1 ;
    divisor      = 5;
    repeat(32)    #10   dividend   = dividend + 1 ;
    divisor      = 4;
    repeat(32)    #10   dividend   = dividend + 1 ;
    divisor      = 6;
    repeat(32)    #10   dividend   = dividend + 1 ;
end

//对输入延迟,便于数据结果同周期对比,完成自校验
reg  [N-1:0]   dividend_ref [N-1:0];
reg  [M-1:0]   divisor_ref [N-1:0];
always @(posedge clk) begin
    dividend_ref[0] <= dividend ;
    divisor_ref[0]  <= divisor ;
end

genvar         i ;
generate
    for(i=1; i<=N-1; i=i+1) begin
        always @(posedge clk) begin
            dividend_ref[i] <= dividend_ref[i-1];
            divisor_ref[i]  <= divisor_ref[i-1];
        end
    end
endgenerate

//自校验
reg  error_flag ;
always @(posedge clk) begin
# 1 ;
    if (merchant * divisor_ref[N-1] + remainder != dividend_ref[N-1] && res_rdy) beginb      //testbench 中可直接用乘号而不考虑运算周期
        error_flag <= 1'b1 ;
    end
    else begin
        error_flag <= 1'b0 ;
    end
end

//module instantiation
divider_man  #(.N(N), .M(M))
u_divider
 (
  .clk              (clk),
  .rstn             (rstn),
  .data_rdy         (data_rdy),
  .dividend         (dividend),
  .divisor          (divisor),
  .res_rdy          (res_rdy),
  .merchant         (merchant),
  .remainder        (remainder));

//simulation finish
initial begin
forever begin
#100;
if ($time >= 10000) $finish ;
end
end

endmodule // test
https://www.zhihu.com/column/c_1295434569844772864
https://www.zhihu.com/column/c_1295434569844772864/
http://www.zhihu.com/column/c_1295434569844772864
http://www.zhihu.com/column/c_1295434569844772864/
https://www.zhihu.com/column/c_1295434531432595456
https://www.zhihu.com/column/c_1295434531432595456/
http://www.zhihu.com/column/c_1295434531432595456
http://www.zhihu.com/column/c_1295434531432595456/
https://www.zhihu.com/column/c_1295434516891287552
https://www.zhihu.com/column/c_1295434516891287552/
http://www.zhihu.com/column/c_1295434516891287552
http://www.zhihu.com/column/c_1295434516891287552/
https://www.zhihu.com/column/c_1295434505046437888
https://www.zhihu.com/column/c_1295434505046437888/
http://www.zhihu.com/column/c_1295434505046437888
http://www.zhihu.com/column/c_1295434505046437888/
https://www.zhihu.com/column/c_1295434492791296000
https://www.zhihu.com/column/c_1295434492791296000/
http://www.zhihu.com/column/c_1295434492791296000
http://www.zhihu.com/column/c_1295434492791296000/
https://www.zhihu.com/column/c_1295434356203937792
https://www.zhihu.com/column/c_1295434356203937792/
http://www.zhihu.com/column/c_1295434356203937792
http://www.zhihu.com/column/c_1295434356203937792/
https://www.zhihu.com/column/c_1295434342605938688
https://www.zhihu.com/column/c_1295434342605938688/
http://www.zhihu.com/column/c_1295434342605938688
http://www.zhihu.com/column/c_1295434342605938688/
https://www.zhihu.com/column/c_1295434330664722432
https://www.zhihu.com/column/c_1295434330664722432/
http://www.zhihu.com/column/c_1295434330664722432
http://www.zhihu.com/column/c_1295434330664722432/
https://www.zhihu.com/column/c_1295434319432187904
https://www.zhihu.com/column/c_1295434319432187904/
http://www.zhihu.com/column/c_1295434319432187904
http://www.zhihu.com/column/c_1295434319432187904/
https://www.zhihu.com/column/c_1295434306761379840
https://www.zhihu.com/column/c_1295434306761379840/
http://www.zhihu.com/column/c_1295434306761379840
http://www.zhihu.com/column/c_1295434306761379840/
https://www.zhihu.com/column/c_1295434294743941120
https://www.zhihu.com/column/c_1295434294743941120/
http://www.zhihu.com/column/c_1295434294743941120
http://www.zhihu.com/column/c_1295434294743941120/
https://www.zhihu.com/column/c_1295434280613527552
https://www.zhihu.com/column/c_1295434280613527552/
http://www.zhihu.com/column/c_1295434280613527552
http://www.zhihu.com/column/c_1295434280613527552/
https://www.zhihu.com/column/c_1295434267027890176
https://www.zhihu.com/column/c_1295434267027890176/
http://www.zhihu.com/column/c_1295434267027890176
http://www.zhihu.com/column/c_1295434267027890176/
https://www.zhihu.com/column/c_1295434203345788928
https://www.zhihu.com/column/c_1295434203345788928/
http://www.zhihu.com/column/c_1295434203345788928
http://www.zhihu.com/column/c_1295434203345788928/
https://www.zhihu.com/column/c_1295434049247408128
https://www.zhihu.com/column/c_1295434049247408128/
http://www.zhihu.com/column/c_1295434049247408128
http://www.zhihu.com/column/c_1295434049247408128/
https://www.zhihu.com/column/c_1295434036928839680
https://www.zhihu.com/column/c_1295434036928839680/
http://www.zhihu.com/column/c_1295434036928839680
http://www.zhihu.com/column/c_1295434036928839680/
https://www.zhihu.com/column/c_1295434024836378624
https://www.zhihu.com/column/c_1295434024836378624/
http://www.zhihu.com/column/c_1295434024836378624
http://www.zhihu.com/column/c_1295434024836378624/
https://www.zhihu.com/column/c_1295434014087139328
https://www.zhihu.com/column/c_1295434014087139328/
http://www.zhihu.com/column/c_1295434014087139328
http://www.zhihu.com/column/c_1295434014087139328/
https://www.zhihu.com/column/c_1295434001634050048
https://www.zhihu.com/column/c_1295434001634050048/
http://www.zhihu.com/column/c_1295434001634050048
http://www.zhihu.com/column/c_1295434001634050048/
https://www.zhihu.com/column/c_1295433988816424960
https://www.zhihu.com/column/c_1295433988816424960/
http://www.zhihu.com/column/c_1295433988816424960
http://www.zhihu.com/column/c_1295433988816424960/
https://www.zhihu.com/column/c_1295433951470108672
https://www.zhihu.com/column/c_1295433951470108672/
http://www.zhihu.com/column/c_1295433951470108672
http://www.zhihu.com/column/c_1295433951470108672/
https://www.zhihu.com/column/c_1295433936483807232
https://www.zhihu.com/column/c_1295433936483807232/
http://www.zhihu.com/column/c_1295433936483807232
http://www.zhihu.com/column/c_1295433936483807232/
https://www.zhihu.com/column/c_1295433923615203328
https://www.zhihu.com/column/c_1295433923615203328/
http://www.zhihu.com/column/c_1295433923615203328
http://www.zhihu.com/column/c_1295433923615203328/
https://www.zhihu.com/column/c_1295433908523925504
https://www.zhihu.com/column/c_1295433908523925504/
http://www.zhihu.com/column/c_1295433908523925504
http://www.zhihu.com/column/c_1295433908523925504/
https://www.zhihu.com/column/c_1295433711409418240
https://www.zhihu.com/column/c_1295433711409418240/
http://www.zhihu.com/column/c_1295433711409418240
http://www.zhihu.com/column/c_1295433711409418240/
https://www.zhihu.com/column/c_1295433700327251968
https://www.zhihu.com/column/c_1295433700327251968/
http://www.zhihu.com/column/c_1295433700327251968
http://www.zhihu.com/column/c_1295433700327251968/
https://www.zhihu.com/column/c_1295433688864907264
https://www.zhihu.com/column/c_1295433688864907264/
http://www.zhihu.com/column/c_1295433688864907264
http://www.zhihu.com/column/c_1295433688864907264/
https://www.zhihu.com/column/c_1295433675849826304
https://www.zhihu.com/column/c_1295433675849826304/
http://www.zhihu.com/column/c_1295433675849826304
http://www.zhihu.com/column/c_1295433675849826304/
https://www.zhihu.com/column/c_1295433662646308864
https://www.zhihu.com/column/c_1295433662646308864/
http://www.zhihu.com/column/c_1295433662646308864
http://www.zhihu.com/column/c_1295433662646308864/
https://www.zhihu.com/column/c_1295433649278918656
https://www.zhihu.com/column/c_1295433649278918656/
http://www.zhihu.com/column/c_1295433649278918656
http://www.zhihu.com/column/c_1295433649278918656/
https://www.zhihu.com/column/c_1295433635240316928
https://www.zhihu.com/column/c_1295433635240316928/
http://www.zhihu.com/column/c_1295433635240316928
http://www.zhihu.com/column/c_1295433635240316928/
https://www.zhihu.com/column/c_1295433549252395008
https://www.zhihu.com/column/c_1295433549252395008/
http://www.zhihu.com/column/c_1295433549252395008
http://www.zhihu.com/column/c_1295433549252395008/
https://www.zhihu.com/column/c_1295433453144956928
https://www.zhihu.com/column/c_1295433453144956928/
http://www.zhihu.com/column/c_1295433453144956928
http://www.zhihu.com/column/c_1295433453144956928/
https://www.zhihu.com/column/c_1295433387772698624
https://www.zhihu.com/column/c_1295433387772698624/
http://www.zhihu.com/column/c_1295433387772698624
http://www.zhihu.com/column/c_1295433387772698624/
https://www.zhihu.com/column/c_1295433375042224128
https://www.zhihu.com/column/c_1295433375042224128/
http://www.zhihu.com/column/c_1295433375042224128
http://www.zhihu.com/column/c_1295433375042224128/
https://www.zhihu.com/column/c_129543336402821939

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值