Merge branch 'main' of github.com:davidharrishmc/riscv-wally

This commit is contained in:
Ross Thompson 2023-01-06 15:16:00 -06:00
commit f119b492bb
31 changed files with 234 additions and 282 deletions

View File

@ -43,11 +43,6 @@
`define COUNTERS 32 `define COUNTERS 32
`define DESIGN_COMPILER 0 `define DESIGN_COMPILER 0
// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
// LSU microarchitectural Features // LSU microarchitectural Features
`define BUS 1 `define BUS 1
`define DCACHE 1 `define DCACHE 1

View File

@ -45,11 +45,6 @@
`define COUNTERS 32 `define COUNTERS 32
`define DESIGN_COMPILER 0 `define DESIGN_COMPILER 0
// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
// LSU microarchitectural Features // LSU microarchitectural Features
`define BUS 1 `define BUS 1
`define DCACHE 1 `define DCACHE 1

View File

@ -45,10 +45,6 @@
`define ZICOUNTERS_SUPPORTED 0 `define ZICOUNTERS_SUPPORTED 0
`define ZFH_SUPPORTED 0 `define ZFH_SUPPORTED 0
// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
// LSU microarchitectural Features // LSU microarchitectural Features
`define BUS 1 `define BUS 1
`define DCACHE 0 `define DCACHE 0

View File

@ -44,10 +44,6 @@
`define ZICOUNTERS_SUPPORTED 1 `define ZICOUNTERS_SUPPORTED 1
`define ZFH_SUPPORTED 0 `define ZFH_SUPPORTED 0
// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
// LSU microarchitectural Features // LSU microarchitectural Features
`define BUS 1 `define BUS 1
`define DCACHE 1 `define DCACHE 1
@ -75,7 +71,7 @@
`define IDIV_ON_FPU 1 `define IDIV_ON_FPU 1
// Legal number of PMP entries are 0, 16, or 64 // Legal number of PMP entries are 0, 16, or 64
`define PMP_ENTRIES 64 `define PMP_ENTRIES 16
// Address space // Address space
`define RESET_VECTOR 32'h80000000 `define RESET_VECTOR 32'h80000000

View File

@ -45,10 +45,6 @@
`define ZICOUNTERS_SUPPORTED 0 `define ZICOUNTERS_SUPPORTED 0
`define ZFH_SUPPORTED 0 `define ZFH_SUPPORTED 0
// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
// LSU microarchitectural Features // LSU microarchitectural Features
`define BUS 0 `define BUS 0
`define DCACHE 0 `define DCACHE 0

View File

@ -44,10 +44,6 @@
`define ZICOUNTERS_SUPPORTED 1 `define ZICOUNTERS_SUPPORTED 1
`define ZFH_SUPPORTED 0 `define ZFH_SUPPORTED 0
// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
// LSU microarchitectural Features // LSU microarchitectural Features
`define BUS 1 `define BUS 1
`define DCACHE 0 `define DCACHE 0

View File

@ -38,7 +38,6 @@
// IEEE 754 compliance // IEEE 754 compliance
`define IEEE754 0 `define IEEE754 0
//`define MISA (32'h00000105)
`define MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) `define MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0)
`define ZICSR_SUPPORTED 1 `define ZICSR_SUPPORTED 1
`define ZIFENCEI_SUPPORTED 1 `define ZIFENCEI_SUPPORTED 1
@ -46,10 +45,6 @@
`define ZICOUNTERS_SUPPORTED 1 `define ZICOUNTERS_SUPPORTED 1
`define ZFH_SUPPORTED 0 `define ZFH_SUPPORTED 0
// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
// LSU microarchitectural Features // LSU microarchitectural Features
`define BUS 1 `define BUS 1
`define DCACHE 1 `define DCACHE 1

View File

@ -45,11 +45,6 @@
`define ZICOUNTERS_SUPPORTED 1 `define ZICOUNTERS_SUPPORTED 1
`define ZFH_SUPPORTED 1 `define ZFH_SUPPORTED 1
/// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
// LSU microarchitectural Features // LSU microarchitectural Features
`define BUS 1 `define BUS 1
`define DCACHE 1 `define DCACHE 1

View File

@ -45,11 +45,6 @@
`define ZICOUNTERS_SUPPORTED 1 `define ZICOUNTERS_SUPPORTED 1
`define ZFH_SUPPORTED 0 `define ZFH_SUPPORTED 0
/// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
// LSU microarchitectural Features // LSU microarchitectural Features
`define BUS 1 `define BUS 1
`define DCACHE 1 `define DCACHE 1
@ -77,7 +72,7 @@
`define IDIV_ON_FPU 1 `define IDIV_ON_FPU 1
// Legal number of PMP entries are 0, 16, or 64 // Legal number of PMP entries are 0, 16, or 64
`define PMP_ENTRIES 64 `define PMP_ENTRIES 16
// Address space // Address space
`define RESET_VECTOR 64'h0000000080000000 `define RESET_VECTOR 64'h0000000080000000

View File

@ -45,11 +45,6 @@
`define ZICOUNTERS_SUPPORTED 0 `define ZICOUNTERS_SUPPORTED 0
`define ZFH_SUPPORTED 0 `define ZFH_SUPPORTED 0
// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
// LSU microarchitectural Features // LSU microarchitectural Features
`define BUS 0 `define BUS 0
`define DCACHE 0 `define DCACHE 0

View File

@ -23,8 +23,8 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// division constants // division constants
`define RADIX 32'h2 `define RADIX 32'h4
`define DIVCOPIES 32'h1 `define DIVCOPIES 32'h2
// Memory synthesis configuration // Memory synthesis configuration
`define USE_SRAM 0 `define USE_SRAM 0

View File

