Line 1... |
Line 1... |
// ============================================================================
|
// ============================================================================
|
// __
|
// __
|
// \\__/ o\ (C) 2006-2016 Robert Finch, Waterloo
|
// \\__/ o\ (C) 2006-2018 Robert Finch, Waterloo
|
// \ __ / All rights reserved.
|
// \ __ / All rights reserved.
|
// \/_// robfinch<remove>@finitron.ca
|
// \/_// robfinch<remove>@finitron.ca
|
// ||
|
// ||
|
//
|
//
|
// fpdivr8.v
|
// fpdivr8.v
|
// Radix 8 floating point divider primitive
|
// Radix8 doesn't work !!!!
|
|
// Radix 2 floating point divider primitive
|
//
|
//
|
//
|
//
|
// This source file is free software: you can redistribute it and/or modify
|
// This source file is free software: you can redistribute it and/or modify
|
// it under the terms of the GNU Lesser General Public License as published
|
// it under the terms of the GNU Lesser General Public License as published
|
// by the Free Software Foundation, either version 3 of the License, or
|
// by the Free Software Foundation, either version 3 of the License, or
|
Line 24... |
Line 25... |
//
|
//
|
// ============================================================================
|
// ============================================================================
|
|
|
module fpdivr8(clk, ld, a, b, q, r, done, lzcnt);
|
module fpdivr8(clk, ld, a, b, q, r, done, lzcnt);
|
parameter WID = 112;
|
parameter WID = 112;
|
parameter RADIX = 8;
|
localparam DMSB = WID-1;
|
localparam WID1 = WID;//((WID+2)/3)*3; // make width a multiple of three
|
|
localparam DMSB = WID1-1;
|
|
input clk;
|
input clk;
|
input ld;
|
input ld;
|
input [WID1-1:0] a;
|
input [WID-1:0] a;
|
input [WID1-1:0] b;
|
input [WID-1:0] b;
|
output reg [WID1*2-1:0] q;
|
output reg [WID-1:0] q;
|
output [WID1-1:0] r;
|
output [WID-1:0] r;
|
output reg done;
|
output reg done;
|
output reg [7:0] lzcnt;
|
output reg [7:0] lzcnt;
|
|
|
|
|
wire [DMSB:0] rx [2:0]; // remainder holds
|
|
reg [DMSB:0] rxx;
|
reg [DMSB:0] rxx;
|
reg [8:0] cnt; // iteration count
|
reg [8:0] cnt; // iteration count
|
wire [DMSB:0] sdq;
|
|
wire [DMSB:0] sdr;
|
|
wire sdval;
|
|
wire sddbz;
|
|
reg [DMSB+1:0] ri = 0;
|
reg [DMSB+1:0] ri = 0;
|
wire b0,b1,b2;
|
wire b0,b1,b2,b3;
|
wire [DMSB+1:0] r1,r2,r3;
|
wire [DMSB+1:0] r1,r2,r3;
|
reg gotnz;
|
reg gotnz;
|
|
|
specialCaseDivider #(WID1) u1 (.a(a), .b(b), .q(sdq), .val(sdval), .dbz(sdbz) );
|
|
|
|
wire [7:0] maxcnt;
|
wire [7:0] maxcnt;
|
wire [2:0] n1;
|
wire [2:0] n1;
|
generate
|
assign maxcnt = WID/3+1;
|
begin
|
|
if (RADIX==8) begin
|
|
assign maxcnt = WID1*2/3+1;
|
|
assign b0 = b < rxx;
|
assign b0 = b < rxx;
|
assign r1 = b0 ? rxx - b : rxx;
|
assign r1 = b0 ? rxx - b : rxx;
|
assign b1 = b < {r1,q[WID*2-1]};
|
assign b1 = b < {r1,q[WID-1]};
|
assign r2 = b1 ? {r1,q[WID*2-1]} - b : {r1,q[WID*2-1]};
|
assign r2 = b1 ? {r1,q[WID-1]} - b : {r1,q[WID-1]};
|
assign b2 = b < {r2,q[WID*2-1-1]};
|
assign b2 = b < {r2,q[WID-2]};
|
assign r3 = b2 ? {r2,q[WID*2-1-1]} - b : {r2,q[WID*2-1-1]};
|
assign r3 = b2 ? {r2,q[WID-2]} - b : {r2,q[WID-2]};
|
assign n1 = 2;
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ld)
|
if (ld)
|
rxx <= 0;
|
rxx <= {WID{1'b0}};
|
else if (!done)
|
else if (!done)
|
rxx <= {r3,q[WID*2-1]};
|
rxx <= {r3,q[WID-3]};
|
end
|
|
else if (RADIX==2) begin
|
|
assign b0 = b <= ri;
|
|
assign r1 = b0 ? ri - b : ri;
|
|
assign maxcnt = WID1*2-1;
|
|
assign n1 = 0;
|
|
// assign rx[0] = rxx [DMSB] ? {rxx ,q[WID*2-1 ]} + b : {rxx ,q[WID*2-1 ]} - b;
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
begin
|
begin
|
done <= 1'b0;
|
done <= 1'b0;
|
if (ld) begin
|
if (ld) begin
|
cnt <= sdval ? 9'h1FE : maxcnt;
|
cnt <= maxcnt;
|
done <= sdval;
|
|
end
|
end
|
else if (cnt != 9'h1FE) begin
|
else if (cnt != 9'h1FE) begin
|
cnt <= cnt - 1;
|
cnt <= cnt - 1;
|
if (cnt==9'h1FF)
|
if (cnt==9'h1FF)
|
done <= 1'b1;
|
done <= 1'b1;
|
end
|
end
|
end
|
end
|
|
|
|
|
generate
|
|
begin
|
|
if (RADIX==8) begin
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ld) begin
|
if (ld) begin
|
gotnz <= 1'b0;
|
q <= a;
|
lzcnt <= 8'h00;
|
|
if (sdval)
|
|
q <= {3'b0,sdq,{WID1{1'b0}}};
|
|
else
|
|
q <= {3'b0,a,{WID1{1'b0}}};
|
|
end
|
end
|
else if (!done) begin
|
else if (!done) begin
|
q[WID1-1:3] <= q[WID1-1-3:0];
|
q[WID-1:3] <= q[WID-4:0];
|
q[0] <= b0;
|
q[2] <= b0;
|
q[1] <= b1;
|
q[1] <= b1;
|
q[2] <= b2;
|
q[0] <= b2;
|
end
|
|
// correct remainder
|
|
assign r = sdval ? sdr : r3;
|
|
end
|
end
|
if (RADIX==2) begin
|
assign r = r3;
|
always @(posedge clk)
|
|
if (ld) begin
|
|
gotnz <= 1'b0;
|
|
lzcnt <= 8'h00;
|
|
ri <= 0;
|
|
if (sdval)
|
|
q <= {3'b0,sdq,{WID1{1'b0}}};
|
|
else
|
|
q <= {3'b0,a,{WID1{1'b0}}};
|
|
end
|
|
else if (cnt!=9'h1FE) begin
|
|
if (b0)
|
|
gotnz <= 1'b1;
|
|
if (b0==0 && !gotnz)
|
|
lzcnt <= lzcnt + 8'd1;
|
|
q[WID1*2-1:1] <= q[WID1*2-1-1:0];
|
|
q[0] <= b0;
|
|
ri <= {r1[DMSB:0],q[WID1*2-1]};
|
|
end
|
|
// correct remainder
|
|
assign r = sdval ? sdr : ri;
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|