恢復餘數除法器

2021-09-21 06:04:05 字數 3697 閱讀 5788

恢復餘數除法器是一種常用的除法器,過程與手算除法的方法很類似,過程為

將除數向左位移直到比被除數大

執行被除數減除數操作,得餘數,並將商向左移位1位,空位補1

若餘數大於0,除數向右移位1位。如餘數小於0,餘數加當前除數,商最後一位置0,除數向右移位1位

重複到2,只到除數比最初的除數小

rtl**就是使用了大量的if語句完成了以上的演算法描述,其中

module restore_divider #(

parameter width = 4

)( input clk, // clock

input rst_n, // asynchronous reset active low

input [width * 2 - 1:0]dividend,

input [width - 1:0]divisor,

input din_valid,

output reg [2 * width - 1:0]dout,

output [width - 1:0]remainder

);reg [2 * width:0]remainder_r;

reg [3 * width - 1:0]divisor_move;

reg [width - 1:0]divisor_lock;

always @ (posedge clk or negedge rst_n) begin

if(~rst_n) begin

//初始化

<= 'b0;

end else begin

if(din_valid == 1'b1) begin

//鎖存輸入,3倍width的寬度用於保證移位後的除數大於被除數

remainder_r[width * 2 - 1:0] <= dividend;

remainder_r[2 * width] <= 'b0;

divisor_move[3 * width - 1:2 * width] <= divisor;

divisor_move[2 * width - 1:0] <= 'b0;

divisor_lock <= divisor;

dout <= 'b0;

end else if((divisor_move > ') && (dout == 'b0)) begin

//開始條件

remainder_r <= remainder_r;

dout <= 'b0;

divisor_move <= divisor_move >> 1;

divisor_lock <= divisor_lock;

end else if(divisor_move >= ') begin

if(remainder_r[2 * width] == 1'b0) begin //執行減法

remainder_r <= remainder_r - divisor_move;

dout <= ;

// divisor_move <= divisor_move >> 1;

divisor_lock <= divisor_lock;

if(remainder_r >= divisor_move) begin

divisor_move <= divisor_move >> 1;

end else begin

divisor_move <= divisor_move;

endend else begin //恢復餘數

remainder_r <= remainder_r + divisor_move;

dout <= ;

divisor_move <= divisor_move >> 1;

divisor_lock <= divisor_lock;

endend else begin

remainder_r <= remainder_r;

divisor_lock <= divisor_lock;

divisor_move <= divisor_move;

dout <= dout;

endend

endassign remainder = remainder_r[width - 1:0];

endmodule

測試平台復用了shiftsub除法器的平台,增加了「遇錯停止」的功能

module tb_divider (

);parameter width = 4;

logic clk; // clock

logic rst_n; // asynchronous reset active low

logic [2 * width - 1:0]dividend;

logic [width - 1:0]divisor;

logic din_valid;

logic [2 * width - 1:0]dout;

logic [width - 1:0]remainder;

restore_divider #(

.width(width)

) dut (

.clk(clk), // clock

.rst_n(rst_n), // asynchronous reset active low

.dividend(dividend),

.divisor(divisor),

.din_valid(din_valid),

.dout(dout),

.remainder(remainder)

);initial begin

clk = 'b0;

forever begin

#50 clk = ~clk;

endendinitial begin

rst_n = 1'b1;

# 5 rst_n = 'b0;

#10 rst_n = 1'b1;

endlogic [2 * width - 1:0]dout_exp;

logic [width - 1:0]remainder_exp;

initial begin

= 'b0;

forever begin

@(negedge clk);

dividend = (2 * width)'($urandom_range(0,2 ** (2 * width)));

divisor = (width)'($urandom_range(1,2 ** width - 1));

din_valid = 1'b1;

remainder_exp = dividend % divisor;

dout_exp = (dividend - remainder_exp) / divisor;

repeat(5 * width) begin

@(negedge clk);

din_valid = 'b0;

endif((remainder == remainder_exp) && (dout_exp == dout)) begin

$display("successfully");

end else begin

$display("failed");

$stop;

endend

endendmodule

不恢復餘數除法器

不恢復餘數除法器的基本演算法來自於恢復餘數除法器,區別在於當餘數變負時不停下恢復餘數而是繼續執行迭代,並在迭代中加上移位後除數而不是減去移位後除數,基本演算法如下所示 將除數向左移位到恰好大於被除數 若餘數為正 餘數減去移位後除數 若餘數為負 餘數加上移位後除數 若現餘數為正,該位結果為1,否則為0...

不恢復餘數除法器

不恢復餘數除法器的基本演算法來自於恢復餘數除法器,區別在於當餘數變負時不停下恢復餘數而是繼續執行迭代,並在迭代中加上移位後除數而不是減去移位後除數,基本演算法如下所示 將除數向左移位到恰好大於被除數 若餘數為正 餘數減去移位後除數 若餘數為負 餘數加上移位後除數 若現餘數為正,該位結果為1,否則為0...

HDL系列 除法器 2 不恢復餘數法

目錄 一 不恢復餘數法 non restoring division algorithm 二 不恢復餘數法流程圖以及例子 上期我們介紹了二進位制除法器中的恢復餘數法,本期介紹不恢復餘數法。不恢復餘數法商數的選擇使用代替。雖然相比於不恢復餘數法演算法複雜一些,但是硬體實現上更有優勢,每產生乙個商的位元...