不恢復餘數除法器

2021-09-21 06:06:18 字數 3978 閱讀 6327

不恢復餘數除法器的基本演算法來自於恢復餘數除法器,區別在於當餘數變負時不停下恢復餘數而是繼續執行迭代,並在迭代中加上移位後除數而不是減去移位後除數,基本演算法如下所示

將除數向左移位到恰好大於被除數

若餘數為正:餘數減去移位後除數;若餘數為負:餘數加上移位後除數;

若現餘數為正,該位結果為1,否則為0,將除數向右移位一位

重複2,3,知道移位後除數小於原除數

module norestore_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

);// parameter judge = 2 ** (2 * width);

reg [2 * width:0]remainder_r;

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

reg [width - 1:0]divisor_lock;

reg [2 * width:0]judge;

always @ (*) begin

if(remainder_r[2 * width] == 1'b0) begin

judge = remainder_r - divisor_move;

end else begin

judge = remainder_r + divisor_move;

endendalways @ (posedge clk or negedge rst_n) begin

if(~rst_n) begin

<= 'b0;

end else begin

if(din_valid == 1'b1) begin //lock input data

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 <= judge;

if(judge[2 * width] == 'b0) begin

dout <= ;

end else begin

dout <= ;

endend else begin

remainder_r <= judge;

if(judge[2 * width] == 'b0) begin

dout <= ;

end else begin

dout <= ;

endend

divisor_move <= divisor_move >> 1;

divisor_lock <= divisor_lock;

end else if(remainder_r[2 * width - 1] == 1'b1) begin

//調整餘數

remainder_r <= remainder_r + divisor_lock;

dout <= dout;

divisor_lock <= divisor_lock;

divisor_move <= divisor_move;

end 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

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;

norestore_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位,空位補1 若餘數大於0,除數向右移位1位。如餘數小於0,餘數加當前除數,商最後一位置0,除數向右移位1位 重複到2,只到除數比最初的除數小 rtl 就...

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

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