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

Subversion Repositories ft816float

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

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

Rev 13 Rev 14
Line 32... Line 32...
//+-inf * 0     = QNaN
//+-inf * 0     = QNaN
//+-0 / +-0      = QNaN
//+-0 / +-0      = QNaN
// ============================================================================
// ============================================================================
 
 
`include "fp_defines.v"
`include "fp_defines.v"
 
`define GOLDSCHMIDT     1'b1
 
 
module fpDiv(clk, clk4x, ce, ld, op, a, b, o, done, sign_exe, overflow, underflow);
module fpDiv(rst, clk, 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 74... Line 75...
                                  WID==32 ? 10 :
                                  WID==32 ? 10 :
                                  WID==24 ? 9 : 11;
                                  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 rst;
input clk;
input clk;
input clk4x;
 
input ce;
input ce;
input ld;
input ld;
input op;
input op;
input [MSB:0] a, b;
input [MSB:0] a, b;
output [EX:0] o;
output [EX:0] o;
Line 88... Line 88...
output sign_exe;
output sign_exe;
output overflow;
output overflow;
output underflow;
output underflow;
 
 
// registered outputs
// registered outputs
reg sign_exe;
reg sign_exe=0;
reg inf;
reg inf=0;
reg     overflow;
reg     overflow=0;
reg     underflow;
reg     underflow=0;
 
 
reg so;
reg so;
reg [EMSB:0] xo;
reg [EMSB:0] xo;
reg [FX:0] mo;
reg [FX:0] mo;
assign o = {so,xo,mo};
assign o = {so,xo,mo};
Line 108... 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
 
`ifndef GOLDSCHMIDT
wire [(FMSB+FADD)*2-1:0] divo;
wire [(FMSB+FADD)*2-1:0] divo;
 
`else
 
wire [(FMSB+5)*2-1:0] divo;
 
`endif
 
 
// 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;
wire a_dn, b_dn;                        // a/b is denormalized
wire a_dn, b_dn;                        // a/b is denormalized
wire az, bz;
wire az, bz;
wire aInf, bInf;
wire aInf, bInf;
wire aNan,bNan;
wire aNan,bNan;
wire done1;
wire done1;
wire [7:0] lzcnt;
wire signed [7:0] lzcnt;
 
 
// -----------------------------------------------------------
// -----------------------------------------------------------
// - decode the input operands
// - decode the input operands
// - derive basic information
// - derive basic information
// - calculate exponent
// - calculate exponent
Line 135... Line 139...
 
 
// 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 + (FADD-1) - lzcnt;
`ifndef GOLDSCHMIDT
 
assign ex1 = (xa|a_dn) - (xb|b_dn) + bias + FMSB + (FADD-1) - lzcnt - 8'd1;
 
`else
 
assign ex1 = (xa|a_dn) - (xb|b_dn) + bias + FMSB - lzcnt + 8'd4;
 
`endif
 
 
// 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
// Divider width must be a multiple of four
// 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));
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);
wire [(FMSB+FADD)*2-1:0] divo1 = divo[(FMSB+FADD)*2-1:0] << (lzcnt-2);
 
`else
 
DivGoldschmidt #(.WID(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));
 
wire [(FMSB+6)*2+1:0] divo1 =
 
        lzcnt > 8'd5 ? divo << (lzcnt-8'd6) :
 
        divo >> (8'd6-lzcnt);
 
        ;
 
`endif
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);
 
 
always @(posedge clk)
always @(posedge clk)
        if (ce) begin
// Simulation likes to see these values reset to zero on reset. Otherwise the
 
// values propagate in sim as X's.
 
if (rst) begin
 
        xo <= 1'd0;
 
        mo <= 1'd0;
 
        so <= 1'd0;
 
        sign_exe <= 1'd0;
 
        overflow <= 1'd0;
 
        underflow <= 1'd0;
 
end
 
else 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})
                        5'b1????:               xo = infXp;     // NaN exponent value
                        5'b1????:               xo <= infXp;    // NaN exponent value
                        5'b01???:               xo = 0;          // divide by inf
                        5'b01???:               xo <= 1'd0;             // divide by inf
                        5'b001??:               xo = infXp;     // divide by zero
                        5'b001??:               xo <= infXp;    // divide by zero
                        5'b0001?:               xo = infXp;     // overflow
                        5'b0001?:               xo <= infXp;    // overflow
                        5'b00001:               xo = 0;          // underflow
                        5'b00001:               xo <= 1'd0;             // 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,aInf&bInf,az&bz})
                        casez({aNan,bNan,qNaNOut,bInf,bz,over,aInf&bInf,az&bz})
                        8'b1???????:    mo = {1'b1,a[FMSB:0],{FMSB+1{1'b0}}};
                        8'b1???????:    mo <= {1'b1,a[FMSB:0],{FMSB+1{1'b0}}};
                        8'b01??????:    mo = {1'b1,b[FMSB:0],{FMSB+1{1'b0}}};
                        8'b01??????:    mo <= {1'b1,b[FMSB:0],{FMSB+1{1'b0}}};
                        8'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}}};
                        8'b0001????:    mo = 0;  // div by inf
                        8'b0001????:    mo <= 1'd0;     // div by inf
                        8'b00001???:    mo = 0;  // div by zero
                        8'b00001???:    mo <= 1'd0;     // div by zero
                        8'b000001??:    mo = 0;  // Inf exponent
                        8'b000001??:    mo <= 1'd0;     // Inf exponent
                        8'b0000001?:    mo = {1'b1,qNaN|`QINFDIV,{FMSB+1{1'b0}}};       // infinity / infinity
                        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
                        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
`ifndef GOLDSCHMIDT
 
                        default:                mo <= divo1[(FMSB+FADD)*2-1:(FADD-2)*2-2];      // plain div
 
`else
 
                        default:                mo <= divo1[(FMSB+6)*2+1:2];    // plain div
 
`endif
                        endcase
                        endcase
 
 
                        so              = sa ^ sb;
                        so              <= sa ^ sb;
                        sign_exe        = sa & sb;
                        sign_exe        <= sa & sb;
                        overflow        = over;
                        overflow        <= over;
                        underflow       = under;
                        underflow       <= under;
                end
                end
        end
        end
 
 
endmodule
endmodule
 
 
module fpDivnr(clk, clk4x, ce, ld, op, a, b, o, rm, done, sign_exe, inf, overflow, underflow);
module fpDivnr(rst, clk, 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 212... Line 243...
                                  WID==32 ? 22 :
                                  WID==32 ? 22 :
                                  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 rst;
input clk;
input clk;
input clk4x;
 
input ce;
input ce;
input ld;
input ld;
input op;
input op;
input  [MSB:0] a, b;
input  [MSB:0] a, b;
output [MSB:0] o;
output [MSB:0] o;
Line 231... Line 262...
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, clk4x, ce, ld, op, a, b, o1, done1, sign_exe1, overflow1, underflow1);
fpDiv       #(WID) u1 (rst, clk, 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.