OpenCores
URL https://opencores.org/ocsvn/ft816float/ft816float/trunk

Subversion Repositories ft816float

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 34 to Rev 35
    Reverse comparison

Rev 34 → Rev 35

/ft816float/trunk/rtl/verilog2/fpConfig.sv
2,7 → 2,7
 
// ============================================================================
// __
// \\__/ o\ (C) 2019 Robert Finch, Waterloo
// \\__/ o\ (C) 2019-2020 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
27,9 → 27,25
// calculations are performed in one long clock cycle. This will result in
// the maximum clock rate being really low.
 
//`define MIN_LATENCY 1'b1
`define MIN_LATENCY 1'b1
 
// Number of bits extra beyond specified FPWIDth for calculation results
// should be a multiple of four
`define EXTRA_BITS 0
 
`define FPWID 80
 
// This file contains defintions for fields to ease dealing with different fp
// FPWIDths. Some of the code still needs to be modified to support FPWIDths
// other than standard 32,64 or 80 bit.
`define MSB (`FPWID-1)
`define EMSB (`FPWID==128 ? 14 : `FPWID==96 ? 14 : `FPWID==80 ? 14 : `FPWID==64 ? 10 : `FPWID==52 ? 10 : `FPWID==48 ? 10 : `FPWID==44 ? 10 : `FPWID==42 ? 10 : `FPWID==40 ? 9 : `FPWID==32 ? 7 : `FPWID==24 ? 6 : 49)
`define FMSB (`FPWID==128 ? (111) : `FPWID==96 ? (79) : `FPWID==80 ? (63) : `FPWID==64 ? (51) : `FPWID==52 ? (39) : `FPWID==48 ? (35) : `FPWID==44 ? (31) : `FPWID==42 ? (29) : `FPWID==40 ? (28) : `FPWID==32 ? (22) : `FPWID==24 ? (15) : (9))
`define FX ((`FMSB+2)*2) // the MSB of the expanded fraction
`define EX (`FX + 1 + `EMSB + 1 + 1 - 1)
 
// Only uncomment one of the following for the divider
// radix four has a faster cycle time
// radix sixteen uses fewer clock cycles
`define DIV_RADIX4 1'b1
//`define DIV_RADIX16 1'b1
/ft816float/trunk/rtl/verilog2/fpDiv.v
87,7 → 87,7
wire [FMSB:0] qNaN = {1'b1,{FMSB{1'b0}}};
 
// variables
wire [EMSB+2:0] ex1; // sum of exponents
reg [EMSB+2:0] ex1; // sum of exponents
`ifndef GOLDSCHMIDT
wire [(FMSB+FADD)*2-1:0] divo;
`else
112,19 → 112,27
// - calculate fraction
// -----------------------------------------------------------
 
fpDecomp #(FPWID) u1a (.i(a), .sgn(sa), .exp(xa), .fract(fracta), .xz(a_dn), .vz(az), .inf(aInf), .nan(aNan) );
fpDecomp #(FPWID) u1b (.i(b), .sgn(sb), .exp(xb), .fract(fractb), .xz(b_dn), .vz(bz), .inf(bInf), .nan(bNan) );
wire ld1;
fpDecompReg #(FPWID) u1a (.clk(clk), .ce(ce), .i(a), .sgn(sa), .exp(xa), .fract(fracta), .xz(a_dn), .vz(az), .inf(aInf), .nan(aNan) );
fpDecompReg #(FPWID) u1b (.clk(clk), .ce(ce), .i(b), .sgn(sb), .exp(xb), .fract(fractb), .xz(b_dn), .vz(bz), .inf(bInf), .nan(bNan) );
delay1 #(1) u5 (.clk(clk), .ce(ce), .i(ld), .o(ld1));
 
// Compute the exponent.
// - correct the exponent for denormalized operands
// - adjust the difference by the bias (add 127)
// - also factor in the different decimal position for division
reg [EMSB+2:0] ex1a;
always @(posedge clk)
if (ce) ex1a = (xa|a_dn) - (xb|b_dn) + bias;
`ifndef GOLDSCHMIDT
assign ex1 = (xa|a_dn) - (xb|b_dn) + bias + FMSB + (FADD-1) - lzcnt - 8'd1;
always @(posedge clk)
if (ce) ex1 = ex1a + FMSB + (FADD-1) - lzcnt - 8'd1;
`else
assign ex1 = (xa|a_dn) - (xb|b_dn) + bias + FMSB - lzcnt + 8'd4;
if (ce) ex1 = ex1a + FMSB - lzcnt + 8'd4;
`endif
 
 
// check for exponent underflow/overflow
wire under = ex1[EMSB+2]; // MSB set = negative exponent
wire over = (&ex1[EMSB:0] | ex1[EMSB+1]) & !ex1[EMSB+2];
132,23 → 140,36
// Perform divide
// Divider width must be a multiple of four
`ifndef GOLDSCHMIDT
fpdivr16 #(FMSB+FADD) u2 (.clk(clk), .ld(ld), .a({3'b0,fracta,8'b0}), .b({3'b0,fractb,8'b0}), .q(divo), .r(), .done(done1), .lzcnt(lzcnt));
`ifdef DIV_RADIX4
fpdivr4 #(FMSB+FADD) u2 (.clk(clk), .ld(ld1), .a({3'b0,fracta,8'b0}), .b({3'b0,fractb,8'b0}), .q(divo), .r(), .done(done1), .lzcnt(lzcnt));
`endif
`ifdef DIV_RADIX16
fpdivr16 #(FMSB+FADD) u2 (.clk(clk), .ld(ld1), .a({3'b0,fracta,8'b0}), .b({3'b0,fractb,8'b0}), .q(divo), .r(), .done(done1), .lzcnt(lzcnt));
`endif
//fpdivr2 #(FMSB+FADD) u2 (.clk4x(clk4x), .ld(ld), .a({3'b0,fracta,8'b0}), .b({3'b0,fractb,8'b0}), .q(divo), .r(), .done(done1), .lzcnt(lzcnt));
reg [(FMSB+FADD)*2-1:0] divo1;
reg [(FMSB+FADD)*2-1:0] divo1, divo2;
reg [7:0] lzcnts;
always @(posedge clk)
if (ce) divo1 = divo[(FMSB+FADD)*2-1:0] << (lzcnt-2);
if (ce) lzcnts = lzcnt - 2;
always @(posedge clk)
if (ce) divo2 = divo[(FMSB+FADD)*2-1:0];
 
always @(posedge clk)
if (ce) divo1 = divo2 << lzcnts;
`else
DivGoldschmidt #(.FPWID(FMSB+6),.WHOLE(1),.POINTS(FMSB+5))
u2 (.rst(rst), .clk(clk), .ld(ld), .a({fracta,4'b0}), .b({fractb,4'b0}), .q(divo), .done(done1), .lzcnt(lzcnt));
reg [(FMSB+6)*2+1:0] divo1;
u2 (.rst(rst), .clk(clk), .ld(ld1), .a({fracta,4'b0}), .b({fractb,4'b0}), .q(divo), .done(done1), .lzcnt(lzcnt));
reg [(FMSB+6)*2+1:0] divo1, divo2;
always @(posedge clk)
if (ce) divo2 = divo;
always @(posedge clk)
if (ce) divo1 =
lzcnt > 8'd5 ? divo << (lzcnt-8'd6) :
divo >> (8'd6-lzcnt);
lzcnt > 8'd5 ? divo2 << (lzcnt-8'd6) :
divo2 >> (8'd6-lzcnt);
;
`endif
delay1 #(1) u3 (.clk(clk), .ce(ce), .i(done1), .o(done2));
delay2 #(1) u4 (.clk(clk), .ce(ce), .i(done1), .o(done));
delay2 #(1) u3 (.clk(clk), .ce(ce), .i(done1), .o(done2));
delay3 #(1) u4 (.clk(clk), .ce(ce), .i(done1), .o(done));
 
 
// determine when a NaN is output
/ft816float/trunk/rtl/verilog2/fpdivr4.v
0,0 → 1,118
// ============================================================================
// __
// \\__/ o\ (C) 2006-2020 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// fpdivr16.v
// Radix 16 floating point divider primitive
//
//
// 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
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ============================================================================
 
module fpdivr4(clk, ld, a, b, q, r, done, lzcnt);
parameter WID1 = 112;
localparam REM = WID1 % 2;
localparam WID = ((WID1*2)+1)/2;
localparam DMSB = WID-1;
input clk;
input ld;
input [WID-1:0] a;
input [WID-1:0] b;
output reg [WID*2-1:0] q = 1'd0;
output reg [WID-1:0] r = 1'd0;
output reg done = 1'd0;
output reg [7:0] lzcnt = 1'd0;
 
initial begin
if (WID % 2) begin
$display("fpdvir4: Width must be a multiple of two.");
$finish;
end
end
 
wire [7:0] maxcnt;
reg [DMSB:0] rxx = 1'd0;
reg [8:0] cnt = 1'd0; // iteration count
// Simulation didn't like all the wiring.
reg [DMSB+1:0] ri = 1'd0;
reg b0 = 1'd0,b1 = 1'd0,b2 = 1'd0,b3 = 1'd0;
reg [DMSB+1:0] r1 = 1'd0,r2 = 1'd0,r3 = 1'd0,r4 = 1'd0;
reg gotnz = 0;
 
assign maxcnt = WID*2/2-1;
always @*
b0 = b <= {rxx,q[WID*2-1]};
always @*
r1 = b0 ? {rxx,q[WID*2-1]} - b : {rxx,q[WID*2-1]};
always @*
b1 = b <= {r1,q[WID*2-2]};
always @*
r2 = b1 ? {r1,q[WID*2-2]} - b : {r1,q[WID*2-2]};
 
reg [2:0] state = 0;
always @(posedge clk)
begin
if (ld) state <= 3'd1;
case(state)
3'd0: ;
3'd1: if (cnt[8]) state <= 3'd2;
3'd2: state <= 3'd0;
default: state <= 3'd0;
endcase
end
 
always @(posedge clk)
begin
done <= 1'b0;
case(state)
3'd0: ;
3'd1:
if (!cnt[8]) begin
q[WID*2-1:2] <= q[WID*2-3:0];
q[1] <= b0;
q[0] <= b1;
if (!gotnz)
casez({b0,b1})
2'b1?: ;
2'b01: lzcnt <= lzcnt + 8'd1;
2'b00: lzcnt <= lzcnt + 8'd2;
endcase
if ({b0,b1} != 2'h0 && !gotnz) begin
gotnz <= 3'd1;
end
rxx <= r2;
cnt <= cnt - 3'd1;
end
3'd2:
begin
r <= r2;
done <= 1'b1;
end
default: ;
endcase
if (ld) begin
lzcnt <= 0;
gotnz <= 1'b0;
cnt <= {1'b0,maxcnt};
q <= {(a << REM),{WID{1'b0}}};
rxx <= {WID{1'b0}};
end
end
 
endmodule
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.