mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	all FCVT imperas tests pass
This commit is contained in:
		
							parent
							
								
									31d87d459e
								
							
						
					
					
						commit
						1d4ff095cf
					
				| @ -1 +1 @@ | |||||||
| Subproject commit 307c77b26e070ae85ffea665ad9b642b40e33c86 | Subproject commit be67c99bd461742aa1c100bcc0732657faae2230 | ||||||
| @ -1,6 +1,7 @@ | |||||||
| 
 | 
 | ||||||
| `include "wally-config.vh" | `include "wally-config.vh" | ||||||
| // `include "../../config/rv64icfd/wally-config.vh"
 | // `include "../../config/rv64icfd/wally-config.vh"
 | ||||||
|  | //  `define XLEN 64
 | ||||||
| module fcvt ( | module fcvt ( | ||||||
| 	input logic             XSgnE,      // X's sign
 | 	input logic             XSgnE,      // X's sign
 | ||||||
|     input logic [10:0]      XExpE,      // X's exponent
 |     input logic [10:0]      XExpE,      // X's exponent
 | ||||||
| @ -59,7 +60,7 @@ module fcvt ( | |||||||
|       //  fcvt.lu.d = 111
 |       //  fcvt.lu.d = 111
 | ||||||
|       //  fcvt.d.l  = 100
 |       //  fcvt.d.l  = 100
 | ||||||
|       //  fcvt.d.lu = 110
 |       //  fcvt.d.lu = 110
 | ||||||
|       //  {long, unsigned, to int, from int}
 |       //  {long, unsigned, to int}
 | ||||||
|     |     | ||||||
|     // calculate signals based off the input and output's size
 |     // calculate signals based off the input and output's size
 | ||||||
|     assign Res64 = (FOpCtrlE[0]&FOpCtrlE[2]) | (FmtE&~FOpCtrlE[0]); |     assign Res64 = (FOpCtrlE[0]&FOpCtrlE[2]) | (FmtE&~FOpCtrlE[0]); | ||||||
| @ -158,19 +159,24 @@ module fcvt ( | |||||||
| 
 | 
 | ||||||
|     // select the integer result
 |     // select the integer result
 | ||||||
|     assign CvtIntRes = Of ? FOpCtrlE[1] ? {64{1'b1}} : SgnRes ? {33'b0, {31{1'b1}}}: {1'b0, {63{1'b1}}} :  |     assign CvtIntRes = Of ? FOpCtrlE[1] ? {64{1'b1}} : SgnRes ? {33'b0, {31{1'b1}}}: {1'b0, {63{1'b1}}} :  | ||||||
|                     Uf ? FOpCtrlE[1] ? 64'b0 : SgnRes ? {32'b0, 1'b1, 31'b0} : {1'b1, 63'b0} : |                     Uf ? FOpCtrlE[1] ? {63'b0, Plus1&~XSgnE} : SgnRes ? {32'b0, 1'b1, 31'b0} : {1'b1, 63'b0} : | ||||||
| 		            Rounded[64-1:0]; | 		            Rounded[64-1:0]; | ||||||
| 
 | 
 | ||||||
|     // select the floating point result            
 |     // select the floating point result            
 | ||||||
|     assign CvtFPRes = FmtE ? {ResSgn, ResExp, ResFrac} : {{32{1'b1}}, ResSgn, ResExp[7:0], ResFrac[51:29]}; |     assign CvtFPRes = FmtE ? {ResSgn, ResExp, ResFrac} : {{32{1'b1}}, ResSgn, ResExp[7:0], ResFrac[51:29]}; | ||||||
| 
 | 
 | ||||||
|     // select the result
 |     // select the result
 | ||||||
|     assign CvtResE = ~FOpCtrlE[0] ? CvtFPRes : CvtIntRes; |     assign CvtResE = FOpCtrlE[0] ? CvtIntRes : CvtFPRes; | ||||||
| 
 | 
 | ||||||
|     // calculate the flags
 |     // calculate the flags
 | ||||||
|     //      - to int only sets the invalid flag
 |     //      - only set invalid flag for out-of-range vales if it isn't be indicated by the inexact
 | ||||||
|     //      - from int only sets the inexact flag
 |     //      - don't set inexact flag if converting a really large number (closest __ bit integer value is the max value)
 | ||||||
|     assign CvtFlgE = {(Of | Uf)&FOpCtrlE[0], 3'b0, (Guard|Round|Sticky)&~FOpCtrlE[0]}; |     //      - don't set inexact flag if converting negitive or tiny number to unsigned (closest integer value is 0 or 1)
 | ||||||
|  |     logic Invalid, Inexact; | ||||||
|  |     assign Invalid = (Of | Uf)&FOpCtrlE[0]; | ||||||
|  |     assign Inexact = (Guard|Round|Sticky)&~((&FOpCtrlE[1:0]&Uf&~(Plus1&~XSgnE))|(FOpCtrlE[0]&Of)); | ||||||
|  |     assign CvtFlgE = {Invalid&~Inexact, 3'b0, Inexact}; | ||||||
|  |     // assign CvtFlgE = {(Of | Uf)&FOpCtrlE[0], 3'b0, (Guard|Round|Sticky)&~FOpCtrlE[0]};
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -28,7 +28,6 @@ | |||||||
| // `define NE   11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
 | // `define NE   11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
 | ||||||
| // `define NF   52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
 | // `define NF   52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
 | ||||||
| // `define XLEN 64
 | // `define XLEN 64
 | ||||||
| `define NANPAYLOAD 1 |  | ||||||
| module fma( | module fma( | ||||||
|     input logic                 clk, |     input logic                 clk, | ||||||
|     input logic                 reset, |     input logic                 reset, | ||||||
| @ -117,7 +116,6 @@ module fma1( | |||||||
|     logic [3*`NF+5:0]   AlignedAddendE;     // Z aligned for addition in U(NF+5.2NF+1)
 |     logic [3*`NF+5:0]   AlignedAddendE;     // Z aligned for addition in U(NF+5.2NF+1)
 | ||||||
|     logic [3*`NF+6:0]   AlignedAddendInv;   // aligned addend possibly inverted
 |     logic [3*`NF+6:0]   AlignedAddendInv;   // aligned addend possibly inverted
 | ||||||
|     logic [2*`NF+1:0]   ProdManKilled;      // the product's mantissa possibly killed
 |     logic [2*`NF+1:0]   ProdManKilled;      // the product's mantissa possibly killed
 | ||||||
|     logic [3*`NF+4:0]   NegProdManKilled;   // a negated ProdManKilled
 |  | ||||||
|     logic [3*`NF+6:0]   PreSum, NegPreSum;  // positive and negitve versions of the sum
 |     logic [3*`NF+6:0]   PreSum, NegPreSum;  // positive and negitve versions of the sum
 | ||||||
|     logic [`NE-1:0]     XExpVal, YExpVal;   // exponent value after taking into accound denormals
 |     logic [`NE-1:0]     XExpVal, YExpVal;   // exponent value after taking into accound denormals
 | ||||||
|     ///////////////////////////////////////////////////////////////////////////////
 |     ///////////////////////////////////////////////////////////////////////////////
 | ||||||
| @ -321,7 +319,6 @@ module add( | |||||||
|     output logic [3*`NF+6:0]    PreSum, NegPreSum// possibly negitive sum
 |     output logic [3*`NF+6:0]    PreSum, NegPreSum// possibly negitive sum
 | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
|     logic [3*`NF+4:0] NegProdManKilled;  // a negated ProdManKilled
 |  | ||||||
|     ///////////////////////////////////////////////////////////////////////////////
 |     ///////////////////////////////////////////////////////////////////////////////
 | ||||||
|     // Addition
 |     // Addition
 | ||||||
|     ///////////////////////////////////////////////////////////////////////////////
 |     ///////////////////////////////////////////////////////////////////////////////
 | ||||||
| @ -335,15 +332,13 @@ module add( | |||||||
|     assign AlignedAddendInv = InvZE ? {1'b1, ~AlignedAddendE} : {1'b0, AlignedAddendE}; |     assign AlignedAddendInv = InvZE ? {1'b1, ~AlignedAddendE} : {1'b0, AlignedAddendE}; | ||||||
|     // Kill the product if the product is too small to effect the addition (determined in fma1.sv)
 |     // Kill the product if the product is too small to effect the addition (determined in fma1.sv)
 | ||||||
|     assign ProdManKilled = ProdManE&{2*`NF+2{~KillProdE}}; |     assign ProdManKilled = ProdManE&{2*`NF+2{~KillProdE}}; | ||||||
|     // Negate ProdMan for LZA and the negitive sum calculation
 |  | ||||||
|     assign NegProdManKilled = {{`NF+3{~(XZeroE|YZeroE|KillProdE)}}, ~ProdManKilled&{2*`NF+2{~(XZeroE|YZeroE|KillProdE)}}}; |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     // Do the addition
 |     // Do the addition
 | ||||||
|     //      - calculate a positive and negitive sum in parallel
 |     //      - calculate a positive and negitive sum in parallel
 | ||||||
|     assign PreSum = AlignedAddendInv + {55'b0, ProdManKilled, 2'b0} + {{3*`NF+6{1'b0}}, InvZE}; |     assign PreSum = AlignedAddendInv + {55'b0, ProdManKilled, 2'b0} + {{3*`NF+6{1'b0}}, InvZE}; | ||||||
|     assign NegPreSum = AlignedAddendE + {NegProdManKilled, 2'b0} + {{(3*`NF+3){1'b0}},~(XZeroE|YZeroE|KillProdE),2'b0}; |     assign NegPreSum = XZeroE|YZeroE|KillProdE ? {1'b0, AlignedAddendE} : {1'b0, AlignedAddendE} + {{`NF+3{1'b1}}, ~ProdManKilled, 2'b0} + {(3*`NF+7)'(4)}; | ||||||
|       |       | ||||||
|     // Is the sum negitive
 |     // Is the sum negitive
 | ||||||
