Goldschmidt division algorithm
Started by 7 years ago●1378 views/************************************************
The Verilog HDL code example is from the book
Computer Principles and Design in Verilog HDL
by Yamin Li, published by A JOHN WILEY & SONS
************************************************/
module goldschmidt (a,b,start,clk,clrn,q,busy,ready,count,yn);
input [31:0] a; // dividend: .1xxx...x
input [31:0] b; // divisor: .1xxx...x
input start; // start
input clk, clrn; // clock and reset
output [31:0] q; // quotient: x.xxx...x
output reg busy; // busy
output reg ready; // ready
output [2:0] count; // counter
output [31:0] yn; // .11111...1
reg [63:0] reg_a; // x.xxxx...x
reg [63:0] reg_b; // 0.xxxx...x
reg [2:0] count;
wire [63:0] two_minus_yi = ~reg_b + 1'b1; // 1.xxxx...x (2 - yi)
wire [127:0] xi = reg_a * two_minus_yi; // 0x.xxx...x
wire [127:0] yi = reg_b * two_minus_yi; // 0x.xxx...x
assign q = reg_a[63:32] + |reg_a[31:29]; // rounding up
assign yn = reg_b[62:31];
always @ (posedge clk or negedge clrn) begin
if (!clrn) begin
busy <= 0;
ready <= 0;
end else begin
if (start) begin
reg_a <= {1'b0,a,31'b0}; // 0.1x...x0...0
reg_b <= {1'b0,b,31'b0}; // 0.1x...x0...0
busy <= 1;
ready <= 0;
count <= 0;
end else begin
reg_a <= xi[126:63]; // x.xxx...x
reg_b <= yi[126:63]; // 0.xxx...x
count <= count + 3'b1; // count++
if (count == 3'h4) begin // finish
busy <= 0;
ready <= 1; // q is ready
end
end
end
end
endmodule