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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog/] [fpDiv.v] - Diff between revs 10 and 13

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 10 Rev 13
Line 31... Line 31...
//+-inf * +-inf = -+inf    (this is handled by exOver)
//+-inf * +-inf = -+inf    (this is handled by exOver)
//+-inf * 0     = QNaN
//+-inf * 0     = QNaN
//+-0 / +-0      = QNaN
//+-0 / +-0      = QNaN
// ============================================================================
// ============================================================================
 
 
module fpDiv(clk, ce, ld, a, b, o, done, sign_exe, overflow, underflow);
`include "fp_defines.v"
 
 
 
module fpDiv(clk, clk4x, ce, ld, op, a, b, o, done, sign_exe, overflow, underflow);
 
 
parameter WID = 128;
parameter WID = 128;
localparam MSB = WID-1;
localparam MSB = WID-1;
localparam EMSB = WID==128 ? 14 :
localparam EMSB = WID==128 ? 14 :
                  WID==96 ? 14 :
                  WID==96 ? 14 :
Line 57... Line 59...
                                  WID==44 ? 31 :
                                  WID==44 ? 31 :
                                  WID==42 ? 29 :
                                  WID==42 ? 29 :
                                  WID==40 ? 28 :
                                  WID==40 ? 28 :
                                  WID==32 ? 22 :
                                  WID==32 ? 22 :
                                  WID==24 ? 15 : 9;
                                  WID==24 ? 15 : 9;
 
// FADD is a constant that makes the divider width a multiple of four and includes eight extra bits.                    
 
localparam FADD = WID==128 ? 9 :
 
                                  WID==96 ? 9 :
 
                                  WID==80 ? 9 :
 
                                  WID==64 ? 13 :
 
                                  WID==52 ? 9 :
 
                                  WID==48 ? 10 :
 
                                  WID==44 ? 9 :
 
                                  WID==42 ? 11 :
 
                                  WID==40 ? 8 :
 
                                  WID==32 ? 10 :
 
                                  WID==24 ? 9 : 11;
 
 
localparam FX = (FMSB+2)*2-1;   // the MSB of the expanded fraction
localparam FX = (FMSB+2)*2-1;   // the MSB of the expanded fraction
localparam EX = FX + 1 + EMSB + 1 + 1 - 1;
localparam EX = FX + 1 + EMSB + 1 + 1 - 1;
 
 
input clk;
input clk;
 
input clk4x;
input ce;
input ce;
input ld;
input ld;
 
input op;
input [MSB:0] a, b;
input [MSB:0] a, b;
output [EX:0] o;
output [EX:0] o;
output done;
output done;
output sign_exe;
output sign_exe;
output overflow;
output overflow;
Line 92... Line 108...
// The following is a template for a quiet nan. (MSB=1)
// The following is a template for a quiet nan. (MSB=1)
wire [FMSB:0] qNaN  = {1'b1,{FMSB{1'b0}}};
wire [FMSB:0] qNaN  = {1'b1,{FMSB{1'b0}}};
 
 
// variables
// variables
wire [EMSB+2:0] ex1;     // sum of exponents
wire [EMSB+2:0] ex1;     // sum of exponents
wire [(FMSB+9)*2-1:0] divo;
wire [(FMSB+FADD)*2-1:0] divo;
 
 
// Operands
// Operands
wire sa, sb;                    // sign bit
wire sa, sb;                    // sign bit
wire [EMSB:0] xa, xb;    // exponent bits
wire [EMSB:0] xa, xb;    // exponent bits
wire [FMSB+1:0] fracta, fractb;
wire [FMSB+1:0] fracta, fractb;
Line 119... Line 135...
 
 
// Compute the exponent.
// Compute the exponent.
// - correct the exponent for denormalized operands
// - correct the exponent for denormalized operands
// - adjust the difference by the bias (add 127)
// - adjust the difference by the bias (add 127)
// - also factor in the different decimal position for division
// - also factor in the different decimal position for division
assign ex1 = (xa|a_dn) - (xb|b_dn) + bias + FMSB + 9 - lzcnt;
assign ex1 = (xa|a_dn) - (xb|b_dn) + bias + FMSB + (FADD-1) - lzcnt;
 
 
// check for exponent underflow/overflow
// check for exponent underflow/overflow
wire under = ex1[EMSB+2];       // MSB set = negative exponent
wire under = ex1[EMSB+2];       // MSB set = negative exponent
wire over = (&ex1[EMSB:0] | ex1[EMSB+1]) & !ex1[EMSB+2];
wire over = (&ex1[EMSB:0] | ex1[EMSB+1]) & !ex1[EMSB+2];
 
 
// Perform divide
// Perform divide
// could take either 1 or 16 clock cycles
// Divider width must be a multiple of four
fpdivr8 #(FMSB+9,2) u2 (.clk(clk), .ld(ld), .a({fracta,7'b0}), .b({fractb,7'b0}), .q(divo), .r(), .done(done1), .lzcnt(lzcnt));
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));
 
wire [(FMSB+FADD)*2-1:0] divo1 = divo[(FMSB+FADD)*2-1:0] << (lzcnt-2);
delay1 #(1) u3 (.clk(clk), .ce(ce), .i(done1), .o(done));
delay1 #(1) u3 (.clk(clk), .ce(ce), .i(done1), .o(done));
 
 
 
 
// determine when a NaN is output
// determine when a NaN is output
wire qNaNOut = (az&bz)|(aInf&bInf);
wire qNaNOut = (az&bz)|(aInf&bInf);
wire [(FMSB+9)*2-1:0] divo1 = divo[(FMSB+9)*2-1:0] << (lzcnt-2);
 
 
 
always @(posedge clk)
always @(posedge clk)
        if (ce) begin
        if (ce) begin
                if (done1) begin
                if (done1) begin
                        casez({qNaNOut|aNan|bNan,bInf,bz,over,under})
                        casez({qNaNOut|aNan|bNan,bInf,bz,over,under})
Line 147... Line 163...
                        5'b0001?:               xo = infXp;     // overflow
                        5'b0001?:               xo = infXp;     // overflow
                        5'b00001:               xo = 0;          // underflow
                        5'b00001:               xo = 0;          // underflow
                        default:                xo = ex1;       // normal or underflow: passthru neg. exp. for normalization
                        default:                xo = ex1;       // normal or underflow: passthru neg. exp. for normalization
                        endcase
                        endcase
 
 
                        casez({aNan,bNan,qNaNOut,bInf,bz,over})
                        casez({aNan,bNan,qNaNOut,bInf,bz,over,aInf&bInf,az&bz})
                        6'b1?????:      mo = {1'b1,a[FMSB:0],{FMSB+1{1'b0}}};
                        8'b1???????:    mo = {1'b1,a[FMSB:0],{FMSB+1{1'b0}}};
                        6'b01????:      mo = {1'b1,b[FMSB:0],{FMSB+1{1'b0}}};
                        8'b01??????:    mo = {1'b1,b[FMSB:0],{FMSB+1{1'b0}}};
                        6'b001???:              mo = {1'b1,qNaN[FMSB:0]|{aInf,1'b0}|{az,bz},{FMSB+1{1'b0}}};
                        8'b001?????:    mo = {1'b1,qNaN[FMSB:0]|{aInf,1'b0}|{az,bz},{FMSB+1{1'b0}}};
                        6'b0001??:              mo = 0;  // div by inf
                        8'b0001????:    mo = 0;  // div by inf
                        6'b00001?:              mo = 0;  // div by zero
                        8'b00001???:    mo = 0;  // div by zero
                        6'b000001:              mo = 0;  // Inf exponent
                        8'b000001??:    mo = 0;  // Inf exponent
                        default:                mo = divo1[(FMSB+9)*2-1:14];    // plain div
                        8'b0000001?:    mo = {1'b1,qNaN|`QINFDIV,{FMSB+1{1'b0}}};       // infinity / infinity
 
                        8'b00000001:    mo = {1'b1,qNaN|`QZEROZERO,{FMSB+1{1'b0}}};     // zero / zero
 
                        default:                mo = divo1[(FMSB+FADD)*2-1:(FADD-2)*2-2];       // plain div
                        endcase
                        endcase
 
 
                        so              = sa ^ sb;
                        so              = sa ^ sb;
                        sign_exe        = sa & sb;
                        sign_exe        = sa & sb;
                        overflow        = over;
                        overflow        = over;
Line 166... Line 184...
                end
                end
        end
        end
 
 
endmodule
endmodule
 
 
module fpDivnr(clk, ce, ld, a, b, o, rm, done, sign_exe, inf, overflow, underflow);
module fpDivnr(clk, clk4x, ce, ld, op, a, b, o, rm, done, sign_exe, inf, overflow, underflow);
parameter WID=32;
parameter WID=32;
localparam MSB = WID-1;
localparam MSB = WID-1;
localparam EMSB = WID==128 ? 14 :
localparam EMSB = WID==128 ? 14 :
                  WID==96 ? 14 :
                  WID==96 ? 14 :
                  WID==80 ? 14 :
                  WID==80 ? 14 :
Line 195... Line 213...
                                  WID==24 ? 15 : 9;
                                  WID==24 ? 15 : 9;
 
 
localparam FX = (FMSB+2)*2-1;   // the MSB of the expanded fraction
localparam FX = (FMSB+2)*2-1;   // the MSB of the expanded fraction
localparam EX = FX + 1 + EMSB + 1 + 1 - 1;
localparam EX = FX + 1 + EMSB + 1 + 1 - 1;
input clk;
input clk;
 
input clk4x;
input ce;
input ce;
input ld;
input ld;
 
input op;
input  [MSB:0] a, b;
input  [MSB:0] a, b;
output [MSB:0] o;
output [MSB:0] o;
input [2:0] rm;
input [2:0] rm;
output sign_exe;
output sign_exe;
output done;
output done;
Line 211... Line 231...
wire [EX:0] o1;
wire [EX:0] o1;
wire sign_exe1, inf1, overflow1, underflow1;
wire sign_exe1, inf1, overflow1, underflow1;
wire [MSB+3:0] fpn0;
wire [MSB+3:0] fpn0;
wire done1;
wire done1;
 
 
fpDiv       #(WID) u1 (clk, ce, ld, a, b, o1, done1, sign_exe1, overflow1, underflow1);
fpDiv       #(WID) u1 (clk, clk4x, ce, ld, op, a, b, o1, done1, sign_exe1, overflow1, underflow1);
fpNormalize #(WID) u2(.clk(clk), .ce(ce), .under(underflow1), .i(o1), .o(fpn0) );
fpNormalize #(WID) u2(.clk(clk), .ce(ce), .under(underflow1), .i(o1), .o(fpn0) );
fpRoundReg  #(WID) u3(.clk(clk), .ce(ce), .rm(rm), .i(fpn0), .o(o) );
fpRoundReg  #(WID) u3(.clk(clk), .ce(ce), .rm(rm), .i(fpn0), .o(o) );
delay2      #(1)   u4(.clk(clk), .ce(ce), .i(sign_exe1), .o(sign_exe));
delay2      #(1)   u4(.clk(clk), .ce(ce), .i(sign_exe1), .o(sign_exe));
delay2      #(1)   u5(.clk(clk), .ce(ce), .i(inf1), .o(inf));
delay2      #(1)   u5(.clk(clk), .ce(ce), .i(inf1), .o(inf));
delay2      #(1)   u6(.clk(clk), .ce(ce), .i(overflow1), .o(overflow));
delay2      #(1)   u6(.clk(clk), .ce(ce), .i(overflow1), .o(overflow));

powered by: WebSVN 2.1.0

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