Line 42... |
Line 42... |
// +-inf * +-inf = -+inf (this is handled by exOver)
|
// +-inf * +-inf = -+inf (this is handled by exOver)
|
// +-inf * 0 = QNaN
|
// +-inf * 0 = QNaN
|
//
|
//
|
// ============================================================================
|
// ============================================================================
|
|
|
module fpFMA (clk, ce, op, rm, a, b, c, o, inf, overflow, underflow);
|
module fpFMA (clk, ce, op, rm, a, b, c, o, inf);
|
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 78... |
Line 78... |
input op; // operation 0 = add, 1 = subtract
|
input op; // operation 0 = add, 1 = subtract
|
input [2:0] rm;
|
input [2:0] rm;
|
input [WID:1] a, b, c;
|
input [WID:1] a, b, c;
|
output [EX:0] o;
|
output [EX:0] o;
|
output inf;
|
output inf;
|
output overflow;
|
|
output underflow;
|
|
|
|
// constants
|
// constants
|
wire [EMSB:0] infXp = {EMSB+1{1'b1}}; // infinite / NaN - all ones
|
wire [EMSB:0] infXp = {EMSB+1{1'b1}}; // infinite / NaN - all ones
|
// The following is the value for an exponent of zero, with the offset
|
// The following is the value for an exponent of zero, with the offset
|
// eg. 8'h7f for eight bit exponent, 11'h7ff for eleven bit exponent, etc.
|
// eg. 8'h7f for eight bit exponent, 11'h7ff for eleven bit exponent, etc.
|
Line 400... |
Line 398... |
reg [EMSB:0] ex6;
|
reg [EMSB:0] ex6;
|
reg [EMSB:0] xc6;
|
reg [EMSB:0] xc6;
|
reg exinf6;
|
reg exinf6;
|
wire [FMSB+1:0] fractc6;
|
wire [FMSB+1:0] fractc6;
|
delay5 #(FMSB+2) u61 (.clk(clk), .ce(ce), .i(fractc1), .o(fractc6) );
|
delay5 #(FMSB+2) u61 (.clk(clk), .ce(ce), .i(fractc1), .o(fractc6) );
|
|
delay1 u62 (.clk(clk), .ce(ce), .i(under5), .o(under6));
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) xc6 <= xc5;
|
if (ce) xc6 <= xc5;
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce)
|
if (ce)
|
Line 453... |
Line 453... |
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) exinf7 <= exinf6;
|
if (ce) exinf7 <= exinf6;
|
// which has greater magnitude ? Used for sign calc
|
// which has greater magnitude ? Used for sign calc
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) ex_gt_xc7 <= ex6 > xc6;
|
if (ce) ex_gt_xc7 <= (ex6 > xc6) && !under6;
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) xeq7 <= ex6==xc6;
|
if (ce) xeq7 <= (ex6==xc6) && !under6;
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) ma_gt_mc7 <= mo6 > {fractc6,{FMSB+1{1'b0}}};
|
if (ce) ma_gt_mc7 <= mo6 > {fractc6,{FMSB+1{1'b0}}};
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) meq7 <= mo6 == {fractc6,{FMSB+1{1'b0}}};
|
if (ce) meq7 <= mo6 == {fractc6,{FMSB+1{1'b0}}};
|
vtdl u71 (.clk(clk), .ce(ce), .a(4'd5), .d(az1), .q(az7));
|
vtdl u71 (.clk(clk), .ce(ce), .a(4'd5), .d(az1), .q(az7));
|
Line 502... |
Line 502... |
|
|
// Find out if the result will be zero.
|
// Find out if the result will be zero.
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce)
|
if (ce)
|
resZero8 <= (realOp7 & xeq7 & meq7) || // subtract, same magnitude
|
resZero8 <= (realOp7 & xeq7 & meq7) || // subtract, same magnitude
|
(az7 | bz7) & cz7; // a or b zero and c zero
|
((az7 | bz7) & cz7); // a or b zero and c zero
|
|
|
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
// CLock #9
|
// CLock #9
|
// Compute output exponent and sign
|
// Compute output exponent and sign
|
//
|
//
|
Line 521... |
Line 521... |
reg [EMSB:0] ex9a;
|
reg [EMSB:0] ex9a;
|
reg ex_gt_xc9;
|
reg ex_gt_xc9;
|
reg [EMSB:0] xc9;
|
reg [EMSB:0] xc9;
|
wire [FX:0] mo9;
|
wire [FX:0] mo9;
|
wire [FMSB+1:0] fractc9;
|
wire [FMSB+1:0] fractc9;
|
|
wire under9;
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) ex_gt_xc9 <= ex_gt_xc8;
|
if (ce) ex_gt_xc9 <= ex_gt_xc8;
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) xc9 <= xc8;
|
if (ce) xc9 <= xc8;
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) ex9a <= ex8;
|
if (ce) ex9a <= ex8;
|
|
|
delay3 #(FX+1) u93 (.clk(clk), .ce(ce), .i(mo6), .o(mo9));
|
delay3 #(FX+1) u93 (.clk(clk), .ce(ce), .i(mo6), .o(mo9));
|
delay3 #(FMSB+2) u94 (.clk(clk), .ce(ce), .i(fractc6), .o(fractc9));
|
delay3 #(FMSB+2) u94 (.clk(clk), .ce(ce), .i(fractc6), .o(fractc9));
|
|
delay3 u95 (.clk(clk), .ce(ce), .i(under6), .o(under9));
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) ex9 <= (exinf8&xcInf8) ? ex8 : resZero8 ? 0 : ex_gt_xc8 ? ex8 : xc8;
|
if (ce) ex9 <= (exinf8&xcInf8) ? ex8 : resZero8 ? 0 : ex_gt_xc8 ? ex8 : xc8;
|
|
|
// Compute output sign
|
// Compute output sign
|
Line 564... |
Line 566... |
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
reg [EMSB:0] xdiff10;
|
reg [EMSB:0] xdiff10;
|
reg [FX:0] mfs;
|
reg [FX:0] mfs;
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) xdiff10 <= ex_gt_xc9 ? ex9a - xc9 : xc9 - ex9a;
|
if (ce) xdiff10 <= ex_gt_xc9 ? ex9a - xc9
|
|
: (under9 ? xc9 + ex9a : xc9 - ex9a);
|
|
|
// determine which fraction to denormalize
|
// determine which fraction to denormalize
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) mfs <= ex_gt_xc9 ? {4'b0,fractc9,{FMSB+1{1'b0}}} : mo9;
|
if (ce) mfs <= ex_gt_xc9 ? {4'b0,fractc9,{FMSB+1{1'b0}}} : mo9;
|
|
|
Line 621... |
Line 624... |
delay4 #(FX+1) u131 (.clk(clk), .ce(ce), .i(mo9), .o(mo13));
|
delay4 #(FX+1) u131 (.clk(clk), .ce(ce), .i(mo9), .o(mo13));
|
delay4 u132 (.clk(clk), .ce(ce), .i(ex_gt_xc9), .o(ex_gt_xc13));
|
delay4 u132 (.clk(clk), .ce(ce), .i(ex_gt_xc9), .o(ex_gt_xc13));
|
vtdl #(FMSB+2) u133 (.clk(clk), .ce(ce), .a(4'd3), .d(fractc9), .q(fractc13));
|
vtdl #(FMSB+2) u133 (.clk(clk), .ce(ce), .a(4'd3), .d(fractc9), .q(fractc13));
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) mfs13 <= ({mfs12,2'b0} >> xdif12)|sticky12;
|
if (ce) mfs13 <= ({mfs12,2'b0} >> xdif12)|{sticky12,1'b0};
|
|
|
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
// Clock #14
|
// Clock #14
|
// Sort operands
|
// Sort operands
|
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
Line 643... |
Line 646... |
// Clock #15
|
// Clock #15
|
// - Sort operands
|
// - Sort operands
|
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
reg [FX+2:0] oaa, obb;
|
reg [FX+2:0] oaa, obb;
|
wire realOp15;
|
wire realOp15;
|
|
wire [EMSB:0] ex15;
|
|
|
vtdl u151 (.clk(clk), .ce(ce), .a(4'd7), .d(realOp7), .q(realOp15));
|
vtdl u151 (.clk(clk), .ce(ce), .a(4'd7), .d(realOp7), .q(realOp15));
|
|
vtdl #(EMSB+1) u152 (.clk(clk), .ce(ce), .a(4'd5), .d(ex9), .q(ex15));
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) oaa <= a_gt_b14 ? oa : ob;
|
if (ce) oaa <= a_gt_b14 ? oa : ob;
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) obb <= a_gt_b14 ? ob : oa;
|
if (ce) obb <= a_gt_b14 ? ob : oa;
|
Line 663... |
Line 668... |
wire [FMSB+1:0] fractc16;
|
wire [FMSB+1:0] fractc16;
|
wire Nan16;
|
wire Nan16;
|
wire cNan16;
|
wire cNan16;
|
wire aInf16, cInf16;
|
wire aInf16, cInf16;
|
wire op16;
|
wire op16;
|
|
wire exinf16;
|
|
|
vtdl u161 (.clk(clk), .ce(ce), .a(4'd10), .d(qNanOut5|aNan5|bNan5), .q(Nan16));
|
vtdl u161 (.clk(clk), .ce(ce), .a(4'd10), .d(qNaNOut5|aNan5|bNan5), .q(Nan16));
|
vtdl u162 (.clk(clk), .ce(ce), .a(4'd14), .d(cNan1), .q(cNan16));
|
vtdl u162 (.clk(clk), .ce(ce), .a(4'd14), .d(cNan1), .q(cNan16));
|
vtdl u163 (.clk(clk), .ce(ce), .a(4'd9), .d(exinf6), .q(aInf16));
|
vtdl u163 (.clk(clk), .ce(ce), .a(4'd9), .d(exinf6), .q(aInf16));
|
vtdl u164 (.clk(clk), .ce(ce), .a(4'd14), .d(cInf1), .q(cInf16));
|
vtdl u164 (.clk(clk), .ce(ce), .a(4'd14), .d(cInf1), .q(cInf16));
|
vtdl u165 (.clk(clk), .ce(ce), .a(4'd14), .d(op1), .q(op16));
|
vtdl u165 (.clk(clk), .ce(ce), .a(4'd14), .d(op1), .q(op16));
|
delay3 #(FX+1) u166 (.clk(clk), .ce(ce), .i(mo13), .o(mo16));
|
delay3 #(FX+1) u166 (.clk(clk), .ce(ce), .i(mo13), .o(mo16));
|
vtdl #(FMSB+2) u167 (.clk(clk), .ce(ce), .a(4'd6), .d(fractc9), .q(fractc16));
|
vtdl #(FMSB+2) u167 (.clk(clk), .ce(ce), .a(4'd6), .d(fractc9), .q(fractc16));
|
|
delay1 u169 (.clk(clk), .ce(ce), .i(&ex15), .o(exinf16));
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) mab = realOp15 ? oaa - obb : oaa + obb;
|
if (ce) mab = realOp15 ? oaa - obb : oaa + obb;
|
|
|
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
Line 684... |
Line 691... |
wire [EMSB:0] ex17;
|
wire [EMSB:0] ex17;
|
reg [FX:0] mo17;
|
reg [FX:0] mo17;
|
wire so17;
|
wire so17;
|
|
|
vtdl u171 (.clk(clk), .ce(ce), .a(4'd7), .d(so9), .q(so17));
|
vtdl u171 (.clk(clk), .ce(ce), .a(4'd7), .d(so9), .q(so17));
|
vtdl #(EMSB+1) u172 (.clk(clk), .ce(ce), .a(4'd7), .d(ex9), .q(ex17));
|
delay2 #(EMSB+1) u172 (.clk(clk), .ce(ce), .i(ex15), .o(ex17));
|
|
|
always @*
|
always @(posedge clk)
|
casez({aInf16&cInf16,Nan16,cNan16})
|
casez({aInf16&cInf16,Nan16,cNan16,exinf16})
|
3'b1??: mo17 = {1'b0,op16,{FMSB-1{1'b0}},op16,{FMSB{1'b0}}}; // inf +/- inf - generate QNaN on subtract, inf on add
|
4'b1???: mo17 <= {1'b0,op16,{FMSB-1{1'b0}},op16,{FMSB{1'b0}}}; // inf +/- inf - generate QNaN on subtract, inf on add
|
3'b01?: mo17 = {1'b0,mo16};
|
4'b01??: mo17 <= {1'b0,mo16};
|
3'b001: mo17 = {1'b0,fractc16[FMSB+1:0],{FMSB{1'b0}}};
|
4'b001?: mo17 <= {1'b0,fractc16[FMSB+1:0],{FMSB{1'b0}}};
|
default: mo17 = mab[FX+3:2]; // mab has an extra lead bit and two trailing bits
|
4'b0001: mo17 <= 1'd0;
|
|
default: mo17 <= mab[FX+3:2]; // mab has an extra lead bit and two trailing bits
|
endcase
|
endcase
|
|
|
assign o = {so17,ex17,mo17};
|
assign o = {so17,ex17,mo17};
|
|
|
vtdl u173 (.clk(clk), .ce(ce), .a(4'd11), .d(over5), .q(overflow) );
|
vtdl u173 (.clk(clk), .ce(ce), .a(4'd11), .d(over5), .q(overflow) );
|
Line 748... |
Line 756... |
|
|
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;
|
|
|
fpFMA #(WID) u1 (clk, ce, op, rm, a, b, c, o1, inf1, overflow1, underflow1);
|
fpFMA #(WID) u1 (clk, ce, op, rm, a, b, c, o1, inf1);
|
fpNormalize #(WID) u2(.clk(clk), .ce(ce), .under(underflow1), .i(o1), .o(fpn0) );
|
fpNormalize #(WID) u2(.clk(clk), .ce(ce), .under(1'b0), .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) u7(.clk(clk), .ce(ce), .i(underflow1), .o(underflow));
|
|
endmodule
|
endmodule
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|