若a和b均有.1xxxxxx的形式,这是二进制表示(a,b在0.5到1之间)。那么有(a*r0*r1*r2...)/(b*r0*r1*r2...) = a/b。x0 = a,y0 = b,r0 = 2 - y0。
通过推导可得:
x(i+1)= x(i)*r(i);
y(i+1)= y(i)*r(i);
r(i+1) = 2 - y(i + 1);
代码实现:
//////////////////////////////////////////////////////////////////////////////////
// Company: SMIE
// Engineer: Chen Yu
// Create Date: 12:58:27 10/06/2014
// Design Name: divider
// Module Name: goldschmidt
// Project Name: divide
// Revision: 1.0
// Address: http://blog.csdn.net/c602273091
// Revision 0.01 - File Created
//////////////////////////////////////////////////////////////////////////////////
module goldschmidt(a,b,q,times,clk,stt,rst,busy,ready);
input [31:0] a,b; //input a/b
input clk,stt,rst; //control signal
input [4:0] times; //to control iteration times
output [31:0] q; //output result a/b
output busy,ready;
reg busy;
reg busy2;
reg [33:0] temp_a,temp_b;
reg [4:0] cnt;
wire ready;
wire [66:0] mul_a;
wire [66:0] mul_b;
wire [33:0] yi_2;
wire [31:0] q;
always@(posedge clk)
begin
if(rst)
begin
busy <= 1'b0;
busy2 <= 1'b0;
temp_a<= 34'b0;
temp_b<= 34'b0;
cnt <= 5'b0;
end
else
if(stt)
begin
busy <= 1'b1;
busy2 <= busy;
temp_a<= {1'b0,a,1'b0};
temp_b<= {1'b0,b,1'b0};
cnt <= 5'b0;
end
else
begin
temp_a <= mul_a[66:33];
temp_b <= mul_b[66:33];
busy2 <= busy;
if(cnt == times)
busy <= 0;
else;
cnt <= cnt + 5'b1;
end
end
assign mul_a = temp_a*yi_2;
assign yi_2 = (~temp_b) + 1'b1;
assign mul_b = temp_b*yi_2;
assign ready = (~busy)&busy2;
assign q = temp_a[33:2] + (temp_a[0] | temp_a[1]);
endmodule
综合结果:
仿真代码:
module test_gold;
// Inputs
reg [31:0] a;
reg [31:0] b;
reg [4:0] times;
reg clk;
reg stt;
reg rst;
// Outputs
wire [31:0] q;
wire busy;
wire ready;
// Instantiate the Unit Under Test (UUT)
goldschmidt uut (
.a(a),
.b(b),
.q(q),
.times(times),
.clk(clk),
.stt(stt),
.rst(rst),
.busy(busy),
.ready(ready)
);
always #5 clk = !clk;
initial begin
// Initialize Inputs
a = 32'hCF00_0000;
b = 32'hC010_0000;
times = 5;
clk = 1;
stt = 0;
rst = 1;
// Wait 100 ns for global reset to finish
#10;
rst = 0;
stt = 1;
#10;
stt = 0;
#100;
// Add stimulus here
$finish;
end
endmodule
仿真结果: