diff --git a/wally-pipelined/src/fpu/fcvt.sv b/wally-pipelined/src/fpu/fcvt.sv index 3ee0be0f..920f187c 100644 --- a/wally-pipelined/src/fpu/fcvt.sv +++ b/wally-pipelined/src/fpu/fcvt.sv @@ -3,8 +3,7 @@ module fcvt ( input logic XSgnE, input logic [10:0] XExpE, - input logic [51:0] XFracE, - input logic XAssumed1E, + input logic [52:0] XManE, input logic XZeroE, input logic XNaNE, input logic XInfE, @@ -108,12 +107,12 @@ module fcvt ( // select the shift value and amount based on operation (to fp or int) assign ShiftCnt = FOpCtrlE[1] ? ExpVal : LZResP; - assign ShiftVal = FOpCtrlE[1] ? {{64-2{1'b0}}, XAssumed1E, XFracE} : {PosInt, 52'b0}; + assign ShiftVal = FOpCtrlE[1] ? {{64-2{1'b0}}, XManE} : {PosInt, 52'b0}; // if shift = -1 then shift one bit right for gaurd bit (right shifting twice never rounds) // if the shift is negitive add a bit for sticky bit calculation // otherwise shift left - assign ShiftedManTmp = &ShiftCnt ? {{64-1{1'b0}}, XAssumed1E, XFracE[51:1]} : ShiftCnt[12] ? {{64+51{1'b0}}, ~XZeroE} : ShiftVal << ShiftCnt; + assign ShiftedManTmp = &ShiftCnt ? {{64-1{1'b0}}, XManE[52:1]} : ShiftCnt[12] ? {{64+51{1'b0}}, ~XZeroE} : ShiftVal << ShiftCnt; // truncate the shifted mantissa assign ShiftedMan = ShiftedManTmp[64+51:50]; @@ -121,7 +120,7 @@ module fcvt ( // calculate sticky bit // - take into account the possible right shift from before // - the sticky bit calculation covers three diffrent sizes depending on the opperation - assign Sticky = |ShiftedManTmp[49:0] | &ShiftCnt&XFracE[0] | (FOpCtrlE[0]&|ShiftedManTmp[62:50]) | (FOpCtrlE[0]&~FmtE&|ShiftedManTmp[91:63]); + assign Sticky = |ShiftedManTmp[49:0] | &ShiftCnt&XManE[0] | (FOpCtrlE[0]&|ShiftedManTmp[62:50]) | (FOpCtrlE[0]&~FmtE&|ShiftedManTmp[91:63]); // determine guard, round, and least significant bit of the result diff --git a/wally-pipelined/src/fpu/fma.sv b/wally-pipelined/src/fpu/fma.sv index 83fc166c..5b9de554 100644 --- a/wally-pipelined/src/fpu/fma.sv +++ b/wally-pipelined/src/fpu/fma.sv @@ -35,11 +35,10 @@ module fma( input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude input logic XSgnE, YSgnE, ZSgnE, input logic [`NE-1:0] XExpE, YExpE, ZExpE, - input logic [`NF-1:0] XFracE, YFracE, ZFracE, + input logic [`NF:0] XManE, YManE, ZManE, input logic XSgnM, YSgnM, ZSgnM, - input logic [`NE-1:0] XExpM, YExpM, ZExpM, - input logic [`NF-1:0] XFracM, YFracM, ZFracM, - input logic XAssumed1E, YAssumed1E, ZAssumed1E, + input logic [`NE-1:0] XExpM, YExpM, ZExpM, // ***needed + input logic [`NF:0] XManM, YManM, ZManM, input logic XDenormE, YDenormE, ZDenormE, input logic XZeroE, YZeroE, ZZeroE, input logic XNaNM, YNaNM, ZNaNM, @@ -57,8 +56,8 @@ module fma( logic AddendStickyE, AddendStickyM; logic KillProdE, KillProdM; - fma1 fma1 (.XExpE, .YExpE, .ZExpE, .XFracE, .YFracE, .ZFracE, - .BiasE, .XAssumed1E, .YAssumed1E, .ZAssumed1E, .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, + fma1 fma1 (.XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE, + .BiasE, .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .FOpCtrlE, .FmtE, .ProdManE, .AlignedAddendE, .ProdExpE, .AddendStickyE, .KillProdE); @@ -69,7 +68,7 @@ module fma( {AddendStickyE, KillProdE}, {AddendStickyM, KillProdM}); - fma2 fma2(.XSgnM, .YSgnM, .ZSgnM, .XExpM, .YExpM, .ZExpM, .XFracM, .YFracM, .ZFracM, + fma2 fma2(.XSgnM, .YSgnM, .ZSgnM, .XExpM, .YExpM, .ZExpM, .XManM, .YManM, .ZManM, .FOpCtrlM, .FrmM, .FmtM, .ProdManM, .AlignedAddendM, .ProdExpM, .AddendStickyM, .KillProdM, .XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM, @@ -82,8 +81,7 @@ endmodule module fma1( // input logic XSgnE, YSgnE, ZSgnE, input logic [`NE-1:0] XExpE, YExpE, ZExpE, // biased exponents in B(NE.0) format - input logic [`NF-1:0] XFracE, YFracE, ZFracE, // fractions in U(0.NF) format] - input logic XAssumed1E, YAssumed1E, ZAssumed1E, + input logic [`NF:0] XManE, YManE, ZManE, // fractions in U(0.NF) format] input logic XDenormE, YDenormE, ZDenormE, input logic XZeroE, YZeroE, ZZeroE, input logic [`NE-1:0] BiasE, @@ -114,8 +112,8 @@ module fma1( // verilator lint_on WIDTH // Calculate the product's mantissa - // - Add the assumed one. If the number is denormalized or zero, it does not have an assumed one. - assign ProdManE = {XAssumed1E, XFracE} * {YAssumed1E, YFracE}; + // - Mantissa includes the assumed one. If the number is denormalized or zero, it does not have an assumed one. + assign ProdManE = XManE * YManE; /////////////////////////////////////////////////////////////////////////////// // Alignment shifter @@ -133,7 +131,7 @@ module fma1( // |1'b0| addnend | // the 1'b0 before the added is because the product's mantissa has two bits before the binary point (xx.xxxxxxxxxx...) - assign ZManPreShifted = {(`NF+3)'(0), {ZAssumed1E, ZFracE}, /*106*/(2*`NF+2)'(0)}; + assign ZManPreShifted = {(`NF+3)'(0), ZManE, /*106*/(2*`NF+2)'(0)}; always_comb begin @@ -143,7 +141,7 @@ module fma1( // | addnend | if ($signed(AlignCnt) <= $signed(-(`NF+4))) begin KillProdE = 1; - ZManShifted = ZManPreShifted;//{107'b0, {~ZAssumed1E, ZFrac}, 54'b0}; + ZManShifted = ZManPreShifted;//{107'b0, XManE, 54'b0}; AddendStickyE = ~(XZeroE|YZeroE); // If the Addend is shifted left (negitive AlignCnt) @@ -185,7 +183,7 @@ module fma2( input logic XSgnM, YSgnM, ZSgnM, input logic [`NE-1:0] XExpM, YExpM, ZExpM, - input logic [`NF-1:0] XFracM, YFracM, ZFracM, + input logic [`NF-1:0] XManM, YManM, ZManM, input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude input logic [2:0] FOpCtrlM, // 000 = fmadd (X*Y)+Z, 001 = fmsub (X*Y)-Z, 010 = fnmsub -(X*Y)+Z, 011 = fnmadd -(X*Y)-Z, 100 = fmul (X*Y) input logic FmtM, // precision 1 = double 0 = single @@ -490,29 +488,29 @@ module fma2( /////////////////////////////////////////////////////////////////////////////// // Select the result /////////////////////////////////////////////////////////////////////////////// - assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XFracM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XFracM[50:29]}; - assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, YFracM[`NF-2:0]} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, YFracM[50:29]}; - assign ZNaNResult = FmtM ? {ZSgnM, ZExpM, 1'b1, ZFracM[`NF-2:0]} : {{32{1'b1}}, ZSgnM, ZExpM[7:0], 1'b1, ZFracM[50:29]}; + assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XManM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XManM[50:29]}; + assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, YManM[`NF-2:0]} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, YManM[50:29]}; + assign ZNaNResult = FmtM ? {ZSgnM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnM, ZExpM[7:0], 1'b1, ZManM[50:29]}; assign OverflowResult = FmtM ? ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} : ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{32{1'b1}}, ResultSgn, 8'hfe, {23{1'b1}}} : {{32{1'b1}}, ResultSgn, 8'hff, 23'b0}; assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, ResultSgn, 8'hff, 1'b1, 22'b0}; - assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZFracM} - (Minus1&AddendStickyM) + (Plus1&AddendStickyM)} : {{32{1'b1}}, ResultSgn, {ZExpM[7:0], ZFracM[51:29]} - {30'b0, (Minus1&AddendStickyM)} + {30'b0, (Plus1&AddendStickyM)}}; + assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZManM[`NF-1:0]} - (Minus1&AddendStickyM) + (Plus1&AddendStickyM)} : {{32{1'b1}}, ResultSgn, {ZExpM[7:0], ZManM[51:29]} - {30'b0, (Minus1&AddendStickyM)} + {30'b0, (Plus1&AddendStickyM)}}; assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + (CalcPlus1&(AddendStickyM|FrmM[1])) : {{32{1'b1}}, {ResultSgn, 31'b0} + {31'b0, (CalcPlus1&(AddendStickyM|FrmM[1]))}}; assign FMAResM = XNaNM ? XNaNResult : YNaNM ? YNaNResult : ZNaNM ? ZNaNResult : Invalid ? InvalidResult : // has to be before inf - XInfM ? FmtM ? {PSgn, XExpM, XFracM} : {{32{1'b1}}, PSgn, XExpM[7:0], XFracM[51:29]} : - YInfM ? FmtM ? {PSgn, YExpM, YFracM} : {{32{1'b1}}, PSgn, YExpM[7:0], YFracM[51:29]} : - ZInfM ? FmtM ? {ZSgnM, ZExpM, ZFracM} : {{32{1'b1}}, ZSgnM, ZExpM[7:0], ZFracM[51:29]} : + XInfM ? FmtM ? {PSgn, XExpM, XManM[`NF-1:0]} : {{32{1'b1}}, PSgn, XExpM[7:0], XManM[51:29]} : + YInfM ? FmtM ? {PSgn, YExpM, YManM[`NF-1:0]} : {{32{1'b1}}, PSgn, YExpM[7:0], YManM[51:29]} : + ZInfM ? FmtM ? {ZSgnM, ZExpM, ZManM[`NF-1:0]} : {{32{1'b1}}, ZSgnM, ZExpM[7:0], ZManM[51:29]} : Overflow ? OverflowResult : KillProdM ? KillProdResult : // has to be after Underflow Underflow & ~ResultDenorm ? UnderflowResult : FmtM ? {ResultSgn, ResultExp, ResultFrac} : {{32{1'b1}}, ResultSgn, ResultExp[7:0], ResultFrac[51:29]}; - +// *** use NF where needed endmodule \ No newline at end of file diff --git a/wally-pipelined/src/fpu/fpu.sv b/wally-pipelined/src/fpu/fpu.sv index 7490c0be..6a0c332f 100755 --- a/wally-pipelined/src/fpu/fpu.sv +++ b/wally-pipelined/src/fpu/fpu.sv @@ -73,8 +73,7 @@ module fpu ( // unpacking signals logic XSgnE, YSgnE, ZSgnE; logic [10:0] XExpE, YExpE, ZExpE; - logic [51:0] XFracE, YFracE, ZFracE; - logic XAssumed1E, YAssumed1E, ZAssumed1E; + logic [52:0] XManE, YManE, ZManE; logic XNaNE, YNaNE, ZNaNE; logic XSNaNE, YSNaNE, ZSNaNE; logic XDenormE, YDenormE, ZDenormE; @@ -86,7 +85,7 @@ module fpu ( logic XSgnM, YSgnM, ZSgnM; logic [10:0] XExpM, YExpM, ZExpM; - logic [51:0] XFracM, YFracM, ZFracM; + logic [52:0] XManM, YManM, ZManM; logic XNaNM, YNaNM, ZNaNM; logic XSNaNM, YSNaNM, ZSNaNM; logic XZeroM, YZeroM, ZZeroM; @@ -170,17 +169,17 @@ module fpu ( unpacking unpacking(.X(FSrcXE), .Y(FSrcYE), .Z(FSrcZE), .FOpCtrlE(FOpCtrlE[2:0]), .FmtE, .XSgnE, .YSgnE, - .ZSgnE, .XExpE, .YExpE, .ZExpE, .XFracE, .YFracE, .ZFracE, - .XAssumed1E, .YAssumed1E, .ZAssumed1E, .XNaNE, .YNaNE, .ZNaNE, + .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE, + .XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE, .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .BiasE, .XInfE, .YInfE, .ZInfE, .XExpMaxE, .XNormE); // first of two-stage instance of floating-point fused multiply-add unit fma fma (.clk, .reset, .FlushM, .StallM, - .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XFracE, .YFracE, . - ZFracE, .XAssumed1E, .YAssumed1E, .ZAssumed1E, .XDenormE, .YDenormE, + .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, . + ZManE, .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .BiasE, - .XSgnM, .YSgnM, .ZSgnM, .XExpM, .YExpM, .ZExpM, .XFracM, - .YFracM, .ZFracM, .XNaNM, .YNaNM, .ZNaNM, .XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM, .ZInfM, .XSNaNM, .YSNaNM, .ZSNaNM, + .XSgnM, .YSgnM, .ZSgnM, .XExpM, .YExpM, .ZExpM, .XManM, + .YManM, .ZManM, .XNaNM, .YNaNM, .ZNaNM, .XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM, .ZInfM, .XSNaNM, .YSNaNM, .ZSNaNM, // .FSrcXE, .FSrcYE, .FSrcZE, .FSrcXM, .FSrcYM, .FSrcZM, .FOpCtrlE(FOpCtrlE[2:0]), .FOpCtrlM(FOpCtrlM[2:0]), .FmtE, .FmtM, .FrmM, .FMAFlgM, .FMAResM); @@ -216,17 +215,17 @@ module fpu ( .FSrcXE, .FSrcYE, .FOpCtrlE, .FAddResM, .FAddFlgM); // first and only instance of floating-point comparator - fcmp fcmp (.op1({XSgnE,XExpE,XFracE}), .op2({YSgnE,YExpE,YFracE}), .FSrcXE, + fcmp fcmp (.op1({XSgnE,XExpE,XManE[`NF-1:0]}), .op2({YSgnE,YExpE,YManE[`NF-1:0]}), .FSrcXE, .FSrcYE, .FOpCtrlE(FOpCtrlE[2:0]), .FmtE, .Invalid(CmpNVE), .CmpResE, .XNaNE, .YNaNE, .XZeroE, .YZeroE); // first and only instance of floating-point sign converter - fsgn fsgn (.SgnOpCodeE(FOpCtrlE[1:0]), .XSgnE, .YSgnE, .FSrcXE, /*.XExpE, .XFracE, */.FmtE, .SgnResE, .SgnNVE, .XExpMaxE); + fsgn fsgn (.SgnOpCodeE(FOpCtrlE[1:0]), .XSgnE, .YSgnE, .FSrcXE, .FmtE, .SgnResE, .SgnNVE, .XExpMaxE); // first and only instance of floating-point classify unit fclassify fclassify (.XSgnE, .XDenormE, .XZeroE, .XNaNE, .XInfE, .XNormE, .XSNaNE, .ClassResE); - fcvt fcvt (.XSgnE, .XExpE, .XFracE, .XAssumed1E, .XZeroE, .XNaNE, .XInfE, .XDenormE, .BiasE, .SrcAE, .FOpCtrlE, .FmtE, .FrmE, .CvtResE, .CvtFlgE); + fcvt fcvt (.XSgnE, .XExpE, .XManE, .XZeroE, .XNaNE, .XInfE, .XDenormE, .BiasE, .SrcAE, .FOpCtrlE, .FmtE, .FrmE, .CvtResE, .CvtFlgE); // output for store instructions assign FWriteDataE = FSrcYE[`XLEN-1:0]; @@ -237,9 +236,9 @@ module fpu ( flopenrc #(64) EMFpReg1(clk, reset, FlushM, ~StallM, FSrcXE, FSrcXM); // flopenrc #(64) EMFpReg2(clk, reset, FlushM, ~StallM, FSrcYE, FSrcYM); // flopenrc #(64) EMFpReg3(clk, reset, FlushM, ~StallM, FSrcZE, FSrcZM); - flopenrc #(64) EMFpReg4(clk, reset, FlushM, ~StallM, {XSgnE,XExpE,XFracE}, {XSgnM,XExpM,XFracM}); - flopenrc #(64) EMFpReg5(clk, reset, FlushM, ~StallM, {YSgnE,YExpE,YFracE}, {YSgnM,YExpM,YFracM}); - flopenrc #(64) EMFpReg6(clk, reset, FlushM, ~StallM, {ZSgnE,ZExpE,ZFracE}, {ZSgnM,ZExpM,ZFracM}); + flopenrc #(65) EMFpReg4(clk, reset, FlushM, ~StallM, {XSgnE,XExpE,XManE}, {XSgnM,XExpM,XManM}); + flopenrc #(65) EMFpReg5(clk, reset, FlushM, ~StallM, {YSgnE,YExpE,YManE}, {YSgnM,YExpM,YManM}); + flopenrc #(65) EMFpReg6(clk, reset, FlushM, ~StallM, {ZSgnE,ZExpE,ZManE}, {ZSgnM,ZExpM,ZManM}); flopenrc #(12) EMFpReg7(clk, reset, FlushM, ~StallM, {XZeroE, YZeroE, ZZeroE, XInfE, YInfE, ZInfE, XNaNE, YNaNE, ZNaNE, XSNaNE, YSNaNE, ZSNaNE}, {XZeroM, YZeroM, ZZeroM, XInfM, YInfM, ZInfM, XNaNM, YNaNM, ZNaNM, XSNaNM, YSNaNM, ZSNaNM}); diff --git a/wally-pipelined/src/fpu/unpacking.sv b/wally-pipelined/src/fpu/unpacking.sv index b7d3eabc..4254ea62 100644 --- a/wally-pipelined/src/fpu/unpacking.sv +++ b/wally-pipelined/src/fpu/unpacking.sv @@ -4,8 +4,7 @@ module unpacking ( input logic [2:0] FOpCtrlE, output logic XSgnE, YSgnE, ZSgnE, output logic [10:0] XExpE, YExpE, ZExpE, - output logic [51:0] XFracE, YFracE, ZFracE, - output logic XAssumed1E, YAssumed1E, ZAssumed1E, + output logic [52:0] XManE, YManE, ZManE, output logic XNormE, output logic XNaNE, YNaNE, ZNaNE, output logic XSNaNE, YSNaNE, ZSNaNE, @@ -16,6 +15,8 @@ module unpacking ( output logic XExpMaxE ); //***rename to make significand = 1.frac m = significand + logic [51:0] XFracE, YFracE, ZFracE; + logic XAssumed1E, YAssumed1E, ZAssumed1E; logic XFracZero, YFracZero, ZFracZero; // input fraction zero logic XExpZero, YExpZero, ZExpZero; // input exponent zero logic [63:0] Addend; // value to add (Z or zero) @@ -38,6 +39,10 @@ module unpacking ( assign YAssumed1E = |YExpE; assign ZAssumed1E = |ZExpE; + assign XManE = {XAssumed1E, XFracE}; + assign YManE = {YAssumed1E, YFracE}; + assign ZManE = {ZAssumed1E, ZFracE}; + assign XExpZero = ~XAssumed1E; assign YExpZero = ~YAssumed1E; assign ZExpZero = ~ZAssumed1E;