@ -33,38 +33,38 @@ module fclassify (
input logic Xs, // sign bit input logic Xs, // sign bit
input logic XNaN, // is NaN input logic XNaN, // is NaN
input logic XSNaN, // is signaling NaN input logic XSNaN, // is signaling NaN
input logic XDenorm,// is denormal input logic XSubnorm,// is Subnormal
input logic XZero, // is zero input logic XZero, // is zero
input logic XInf, // is infinity input logic XInf, // is infinity
output logic [`XLEN-1:0] ClassRes// classify result output logic [`XLEN-1:0] ClassRes// classify result
); );
logic PInf, PZero, PNorm, PDenorm; logic PInf, PZero, PNorm, PSubnorm;
logic NInf, NZero, NNorm, NDenorm; logic NInf, NZero, NNorm, NSubnorm;
logic XNorm; logic XNorm;
// determine the sub categories // determine the sub categories
assign XNorm= ~(XNaN | XInf| XDenorm| XZero); assign XNorm= ~(XNaN | XInf| XSubnorm| XZero);
assign PInf = ~Xs&XInf; assign PInf = ~Xs&XInf;
assign NInf = Xs&XInf; assign NInf = Xs&XInf;
assign PNorm = ~Xs&XNorm; assign PNorm = ~Xs&XNorm;
assign NNorm = Xs&XNorm; assign NNorm = Xs&XNorm;
assign PDenorm = ~Xs&XDenorm; assign PSubnorm = ~Xs&XSubnorm;
assign NDenorm = Xs&XDenorm; assign NSubnorm = Xs&XSubnorm;
assign PZero = ~Xs&XZero; assign PZero = ~Xs&XZero;
assign NZero = Xs&XZero; assign NZero = Xs&XZero;
// determine sub category and combine into the result // determine sub category and combine into the result
// bit 0 - -Inf // bit 0 - -Inf
// bit 1 - -Norm // bit 1 - -Norm
// bit 2 - -Denorm // bit 2 - -Subnorm
// bit 3 - -Zero // bit 3 - -Zero
// bit 4 - +Zero // bit 4 - +Zero
// bit 5 - +Denorm // bit 5 - +Subnorm
// bit 6 - +Norm // bit 6 - +Norm
// bit 7 - +Inf // bit 7 - +Inf
// bit 8 - signaling NaN // bit 8 - signaling NaN
// bit 9 - quiet NaN // bit 9 - quiet NaN
assign ClassRes = {{`XLEN-10{1'b0}}, XNaN&~XSNaN, XSNaN, PInf, PNorm, PDenorm, PZero, NZero, NDenorm, NNorm, NInf}; assign ClassRes = {{`XLEN-10{1'b0}}, XNaN&~XSNaN, XSNaN, PInf, PNorm, PSubnorm, PZero, NZero, NSubnorm, NNorm, NInf};
endmodule endmodule

View File

@ -39,11 +39,11 @@ module fcvt (
input logic [2:0] OpCtrl, // choose which opperation (look below for values) input logic [2:0] OpCtrl, // choose which opperation (look below for values)
input logic ToInt, // is fp->int (since it's writting to the integer register) input logic ToInt, // is fp->int (since it's writting to the integer register)
input logic XZero, // is the input zero input logic XZero, // is the input zero
input logic XDenorm, // is the input denormalized input logic XSubnorm, // is the input Subnormalized
input logic [`FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half) input logic [`FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half)
output logic [`NE:0] Ce, // the calculated expoent output logic [`NE:0] Ce, // the calculated expoent
output logic [`LOGCVTLEN-1:0] ShiftAmt, // how much to shift by output logic [`LOGCVTLEN-1:0] ShiftAmt, // how much to shift by
output logic ResDenormUf,// does the result underflow or is denormalized output logic ResSubnormUf, // does the result underflow or is Subnormalized
output logic Cs, // the result's sign output logic Cs, // the result's sign
output logic IntZero, // is the integer zero? output logic IntZero, // is the integer zero?
output logic [`CVTLEN-1:0] LzcIn // input to the Leading Zero Counter (priority encoder) output logic [`CVTLEN-1:0] LzcIn // input to the Leading Zero Counter (priority encoder)
@ -165,7 +165,7 @@ module fcvt (
// calculate CalcExp // calculate CalcExp
// fp -> fp : // fp -> fp :
// - XExp - Largest bias + new bias - (LeadingZeros+1) // - XExp - Largest bias + new bias - (LeadingZeros+1)
// only do ^ if the input was denormalized // only do ^ if the input was Subnormalized
// - convert the expoenent to the final preciaion (Exp - oldBias + newBias) // - convert the expoenent to the final preciaion (Exp - oldBias + newBias)
// - correct the expoent when there is a normalization shift ( + LeadingZeros+1) // - correct the expoent when there is a normalization shift ( + LeadingZeros+1)
// - the plus 1 is built into the leading zeros by counting the leading zeroes in the mantissa rather than the fraction // - the plus 1 is built into the leading zeros by counting the leading zeroes in the mantissa rather than the fraction
@ -183,7 +183,7 @@ module fcvt (
// | 0's | Mantissa | 0's if nessisary | // | 0's | Mantissa | 0's if nessisary |
// | keep | // | keep |
// //
// - if the input is denormalized then we dont shift... so the "- LeadingZeros" is just leftovers from other options // - if the input is Subnormalized then we dont shift... so the "- LeadingZeros" is just leftovers from other options
// int -> fp : largest bias + XLEN-1 - Largest bias + new bias - LeadingZeros = XLEN-1 + NewBias - LeadingZeros // int -> fp : largest bias + XLEN-1 - Largest bias + new bias - LeadingZeros = XLEN-1 + NewBias - LeadingZeros
// Process: // Process:
// |XLEN|.0000 // |XLEN|.0000
@ -200,7 +200,7 @@ module fcvt (
// find if the result is dnormal or underflows // find if the result is dnormal or underflows
// - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0) // - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0)
// - can't underflow an integer to Fp conversion // - can't underflow an integer to Fp conversion
assign ResDenormUf = (~|Ce | Ce[`NE])&~XZero&~IntToFp; assign ResSubnormUf = (~|Ce | Ce[`NE])&~XZero&~IntToFp;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -211,17 +211,17 @@ module fcvt (
// select the amount to shift by // select the amount to shift by
// fp -> int: // fp -> int:
// - shift left by CalcExp - essentially shifting until the unbiased exponent = 0 // - shift left by CalcExp - essentially shifting until the unbiased exponent = 0
// - don't shift if supposed to shift right (underflowed or denorm input) // - don't shift if supposed to shift right (underflowed or Subnorm input)
// denormalized/undeflowed result fp -> fp: // Subnormalized/undeflowed result fp -> fp:
// - shift left by NF-1+CalcExp - to shift till the biased expoenent is 0 // - shift left by NF-1+CalcExp - to shift till the biased expoenent is 0
// ??? -> fp: // ??? -> fp:
// - shift left by LeadingZeros - to shift till the result is normalized // - shift left by LeadingZeros - to shift till the result is normalized
// - only shift fp -> fp if the intital value is denormalized // - only shift fp -> fp if the intital value is Subnormalized
// - this is a problem because the input to the lzc was the fraction rather than the mantissa // - this is a problem because the input to the lzc was the fraction rather than the mantissa
// - rather have a few and-gates than an extra bit in the priority encoder??? *** is this true? // - rather have a few and-gates than an extra bit in the priority encoder??? *** is this true?
always_comb//***change denorm to subnorm always_comb
if(ToInt) ShiftAmt = Ce[`LOGCVTLEN-1:0]&{`LOGCVTLEN{~Ce[`NE]}}; if(ToInt) ShiftAmt = Ce[`LOGCVTLEN-1:0]&{`LOGCVTLEN{~Ce[`NE]}};
else if (ResDenormUf) ShiftAmt = (`LOGCVTLEN)'(`NF-1)+Ce[`LOGCVTLEN-1:0]; else if (ResSubnormUf) ShiftAmt = (`LOGCVTLEN)'(`NF-1)+Ce[`LOGCVTLEN-1:0];
else ShiftAmt = LeadingZeros; else ShiftAmt = LeadingZeros;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// sign // sign

View File

@ -70,7 +70,7 @@ module fdivsqrtexpcalc(
assign SXExp = {2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - (`NE+2)'(`BIAS); assign SXExp = {2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - (`NE+2)'(`BIAS);
assign SExp = {SXExp[`NE+1], SXExp[`NE+1:1]} + {2'b0, Bias}; assign SExp = {SXExp[`NE+1], SXExp[`NE+1:1]} + {2'b0, Bias};
// correct exponent for denormalized input's normalization shifts // correct exponent for Subnormalized input's normalization shifts
assign DExp = ({2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(`NE+1-`DIVBLEN){1'b0}}, m} + {3'b0, Bias}) & {`NE+2{~XZero}}; assign DExp = ({2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(`NE+1-`DIVBLEN){1'b0}}, m} + {3'b0, Bias}) & {`NE+2{~XZero}};
assign Qe = Sqrt ? SExp : DExp; assign Qe = Sqrt ? SExp : DExp;
endmodule endmodule

View File

@ -147,7 +147,7 @@ module fdivsqrtpreproc (
assign X = PreShiftX; assign X = PreShiftX;
end end
// count leading zeros for denorm FP and to normalize integer inputs // count leading zeros for Subnorm FP and to normalize integer inputs
lzc #(`DIVb) lzcX (IFNormLenX, ell); lzc #(`DIVb) lzcX (IFNormLenX, ell);
lzc #(`DIVb) lzcY (IFNormLenD, mE); lzc #(`DIVb) lzcY (IFNormLenD, mE);

View File

@ -34,7 +34,7 @@ module fmaadd(
input logic [3*`NF+3:0] Am, // aligned addend's mantissa for addition in U(NF+5.2NF+1) input logic [3*`NF+3:0] Am, // aligned addend's mantissa for addition in U(NF+5.2NF+1)
input logic [2*`NF+1:0] Pm, // the product's mantissa input logic [2*`NF+1:0] Pm, // the product's mantissa
input logic Ps, // the product sign and the alligend addeded's sign (Modified Z sign for other opperations) input logic Ps, // the product sign and the alligend addeded's sign (Modified Z sign for other opperations)
input logic InvA, // invert the aligned addend input logic InvA, // invert the aligned addend
input logic KillProd, // should the product be set to 0 input logic KillProd, // should the product be set to 0
input logic ASticky, input logic ASticky,
input logic [`NE-1:0] Ze, input logic [`NE-1:0] Ze,
@ -55,9 +55,9 @@ module fmaadd(
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Choose an inverted or non-inverted addend. Put carry into adder/LZA for addition // Choose an inverted or non-inverted addend. Put carry into adder/LZA for addition
assign AmInv = InvA ? ~Am : Am; assign AmInv = {3*`NF+4{InvA}}^Am;
// 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 PmKilled = KillProd ? '0 : Pm; assign PmKilled = {2*`NF+2{~KillProd}}&Pm;
// Do the addition // Do the addition
// - calculate a positive and negitive sum in parallel // - calculate a positive and negitive sum in parallel
// if there was a small negitive number killed in the alignment stage one needs to be subtracted from the sum // if there was a small negitive number killed in the alignment stage one needs to be subtracted from the sum

View File

@ -39,23 +39,23 @@ module fmalza #(WIDTH) ( // [Schmookler & Nowka, Leading zero anticipation and d
); );
logic [WIDTH:0] F; logic [WIDTH:0] F;
logic [WIDTH-1:0] B, P, G, K; logic [WIDTH-1:0] B, P, Guard, K;
logic [WIDTH-1:0] Pp1, Gm1, Km1; logic [WIDTH-1:0] Pp1, Gm1, Km1;
assign B = {{(`NF+1){1'b0}}, Pm}; // Zero extend product assign B = {{(`NF+1){1'b0}}, Pm}; // Zero extend product
assign P = A^B; assign P = A^B;
assign G = A&B; assign Guard = A&B;
assign K= ~A&~B; assign K= ~A&~B;
assign Pp1 = {sub, P[WIDTH-1:1]}; assign Pp1 = {sub, P[WIDTH-1:1]};
assign Gm1 = {G[WIDTH-2:0], Cin}; assign Gm1 = {Guard[WIDTH-2:0], Cin};
assign Km1 = {K[WIDTH-2:0], ~Cin}; assign Km1 = {K[WIDTH-2:0], ~Cin};
// Apply function to determine Leading pattern // Apply function to determine Leading pattern
// - 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
assign F[WIDTH] = ~sub&P[WIDTH-1]; assign F[WIDTH] = ~sub&P[WIDTH-1];
assign F[WIDTH-1:0] = (Pp1&(G&~Km1 | K&~Gm1)) | (~Pp1&(K&~Km1 | G&~Gm1)); assign F[WIDTH-1:0] = (Pp1&(Guard&~Km1 | K&~Gm1)) | (~Pp1&(K&~Km1 | Guard&~Gm1));
lzc #(WIDTH+1) lzc (.num(F), .ZeroCnt(SCnt)); lzc #(WIDTH+1) lzc (.num(F), .ZeroCnt(SCnt));
endmodule endmodule

View File

@ -101,7 +101,7 @@ module fpu (
logic XNaNQ, YNaNQ; // is the input a NaN - divide logic XNaNQ, YNaNQ; // is the input a NaN - divide
logic XSNaNE, YSNaNE, ZSNaNE; // is the input a signaling NaN - execute stage logic XSNaNE, YSNaNE, ZSNaNE; // is the input a signaling NaN - execute stage
logic XSNaNM, YSNaNM, ZSNaNM; // is the input a signaling NaN - memory stage logic XSNaNM, YSNaNM, ZSNaNM; // is the input a signaling NaN - memory stage
logic XDenormE, ZDenormE, ZDenormM; // is the input denormalized logic XSubnormE, ZSubnormE, ZSubnormM; // is the input Subnormalized
logic XZeroE, YZeroE, ZZeroE; // is the input zero - execute stage logic XZeroE, YZeroE, ZZeroE; // is the input zero - execute stage
logic XZeroM, YZeroM, ZZeroM; // is the input zero - memory stage logic XZeroM, YZeroM, ZZeroM; // is the input zero - memory stage
logic XInfE, YInfE, ZInfE; // is the input infinity - execute stage logic XInfE, YInfE, ZInfE; // is the input infinity - execute stage
@ -121,7 +121,7 @@ module fpu (
// Cvt Signals // Cvt Signals
logic [`NE:0] CeE, CeM; // the calculated expoent logic [`NE:0] CeE, CeM; // the calculated expoent
logic [`LOGCVTLEN-1:0] CvtShiftAmtE, CvtShiftAmtM; // how much to shift by logic [`LOGCVTLEN-1:0] CvtShiftAmtE, CvtShiftAmtM; // how much to shift by
logic CvtResDenormUfE, CvtResDenormUfM;// does the result underflow or is denormalized logic CvtResSubnormUfE, CvtResSubnormUfM;// does the result underflow or is Subnormalized
logic CsE, CsM; // the result's sign logic CsE, CsM; // the result's sign
logic IntZeroE, IntZeroM; // is the integer zero? logic IntZeroE, IntZeroM; // is the integer zero?
logic [`CVTLEN-1:0] CvtLzcInE, CvtLzcInM; // input to the Leading Zero Counter (priority encoder) logic [`CVTLEN-1:0] CvtLzcInE, CvtLzcInM; // input to the Leading Zero Counter (priority encoder)
@ -238,11 +238,11 @@ module fpu (
// unpack unit // unpack unit
// - splits FP inputs into their various parts // - splits FP inputs into their various parts
// - does some classifications (SNaN, NaN, Denorm, Norm, Zero, Infifnity) // - does some classifications (SNaN, NaN, Subnorm, Norm, Zero, Infifnity)
unpack unpack (.X(XE), .Y(YE), .Z(ZE), .Fmt(FmtE), .Xs(XsE), .Ys(YsE), .Zs(ZsE), unpack unpack (.X(XE), .Y(YE), .Z(ZE), .Fmt(FmtE), .Xs(XsE), .Ys(YsE), .Zs(ZsE),
.Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE), .YEn(YEnE), .Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE), .YEn(YEnE),
.XNaN(XNaNE), .YNaN(YNaNE), .ZNaN(ZNaNE), .XSNaN(XSNaNE), .XEn(XEnE), .XNaN(XNaNE), .YNaN(YNaNE), .ZNaN(ZNaNE), .XSNaN(XSNaNE), .XEn(XEnE),
.YSNaN(YSNaNE), .ZSNaN(ZSNaNE), .XDenorm(XDenormE), .ZDenorm(ZDenormE), .YSNaN(YSNaNE), .ZSNaN(ZSNaNE), .XSubnorm(XSubnormE), .ZSubnorm(ZSubnormE),
.XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), .XInf(XInfE), .YInf(YInfE), .XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), .XInf(XInfE), .YInf(YInfE),
.ZEn(ZEnE), .ZInf(ZInfE), .XExpMax(XExpMaxE)); .ZEn(ZEnE), .ZInf(ZInfE), .XExpMax(XExpMaxE));
@ -284,14 +284,14 @@ module fpu (
// classify // classify
// - fclass // - fclass
fclassify fclassify (.Xs(XsE), .XDenorm(XDenormE), .XZero(XZeroE), .XNaN(XNaNE), fclassify fclassify (.Xs(XsE), .XSubnorm(XSubnormE), .XZero(XZeroE), .XNaN(XNaNE),
.XInf(XInfE), .XSNaN(XSNaNE), .ClassRes(ClassResE)); .XInf(XInfE), .XSNaN(XSNaNE), .ClassRes(ClassResE));
// convert // convert
// - fcvt.*.* // - fcvt.*.*
fcvt fcvt (.Xs(XsE), .Xe(XeE), .Xm(XmE), .Int(ForwardedSrcAE), .OpCtrl(OpCtrlE), fcvt fcvt (.Xs(XsE), .Xe(XeE), .Xm(XmE), .Int(ForwardedSrcAE), .OpCtrl(OpCtrlE),
.ToInt(FWriteIntE), .XZero(XZeroE), .XDenorm(XDenormE), .Fmt(FmtE), .Ce(CeE), .ToInt(FWriteIntE), .XZero(XZeroE), .XSubnorm(XSubnormE), .Fmt(FmtE), .Ce(CeE),
.ShiftAmt(CvtShiftAmtE), .ResDenormUf(CvtResDenormUfE), .Cs(CsE), .IntZero(IntZeroE), .ShiftAmt(CvtShiftAmtE), .ResSubnormUf(CvtResSubnormUfE), .Cs(CsE), .IntZero(IntZeroE),
.LzcIn(CvtLzcInE)); .LzcIn(CvtLzcInE));
// data to be stored in memory - to IEU // data to be stored in memory - to IEU
@ -349,16 +349,16 @@ module fpu (
flopenrc #(`XLEN) EMFpReg6 (clk, reset, FlushM, ~StallM, FIntResE, FIntResM); flopenrc #(`XLEN) EMFpReg6 (clk, reset, FlushM, ~StallM, FIntResE, FIntResM);
flopenrc #(`FLEN) EMFpReg7 (clk, reset, FlushM, ~StallM, PreFpResE, PreFpResM); flopenrc #(`FLEN) EMFpReg7 (clk, reset, FlushM, ~StallM, PreFpResE, PreFpResM);
flopenr #(15) EMFpReg5 (clk, reset, ~StallUnpackedM, flopenr #(15) EMFpReg5 (clk, reset, ~StallUnpackedM,
{XsE, YsE, XZeroE, YZeroE, ZZeroE, XInfE, YInfE, ZInfE, XNaNE, YNaNE, ZNaNE, XSNaNE, YSNaNE, ZSNaNE, ZDenormE}, {XsE, YsE, XZeroE, YZeroE, ZZeroE, XInfE, YInfE, ZInfE, XNaNE, YNaNE, ZNaNE, XSNaNE, YSNaNE, ZSNaNE, ZSubnormE},
{XsM, YsM, XZeroM, YZeroM, ZZeroM, XInfM, YInfM, ZInfM, XNaNM, YNaNM, ZNaNM, XSNaNM, YSNaNM, ZSNaNM, ZDenormM}); {XsM, YsM, XZeroM, YZeroM, ZZeroM, XInfM, YInfM, ZInfM, XNaNM, YNaNM, ZNaNM, XSNaNM, YSNaNM, ZSNaNM, ZSubnormM});
flopenrc #(1) EMRegCmpFlg (clk, reset, FlushM, ~StallM, PreNVE, PreNVM); flopenrc #(1) EMRegCmpFlg (clk, reset, FlushM, ~StallM, PreNVE, PreNVM);
flopenrc #(3*`NF+4) EMRegFma2(clk, reset, FlushM, ~StallM, SmE, SmM); flopenrc #(3*`NF+4) EMRegFma2(clk, reset, FlushM, ~StallM, SmE, SmM);
flopenrc #($clog2(3*`NF+5)+7+`NE) EMRegFma4(clk, reset, FlushM, ~StallM, flopenrc #($clog2(3*`NF+5)+7+`NE) EMRegFma4(clk, reset, FlushM, ~StallM,
{FmaAStickyE, InvAE, SCntE, AsE, PsE, SsE, SeE}, {FmaAStickyE, InvAE, SCntE, AsE, PsE, SsE, SeE},
{FmaAStickyM, InvAM, SCntM, AsM, PsM, SsM, SeM}); {FmaAStickyM, InvAM, SCntM, AsM, PsM, SsM, SeM});
flopenrc #(`NE+`LOGCVTLEN+`CVTLEN+4) EMRegCvt(clk, reset, FlushM, ~StallM, flopenrc #(`NE+`LOGCVTLEN+`CVTLEN+4) EMRegCvt(clk, reset, FlushM, ~StallM,
{CeE, CvtShiftAmtE, CvtResDenormUfE, CsE, IntZeroE, CvtLzcInE}, {CeE, CvtShiftAmtE, CvtResSubnormUfE, CsE, IntZeroE, CvtLzcInE},
{CeM, CvtShiftAmtM, CvtResDenormUfM, CsM, IntZeroM, CvtLzcInM}); {CeM, CvtShiftAmtM, CvtResSubnormUfM, CsM, IntZeroM, CvtLzcInM});
// BEGIN MEMORY STAGE // BEGIN MEMORY STAGE
@ -377,8 +377,8 @@ module fpu (
postprocess postprocess(.Xs(XsM), .Ys(YsM), .Xm(XmM), .Ym(YmM), .Zm(ZmM), .Frm(FrmM), .Fmt(FmtM), postprocess postprocess(.Xs(XsM), .Ys(YsM), .Xm(XmM), .Ym(YmM), .Zm(ZmM), .Frm(FrmM), .Fmt(FmtM),
.FmaASticky(FmaAStickyM), .XZero(XZeroM), .YZero(YZeroM), .ZZero(ZZeroM), .XInf(XInfM), .YInf(YInfM), .DivQm(QmM), .FmaSs(SsM), .FmaASticky(FmaAStickyM), .XZero(XZeroM), .YZero(YZeroM), .ZZero(ZZeroM), .XInf(XInfM), .YInf(YInfM), .DivQm(QmM), .FmaSs(SsM),
.ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM), .FmaSm(SmM), .DivQe(QeM), /*.DivDone(DivDoneM), */ .ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM), .FmaSm(SmM), .DivQe(QeM), /*.DivDone(DivDoneM), */
.ZDenorm(ZDenormM), .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM), .ZSubnorm(ZSubnormM), .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM),
.CvtCe(CeM), .CvtResDenormUf(CvtResDenormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CsM), .ToInt(FWriteIntM), .DivS(DivSM), .CvtCe(CeM), .CvtResSubnormUf(CvtResSubnormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CsM), .ToInt(FWriteIntM), .DivS(DivSM),
.CvtLzcIn(CvtLzcInM), .IntZero(IntZeroM), .PostProcSel(PostProcSelM), .PostProcRes(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM)); .CvtLzcIn(CvtLzcInM), .IntZero(IntZeroM), .PostProcSel(PostProcSelM), .PostProcRes(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM));
// FPU flag selection - to privileged // FPU flag selection - to privileged

View File

@ -37,7 +37,7 @@ module cvtshiftcalc(
input logic [`NF:0] Xm, // input mantissas input logic [`NF:0] Xm, // input mantissas
input logic [`FMTBITS-1:0] OutFmt, // output format input logic [`FMTBITS-1:0] OutFmt, // output format
input logic [`CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (priority encoder) input logic [`CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (priority encoder)
input logic CvtResDenormUf, // is the conversion result subnormal or underlows input logic CvtResSubnormUf, // is the conversion result subnormal or underlows
output logic CvtResUf, // does the cvt result unerflow output logic CvtResUf, // does the cvt result unerflow
output logic [`CVTLEN+`NF:0] CvtShiftIn // number to be shifted output logic [`CVTLEN+`NF:0] CvtShiftIn // number to be shifted
); );
@ -57,7 +57,7 @@ module cvtshiftcalc(
// - we do however want to keep the one in the sticky bit so set one of bits in the sticky bit area to 1 // - we do however want to keep the one in the sticky bit so set one of bits in the sticky bit area to 1
// - ex: for the case 0010000.... (double) // - ex: for the case 0010000.... (double)
// ??? -> fp: // ??? -> fp:
// - if result is denormalized or underflowed then we want to shift right i.e. shift right then shift left: // - if result is Subnormalized or underflowed then we want to shift right i.e. shift right then shift left:
// | `NF-1 zeros | Mantissa | 0's if nessisary | // | `NF-1 zeros | Mantissa | 0's if nessisary |
// . // .
// - otherwise: // - otherwise:
@ -68,7 +68,7 @@ module cvtshiftcalc(
always_comb // get rid of round bit if needed always_comb // get rid of round bit if needed
// | add sticky bit if needed // | add sticky bit if needed
if (ToInt) CvtShiftIn = {{`XLEN{1'b0}}, Xm[`NF]&~CvtCe[`NE], Xm[`NF-1]|(CvtCe[`NE]&Xm[`NF]), Xm[`NF-2:0], {`CVTLEN-`XLEN{1'b0}}}; if (ToInt) CvtShiftIn = {{`XLEN{1'b0}}, Xm[`NF]&~CvtCe[`NE], Xm[`NF-1]|(CvtCe[`NE]&Xm[`NF]), Xm[`NF-2:0], {`CVTLEN-`XLEN{1'b0}}};
else if (CvtResDenormUf) CvtShiftIn = {{`NF-1{1'b0}}, Xm, {`CVTLEN-`NF+1{1'b0}}}; else if (CvtResSubnormUf) CvtShiftIn = {{`NF-1{1'b0}}, Xm, {`CVTLEN-`NF+1{1'b0}}};
else CvtShiftIn = {CvtLzcIn, {`NF+1{1'b0}}}; else CvtShiftIn = {CvtLzcIn, {`NF+1{1'b0}}};
// choose the negative of the fraction size // choose the negative of the fraction size

View File

@ -36,24 +36,24 @@ module divshiftcalc(
input logic [`NE+1:0] DivQe, input logic [`NE+1:0] DivQe,
output logic [`LOGNORMSHIFTSZ-1:0] DivShiftAmt, output logic [`LOGNORMSHIFTSZ-1:0] DivShiftAmt,
output logic [`NORMSHIFTSZ-1:0] DivShiftIn, output logic [`NORMSHIFTSZ-1:0] DivShiftIn,
output logic DivResDenorm, output logic DivResSubnorm,
output logic DivDenormShiftPos output logic DivSubnormShiftPos
); );
logic [`LOGNORMSHIFTSZ-1:0] NormShift, DivDenormShiftAmt; logic [`LOGNORMSHIFTSZ-1:0] NormShift, DivSubnormShiftAmt;
logic [`NE+1:0] DivDenormShift; logic [`NE+1:0] DivSubnormShift;
// is the result denormalized // is the result Subnormalized
// if the exponent is 1 then the result needs to be normalized then the result is denormalizes // if the exponent is 1 then the result needs to be normalized then the result is Subnormalizes
assign DivResDenorm = DivQe[`NE+1]|(~|DivQe[`NE+1:0]); assign DivResSubnorm = DivQe[`NE+1]|(~|DivQe[`NE+1:0]);
// if the result is denormalized // if the result is Subnormalized
// 00000000x.xxxxxx... Exp = DivQe // 00000000x.xxxxxx... Exp = DivQe
// .00000000xxxxxxx... >> NF+1 Exp = DivQe+NF+1 // .00000000xxxxxxx... >> NF+1 Exp = DivQe+NF+1
// .00xxxxxxxxxxxxx... << DivQe+NF+1 Exp = +1 // .00xxxxxxxxxxxxx... << DivQe+NF+1 Exp = +1
// .0000xxxxxxxxxxx... >> 1 Exp = 1 // .0000xxxxxxxxxxx... >> 1 Exp = 1
// Left shift amount = DivQe+NF+1-1 // Left shift amount = DivQe+NF+1-1
assign DivDenormShift = (`NE+2)'(`NF)+DivQe; assign DivSubnormShift = (`NE+2)'(`NF)+DivQe;
assign DivDenormShiftPos = ~DivDenormShift[`NE+1]; assign DivSubnormShiftPos = ~DivSubnormShift[`NE+1];
// if the result is normalized // if the result is normalized
// 00000000x.xxxxxx... Exp = DivQe // 00000000x.xxxxxx... Exp = DivQe
@ -67,8 +67,8 @@ module divshiftcalc(
// if the shift amount is negitive then don't shift (keep sticky bit) // if the shift amount is negitive then don't shift (keep sticky bit)
// need to multiply the early termination shift by LOGR*DIVCOPIES = left shift of log2(LOGR*DIVCOPIES) // need to multiply the early termination shift by LOGR*DIVCOPIES = left shift of log2(LOGR*DIVCOPIES)
assign DivDenormShiftAmt = DivDenormShiftPos ? DivDenormShift[`LOGNORMSHIFTSZ-1:0] : '0; assign DivSubnormShiftAmt = DivSubnormShiftPos ? DivSubnormShift[`LOGNORMSHIFTSZ-1:0] : '0;
assign DivShiftAmt = DivResDenorm ? DivDenormShiftAmt : NormShift; assign DivShiftAmt = DivResSubnorm ? DivSubnormShiftAmt : NormShift;
assign DivShiftIn = {{`NF{1'b0}}, DivQm, {`NORMSHIFTSZ-`DIVb-1-`NF{1'b0}}}; assign DivShiftIn = {{`NF{1'b0}}, DivQm, {`NORMSHIFTSZ-`DIVb-1-`NF{1'b0}}};
endmodule endmodule

View File

@ -51,7 +51,7 @@ module flags(
input logic [`NE+1:0] Me, // exponent of the normalized sum input logic [`NE+1:0] Me, // exponent of the normalized sum
input logic [1:0] CvtNegResMsbs, // the negitive integer result's most significant bits input logic [1:0] CvtNegResMsbs, // the negitive integer result's most significant bits
input logic FmaAs, FmaPs, // the product and modified Z signs input logic FmaAs, FmaPs, // the product and modified Z signs
input logic R, G, S, UfPlus1, // bits used to determine rounding input logic Round, Guard, Sticky, UfPlus1, // bits used to determine rounding
output logic DivByZero, output logic DivByZero,
output logic IntInvalid, Invalid, Overflow, // flags used to select the res output logic IntInvalid, Invalid, Overflow, // flags used to select the res
output logic [4:0] PostProcFlg // flags output logic [4:0] PostProcFlg // flags
@ -121,24 +121,24 @@ module flags(
// detecting tininess after rounding // detecting tininess after rounding
// the exponent is negitive // the exponent is negitive
// | the result is denormalized // | the result is Subnormalized
// | | the result is normal and rounded from a denorm // | | the result is normal and rounded from a Subnorm
// | | | and if given an unbounded exponent the result does not round // | | | and if given an unbounded exponent the result does not round
// | | | | and if the result is not exact // | | | | and if the result is not exact
// | | | | | and if the input isnt infinity or NaN // | | | | | and if the input isnt infinity or NaN
// | | | | | | // | | | | | |
assign Underflow = ((FullRe[`NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&G)))&(R|S|G))&~(InfIn|NaNIn|DivByZero|Invalid); assign Underflow = ((FullRe[`NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&Guard)))&(Round|Sticky|Guard))&~(InfIn|NaNIn|DivByZero|Invalid);
//assign Underflow = ((FullRe[`NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&G)))&(R|S|G))&~(InfIn|NaNIn|DivByZero|Invalid|XZero); //assign Underflow = ((FullRe[`NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&Guard)))&(Round|Sticky|Guard))&~(InfIn|NaNIn|DivByZero|Invalid|XZero);
// Set Inexact flag if the res is diffrent from what would be outputed given infinite precision // Set Inexact flag if the res is diffrent from what would be outputed given infinite precision
// - Don't set the underflow flag if an underflowed res isn't outputed // - Don't set the underflow flag if an underflowed res isn't outputed
assign FpInexact = (S|G|Overflow|R)&~(InfIn|NaNIn|DivByZero|Invalid); assign FpInexact = (Sticky|Guard|Overflow|Round)&~(InfIn|NaNIn|DivByZero|Invalid);
//assign FpInexact = (S|G|Overflow|R)&~(InfIn|NaNIn|DivByZero|Invalid|XZero); //assign FpInexact = (Sticky|Guard|Overflow|Round)&~(InfIn|NaNIn|DivByZero|Invalid|XZero);
// if the res is too small to be represented and not 0 // if the res is too small to be represented and not 0
// | and if the res is not invalid (outside the integer bounds) // | and if the res is not invalid (outside the integer bounds)
// | | // | |
assign IntInexact = ((CvtCe[`NE]&~XZero)|S|R|G)&~IntInvalid; assign IntInexact = ((CvtCe[`NE]&~XZero)|Sticky|Round|Guard)&~IntInvalid;
// select the inexact flag to output // select the inexact flag to output
assign Inexact = ToInt ? IntInexact : FpInexact; assign Inexact = ToInt ? IntInexact : FpInexact;

View File

@ -34,9 +34,9 @@ module fmashiftcalc(
input logic [$clog2(3*`NF+5)-1:0] FmaSCnt, // normalization shift count input logic [$clog2(3*`NF+5)-1:0] FmaSCnt, // normalization shift count
input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
input logic [`NE+1:0] FmaSe, // sum's exponent input logic [`NE+1:0] FmaSe, // sum's exponent
output logic [`NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account denormal or zero results output logic [`NE+1:0] NormSumExp, //*** add fma // exponent of the normalized sum not taking into account Subnormal or zero results
output logic FmaSZero, // is the result denormalized - calculated before LZA corection output logic FmaSZero, // is the result Subnormalized - calculated before LZA corection
output logic FmaPreResultDenorm, // is the result denormalized - calculated before LZA corection output logic FmaPreResultSubnorm, // is the result Subnormalized - calculated before LZA corection
output logic [$clog2(3*`NF+5)-1:0] FmaShiftAmt, // normalization shift count output logic [$clog2(3*`NF+5)-1:0] FmaShiftAmt, // normalization shift count
output logic [3*`NF+5:0] FmaShiftIn // is the sum zero output logic [3*`NF+5:0] FmaShiftIn // is the sum zero
); );
@ -46,7 +46,6 @@ module fmashiftcalc(
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Normalization // Normalization
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
//*** insert bias-bias simplification in fcvt.sv/phone pictures
// Determine if the sum is zero // Determine if the sum is zero
assign FmaSZero = ~(|FmaSm); assign FmaSZero = ~(|FmaSm);
// calculate the sum's exponent // calculate the sum's exponent
@ -84,13 +83,13 @@ module fmashiftcalc(
end end
// determine if the result is denormalized // determine if the result is Subnormalized
if (`FPSIZES == 1) begin if (`FPSIZES == 1) begin
logic Sum0LEZ, Sum0GEFL; logic Sum0LEZ, Sum0GEFL;
assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp; assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp;
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2)); assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2));
assign FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; assign FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
end else if (`FPSIZES == 2) begin end else if (`FPSIZES == 2) begin
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL; logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL;
@ -98,7 +97,7 @@ module fmashiftcalc(
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2)); assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2));
assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS1)); assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS1));
assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF1-2+`BIAS-`BIAS1)) | ~|PreNormSumExp; assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF1-2+`BIAS-`BIAS1)) | ~|PreNormSumExp;
assign FmaPreResultDenorm = (Fmt ? Sum0LEZ : Sum1LEZ) & (Fmt ? Sum0GEFL : Sum1GEFL) & ~FmaSZero; assign FmaPreResultSubnorm = (Fmt ? Sum0LEZ : Sum1LEZ) & (Fmt ? Sum0GEFL : Sum1GEFL) & ~FmaSZero;
end else if (`FPSIZES == 3) begin end else if (`FPSIZES == 3) begin
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL; logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL;
@ -110,10 +109,10 @@ module fmashiftcalc(
assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF2-2+`BIAS-`BIAS2)) | ~|PreNormSumExp; assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF2-2+`BIAS-`BIAS2)) | ~|PreNormSumExp;
always_comb begin always_comb begin
case (Fmt) case (Fmt)
`FMT: FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; `FMT: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
`FMT1: FmaPreResultDenorm = Sum1LEZ & Sum1GEFL & ~FmaSZero; `FMT1: FmaPreResultSubnorm = Sum1LEZ & Sum1GEFL & ~FmaSZero;
`FMT2: FmaPreResultDenorm = Sum2LEZ & Sum2GEFL & ~FmaSZero; `FMT2: FmaPreResultSubnorm = Sum2LEZ & Sum2GEFL & ~FmaSZero;
default: FmaPreResultDenorm = 1'bx; default: FmaPreResultSubnorm = 1'bx;
endcase endcase
end end
@ -129,10 +128,10 @@ module fmashiftcalc(
assign Sum3GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`H_NF-2+`BIAS-`H_BIAS)) | ~|PreNormSumExp; assign Sum3GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`H_NF-2+`BIAS-`H_BIAS)) | ~|PreNormSumExp;
always_comb begin always_comb begin
case (Fmt) case (Fmt)
2'h3: FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; 2'h3: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
2'h1: FmaPreResultDenorm = Sum1LEZ & Sum1GEFL & ~FmaSZero; 2'h1: FmaPreResultSubnorm = Sum1LEZ & Sum1GEFL & ~FmaSZero;
2'h0: FmaPreResultDenorm = Sum2LEZ & Sum2GEFL & ~FmaSZero; 2'h0: FmaPreResultSubnorm = Sum2LEZ & Sum2GEFL & ~FmaSZero;
2'h2: FmaPreResultDenorm = Sum3LEZ & Sum3GEFL & ~FmaSZero; 2'h2: FmaPreResultSubnorm = Sum3LEZ & Sum3GEFL & ~FmaSZero;
endcase endcase
end end
@ -143,14 +142,14 @@ module fmashiftcalc(
// - add one from exp // - add one from exp
// - if kill prod dont add to exp // - if kill prod dont add to exp
// Determine if the result is denormal // Determine if the result is Subnormal
// assign FmaPreResultDenorm = $signed(NormSumExp)<=0 & ($signed(NormSumExp)>=$signed(-FracLen)) & ~FmaSZero; // assign FmaPreResultSubnorm = $signed(NormSumExp)<=0 & ($signed(NormSumExp)>=$signed(-FracLen)) & ~FmaSZero;
// set and calculate the shift input and amount // set and calculate the shift input and amount
// - shift once if killing a product and the result is denormalized // - shift once if killing a product and the result is Subnormalized
assign FmaShiftIn = {2'b0, FmaSm}; assign FmaShiftIn = {2'b0, FmaSm};
if (`FPSIZES == 1) if (`FPSIZES == 1)
assign FmaShiftAmt = FmaPreResultDenorm ? FmaSe[$clog2(3*`NF+5)-1:0]+($clog2(3*`NF+5))'(`NF+2): FmaSCnt+1; assign FmaShiftAmt = FmaPreResultSubnorm ? FmaSe[$clog2(3*`NF+5)-1:0]+($clog2(3*`NF+5))'(`NF+2): FmaSCnt+1;
else else
assign FmaShiftAmt = FmaPreResultDenorm ? FmaSe[$clog2(3*`NF+5)-1:0]+($clog2(3*`NF+5))'(`NF+2)+BiasCorr[$clog2(3*`NF+5)-1:0]: FmaSCnt+1; assign FmaShiftAmt = FmaPreResultSubnorm ? FmaSe[$clog2(3*`NF+5)-1:0]+($clog2(3*`NF+5))'(`NF+2)+BiasCorr[$clog2(3*`NF+5)-1:0]: FmaSCnt+1;
endmodule endmodule

View File

@ -45,7 +45,7 @@
// | keep | // | keep |
// //
// fp -> fp: // fp -> fp:
// - if result is denormalized or underflowed: // - if result is Subnormalized or underflowed:
// | `NF-1 zeros | Mantissa | 0's if nessisary | << NF+CalcExp-1 // | `NF-1 zeros | Mantissa | 0's if nessisary | << NF+CalcExp-1
// process: // process:
// - start // - start
@ -58,7 +58,7 @@
// | 0's | mantissa | 0's | // | 0's | mantissa | 0's |
// | keep | // | keep |
// //
// - if the input is denormalized: // - if the input is Subnormalized:
// | lzcIn | 0's if nessisary | << ZeroCnt+1 // | lzcIn | 0's if nessisary | << ZeroCnt+1
// - plus 1 to shift out the first 1 // - plus 1 to shift out the first 1
// //

View File

@ -41,7 +41,7 @@ module postprocess (
input logic XInf, YInf, ZInf, // inputs are infinity input logic XInf, YInf, ZInf, // inputs are infinity
input logic XNaN, YNaN, ZNaN, // inputs are NaN input logic XNaN, YNaN, ZNaN, // inputs are NaN
input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
input logic ZDenorm, // is the original precision denormalized input logic ZSubnorm, // is the original precision Subnormalized
input logic [1:0] PostProcSel, // select result to be written to fp register input logic [1:0] PostProcSel, // select result to be written to fp register
//fma signals //fma signals
input logic FmaAs, // the modified Z sign - depends on instruction input logic FmaAs, // the modified Z sign - depends on instruction
@ -58,7 +58,7 @@ module postprocess (
// conversion signals // conversion signals
input logic CvtCs, // the result's sign input logic CvtCs, // the result's sign
input logic [`NE:0] CvtCe, // the calculated expoent input logic [`NE:0] CvtCe, // the calculated expoent
input logic CvtResDenormUf, input logic CvtResSubnormUf,
input logic [`LOGCVTLEN-1:0] CvtShiftAmt, // how much to shift by input logic [`LOGCVTLEN-1:0] CvtShiftAmt, // how much to shift by
input logic ToInt, // is fp->int (since it's writting to the integer register) input logic ToInt, // is fp->int (since it's writting to the integer register)
input logic [`CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (priority encoder) input logic [`CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (priority encoder)
@ -70,7 +70,7 @@ module postprocess (
); );
// general signals // general signals
logic Ws; logic Rs;
logic [`NF-1:0] Rf; // Result fraction logic [`NF-1:0] Rf; // Result fraction
logic [`NE-1:0] Re; // Result exponent logic [`NE-1:0] Re; // Result exponent
logic Ms; logic Ms;
@ -83,22 +83,22 @@ module postprocess (
logic [`NORMSHIFTSZ-1:0] Shifted; // the shifted result logic [`NORMSHIFTSZ-1:0] Shifted; // the shifted result
logic Plus1; // add one to the final result? logic Plus1; // add one to the final result?
logic IntInvalid, Overflow, Invalid; // flags logic IntInvalid, Overflow, Invalid; // flags
logic G, R, S; // bits needed to determine rounding logic Guard, Round, Sticky; // bits needed to determine rounding
logic [`FMTBITS-1:0] OutFmt; logic [`FMTBITS-1:0] OutFmt;
// fma signals // fma signals
logic [`NE+1:0] FmaMe; // exponent of the normalized sum logic [`NE+1:0] FmaMe; // exponent of the normalized sum
logic FmaSZero; // is the sum zero logic FmaSZero; // is the sum zero
logic [3*`NF+5:0] FmaShiftIn; // shift input logic [3*`NF+5:0] FmaShiftIn; // shift input
logic [`NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account denormal or zero results logic [`NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account Subnormal or zero results
logic FmaPreResultDenorm; // is the result denormalized - calculated before LZA corection logic FmaPreResultSubnorm; // is the result Subnormalized - calculated before LZA corection
logic [$clog2(3*`NF+5)-1:0] FmaShiftAmt; // normalization shift count logic [$clog2(3*`NF+5)-1:0] FmaShiftAmt; // normalization shift count
// division singals // division singals
logic [`LOGNORMSHIFTSZ-1:0] DivShiftAmt; logic [`LOGNORMSHIFTSZ-1:0] DivShiftAmt;
logic [`NORMSHIFTSZ-1:0] DivShiftIn; logic [`NORMSHIFTSZ-1:0] DivShiftIn;
logic [`NE+1:0] Qe; logic [`NE+1:0] Qe;
logic DivByZero; logic DivByZero;
logic DivResDenorm; logic DivResSubnorm;
logic DivDenormShiftPos; logic DivSubnormShiftPos;
// conversion signals // conversion signals
logic [`CVTLEN+`NF:0] CvtShiftIn; // number to be shifted logic [`CVTLEN+`NF:0] CvtShiftIn; // number to be shifted
logic [1:0] CvtNegResMsbs; logic [1:0] CvtNegResMsbs;
@ -142,11 +142,11 @@ module postprocess (
// Normalization // Normalization
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
cvtshiftcalc cvtshiftcalc(.ToInt, .CvtCe, .CvtResDenormUf, .Xm, .CvtLzcIn, cvtshiftcalc cvtshiftcalc(.ToInt, .CvtCe, .CvtResSubnormUf, .Xm, .CvtLzcIn,
.XZero, .IntToFp, .OutFmt, .CvtResUf, .CvtShiftIn); .XZero, .IntToFp, .OutFmt, .CvtResUf, .CvtShiftIn);
fmashiftcalc fmashiftcalc(.FmaSm, .FmaSCnt, .Fmt, .NormSumExp, .FmaSe, fmashiftcalc fmashiftcalc(.FmaSm, .FmaSCnt, .Fmt, .NormSumExp, .FmaSe,
.FmaSZero, .FmaPreResultDenorm, .FmaShiftAmt, .FmaShiftIn); .FmaSZero, .FmaPreResultSubnorm, .FmaShiftAmt, .FmaShiftIn);
divshiftcalc divshiftcalc(.Sqrt, .DivQe, .DivQm, .DivResDenorm, .DivDenormShiftPos, .DivShiftAmt, .DivShiftIn); divshiftcalc divshiftcalc(.Sqrt, .DivQe, .DivQm, .DivResSubnorm, .DivSubnormShiftPos, .DivShiftAmt, .DivShiftIn);
always_comb always_comb
case(PostProcSel) case(PostProcSel)
@ -175,8 +175,8 @@ module postprocess (
normshift normshift (.ShiftIn, .ShiftAmt, .Shifted); normshift normshift (.ShiftIn, .ShiftAmt, .Shifted);
shiftcorrection shiftcorrection(.FmaOp, .FmaPreResultDenorm, .NormSumExp, shiftcorrection shiftcorrection(.FmaOp, .FmaPreResultSubnorm, .NormSumExp,
.DivResDenorm, .DivDenormShiftPos, .DivOp, .DivQe, .DivResSubnorm, .DivSubnormShiftPos, .DivOp, .DivQe,
.Qe, .FmaSZero, .Shifted, .FmaMe, .Mf); .Qe, .FmaSZero, .Shifted, .FmaMe, .Mf);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -193,16 +193,16 @@ module postprocess (
roundsign roundsign(.FmaOp, .DivOp, .CvtOp, .Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms); roundsign roundsign(.FmaOp, .DivOp, .CvtOp, .Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms);
round round(.OutFmt, .Frm, .FmaASticky, .Plus1, .PostProcSel, .CvtCe, .Qe, round round(.OutFmt, .Frm, .FmaASticky, .Plus1, .PostProcSel, .CvtCe, .Qe,
.Ms, .FmaMe, .FmaOp, .CvtOp, .CvtResDenormUf, .Mf, .ToInt, .CvtResUf, .Ms, .FmaMe, .FmaOp, .CvtOp, .CvtResSubnormUf, .Mf, .ToInt, .CvtResUf,
.DivS, //.DivDone, .DivS, //.DivDone,
.DivOp, .UfPlus1, .FullRe, .Rf, .Re, .S, .R, .G, .Me); .DivOp, .UfPlus1, .FullRe, .Rf, .Re, .Sticky, .Round, .Guard, .Me);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Sign calculation // Sign calculation
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
resultsign resultsign(.Frm, .FmaPs, .FmaAs, .R, .S, .G, resultsign resultsign(.Frm, .FmaPs, .FmaAs, .Round, .Sticky, .Guard,
.FmaOp, .ZInf, .InfIn, .FmaSZero, .Mult, .Ms, .Ws); .FmaOp, .ZInf, .InfIn, .FmaSZero, .Mult, .Ms, .Rs);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Flags // Flags
@ -210,8 +210,8 @@ module postprocess (
flags flags(.XSNaN, .YSNaN, .ZSNaN, .XInf, .YInf, .ZInf, .InfIn, .XZero, .YZero, flags flags(.XSNaN, .YSNaN, .ZSNaN, .XInf, .YInf, .ZInf, .InfIn, .XZero, .YZero,
.Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCe, .Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCe,
.NaNIn, .FmaAs, .FmaPs, .R, .IntInvalid, .DivByZero, .NaNIn, .FmaAs, .FmaPs, .Round, .IntInvalid, .DivByZero,
.G, .S, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullRe, .Plus1, .Guard, .Sticky, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullRe, .Plus1,
.Me, .CvtNegResMsbs, .Invalid, .Overflow, .PostProcFlg); .Me, .CvtNegResMsbs, .Invalid, .Overflow, .PostProcFlg);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -223,6 +223,6 @@ module postprocess (
.IntZero, .Frm, .OutFmt, .XNaN, .YNaN, .ZNaN, .CvtResUf, .IntZero, .Frm, .OutFmt, .XNaN, .YNaN, .ZNaN, .CvtResUf,
.NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .CvtNegRes, .NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .CvtNegRes,
.XInf, .YInf, .DivOp, .XInf, .YInf, .DivOp,
.DivByZero, .FullRe, .CvtCe, .Ws, .Re, .Rf, .PostProcRes, .FCvtIntRes); .DivByZero, .FullRe, .CvtCe, .Rs, .Re, .Rf, .PostProcRes, .FCvtIntRes);
endmodule endmodule

View File

@ -37,11 +37,11 @@ module resultsign(
input logic FmaOp, input logic FmaOp,
input logic FmaSZero, input logic FmaSZero,
input logic Mult, input logic Mult,
input logic R, input logic Round,
input logic S, input logic Sticky,
input logic G, input logic Guard,
input logic Ms, input logic Ms,
output logic Ws output logic Rs
); );
logic Zeros; logic Zeros;
@ -59,9 +59,9 @@ module resultsign(
// - Z is killed and P is zero - impossible // - Z is killed and P is zero - impossible
// Zero sign calculation: // Zero sign calculation:
// - if a multiply opperation is done, then use the products sign(Ps) // - if a multiply opperation is done, then use the products sign(Ps)
// - if the zero sum is not exactly zero i.e. R|S use the sign of the exact result (which is the product's sign) // - if the zero sum is not exactly zero i.e. Round|Sticky use the sign of the exact result (which is the product's sign)
// - if an effective addition occurs (P+A or -P+-A or P--A) then use the product's sign // - if an effective addition occurs (P+A or -P+-A or P--A) then use the product's sign
assign Zeros = (FmaPs^FmaAs)&~(R|G|S)&~Mult ? Frm[1:0] == 2'b10 : FmaPs; assign Zeros = (FmaPs^FmaAs)&~(Round|Guard|Sticky)&~Mult ? Frm[1:0] == 2'b10 : FmaPs;
// is the result negitive // is the result negitive
@ -70,8 +70,8 @@ module resultsign(
// if -p - z then the Sum is negitive // if -p - z then the Sum is negitive
assign Infs = ZInf ? FmaAs : FmaPs; assign Infs = ZInf ? FmaAs : FmaPs;
always_comb always_comb
if(InfIn&FmaOp) Ws = Infs; if(InfIn&FmaOp) Rs = Infs;
else if(FmaSZero&FmaOp) Ws = Zeros; else if(FmaSZero&FmaOp) Rs = Zeros;
else Ws = Ms; else Rs = Ms;
endmodule endmodule

View File

@ -37,15 +37,14 @@
`define XLENPOS ((`XLEN>`NF) ? 1 : (`XLEN>`NF1) ? 2 : 3) `define XLENPOS ((`XLEN>`NF) ? 1 : (`XLEN>`NF1) ? 2 : 3)
module round( module round(
input logic [`FMTBITS-1:0] OutFmt, // precision 1 = double 0 = single input logic [`FMTBITS-1:0] OutFmt, // precision 1 = double 0 = single
input logic [2:0] Frm, // rounding mode input logic [2:0] Frm, // rounding mode
input logic FmaOp, input logic FmaOp, // is an fma opperation being done?
input logic DivOp, input logic DivOp, // is a division opperation being done
input logic CvtOp, input logic CvtOp, // is a convert opperation being done
input logic ToInt, input logic ToInt, // is the cvt op a cvt to integer
// input logic DivDone, input logic [1:0] PostProcSel, // select the postprocessor output
input logic [1:0] PostProcSel, input logic CvtResSubnormUf, // is the cvt result subnormal or underflow
input logic CvtResDenormUf,
input logic CvtResUf, input logic CvtResUf,
input logic [`CORRSHIFTSZ-1:0] Mf, input logic [`CORRSHIFTSZ-1:0] Mf,
input logic FmaASticky, // addend's sticky bit input logic FmaASticky, // addend's sticky bit
@ -58,17 +57,17 @@ module round(
output logic [`NE+1:0] FullRe, // Re with bits to determine sign and overflow output logic [`NE+1:0] FullRe, // Re with bits to determine sign and overflow
output logic [`NF-1:0] Rf, // Result fraction output logic [`NF-1:0] Rf, // Result fraction
output logic [`NE-1:0] Re, // Result exponent output logic [`NE-1:0] Re, // Result exponent
output logic S, // sticky bit output logic Sticky, // sticky bit
output logic [`NE+1:0] Me, output logic [`NE+1:0] Me,
output logic Plus1, output logic Plus1,
output logic R, G // bits needed to calculate rounding output logic Round, Guard // bits needed to calculate rounding
); );
logic UfCalcPlus1; logic UfCalcPlus1;
logic NormS; // normalized sum's sticky bit logic NormS; // normalized sum's sticky bit
logic [`NF-1:0] RoundFrac; logic [`NF-1:0] RoundFrac;
logic FpRes, IntRes; logic FpRes, IntRes;
logic FpG, FpL, FpR; logic FpGuard, FpLsbRes, FpRound;
logic L; // lsb of result logic LsbRes; // lsb of result
logic CalcPlus1, FpPlus1; logic CalcPlus1, FpPlus1;
logic [`FLEN:0] RoundAdd; // how much to add to the result logic [`FLEN:0] RoundAdd; // how much to add to the result
@ -77,7 +76,7 @@ module round(
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// round to nearest even // round to nearest even
// {R, S} // {Round, Sticky}
// 0x - do nothing // 0x - do nothing
// 10 - tie - Plus1 if result is odd (LSBNormSum = 1) // 10 - tie - Plus1 if result is odd (LSBNormSum = 1)
// - don't add 1 if a small number was supposed to be subtracted // - don't add 1 if a small number was supposed to be subtracted
@ -95,7 +94,7 @@ module round(
// - subtract 1 if a small number was supposed to be subtracted from a negative result with guard and round bits of 0 // - subtract 1 if a small number was supposed to be subtracted from a negative result with guard and round bits of 0
// round to nearest max magnitude // round to nearest max magnitude
// {Guard, R, S} // {Guard, Round, Sticky}
// 0x - do nothing // 0x - do nothing
// 10 - tie - Plus1 // 10 - tie - Plus1
// - don't add 1 if a small number was supposed to be subtracted // - don't add 1 if a small number was supposed to be subtracted
@ -175,101 +174,101 @@ module round(
// only add the Addend sticky if doing an FMA opperation // only add the Addend sticky if doing an FMA opperation
// - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits) // - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits)
assign S = FmaASticky&FmaOp | NormS | CvtResUf&CvtOp | FmaMe[`NE+1]&FmaOp | DivS&DivOp; assign Sticky = FmaASticky&FmaOp | NormS | CvtResUf&CvtOp | FmaMe[`NE+1]&FmaOp | DivS&DivOp;
// determine round and LSB of the rounded value // determine round and LSB of the rounded value
// - underflow round bit is used to determint the underflow flag // - underflow round bit is used to determint the underflow flag
if (`FPSIZES == 1) begin if (`FPSIZES == 1) begin
assign FpG = Mf[`CORRSHIFTSZ-`NF-1]; assign FpGuard = Mf[`CORRSHIFTSZ-`NF-1];
assign FpL = Mf[`CORRSHIFTSZ-`NF]; assign FpLsbRes = Mf[`CORRSHIFTSZ-`NF];
assign FpR = Mf[`CORRSHIFTSZ-`NF-2]; assign FpRound = Mf[`CORRSHIFTSZ-`NF-2];
end else if (`FPSIZES == 2) begin end else if (`FPSIZES == 2) begin
assign FpG = OutFmt ? Mf[`CORRSHIFTSZ-`NF-1] : Mf[`CORRSHIFTSZ-`NF1-1]; assign FpGuard = OutFmt ? Mf[`CORRSHIFTSZ-`NF-1] : Mf[`CORRSHIFTSZ-`NF1-1];
assign FpL = OutFmt ? Mf[`CORRSHIFTSZ-`NF] : Mf[`CORRSHIFTSZ-`NF1]; assign FpLsbRes = OutFmt ? Mf[`CORRSHIFTSZ-`NF] : Mf[`CORRSHIFTSZ-`NF1];
assign FpR = OutFmt ? Mf[`CORRSHIFTSZ-`NF-2] : Mf[`CORRSHIFTSZ-`NF1-2]; assign FpRound = OutFmt ? Mf[`CORRSHIFTSZ-`NF-2] : Mf[`CORRSHIFTSZ-`NF1-2];
end else if (`FPSIZES == 3) begin end else if (`FPSIZES == 3) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
`FMT: begin `FMT: begin
FpG = Mf[`CORRSHIFTSZ-`NF-1]; FpGuard = Mf[`CORRSHIFTSZ-`NF-1];
FpL = Mf[`CORRSHIFTSZ-`NF]; FpLsbRes = Mf[`CORRSHIFTSZ-`NF];
FpR = Mf[`CORRSHIFTSZ-`NF-2]; FpRound = Mf[`CORRSHIFTSZ-`NF-2];
end end
`FMT1: begin `FMT1: begin
FpG = Mf[`CORRSHIFTSZ-`NF1-1]; FpGuard = Mf[`CORRSHIFTSZ-`NF1-1];
FpL = Mf[`CORRSHIFTSZ-`NF1]; FpLsbRes = Mf[`CORRSHIFTSZ-`NF1];
FpR = Mf[`CORRSHIFTSZ-`NF1-2]; FpRound = Mf[`CORRSHIFTSZ-`NF1-2];
end end
`FMT2: begin `FMT2: begin
FpG = Mf[`CORRSHIFTSZ-`NF2-1]; FpGuard = Mf[`CORRSHIFTSZ-`NF2-1];
FpL = Mf[`CORRSHIFTSZ-`NF2]; FpLsbRes = Mf[`CORRSHIFTSZ-`NF2];
FpR = Mf[`CORRSHIFTSZ-`NF2-2]; FpRound = Mf[`CORRSHIFTSZ-`NF2-2];
end end
default: begin default: begin
FpG = 1'bx; FpGuard = 1'bx;
FpL = 1'bx; FpLsbRes = 1'bx;
FpR = 1'bx; FpRound = 1'bx;
end end
endcase endcase
end else if (`FPSIZES == 4) begin end else if (`FPSIZES == 4) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
2'h3: begin 2'h3: begin
FpG = Mf[`CORRSHIFTSZ-`Q_NF-1]; FpGuard = Mf[`CORRSHIFTSZ-`Q_NF-1];
FpL = Mf[`CORRSHIFTSZ-`Q_NF]; FpLsbRes = Mf[`CORRSHIFTSZ-`Q_NF];
FpR = Mf[`CORRSHIFTSZ-`Q_NF-2]; FpRound = Mf[`CORRSHIFTSZ-`Q_NF-2];
end end
2'h1: begin 2'h1: begin
FpG = Mf[`CORRSHIFTSZ-`D_NF-1]; FpGuard = Mf[`CORRSHIFTSZ-`D_NF-1];
FpL = Mf[`CORRSHIFTSZ-`D_NF]; FpLsbRes = Mf[`CORRSHIFTSZ-`D_NF];
FpR = Mf[`CORRSHIFTSZ-`D_NF-2]; FpRound = Mf[`CORRSHIFTSZ-`D_NF-2];
end end
2'h0: begin 2'h0: begin
FpG = Mf[`CORRSHIFTSZ-`S_NF-1]; FpGuard = Mf[`CORRSHIFTSZ-`S_NF-1];
FpL = Mf[`CORRSHIFTSZ-`S_NF]; FpLsbRes = Mf[`CORRSHIFTSZ-`S_NF];
FpR = Mf[`CORRSHIFTSZ-`S_NF-2]; FpRound = Mf[`CORRSHIFTSZ-`S_NF-2];
end end
2'h2: begin 2'h2: begin
FpG = Mf[`CORRSHIFTSZ-`H_NF-1]; FpGuard = Mf[`CORRSHIFTSZ-`H_NF-1];
FpL = Mf[`CORRSHIFTSZ-`H_NF]; FpLsbRes = Mf[`CORRSHIFTSZ-`H_NF];
FpR = Mf[`CORRSHIFTSZ-`H_NF-2]; FpRound = Mf[`CORRSHIFTSZ-`H_NF-2];
end end
endcase endcase
end end
assign G = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-1] : FpG; assign Guard = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-1] : FpGuard;
assign L = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN] : FpL; assign LsbRes = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN] : FpLsbRes;
assign R = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-2] : FpR; assign Round = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-2] : FpRound;
always_comb begin always_comb begin
// Determine if you add 1 // Determine if you add 1
case (Frm) case (Frm)
3'b000: CalcPlus1 = G & (R|S|L);//round to nearest even 3'b000: CalcPlus1 = Guard & (Round|Sticky|LsbRes);//round to nearest even
3'b001: CalcPlus1 = 0;//round to zero 3'b001: CalcPlus1 = 0;//round to zero
3'b010: CalcPlus1 = Ms;//round down 3'b010: CalcPlus1 = Ms;//round down
3'b011: CalcPlus1 = ~Ms;//round up 3'b011: CalcPlus1 = ~Ms;//round up
3'b100: CalcPlus1 = G;//round to nearest max magnitude 3'b100: CalcPlus1 = Guard;//round to nearest max magnitude
default: CalcPlus1 = 1'bx; default: CalcPlus1 = 1'bx;
endcase endcase
// Determine if you add 1 (for underflow flag) // Determine if you add 1 (for underflow flag)
case (Frm) case (Frm)
3'b000: UfCalcPlus1 = R & (S|G);//round to nearest even 3'b000: UfCalcPlus1 = Round & (Sticky|Guard);//round to nearest even
3'b001: UfCalcPlus1 = 0;//round to zero 3'b001: UfCalcPlus1 = 0;//round to zero
3'b010: UfCalcPlus1 = Ms;//round down 3'b010: UfCalcPlus1 = Ms;//round down
3'b011: UfCalcPlus1 = ~Ms;//round up 3'b011: UfCalcPlus1 = ~Ms;//round up
3'b100: UfCalcPlus1 = R;//round to nearest max magnitude 3'b100: UfCalcPlus1 = Round;//round to nearest max magnitude
default: UfCalcPlus1 = 1'bx; default: UfCalcPlus1 = 1'bx;
endcase endcase
end end
// If an answer is exact don't round // If an answer is exact don't round
assign Plus1 = CalcPlus1 & (S|R|G); assign Plus1 = CalcPlus1 & (Sticky|Round|Guard);
assign FpPlus1 = Plus1&~(ToInt&CvtOp); assign FpPlus1 = Plus1&~(ToInt&CvtOp);
assign UfPlus1 = UfCalcPlus1 & (S|R); assign UfPlus1 = UfCalcPlus1 & (Sticky|Round);
// Compute rounded result // Compute rounded result
if (`FPSIZES == 1) begin if (`FPSIZES == 1) begin
@ -294,7 +293,7 @@ module round(
always_comb always_comb
case(PostProcSel) case(PostProcSel)
2'b10: Me = FmaMe; // fma 2'b10: Me = FmaMe; // fma
2'b00: Me = {CvtCe[`NE], CvtCe}&{`NE+2{~CvtResDenormUf|CvtResUf}}; // cvt 2'b00: Me = {CvtCe[`NE], CvtCe}&{`NE+2{~CvtResSubnormUf|CvtResUf}}; // cvt
// 2'b01: Me = DivDone ? Qe : '0; // divide // 2'b01: Me = DivDone ? Qe : '0; // divide
2'b01: Me = Qe; // divide 2'b01: Me = Qe; // divide
default: Me = '0; default: Me = '0;

View File

@ -33,11 +33,11 @@ module shiftcorrection(
input logic [`NORMSHIFTSZ-1:0] Shifted, // the shifted sum before LZA correction input logic [`NORMSHIFTSZ-1:0] Shifted, // the shifted sum before LZA correction
input logic FmaOp, input logic FmaOp,
input logic DivOp, input logic DivOp,
input logic DivResDenorm, input logic DivResSubnorm,
input logic [`NE+1:0] DivQe, input logic [`NE+1:0] DivQe,
input logic DivDenormShiftPos, input logic DivSubnormShiftPos,
input logic [`NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account denormal or zero results input logic [`NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
input logic FmaPreResultDenorm, // is the result denormalized - calculated before LZA corection input logic FmaPreResultSubnorm, // is the result Subnormalized - calculated before LZA corection
input logic FmaSZero, input logic FmaSZero,
output logic [`CORRSHIFTSZ-1:0] Mf, // the shifted sum before LZA correction output logic [`CORRSHIFTSZ-1:0] Mf, // the shifted sum before LZA correction
output logic [`NE+1:0] Qe, output logic [`NE+1:0] Qe,
@ -45,27 +45,27 @@ module shiftcorrection(
); );
logic [3*`NF+3:0] CorrSumShifted; // the shifted sum after LZA correction logic [3*`NF+3:0] CorrSumShifted; // the shifted sum after LZA correction
logic [`CORRSHIFTSZ-1:0] CorrQmShifted; logic [`CORRSHIFTSZ-1:0] CorrQmShifted;
logic ResDenorm; // is the result denormalized logic ResSubnorm; // is the result Subnormalized
logic LZAPlus1; // add one or two to the sum's exponent due to LZA correction logic LZAPlus1; // add one or two to the sum's exponent due to LZA correction
// LZA correction // LZA correction
assign LZAPlus1 = Shifted[`NORMSHIFTSZ-1]; assign LZAPlus1 = Shifted[`NORMSHIFTSZ-1];
// the only possible mantissa for a plus two is all zeroes - a one has to propigate all the way through a sum. so we can leave the bottom statement alone // the only possible mantissa for a plus two is all zeroes - a one has to propigate all the way through a sum. so we can leave the bottom statement alone
assign CorrSumShifted = LZAPlus1 ? Shifted[`NORMSHIFTSZ-2:1] : Shifted[`NORMSHIFTSZ-3:0]; assign CorrSumShifted = LZAPlus1 ? Shifted[`NORMSHIFTSZ-2:1] : Shifted[`NORMSHIFTSZ-3:0];
// if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Denorm) // if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Subnorm)
assign CorrQmShifted = (LZAPlus1|(DivQe==1&~LZAPlus1)) ? Shifted[`NORMSHIFTSZ-2:`NORMSHIFTSZ-`CORRSHIFTSZ-1] : Shifted[`NORMSHIFTSZ-3:`NORMSHIFTSZ-`CORRSHIFTSZ-2]; assign CorrQmShifted = (LZAPlus1|(DivQe==1&~LZAPlus1)) ? Shifted[`NORMSHIFTSZ-2:`NORMSHIFTSZ-`CORRSHIFTSZ-1] : Shifted[`NORMSHIFTSZ-3:`NORMSHIFTSZ-`CORRSHIFTSZ-2];
// if the result of the divider was calculated to be denormalized, then the result was correctly normalized, so select the top shifted bits // if the result of the divider was calculated to be Subnormalized, then the result was correctly normalized, so select the top shifted bits
always_comb always_comb
if(FmaOp) Mf = {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+4){1'b0}}}; if(FmaOp) Mf = {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+4){1'b0}}};
else if (DivOp&~DivResDenorm) Mf = CorrQmShifted; else if (DivOp&~DivResSubnorm) Mf = CorrQmShifted;
else Mf = Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ]; else Mf = Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ];
// Determine sum's exponent // Determine sum's exponent
// if plus1 If plus2 if said denorm but norm plus 1 if said denorm but norm plus 2 // if plus1 If plus2 if said Subnorm but norm plus 1 if said Subnorm but norm plus 2
assign FmaMe = (NormSumExp+{{`NE+1{1'b0}}, LZAPlus1} +{{`NE+1{1'b0}}, ~ResDenorm&FmaPreResultDenorm}) & {`NE+2{~(FmaSZero|ResDenorm)}}; assign FmaMe = (NormSumExp+{{`NE+1{1'b0}}, LZAPlus1} +{{`NE+1{1'b0}}, ~ResSubnorm&FmaPreResultSubnorm}) & {`NE+2{~(FmaSZero|ResSubnorm)}};
// recalculate if the result is denormalized // recalculate if the result is Subnormalized
assign ResDenorm = FmaPreResultDenorm&~Shifted[`NORMSHIFTSZ-2]&~Shifted[`NORMSHIFTSZ-1]; assign ResSubnorm = FmaPreResultSubnorm&~Shifted[`NORMSHIFTSZ-2]&~Shifted[`NORMSHIFTSZ-1];
// the quotent is in the range [.5,2) if there is no early termination // the quotent is in the range [.5,2) if there is no early termination
// if the quotent < 1 and not denormal then subtract 1 to account for the normalization shift // if the quotent < 1 and not Subnormal then subtract 1 to account for the normalization shift
assign Qe = (DivResDenorm & DivDenormShiftPos) ? '0 : DivQe - {(`NE+1)'(0), ~LZAPlus1}; assign Qe = (DivResSubnorm & DivSubnormShiftPos) ? '0 : DivQe - {(`NE+1)'(0), ~LZAPlus1};
endmodule endmodule

View File

@ -50,7 +50,7 @@ module specialcase(
input logic Plus1, input logic Plus1,
input logic DivByZero, input logic DivByZero,
input logic [`NE:0] CvtCe, // the calculated expoent input logic [`NE:0] CvtCe, // the calculated expoent
input logic Ws, // the res's sign input logic Rs, // the res's sign
input logic IntInvalid, Invalid, Overflow, // flags input logic IntInvalid, Invalid, Overflow, // flags
input logic CvtResUf, input logic CvtResUf,
input logic [`NE-1:0] Re, // Res exponent input logic [`NE-1:0] Re, // Res exponent
@ -69,7 +69,7 @@ module specialcase(
// does the overflow result output the maximum normalized floating point number // does the overflow result output the maximum normalized floating point number
// output infinity if the input is infinity // output infinity if the input is infinity
assign OfResMax = (~InfIn|(IntToFp&CvtOp))&~DivByZero&((Frm[1:0]==2'b01) | (Frm[1:0]==2'b10&~Ws) | (Frm[1:0]==2'b11&Ws)); assign OfResMax = (~InfIn|(IntToFp&CvtOp))&~DivByZero&((Frm[1:0]==2'b01) | (Frm[1:0]==2'b10&~Rs) | (Frm[1:0]==2'b11&Rs));
if (`FPSIZES == 1) begin if (`FPSIZES == 1) begin
@ -83,9 +83,9 @@ module specialcase(
assign InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; assign InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
end end
assign OfRes = OfResMax ? {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Ws, {`NE{1'b1}}, {`NF{1'b0}}}; assign OfRes = OfResMax ? {Rs, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Rs, {`NE{1'b1}}, {`NF{1'b0}}};
assign UfRes = {Ws, {`FLEN-2{1'b0}}, Plus1&Frm[1]&~(DivOp&YInf)}; assign UfRes = {Rs, {`FLEN-2{1'b0}}, Plus1&Frm[1]&~(DivOp&YInf)};
assign NormRes = {Ws, Re, Rf}; assign NormRes = {Rs, Re, Rf};
end else if (`FPSIZES == 2) begin //will the format conversion in killprod work in other conversions? end else if (`FPSIZES == 2) begin //will the format conversion in killprod work in other conversions?
if(`IEEE754) begin if(`IEEE754) begin
@ -99,13 +99,13 @@ module specialcase(
always_comb always_comb
if(OutFmt) if(OutFmt)
if(OfResMax) OfRes = {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}}; if(OfResMax) OfRes = {Rs, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}};
else OfRes = {Ws, {`NE{1'b1}}, {`NF{1'b0}}}; else OfRes = {Rs, {`NE{1'b1}}, {`NF{1'b0}}};
else else
if(OfResMax) OfRes = {{`FLEN-`LEN1{1'b1}}, Ws, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}}; if(OfResMax) OfRes = {{`FLEN-`LEN1{1'b1}}, Rs, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}};
else OfRes = {{`FLEN-`LEN1{1'b1}}, Ws, {`NE1{1'b1}}, (`NF1)'(0)}; else OfRes = {{`FLEN-`LEN1{1'b1}}, Rs, {`NE1{1'b1}}, (`NF1)'(0)};
assign UfRes = OutFmt ? {Ws, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)} : {{`FLEN-`LEN1{1'b1}}, Ws, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; assign UfRes = OutFmt ? {Rs, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)} : {{`FLEN-`LEN1{1'b1}}, Rs, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
assign NormRes = OutFmt ? {Ws, Re, Rf} : {{`FLEN-`LEN1{1'b1}}, Ws, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]}; assign NormRes = OutFmt ? {Rs, Re, Rf} : {{`FLEN-`LEN1{1'b1}}, Rs, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]};
end else if (`FPSIZES == 3) begin end else if (`FPSIZES == 3) begin
always_comb always_comb
@ -120,9 +120,9 @@ module specialcase(
InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
end end
OfRes = OfResMax ? {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Ws, {`NE{1'b1}}, {`NF{1'b0}}}; OfRes = OfResMax ? {Rs, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Rs, {`NE{1'b1}}, {`NF{1'b0}}};
UfRes = {Ws, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {Rs, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {Ws, Re, Rf}; NormRes = {Rs, Re, Rf};
end end
`FMT1: begin `FMT1: begin
if(`IEEE754) begin if(`IEEE754) begin
@ -133,9 +133,9 @@ module specialcase(
end else begin end else begin
InvalidRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; InvalidRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`LEN1{1'b1}}, Ws, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : {{`FLEN-`LEN1{1'b1}}, Ws, {`NE1{1'b1}}, (`NF1)'(0)}; OfRes = OfResMax ? {{`FLEN-`LEN1{1'b1}}, Rs, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : {{`FLEN-`LEN1{1'b1}}, Rs, {`NE1{1'b1}}, (`NF1)'(0)};
UfRes = {{`FLEN-`LEN1{1'b1}}, Ws, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {{`FLEN-`LEN1{1'b1}}, Rs, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`LEN1{1'b1}}, Ws, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]}; NormRes = {{`FLEN-`LEN1{1'b1}}, Rs, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]};
end end
`FMT2: begin `FMT2: begin
if(`IEEE754) begin if(`IEEE754) begin
@ -147,9 +147,9 @@ module specialcase(
InvalidRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; InvalidRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`LEN2{1'b1}}, Ws, {`NE2-1{1'b1}}, 1'b0, {`NF2{1'b1}}} : {{`FLEN-`LEN2{1'b1}}, Ws, {`NE2{1'b1}}, (`NF2)'(0)}; OfRes = OfResMax ? {{`FLEN-`LEN2{1'b1}}, Rs, {`NE2-1{1'b1}}, 1'b0, {`NF2{1'b1}}} : {{`FLEN-`LEN2{1'b1}}, Rs, {`NE2{1'b1}}, (`NF2)'(0)};
UfRes = {{`FLEN-`LEN2{1'b1}}, Ws, (`LEN2-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {{`FLEN-`LEN2{1'b1}}, Rs, (`LEN2-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`LEN2{1'b1}}, Ws, Re[`NE2-1:0], Rf[`NF-1:`NF-`NF2]}; NormRes = {{`FLEN-`LEN2{1'b1}}, Rs, Re[`NE2-1:0], Rf[`NF-1:`NF-`NF2]};
end end
default: begin default: begin
if(`IEEE754) begin if(`IEEE754) begin
@ -179,9 +179,9 @@ module specialcase(
InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
end end
OfRes = OfResMax ? {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Ws, {`NE{1'b1}}, {`NF{1'b0}}}; OfRes = OfResMax ? {Rs, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Rs, {`NE{1'b1}}, {`NF{1'b0}}};
UfRes = {Ws, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {Rs, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {Ws, Re, Rf}; NormRes = {Rs, Re, Rf};
end end
2'h1: begin 2'h1: begin
if(`IEEE754) begin if(`IEEE754) begin
@ -192,9 +192,9 @@ module specialcase(
end else begin end else begin
InvalidRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; InvalidRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`D_LEN{1'b1}}, Ws, {`D_NE-1{1'b1}}, 1'b0, {`D_NF{1'b1}}} : {{`FLEN-`D_LEN{1'b1}}, Ws, {`D_NE{1'b1}}, (`D_NF)'(0)}; OfRes = OfResMax ? {{`FLEN-`D_LEN{1'b1}}, Rs, {`D_NE-1{1'b1}}, 1'b0, {`D_NF{1'b1}}} : {{`FLEN-`D_LEN{1'b1}}, Rs, {`D_NE{1'b1}}, (`D_NF)'(0)};
UfRes = {{`FLEN-`D_LEN{1'b1}}, Ws, (`D_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {{`FLEN-`D_LEN{1'b1}}, Rs, (`D_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`D_LEN{1'b1}}, Ws, Re[`D_NE-1:0], Rf[`NF-1:`NF-`D_NF]}; NormRes = {{`FLEN-`D_LEN{1'b1}}, Rs, Re[`D_NE-1:0], Rf[`NF-1:`NF-`D_NF]};
end end
2'h0: begin 2'h0: begin
if(`IEEE754) begin if(`IEEE754) begin
@ -206,9 +206,9 @@ module specialcase(
InvalidRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; InvalidRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`S_LEN{1'b1}}, Ws, {`S_NE-1{1'b1}}, 1'b0, {`S_NF{1'b1}}} : {{`FLEN-`S_LEN{1'b1}}, Ws, {`S_NE{1'b1}}, (`S_NF)'(0)}; OfRes = OfResMax ? {{`FLEN-`S_LEN{1'b1}}, Rs, {`S_NE-1{1'b1}}, 1'b0, {`S_NF{1'b1}}} : {{`FLEN-`S_LEN{1'b1}}, Rs, {`S_NE{1'b1}}, (`S_NF)'(0)};
UfRes = {{`FLEN-`S_LEN{1'b1}}, Ws, (`S_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {{`FLEN-`S_LEN{1'b1}}, Rs, (`S_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`S_LEN{1'b1}}, Ws, Re[`S_NE-1:0], Rf[`NF-1:`NF-`S_NF]}; NormRes = {{`FLEN-`S_LEN{1'b1}}, Rs, Re[`S_NE-1:0], Rf[`NF-1:`NF-`S_NF]};
end end
2'h2: begin 2'h2: begin
if(`IEEE754) begin if(`IEEE754) begin
@ -220,10 +220,10 @@ module specialcase(
InvalidRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; InvalidRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`H_LEN{1'b1}}, Ws, {`H_NE-1{1'b1}}, 1'b0, {`H_NF{1'b1}}} : {{`FLEN-`H_LEN{1'b1}}, Ws, {`H_NE{1'b1}}, (`H_NF)'(0)}; OfRes = OfResMax ? {{`FLEN-`H_LEN{1'b1}}, Rs, {`H_NE-1{1'b1}}, 1'b0, {`H_NF{1'b1}}} : {{`FLEN-`H_LEN{1'b1}}, Rs, {`H_NE{1'b1}}, (`H_NF)'(0)};
// zero is exact fi dividing by infinity so don't add 1 // zero is exact fi dividing by infinity so don't add 1
UfRes = {{`FLEN-`H_LEN{1'b1}}, Ws, (`H_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {{`FLEN-`H_LEN{1'b1}}, Rs, (`H_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`H_LEN{1'b1}}, Ws, Re[`H_NE-1:0], Rf[`NF-1:`NF-`H_NF]}; NormRes = {{`FLEN-`H_LEN{1'b1}}, Rs, Re[`H_NE-1:0], Rf[`NF-1:`NF-`H_NF]};
end end
endcase endcase
@ -237,7 +237,7 @@ module specialcase(
// - do so if the res underflows, is zero (the exp doesnt calculate correctly). or the integer input is 0 // - do so if the res underflows, is zero (the exp doesnt calculate correctly). or the integer input is 0
// - dont set to zero if fp input is zero but not using the fp input // - dont set to zero if fp input is zero but not using the fp input
// - dont set to zero if int input is zero but not using the int input // - dont set to zero if int input is zero but not using the int input
assign KillRes = CvtOp ? (CvtResUf|(XZero&~IntToFp)|(IntZero&IntToFp)) : FullRe[`NE+1] | (((YInf&~XInf)|XZero)&DivOp);//Underflow & ~ResDenorm & (Re!=1); assign KillRes = CvtOp ? (CvtResUf|(XZero&~IntToFp)|(IntZero&IntToFp)) : FullRe[`NE+1] | (((YInf&~XInf)|XZero)&DivOp);//Underflow & ~ResSubnorm & (Re!=1);
assign SelOfRes = Overflow|DivByZero|(InfIn&~(YInf&DivOp)); assign SelOfRes = Overflow|DivByZero|(InfIn&~(YInf&DivOp));
// output infinity with result sign if divide by zero // output infinity with result sign if divide by zero
if(`IEEE754) if(`IEEE754)

View File

@ -38,7 +38,7 @@ module unpack (
output logic [`NF:0] Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision) output logic [`NF:0] Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision)
output logic XNaN, YNaN, ZNaN, // is XYZ a NaN output logic XNaN, YNaN, ZNaN, // is XYZ a NaN
output logic XSNaN, YSNaN, ZSNaN, // is XYZ a signaling NaN output logic XSNaN, YSNaN, ZSNaN, // is XYZ a signaling NaN
output logic XDenorm, ZDenorm, // is XYZ denormalized output logic XSubnorm, ZSubnorm, // is XYZ Subnormalized
output logic XZero, YZero, ZZero, // is XYZ zero output logic XZero, YZero, ZZero, // is XYZ zero
output logic XInf, YInf, ZInf, // is XYZ infinity output logic XInf, YInf, ZInf, // is XYZ infinity
output logic XExpMax // does X have the maximum exponent (NaN or Inf) output logic XExpMax // does X have the maximum exponent (NaN or Inf)
@ -59,7 +59,7 @@ module unpack (
unpackinput unpackinputZ (.In(Z), .Fmt, .Sgn(Zs), .Exp(Ze), .Man(Zm), .En(ZEn), unpackinput unpackinputZ (.In(Z), .Fmt, .Sgn(Zs), .Exp(Ze), .Man(Zm), .En(ZEn),
.NaN(ZNaN), .SNaN(ZSNaN), .ExpNonZero(ZExpNonZero), .NaN(ZNaN), .SNaN(ZSNaN), .ExpNonZero(ZExpNonZero),
.Zero(ZZero), .Inf(ZInf), .ExpMax(ZExpMax), .FracZero(ZFracZero)); .Zero(ZZero), .Inf(ZInf), .ExpMax(ZExpMax), .FracZero(ZFracZero));
// is the input denormalized // is the input Subnormalized
assign XDenorm = ~XExpNonZero & ~XFracZero; assign XSubnorm = ~XExpNonZero & ~XFracZero;
assign ZDenorm = ~ZExpNonZero & ~ZFracZero; assign ZSubnorm = ~ZExpNonZero & ~ZFracZero;
endmodule endmodule

View File

@ -54,7 +54,7 @@ module unpackinput (
assign Sgn = In[`FLEN-1]; // sign bit assign Sgn = In[`FLEN-1]; // sign bit
assign Frac = In[`NF-1:0]; // fraction (no assumed 1) assign Frac = In[`NF-1:0]; // fraction (no assumed 1)
assign ExpNonZero = |In[`FLEN-2:`NF]; // is the exponent non-zero assign ExpNonZero = |In[`FLEN-2:`NF]; // is the exponent non-zero
assign Exp = {In[`FLEN-2:`NF+1], In[`NF]|~ExpNonZero}; // exponent. Denormalized numbers have effective biased exponent of 1 assign Exp = {In[`FLEN-2:`NF+1], In[`NF]|~ExpNonZero}; // exponent. Subnormalized numbers have effective biased exponent of 1
assign ExpMax = &In[`FLEN-2:`NF]; // is the exponent all 1's assign ExpMax = &In[`FLEN-2:`NF]; // is the exponent all 1's
end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported
//***need better names for these constants //***need better names for these constants
@ -64,7 +64,7 @@ module unpackinput (
// `NE | `NE1 length of exponent // `NE | `NE1 length of exponent
// `NF | `NF1 length of fraction // `NF | `NF1 length of fraction
// `BIAS | `BIAS1 exponent's bias value // `BIAS | `BIAS1 exponent's bias value
// `FMT | `FMT1 precision's format value - Q=11 D=01 S=00 H=10 // `FMT | `FMT1 precision's format value - Q=11 D=01 Sticky=00 H=10
// Possible combinantions specified by spec: // Possible combinantions specified by spec:
// double and single // double and single
@ -93,10 +93,10 @@ module unpackinput (
// 896 = 0011 1000 0000 // 896 = 0011 1000 0000
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
// dexp = 0bdd dbbb bbbb // dexp = 0bdd dbbb bbbb
// also need to take into account possible zero/denorm/inf/NaN values // also need to take into account possible zero/Subnorm/inf/NaN values
// extract the exponent, converting the smaller exponent into the larger precision if nessisary // extract the exponent, converting the smaller exponent into the larger precision if nessisary
// - if the original precision had a denormal number convert the exponent value 1 // - if the original precision had a Subnormal number convert the exponent value 1
assign Exp = Fmt ? {In[`FLEN-2:`NF+1], In[`NF]|~ExpNonZero} : {In[`LEN1-2], {`NE-`NE1{~In[`LEN1-2]}}, In[`LEN1-3:`NF1+1], In[`NF1]|~ExpNonZero}; assign Exp = Fmt ? {In[`FLEN-2:`NF+1], In[`NF]|~ExpNonZero} : {In[`LEN1-2], {`NE-`NE1{~In[`LEN1-2]}}, In[`LEN1-3:`NF1+1], In[`NF1]|~ExpNonZero};
// is the exponent all 1's // is the exponent all 1's
@ -112,7 +112,7 @@ module unpackinput (
// `NE | `NE1 | `NE2 length of exponent // `NE | `NE1 | `NE2 length of exponent
// `NF | `NF1 | `NF2 length of fraction // `NF | `NF1 | `NF2 length of fraction
// `BIAS | `BIAS1 | `BIAS2 exponent's bias value // `BIAS | `BIAS1 | `BIAS2 exponent's bias value
// `FMT | `FMT1 | `FMT2 precision's format value - Q=11 D=01 S=00 H=10 // `FMT | `FMT1 | `FMT2 precision's format value - Q=11 D=01 Sticky=00 H=10
// Possible combinantions specified by spec: // Possible combinantions specified by spec:
// quad and double and single // quad and double and single
@ -164,7 +164,7 @@ module unpackinput (
// 896 = 0011 1000 0000 // 896 = 0011 1000 0000
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
// dexp = 0bdd dbbb bbbb // dexp = 0bdd dbbb bbbb
// also need to take into account possible zero/denorm/inf/NaN values // also need to take into account possible zero/Subnorm/inf/NaN values
// convert the larger precision's exponent to use the largest precision's bias // convert the larger precision's exponent to use the largest precision's bias
always_comb always_comb
@ -192,7 +192,7 @@ module unpackinput (
// `Q_NE | `D_NE | `S_NE | `H_NE length of exponent // `Q_NE | `D_NE | `S_NE | `H_NE length of exponent
// `Q_NF | `D_NF | `S_NF | `H_NF length of fraction // `Q_NF | `D_NF | `S_NF | `H_NF length of fraction
// `Q_BIAS | `D_BIAS | `S_BIAS | `H_BIAS exponent's bias value // `Q_BIAS | `D_BIAS | `S_BIAS | `H_BIAS exponent's bias value
// `Q_FMT | `D_FMT | `S_FMT | `H_FMT precision's format value - Q=11 D=01 S=00 H=10 // `Q_FMT | `D_FMT | `S_FMT | `H_FMT precision's format value - Q=11 D=01 Sticky=00 H=10
// Check NaN boxing // Check NaN boxing
always_comb always_comb
@ -238,7 +238,7 @@ module unpackinput (
// 896 = 0011 1000 0000 // 896 = 0011 1000 0000
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
// dexp = 0bdd dbbb bbbb // dexp = 0bdd dbbb bbbb
// also need to take into account possible zero/denorm/inf/NaN values // also need to take into account possible zero/Subnorm/inf/NaN values
// convert the double precsion exponent into quad precsion // convert the double precsion exponent into quad precsion
// 1 is added to the exponent if the input is zero or subnormal // 1 is added to the exponent if the input is zero or subnormal
@ -264,7 +264,7 @@ module unpackinput (
// Output logic // Output logic
assign FracZero = ~|Frac; // is the fraction zero? assign FracZero = ~|Frac; // is the fraction zero?
assign Man = {ExpNonZero, Frac}; // add the assumed one (or zero if denormal or zero) to create the significand assign Man = {ExpNonZero, Frac}; // add the assumed one (or zero if Subnormal or zero) to create the significand
assign NaN = ((ExpMax & ~FracZero)|BadNaNBox)&En; // is the input a NaN? assign NaN = ((ExpMax & ~FracZero)|BadNaNBox)&En; // is the input a NaN?
assign SNaN = NaN&~Frac[`NF-1]&~BadNaNBox; // is the input a singnaling NaN? assign SNaN = NaN&~Frac[`NF-1]&~BadNaNBox; // is the input a singnaling NaN?
assign Inf = ExpMax & FracZero &En; // is the input infinity? assign Inf = ExpMax & FracZero &En; // is the input infinity?

View File

@ -32,7 +32,7 @@
`include "wally-config.vh" `include "wally-config.vh"
`include "tests.vh" `include "tests.vh"
`define PrintHPMCounters 1 `define PrintHPMCounters 0
module testbench; module testbench;
parameter DEBUG=0; parameter DEBUG=0;