kommu4946
Member level 4
Hi,
I have found restoring division algorithm in below pdf.**broken link removed**
i used 4 bits for dividend ,divisor,quotient, what i observed is for 15/10,the algorithm is giving quotient as 14 and reminder as 3 but actually it should be 1 and 5 respectively.Is there any bit length problem in algorithm or any limitation of restoring algorithm is there? I have written verilog code for it and randomly given inputs and it is working for 15/1...to..15/9 and from 15/10 on wards results are not matching with paper pen type division .Please find the code and tb
and tb is
I have found restoring division algorithm in below pdf.**broken link removed**
i used 4 bits for dividend ,divisor,quotient, what i observed is for 15/10,the algorithm is giving quotient as 14 and reminder as 3 but actually it should be 1 and 5 respectively.Is there any bit length problem in algorithm or any limitation of restoring algorithm is there? I have written verilog code for it and randomly given inputs and it is working for 15/1...to..15/9 and from 15/10 on wards results are not matching with paper pen type division .Please find the code and tb
Code:
module restore_divider#(parameter BIT_WIDTH = 16)
(
input wire clk,
input wire n_rst,
input wire [BIT_WIDTH -1 :0] dividend,
input wire [BIT_WIDTH -1 :0] divisor,
input wire data_vld,
output reg [BIT_WIDTH -1 :0] reminder,
output reg [BIT_WIDTH -1 :0] quotient,
output reg div_out_vld
);
parameter INIT = 4'b0001,
SHIFT = 4'b0010,
RESTORE = 4'b0100,
DIV_END = 4'b1000;
reg [BIT_WIDTH-1 :0] count;
//wire signed [BIT_WIDTH-1 :0] temp;
wire [BIT_WIDTH-1 :0] temp;
reg [BIT_WIDTH-1 :0] accum;
reg [BIT_WIDTH-1 :0] mq;
reg [3:0] state;
assign temp = accum - divisor;
always @(posedge clk)
begin
if(!n_rst)
begin
count <= 0;
accum <= 0;
mq <= 0;
state <= INIT;
reminder <= 0;
quotient <= 0;
div_out_vld <= 0;
end
else
begin
case(state)
INIT: begin
count <= 0;
accum <= 0;
quotient <= 0;
reminder <= 0;
div_out_vld <= 0;
if(data_vld)
begin
mq <= dividend;
state <= SHIFT;
end
else
begin
mq <= mq;
state <= INIT;
end
end
SHIFT :begin
mq <= mq << 1'b1;
accum <= {accum ,mq[BIT_WIDTH-1]};
state <= RESTORE;
end
RESTORE: begin
if(temp[BIT_WIDTH-1] == 1'b0)
begin
accum <= temp;
mq <= {mq[BIT_WIDTH-1:1],1'b1};
end
else
begin
accum <= temp + divisor;
mq <= {mq[BIT_WIDTH-1:1],1'b0};;
end
count <= count + 1'b1;
if(count == BIT_WIDTH-1)
state <= DIV_END;
else
state <= SHIFT;
end
DIV_END : begin
quotient <= mq;
reminder <= accum;
div_out_vld <= 1'b1;
state <= INIT;
end
endcase
end
end
endmodule
Code:
module tb_sim();
parameter BIT_WIDTH = 4;
reg clk;
reg n_rst;
reg [BIT_WIDTH -1 :0] dividend;
reg [BIT_WIDTH -1 :0] divisor;
reg data_vld;
wire [BIT_WIDTH -1 :0] reminder;
wire [BIT_WIDTH -1 :0] quotient;
wire div_out_vld;
initial
begin
clk = 0;
n_rst = 0;
dividend = 0;
divisor = 0;
data_vld = 0;
repeat(5) @(posedge clk);
n_rst = 1;
dividend = 15;
divisor = 10;
data_vld = 1'b1;
@(posedge clk);
data_vld = 1'b0;
repeat(20) @(posedge clk);
n_rst = 1;
dividend = 15;
divisor = 9;
data_vld = 1'b1;
@(posedge clk);
data_vld = 1'b0;
repeat(20) @(posedge clk);
n_rst = 1;
dividend = 15;
divisor = 8;
data_vld = 1'b1;
@(posedge clk);
data_vld = 1'b0;
end
always #10 clk = ~clk;
restore_divider#(.BIT_WIDTH(BIT_WIDTH))
DUT
(
.clk (clk ),
.n_rst (n_rst ),
.dividend (dividend ),
.divisor (divisor ),
.data_vld (data_vld ),
.reminder (reminder ),
.quotient (quotient ),
.div_out_vld (div_out_vld )
);
endmodule