|     assign NegSumE = PreSum[3*`NF+6]; |     assign NegSumE = PreSum[3*`NF+6]; | ||||||
| @ -360,6 +355,8 @@ module loa( //https://ieeexplore.ieee.org/abstract/document/930098 | |||||||
|     logic [3*`NF+6:0] T; |     logic [3*`NF+6:0] T; | ||||||
|     logic [3*`NF+6:0] G; |     logic [3*`NF+6:0] G; | ||||||
|     logic [3*`NF+6:0] Z; |     logic [3*`NF+6:0] Z; | ||||||
|  |     logic [3*`NF+6:0] f; | ||||||
|  | 
 | ||||||
|     assign T[3*`NF+6:2*`NF+4] = A[3*`NF+6:2*`NF+4]; |     assign T[3*`NF+6:2*`NF+4] = A[3*`NF+6:2*`NF+4]; | ||||||
|     assign G[3*`NF+6:2*`NF+4] = 0; |     assign G[3*`NF+6:2*`NF+4] = 0; | ||||||
|     assign Z[3*`NF+6:2*`NF+4] = ~A[3*`NF+6:2*`NF+4]; |     assign Z[3*`NF+6:2*`NF+4] = ~A[3*`NF+6:2*`NF+4]; | ||||||
| @ -375,7 +372,6 @@ module loa( //https://ieeexplore.ieee.org/abstract/document/930098 | |||||||
|     //      - note: the paper linked above uses the numbering system where 0 is the most significant bit
 |     //      - note: the paper linked above uses the numbering system where 0 is the most significant bit
 | ||||||
|     //f[n] = ~T[n]&T[n-1]           note: n is the MSB
 |     //f[n] = ~T[n]&T[n-1]           note: n is the MSB
 | ||||||
|     //f[i] = (T[i+1]&(G[i]&~Z[i-1] | Z[i]&~G[i-1])) | (~T[i+1]&(Z[i]&~Z[i-1] | G[i]&~G[i-1]))
 |     //f[i] = (T[i+1]&(G[i]&~Z[i-1] | Z[i]&~G[i-1])) | (~T[i+1]&(Z[i]&~Z[i-1] | G[i]&~G[i-1]))
 | ||||||
|     logic [3*`NF+6:0] f; |  | ||||||
|     assign f[3*`NF+6] = ~T[3*`NF+6]&T[3*`NF+5]; |     assign f[3*`NF+6] = ~T[3*`NF+6]&T[3*`NF+5]; | ||||||
|     assign f[3*`NF+5:0] = (T[3*`NF+6:1]&(G[3*`NF+5:0]&{~Z[3*`NF+4:0], 1'b0} | Z[3*`NF+5:0]&{~G[3*`NF+4:0], 1'b1})) | (~T[3*`NF+6:1]&(Z[3*`NF+5:0]&{~Z[3*`NF+4:0], 1'b0} | G[3*`NF+5:0]&{~G[3*`NF+4:0], 1'b1})); |     assign f[3*`NF+5:0] = (T[3*`NF+6:1]&(G[3*`NF+5:0]&{~Z[3*`NF+4:0], 1'b0} | Z[3*`NF+5:0]&{~G[3*`NF+4:0], 1'b1})) | (~T[3*`NF+6:1]&(Z[3*`NF+5:0]&{~Z[3*`NF+4:0], 1'b0} | G[3*`NF+5:0]&{~G[3*`NF+4:0], 1'b1})); | ||||||
| 
 | 
 | ||||||
| @ -440,11 +436,12 @@ module fma2( | |||||||
|     logic               SumZero;        // is the sum zero
 |     logic               SumZero;        // is the sum zero
 | ||||||
|     logic               ResultDenorm;   // is the result denormalized
 |     logic               ResultDenorm;   // is the result denormalized
 | ||||||
|     logic               Sticky, UfSticky;           // Sticky bit
 |     logic               Sticky, UfSticky;           // Sticky bit
 | ||||||
|     logic               Plus1, Minus1, CalcPlus1;   // do you add or subtract one for rounding
 |     logic               CalcPlus1;                  // do you add or subtract one for rounding
 | ||||||
|     logic               UfPlus1;                    // do you add one (for determining underflow flag)
 |     logic               UfPlus1;                    // do you add one (for determining underflow flag)
 | ||||||
|     logic               Invalid,Underflow,Overflow; // flags
 |     logic               Invalid,Underflow,Overflow; // flags
 | ||||||
|     logic               Guard, Round;   // bits needed to determine rounding
 |     logic               Guard, Round;   // bits needed to determine rounding
 | ||||||
|     logic               UfLSBNormSum;   // bits needed to determine rounding for underflow flag
 |     logic               UfLSBNormSum;   // bits needed to determine rounding for underflow flag
 | ||||||
|  |     logic [`FLEN:0]     RoundAdd;       // how much to add to the result
 | ||||||
|     |     | ||||||
|      |      | ||||||
| 
 | 
 | ||||||
| @ -471,7 +468,7 @@ module fma2( | |||||||
|     // round to nearest max magnitude
 |     // round to nearest max magnitude
 | ||||||
| 
 | 
 | ||||||
|     fmaround fmaround(.FmtM, .FrmM, .Sticky, .UfSticky, .NormSum, .AddendStickyM, .NormSumSticky, .ZZeroM, .InvZM, .ResultSgnTmp, .SumExp, |     fmaround fmaround(.FmtM, .FrmM, .Sticky, .UfSticky, .NormSum, .AddendStickyM, .NormSumSticky, .ZZeroM, .InvZM, .ResultSgnTmp, .SumExp, | ||||||
|         .CalcPlus1, .Plus1, .UfPlus1, .Minus1, .FullResultExp, .ResultFrac, .ResultExp, .Round, .Guard, .UfLSBNormSum); |         .CalcPlus1, .UfPlus1, .FullResultExp, .ResultFrac, .ResultExp, .Round, .Guard, .RoundAdd, .UfLSBNormSum); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -503,8 +500,8 @@ module fma2( | |||||||
|     ///////////////////////////////////////////////////////////////////////////////
 |     ///////////////////////////////////////////////////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
|     resultselect resultselect(.XSgnM, .YSgnM, .XExpM, .YExpM, .ZExpM, .XManM, .YManM, .ZManM,  |     resultselect resultselect(.XSgnM, .YSgnM, .XExpM, .YExpM, .ZExpM, .XManM, .YManM, .ZManM,  | ||||||
|         .FrmM, .FmtM, .AddendStickyM, .KillProdM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM,  |         .FrmM, .FmtM, .AddendStickyM, .KillProdM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .RoundAdd, | ||||||
|         .ZSgnEffM, .PSgnM, .ResultSgn, .Minus1, .Plus1, .CalcPlus1, .Invalid, .Overflow, .Underflow,  |         .ZSgnEffM, .PSgnM, .ResultSgn, .CalcPlus1, .Invalid, .Overflow, .Underflow,  | ||||||
|         .ResultDenorm, .ResultExp, .ResultFrac, .FMAResM); |         .ResultDenorm, .ResultExp, .ResultFrac, .FMAResM); | ||||||
| 
 | 
 | ||||||
| // *** use NF where needed
 | // *** use NF where needed
 | ||||||
| @ -539,61 +536,6 @@ module resultsign( | |||||||
| 
 | 
 | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module resultselect( |  | ||||||
|     input logic                 XSgnM, YSgnM,        // input signs
 |  | ||||||
|     input logic     [`NE-1:0]   XExpM, YExpM, ZExpM, // input exponents
 |  | ||||||
|     input logic     [`NF:0]     XManM, YManM, ZManM, // input mantissas
 |  | ||||||
|     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                 FmtM,       // precision 1 = double 0 = single
 |  | ||||||
|     input logic                 AddendStickyM,  // sticky bit that is calculated during alignment
 |  | ||||||
|     input logic                 KillProdM,      // set the product to zero before addition if the product is too small to matter
 |  | ||||||
|     input logic                 XInfM, YInfM, ZInfM,    // inputs are infinity
 |  | ||||||
|     input logic                 XNaNM, YNaNM, ZNaNM,    // inputs are NaN
 |  | ||||||
|     input logic                 ZSgnEffM,   // the modified Z sign - depends on instruction
 |  | ||||||
|     input logic                 PSgnM,      // the product's sign
 |  | ||||||
|     input logic                 ResultSgn,  // the result's sign
 |  | ||||||
|     input logic                 Minus1, Plus1, CalcPlus1, // rounding bits
 |  | ||||||
|     input logic                 Invalid, Overflow, Underflow,  // flags
 |  | ||||||
|     input logic                 ResultDenorm,       // is the result denormalized
 |  | ||||||
|     input logic     [`NE-1:0]   ResultExp,          // Result exponent
 |  | ||||||
|     input logic     [`NF-1:0]   ResultFrac,         // Result fraction
 |  | ||||||
|     output logic    [`FLEN-1:0] FMAResM     // FMA final result
 |  | ||||||
| ); |  | ||||||
|     logic [`FLEN-1:0]   XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results
 |  | ||||||
| 
 |  | ||||||
|     generate if(`NANPAYLOAD) begin |  | ||||||
|         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 ? {ZSgnEffM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, ZManM[50:29]}; |  | ||||||
|     end else begin |  | ||||||
|         assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, 51'b0} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, 22'b0}; |  | ||||||
|         assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, 51'b0} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, 22'b0}; |  | ||||||
|         assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, 51'b0} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, 22'b0}; |  | ||||||
|     end |  | ||||||
|     endgenerate |  | ||||||
|      |  | ||||||
|      |  | ||||||
|     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, ZManM[`NF-1:0]} - {62'b0, (Minus1&AddendStickyM)} + {62'b0, (Plus1&AddendStickyM)}} : {{32{1'b1}}, ResultSgn, {ZExpM[`NE-1],ZExpM[6:0], ZManM[51:29]} - {30'b0, (Minus1&AddendStickyM)} + {30'b0, (Plus1&AddendStickyM)}}; |  | ||||||
|     assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + {63'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 : |  | ||||||
|                         XInfM ? FmtM ? {PSgnM, XExpM, XManM[`NF-1:0]} : {{32{1'b1}}, PSgnM,  XExpM[7:0], XManM[51:29]} :  |  | ||||||
|                         YInfM ? FmtM ? {PSgnM, YExpM, YManM[`NF-1:0]} : {{32{1'b1}}, PSgnM,  YExpM[7:0], YManM[51:29]} : |  | ||||||
|                         ZInfM ? FmtM ? {ZSgnEffM, ZExpM, ZManM[`NF-1:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], ZManM[51:29]} : |  | ||||||
|                         KillProdM ? KillProdResult :   |  | ||||||
| 			            Overflow ? OverflowResult : |  | ||||||
|                         Underflow & ~ResultDenorm & (ResultExp!=1) ? UnderflowResult :   |  | ||||||
|                         FmtM ? {ResultSgn, ResultExp, ResultFrac} : |  | ||||||
|                                {{32{1'b1}}, ResultSgn, ResultExp[7:0], ResultFrac[51:29]}; |  | ||||||
| 
 |  | ||||||
| endmodule |  | ||||||
| 
 | 
 | ||||||
| module normalize( | module normalize( | ||||||
|     input logic  [3*`NF+5:0]    SumM,       // the positive sum
 |     input logic  [3*`NF+5:0]    SumM,       // the positive sum
 | ||||||
| @ -624,19 +566,6 @@ module normalize( | |||||||
|     // Normalization
 |     // Normalization
 | ||||||
|     ///////////////////////////////////////////////////////////////////////////////
 |     ///////////////////////////////////////////////////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     // logic [8:0] supposedNormCnt;
 |  | ||||||
|     // logic [8:0] i;
 |  | ||||||
|     // always_comb begin
 |  | ||||||
|     //         i = 0;
 |  | ||||||
|     //         while (~SumM[3*`NF+5-i] && $unsigned(i) <= $unsigned(3*`NF+5)) i = i+1;  // search for leading one
 |  | ||||||
|     //         supposedNormCnt = i;    // compute shift count
 |  | ||||||
|     // end
 |  | ||||||
| 
 |  | ||||||
|     // always_comb begin
 |  | ||||||
|     //     assert (NormCntM == supposedNormCnt | NormCntM == supposedNormCnt+1 | NormCntM == supposedNormCnt+2) else $fatal ("normcnt not expected");
 |  | ||||||
|     // end
 |  | ||||||
| 
 |  | ||||||
|     // Determine if the sum is zero
 |     // Determine if the sum is zero
 | ||||||
|     assign SumZero = ~(|SumM); |     assign SumZero = ~(|SumM); | ||||||
| 
 | 
 | ||||||
| @ -644,18 +573,15 @@ module normalize( | |||||||
|     assign FracLen = FmtM ? `NF+1 : 13'd24; |     assign FracLen = FmtM ? `NF+1 : 13'd24; | ||||||
| 
 | 
 | ||||||
|     // calculate the sum's exponent
 |     // calculate the sum's exponent
 | ||||||
|     assign SumExpTmpTmp = KillProdM ? {2'b0, ZExpM} : ProdExpM + -({4'b0, NormCntM} + 1 - (`NF+4)); // ****try moving this into previous stage
 |     assign SumExpTmpTmp = KillProdM ? {2'b0, ZExpM} : ProdExpM + -({4'b0, NormCntM} + 1 - (`NF+4)); | ||||||
|     assign SumExpTmp = FmtM ? SumExpTmpTmp : (SumExpTmpTmp-1023+127)&{`NE+2{|SumExpTmpTmp}}; // ***move this ^ the subtraction by a constant isn't simplified
 |     assign SumExpTmp = FmtM ? SumExpTmpTmp : (SumExpTmpTmp-1023+127)&{`NE+2{|SumExpTmpTmp}}; | ||||||
|      |      | ||||||
|     logic SumDLTEZ, SumDGEFL, SumSLTEZ, SumSGEFL; |     logic SumDLTEZ, SumDGEFL, SumSLTEZ, SumSGEFL; | ||||||
|     assign SumDLTEZ = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp; |     assign SumDLTEZ = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp; | ||||||
|     assign SumDGEFL = ($signed(SumExpTmpTmp)>=$signed(-(13'd`NF+13'd1))); |     assign SumDGEFL = ($signed(SumExpTmpTmp)>=$signed(-(13'd`NF+13'd2))); | ||||||
|     assign SumSLTEZ = $signed(SumExpTmpTmp) <= $signed(13'd1023-13'd127); |     assign SumSLTEZ = $signed(SumExpTmpTmp) <= $signed(13'd1023-13'd127); | ||||||
|     assign SumSGEFL = ($signed(SumExpTmpTmp)>=$signed(-13'd24+13'd1023-13'd127)) | ~|SumExpTmpTmp; |     assign SumSGEFL = ($signed(SumExpTmpTmp)>=$signed(-13'd25+13'd1023-13'd127)) | ~|SumExpTmpTmp; | ||||||
|     assign PreResultDenorm2 = (FmtM ? SumDLTEZ : SumSLTEZ) & (FmtM ? SumDGEFL : SumSGEFL) & ~SumZero; //***make sure math good
 |     assign PreResultDenorm2 = (FmtM ? SumDLTEZ : SumSLTEZ) & (FmtM ? SumDGEFL : SumSGEFL) & ~SumZero; | ||||||
|     // always_comb begin
 |  | ||||||
|     //     assert (PreResultDenorm == PreResultDenorm2) else $fatal ("PreResultDenorms not equal");
 |  | ||||||
|     // end
 |  | ||||||
| 
 | 
 | ||||||
|     // 010. when should be 001.
 |     // 010. when should be 001.
 | ||||||
|     //      - shift left one
 |     //      - shift left one
 | ||||||
| @ -667,9 +593,9 @@ module normalize( | |||||||
| 
 | 
 | ||||||
|     // Determine the shift needed for denormal results
 |     // Determine the shift needed for denormal results
 | ||||||
|     //  - if not denorm add 1 to shift out the leading 1
 |     //  - if not denorm add 1 to shift out the leading 1
 | ||||||
|     assign DenormShift = PreResultDenorm2 ? SumExpTmp[8:0] : 1; //*** change this when changing the size of DenormShift also change to an and opperation
 |     assign DenormShift = PreResultDenorm2 ? SumExpTmp[8:0] : 1; | ||||||
|     // Normalize the sum
 |     // Normalize the sum
 | ||||||
|     assign SumShifted = {3'b0, SumM} << NormCntM+DenormShift; //*** fix mux's with constants in them //***NormCnt can be simplified
 |     assign SumShifted = {3'b0, SumM} << NormCntM+DenormShift; | ||||||
|     // LZA correction
 |     // LZA correction
 | ||||||
|     assign LZAPlus1 = SumShifted[3*`NF+7]; |     assign LZAPlus1 = SumShifted[3*`NF+7]; | ||||||
|     assign LZAPlus2 = SumShifted[3*`NF+8]; |     assign LZAPlus2 = SumShifted[3*`NF+8]; | ||||||
| @ -699,18 +625,18 @@ module fmaround( | |||||||
|     input logic             InvZM,          // invert Z
 |     input logic             InvZM,          // invert Z
 | ||||||
|     input logic  [`NE+1:0]  SumExp,         // exponent of the normalized sum
 |     input logic  [`NE+1:0]  SumExp,         // exponent of the normalized sum
 | ||||||
|     input logic             ResultSgnTmp,      // the result's sign
 |     input logic             ResultSgnTmp,      // the result's sign
 | ||||||
|     output logic            CalcPlus1, Plus1, UfPlus1, Minus1,  // do you add or subtract on from the result
 |     output logic            CalcPlus1, UfPlus1,  // do you add or subtract on from the result
 | ||||||
|     output logic [`NE+1:0]  FullResultExp,      // ResultExp with bits to determine sign and overflow
 |     output logic [`NE+1:0]  FullResultExp,      // ResultExp with bits to determine sign and overflow
 | ||||||
|     output logic [`NF-1:0]  ResultFrac,         // Result fraction
 |     output logic [`NF-1:0]  ResultFrac,         // Result fraction
 | ||||||
|     output logic [`NE-1:0]  ResultExp,          // Result exponent
 |     output logic [`NE-1:0]  ResultExp,          // Result exponent
 | ||||||
|     output logic            Sticky,             // sticky bit
 |     output logic            Sticky,             // sticky bit
 | ||||||
|  |     output logic [`FLEN:0]  RoundAdd,           // how much to add to the result
 | ||||||
|     output logic            Round, Guard, UfLSBNormSum // bits needed to calculate rounding
 |     output logic            Round, Guard, UfLSBNormSum // bits needed to calculate rounding
 | ||||||
| ); | ); | ||||||
|     logic           LSBNormSum;         // bit used for rounding - least significant bit of the normalized sum
 |     logic           LSBNormSum;         // bit used for rounding - least significant bit of the normalized sum
 | ||||||
|     logic           SubBySmallNum, UfSubBySmallNum;  // was there supposed to be a subtraction by a small number
 |     logic           SubBySmallNum, UfSubBySmallNum;  // was there supposed to be a subtraction by a small number
 | ||||||
|     logic           UfGuard;            // gaurd bit used to caluculate underflow
 |     logic           UfGuard;            // guard bit used to caluculate underflow
 | ||||||
|     logic           UfCalcPlus1, CalcMinus1;    // do you add or subtract on from the result
 |     logic           UfCalcPlus1, CalcMinus1, Plus1, Minus1; // do you add or subtract on from the result
 | ||||||
|     logic [`FLEN:0] RoundAdd;           // how much to add to the result
 |  | ||||||
|     logic [`NF-1:0] NormSumTruncated;   // the normalized sum trimed to fit the mantissa
 |     logic [`NF-1:0] NormSumTruncated;   // the normalized sum trimed to fit the mantissa
 | ||||||
|     logic           UfRound; |     logic           UfRound; | ||||||
| 
 | 
 | ||||||
| @ -858,3 +784,61 @@ module fmaflags( | |||||||
|     assign FMAFlgM = {Invalid, 1'b0, Overflow, UnderflowFlag, Inexact}; |     assign FMAFlgM = {Invalid, 1'b0, Overflow, UnderflowFlag, Inexact}; | ||||||
| 
 | 
 | ||||||
| endmodule | endmodule | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module resultselect( | ||||||
|  |     input logic                 XSgnM, YSgnM,        // input signs
 | ||||||
|  |     input logic     [`NE-1:0]   XExpM, YExpM, ZExpM, // input exponents
 | ||||||
|  |     input logic     [`NF:0]     XManM, YManM, ZManM, // input mantissas
 | ||||||
|  |     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                 FmtM,       // precision 1 = double 0 = single
 | ||||||
|  |     input logic                 AddendStickyM,  // sticky bit that is calculated during alignment
 | ||||||
|  |     input logic                 KillProdM,      // set the product to zero before addition if the product is too small to matter
 | ||||||
|  |     input logic                 XInfM, YInfM, ZInfM,    // inputs are infinity
 | ||||||
|  |     input logic                 XNaNM, YNaNM, ZNaNM,    // inputs are NaN
 | ||||||
|  |     input logic                 ZSgnEffM,   // the modified Z sign - depends on instruction
 | ||||||
|  |     input logic                 PSgnM,      // the product's sign
 | ||||||
|  |     input logic                 ResultSgn,  // the result's sign
 | ||||||
|  |     input logic                 CalcPlus1,  // rounding bits
 | ||||||
|  |     input logic     [`FLEN:0]   RoundAdd,   // how much to add to the result
 | ||||||
|  |     input logic                 Invalid, Overflow, Underflow,  // flags
 | ||||||
|  |     input logic                 ResultDenorm,       // is the result denormalized
 | ||||||
|  |     input logic     [`NE-1:0]   ResultExp,          // Result exponent
 | ||||||
|  |     input logic     [`NF-1:0]   ResultFrac,         // Result fraction
 | ||||||
|  |     output logic    [`FLEN-1:0] FMAResM     // FMA final result
 | ||||||
|  | ); | ||||||
|  |     logic [`FLEN-1:0]   XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results
 | ||||||
|  | 
 | ||||||
|  |     generate if(`IEEE754) begin | ||||||
|  |         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 ? {ZSgnEffM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, ZManM[50:29]}; | ||||||
|  |     end else begin | ||||||
|  |         assign XNaNResult = FmtM ? {1'b0, XExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpM[7:0], 1'b1, 22'b0}; | ||||||
|  |         assign YNaNResult = FmtM ? {1'b0, YExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, YExpM[7:0], 1'b1, 22'b0}; | ||||||
|  |         assign ZNaNResult = FmtM ? {1'b0, ZExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, ZExpM[7:0], 1'b1, 22'b0}; | ||||||
|  |     end | ||||||
|  |     endgenerate | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     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, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})} : {{32{1'b1}}, ResultSgn, {ZExpM[`NE-1],ZExpM[6:0], ZManM[51:29]} + (RoundAdd[59:29]&{31{AddendStickyM}})}; | ||||||
|  |     assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + {63'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 : | ||||||
|  |                         XInfM ? FmtM ? {PSgnM, XExpM, XManM[`NF-1:0]} : {{32{1'b1}}, PSgnM,  XExpM[7:0], XManM[51:29]} :  | ||||||
|  |                         YInfM ? FmtM ? {PSgnM, YExpM, YManM[`NF-1:0]} : {{32{1'b1}}, PSgnM,  YExpM[7:0], YManM[51:29]} : | ||||||
|  |                         ZInfM ? FmtM ? {ZSgnEffM, ZExpM, ZManM[`NF-1:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], ZManM[51:29]} : | ||||||
|  |                         KillProdM ? KillProdResult :   | ||||||
|  | 			            Overflow ? OverflowResult : | ||||||
|  |                         Underflow & ~ResultDenorm & (ResultExp!=1) ? UnderflowResult :   | ||||||
|  |                         FmtM ? {ResultSgn, ResultExp, ResultFrac} : | ||||||
|  |                                {{32{1'b1}}, ResultSgn, ResultExp[7:0], ResultFrac[51:29]}; | ||||||
|  | 
 | ||||||
|  | endmodule | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user