Line 85... |
Line 85... |
wire [EMSB:0] bias = {1'b0,{EMSB{1'b1}}}; //2^0 exponent
|
wire [EMSB:0] bias = {1'b0,{EMSB{1'b1}}}; //2^0 exponent
|
// 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
|
reg [EMSB+2:0] ex1; // sum of exponents
|
`ifndef GOLDSCHMIDT
|
`ifndef GOLDSCHMIDT
|
wire [(FMSB+FADD)*2-1:0] divo;
|
wire [(FMSB+FADD)*2-1:0] divo;
|
`else
|
`else
|
wire [(FMSB+5)*2-1:0] divo;
|
wire [(FMSB+5)*2-1:0] divo;
|
`endif
|
`endif
|
Line 110... |
Line 110... |
// - derive basic information
|
// - derive basic information
|
// - calculate exponent
|
// - calculate exponent
|
// - calculate fraction
|
// - calculate fraction
|
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
|
|
fpDecomp #(FPWID) u1a (.i(a), .sgn(sa), .exp(xa), .fract(fracta), .xz(a_dn), .vz(az), .inf(aInf), .nan(aNan) );
|
wire ld1;
|
fpDecomp #(FPWID) u1b (.i(b), .sgn(sb), .exp(xb), .fract(fractb), .xz(b_dn), .vz(bz), .inf(bInf), .nan(bNan) );
|
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.
|
// 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
|
|
reg [EMSB+2:0] ex1a;
|
|
always @(posedge clk)
|
|
if (ce) ex1a = (xa|a_dn) - (xb|b_dn) + bias;
|
|
|
`ifndef GOLDSCHMIDT
|
`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
|
`else
|
assign ex1 = (xa|a_dn) - (xb|b_dn) + bias + FMSB - lzcnt + 8'd4;
|
if (ce) ex1 = ex1a + FMSB - lzcnt + 8'd4;
|
`endif
|
`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
|
`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));
|
//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) lzcnts = lzcnt - 2;
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) divo1 = divo[(FMSB+FADD)*2-1:0] << (lzcnt-2);
|
if (ce) divo2 = divo[(FMSB+FADD)*2-1:0];
|
|
|
|
always @(posedge clk)
|
|
if (ce) divo1 = divo2 << lzcnts;
|
`else
|
`else
|
DivGoldschmidt #(.FPWID(FMSB+6),.WHOLE(1),.POINTS(FMSB+5))
|
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));
|
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;
|
reg [(FMSB+6)*2+1:0] divo1, divo2;
|
|
always @(posedge clk)
|
|
if (ce) divo2 = divo;
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) divo1 =
|
if (ce) divo1 =
|
lzcnt > 8'd5 ? divo << (lzcnt-8'd6) :
|
lzcnt > 8'd5 ? divo2 << (lzcnt-8'd6) :
|
divo >> (8'd6-lzcnt);
|
divo2 >> (8'd6-lzcnt);
|
;
|
;
|
`endif
|
`endif
|
delay1 #(1) u3 (.clk(clk), .ce(ce), .i(done1), .o(done2));
|
delay2 #(1) u3 (.clk(clk), .ce(ce), .i(done1), .o(done2));
|
delay2 #(1) u4 (.clk(clk), .ce(ce), .i(done1), .o(done));
|
delay3 #(1) u4 (.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);
|
|
|