mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of github.com:davidharrishmc/riscv-wally
This commit is contained in:
commit
f119b492bb
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
//
|
//
|
||||||
|
@ -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
|
||||||
|
@ -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
|
@ -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;
|
||||||
|
@ -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
|
@ -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)
|
||||||
|
@ -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
|
@ -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?
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user