forked from Github_Repos/cvw
Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into HEAD
This commit is contained in:
commit
3e19500fc8
@ -32,11 +32,11 @@ module cvtshiftcalc(
|
||||
input logic XZero,
|
||||
input logic ToInt,
|
||||
input logic IntToFp,
|
||||
input logic [`NE:0] CvtCalcExpM, // the calculated expoent
|
||||
input logic [`NE:0] CvtCe, // the calculated expoent
|
||||
input logic [`NF:0] Xm, // input mantissas
|
||||
input logic [`FMTBITS-1:0] OutFmt, // output format
|
||||
input logic [`CVTLEN-1:0] CvtLzcInM, // input to the Leading Zero Counter (priority encoder)
|
||||
input logic CvtResDenormUfM,
|
||||
input logic [`CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (priority encoder)
|
||||
input logic CvtResDenormUf,
|
||||
output logic CvtResUf,
|
||||
output logic [`CVTLEN+`NF:0] CvtShiftIn // number to be shifted
|
||||
);
|
||||
@ -60,9 +60,9 @@ module cvtshiftcalc(
|
||||
// - otherwise:
|
||||
// | LzcInM | 0's if nessisary |
|
||||
// change to int shift to the left one
|
||||
assign CvtShiftIn = ToInt ? {{`XLEN{1'b0}}, Xm[`NF]&~CvtCalcExpM[`NE], Xm[`NF-1]|(CvtCalcExpM[`NE]&Xm[`NF]), Xm[`NF-2:0], {`CVTLEN-`XLEN{1'b0}}} :
|
||||
CvtResDenormUfM ? {{`NF-1{1'b0}}, Xm, {`CVTLEN-`NF+1{1'b0}}} :
|
||||
{CvtLzcInM, {`NF+1{1'b0}}};
|
||||
assign CvtShiftIn = ToInt ? {{`XLEN{1'b0}}, Xm[`NF]&~CvtCe[`NE], Xm[`NF-1]|(CvtCe[`NE]&Xm[`NF]), Xm[`NF-2:0], {`CVTLEN-`XLEN{1'b0}}} :
|
||||
CvtResDenormUf ? {{`NF-1{1'b0}}, Xm, {`CVTLEN-`NF+1{1'b0}}} :
|
||||
{CvtLzcIn, {`NF+1{1'b0}}};
|
||||
|
||||
|
||||
// choose the negative of the fraction size
|
||||
@ -93,6 +93,6 @@ module cvtshiftcalc(
|
||||
// determine if the result underflows ??? -> fp
|
||||
// - if the first 1 is shifted out of the result then the result underflows
|
||||
// - can't underflow an integer to fp conversions
|
||||
assign CvtResUf = ($signed(CvtCalcExpM) < $signed({{`NE-$clog2(`NF){1'b1}}, ResNegNF}))&~XZero&~IntToFp;
|
||||
assign CvtResUf = ($signed(CvtCe) < $signed({{`NE-$clog2(`NF){1'b1}}, ResNegNF}))&~XZero&~IntToFp;
|
||||
|
||||
endmodule
|
@ -3,60 +3,36 @@
|
||||
module divshiftcalc(
|
||||
input logic [`DIVLEN+2:0] Quot,
|
||||
input logic [`FMTBITS-1:0] Fmt,
|
||||
input logic [$clog2(`DIVLEN/2+3)-1:0] EarlyTermShiftDiv2M,
|
||||
input logic [`NE+1:0] DivCalcExpM,
|
||||
input logic [$clog2(`DIVLEN/2+3)-1:0] DivEarlyTermShiftDiv2,
|
||||
input logic [`NE+1:0] DivCalcExp,
|
||||
output logic [$clog2(`NORMSHIFTSZ)-1:0] DivShiftAmt,
|
||||
output logic [`NORMSHIFTSZ-1:0] DivShiftIn,
|
||||
output logic DivResDenorm,
|
||||
output logic [`NE+1:0] DivDenormShift
|
||||
);
|
||||
logic [`NE+1:0] NormShift;
|
||||
logic [`NE+1:0] Nf;
|
||||
|
||||
// is the result denromalized
|
||||
// if the exponent is 1 then the result needs to be normalized then the result is denormalizes
|
||||
assign DivResDenorm = DivCalcExpM[`NE+1]|(~|DivCalcExpM[`NE+1:0]);
|
||||
// select the proper fraction lengnth
|
||||
// if (`FPSIZES == 1) begin
|
||||
// assign Nf = (`NE+2)'(`NF);
|
||||
assign DivResDenorm = DivCalcExp[`NE+1]|(~|DivCalcExp[`NE+1:0]);
|
||||
|
||||
// end else if (`FPSIZES == 2) begin
|
||||
// assign Nf = Fmt ? (`NE+2)'(`NF) : (`NE+2)'(`NF1);
|
||||
|
||||
// end else if (`FPSIZES == 3) begin
|
||||
// always_comb
|
||||
// case (Fmt)
|
||||
// `FMT: Nf = (`NE+2)'(`NF);
|
||||
// `FMT1: Nf = (`NE+2)'(`NF1);
|
||||
// `FMT2: Nf = (`NE+2)'(`NF2);
|
||||
// default: Nf = 1'bx;
|
||||
// endcase
|
||||
// end else if (`FPSIZES == 4) begin
|
||||
// always_comb
|
||||
// case (Fmt)
|
||||
// 2'h3: Nf = (`NE+2)'(`Q_NF);
|
||||
// 2'h1: Nf = (`NE+2)'(`D_NF);
|
||||
// 2'h0: Nf = (`NE+2)'(`S_NF);
|
||||
// 2'h2: Nf = (`NE+2)'(`H_NF);
|
||||
// endcase
|
||||
// end
|
||||
// if the result is denormalized
|
||||
// 00000000x.xxxxxx... Exp = DivCalcExpM
|
||||
// .00000000xxxxxxx... >> NF+1 Exp = DivCalcExpM+NF+1
|
||||
// .00xxxxxxxxxxxxx... << DivCalcExpM+NF+1 Exp = +1
|
||||
// 00000000x.xxxxxx... Exp = DivCalcExp
|
||||
// .00000000xxxxxxx... >> NF+1 Exp = DivCalcExp+NF+1
|
||||
// .00xxxxxxxxxxxxx... << DivCalcExp+NF+1 Exp = +1
|
||||
// .0000xxxxxxxxxxx... >> 1 Exp = 1
|
||||
// Left shift amount = DivCalcExpM+NF+1-1
|
||||
assign DivDenormShift = (`NE+2)'(`NF)+DivCalcExpM;
|
||||
// Left shift amount = DivCalcExp+NF+1-1
|
||||
assign DivDenormShift = (`NE+2)'(`NF)+DivCalcExp;
|
||||
// if the result is normalized
|
||||
// 00000000x.xxxxxx... Exp = DivCalcExpM
|
||||
// .00000000xxxxxxx... >> NF+1 Exp = DivCalcExpM+NF+1
|
||||
// 00000000.xxxxxxx... << NF Exp = DivCalcExpM+1
|
||||
// 00000000x.xxxxxx... << NF Exp = DivCalcExpM (extra shift done afterwards)
|
||||
// 00000000xx.xxxxx... << 1? Exp = DivCalcExpM-1 (determined after)
|
||||
// 00000000x.xxxxxx... Exp = DivCalcExp
|
||||
// .00000000xxxxxxx... >> NF+1 Exp = DivCalcExp+NF+1
|
||||
// 00000000.xxxxxxx... << NF Exp = DivCalcExp+1
|
||||
// 00000000x.xxxxxx... << NF Exp = DivCalcExp (extra shift done afterwards)
|
||||
// 00000000xx.xxxxx... << 1? Exp = DivCalcExp-1 (determined after)
|
||||
// inital Left shift amount = NF
|
||||
assign NormShift = (`NE+2)'(`NF);
|
||||
// if the shift amount is negitive then dont shift (keep sticky bit)
|
||||
assign DivShiftAmt = (DivResDenorm ? DivDenormShift[$clog2(`NORMSHIFTSZ)-1:0]&{$clog2(`NORMSHIFTSZ){~DivDenormShift[`NE+1]}} : NormShift[$clog2(`NORMSHIFTSZ)-1:0])+{{$clog2(`NORMSHIFTSZ)-$clog2(`DIVLEN/2+3)-1{1'b0}}, EarlyTermShiftDiv2M&{$clog2(`DIVLEN/2+3){~DivDenormShift[`NE+1]}}, 1'b0};
|
||||
assign DivShiftAmt = (DivResDenorm ? DivDenormShift[$clog2(`NORMSHIFTSZ)-1:0]&{$clog2(`NORMSHIFTSZ){~DivDenormShift[`NE+1]}} : NormShift[$clog2(`NORMSHIFTSZ)-1:0])+{{$clog2(`NORMSHIFTSZ)-$clog2(`DIVLEN/2+3)-1{1'b0}}, DivEarlyTermShiftDiv2&{$clog2(`DIVLEN/2+3){~DivDenormShift[`NE+1]}}, 1'b0};
|
||||
|
||||
// *** may be able to reduce shifter size
|
||||
assign DivShiftIn = {{`NF{1'b0}}, Quot[`DIVLEN+2:0], {`NORMSHIFTSZ-`DIVLEN-3-`NF{1'b0}}};
|
||||
|
@ -6,7 +6,7 @@
|
||||
//
|
||||
// Purpose: Floating point conversions of configurable size
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
// Int component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
@ -21,7 +21,7 @@
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR Int PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
@ -31,21 +31,21 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module fcvt (
|
||||
input logic XSgnE, // input's sign
|
||||
input logic [`NE-1:0] XExpE, // input's exponent
|
||||
input logic [`NF:0] XManE, // input's fraction
|
||||
input logic [`XLEN-1:0] ForwardedSrcAE, // integer input - from IEU
|
||||
input logic [2:0] FOpCtrlE, // choose which opperation (look below for values)
|
||||
input logic FWriteIntE, // is fp->int (since it's writting to the integer register)
|
||||
input logic XZeroE, // is the input zero
|
||||
input logic XDenormE, // is the input denormalized
|
||||
input logic [`FMTBITS-1:0] FmtE, // the input's precision (11=quad 01=double 00=single 10=half)
|
||||
output logic [`NE:0] CvtCalcExpE, // the calculated expoent
|
||||
output logic [`LOGCVTLEN-1:0] CvtShiftAmtE, // how much to shift by
|
||||
output logic CvtResDenormUfE,// does the result underflow or is denormalized
|
||||
output logic CvtResSgnE, // the result's sign
|
||||
output logic IntZeroE, // is the integer zero?
|
||||
output logic [`CVTLEN-1:0] CvtLzcInE // input to the Leading Zero Counter (priority encoder)
|
||||
input logic Xs, // input's sign
|
||||
input logic [`NE-1:0] Xe, // input's exponent
|
||||
input logic [`NF:0] Xm, // input's fraction
|
||||
input logic [`XLEN-1:0] Int, // integer input - from IEU
|
||||
input logic [2:0] FOpCtrl, // choose which opperation (look below for values)
|
||||
input logic ToInt, // is fp->int (since it's writting to the integer register)
|
||||
input logic XZero, // is the input zero
|
||||
input logic XDenorm, // is the input denormalized
|
||||
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 [`LOGCVTLEN-1:0] ShiftAmt, // how much to shift by
|
||||
output logic ResDenormUf,// does the result underflow or is denormalized
|
||||
output logic Cs, // the result's sign
|
||||
output logic IntZero, // is the integer zero?
|
||||
output logic [`CVTLEN-1:0] LzcIn // input to the Leading Zero Counter (priority encoder)
|
||||
);
|
||||
|
||||
// OpCtrls:
|
||||
@ -58,9 +58,6 @@ module fcvt (
|
||||
// bit 2 bit 1 bit 0
|
||||
// for example: signed long -> single floating point has the OpCode 101
|
||||
|
||||
// (FF) fp -> fp coversion signals
|
||||
// (IF) int -> fp coversion signals
|
||||
// (FI) fp -> int coversion signals
|
||||
|
||||
|
||||
logic [`FMTBITS-1:0] OutFmt; // format of the output
|
||||
@ -71,23 +68,21 @@ module fcvt (
|
||||
logic Signed; // is the opperation with a signed integer?
|
||||
logic Int64; // is the integer 64 bits?
|
||||
logic IntToFp; // is the opperation an int->fp conversion?
|
||||
logic ToInt; // is the opperation an fp->int conversion?
|
||||
logic [`LOGCVTLEN-1:0] ZeroCnt; // output from the LZC
|
||||
logic [`LOGCVTLEN-1:0] LeadingZeros; // output from the LZC
|
||||
|
||||
|
||||
// seperate OpCtrl for code readability
|
||||
assign Signed = FOpCtrlE[0];
|
||||
assign Int64 = FOpCtrlE[1];
|
||||
assign IntToFp = FOpCtrlE[2];
|
||||
assign ToInt = FWriteIntE;
|
||||
assign Signed = FOpCtrl[0];
|
||||
assign Int64 = FOpCtrl[1];
|
||||
assign IntToFp = FOpCtrl[2];
|
||||
|
||||
// choose the ouptut format depending on the opperation
|
||||
// - fp -> fp: OpCtrl contains the percision of the output
|
||||
// - int -> fp: FmtE contains the percision of the output
|
||||
// - int -> fp: Fmt contains the percision of the output
|
||||
if (`FPSIZES == 2)
|
||||
assign OutFmt = IntToFp ? FmtE : (FOpCtrlE[1:0] == `FMT);
|
||||
assign OutFmt = IntToFp ? Fmt : (FOpCtrl[1:0] == `FMT);
|
||||
else if (`FPSIZES == 3 | `FPSIZES == 4)
|
||||
assign OutFmt = IntToFp ? FmtE : FOpCtrlE[1:0];
|
||||
assign OutFmt = IntToFp ? Fmt : FOpCtrl[1:0];
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -96,9 +91,9 @@ module fcvt (
|
||||
// 1) negate the input if the input is a negitive singed integer
|
||||
// 2) trim the input to the proper size (kill the 32 most significant zeroes if needed)
|
||||
|
||||
assign PosInt = CvtResSgnE ? -ForwardedSrcAE : ForwardedSrcAE;
|
||||
assign PosInt = Cs ? -Int : Int;
|
||||
assign TrimInt = {{`XLEN-32{Int64}}, {32{1'b1}}} & PosInt;
|
||||
assign IntZeroE = ~|TrimInt;
|
||||
assign IntZero = ~|TrimInt;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// lzc
|
||||
@ -107,10 +102,10 @@ module fcvt (
|
||||
// choose the input to the leading zero counter i.e. priority encoder
|
||||
// int -> fp : | positive integer | 00000... (if needed) |
|
||||
// fp -> fp : | fraction | 00000... (if needed) |
|
||||
assign CvtLzcInE = IntToFp ? {TrimInt, {`CVTLEN-`XLEN{1'b0}}} :
|
||||
{XManE[`NF-1:0], {`CVTLEN-`NF{1'b0}}};
|
||||
assign LzcIn = IntToFp ? {TrimInt, {`CVTLEN-`XLEN{1'b0}}} :
|
||||
{Xm[`NF-1:0], {`CVTLEN-`NF{1'b0}}};
|
||||
|
||||
lzc #(`CVTLEN) lzc (.num(CvtLzcInE), .ZeroCnt);
|
||||
lzc #(`CVTLEN) lzc (.num(LzcIn), .ZeroCnt(LeadingZeros));
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// shifter
|
||||
@ -124,13 +119,13 @@ module fcvt (
|
||||
// denormalized/undeflowed result fp -> fp:
|
||||
// - shift left by NF-1+CalcExp - to shift till the biased expoenent is 0
|
||||
// ??? -> fp:
|
||||
// - shift left by ZeroCnt+1 - to shift till the result is normalized
|
||||
// - shift left by LeadingZeros+1 - to shift till the result is normalized
|
||||
// - only shift fp -> fp if the intital value is denormalized
|
||||
// - 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?
|
||||
assign CvtShiftAmtE = ToInt ? CvtCalcExpE[`LOGCVTLEN-1:0]&{`LOGCVTLEN{~CvtCalcExpE[`NE]}} :
|
||||
CvtResDenormUfE&~IntToFp ? (`LOGCVTLEN)'(`NF-1)+CvtCalcExpE[`LOGCVTLEN-1:0] :
|
||||
(ZeroCnt+1)&{`LOGCVTLEN{XDenormE|IntToFp}};
|
||||
assign ShiftAmt = ToInt ? Ce[`LOGCVTLEN-1:0]&{`LOGCVTLEN{~Ce[`NE]}} :
|
||||
ResDenormUf&~IntToFp ? (`LOGCVTLEN)'(`NF-1)+Ce[`LOGCVTLEN-1:0] :
|
||||
(LeadingZeros+1)&{`LOGCVTLEN{XDenorm|IntToFp}};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// exp calculations
|
||||
@ -180,15 +175,15 @@ module fcvt (
|
||||
// select the old exponent
|
||||
// int -> fp : largest bias + XLEN
|
||||
// fp -> ??? : XExp
|
||||
assign OldExp = IntToFp ? (`NE)'(`BIAS)+(`NE)'(`XLEN) : XExpE;
|
||||
assign OldExp = IntToFp ? (`NE)'(`BIAS)+(`NE)'(`XLEN) : Xe;
|
||||
|
||||
// calculate CalcExp
|
||||
// fp -> fp :
|
||||
// - XExp - Largest bias + new bias - (ZeroCnt+1)
|
||||
// - XExp - Largest bias + new bias - (LeadingZeros+1)
|
||||
// only do ^ if the input was denormalized
|
||||
// - convert the expoenent to the final preciaion (Exp - oldBias + newBias)
|
||||
// - correct the expoent when there is a normalization shift ( + ZeroCnt+1)
|
||||
// fp -> int : XExp - Largest Bias + 1 - (ZeroCnt+1)
|
||||
// - correct the expoent when there is a normalization shift ( + LeadingZeros+1)
|
||||
// fp -> int : XExp - Largest Bias + 1 - (LeadingZeros+1)
|
||||
// | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp
|
||||
// process:
|
||||
// - start
|
||||
@ -202,18 +197,18 @@ module fcvt (
|
||||
// | 0's | Mantissa | 0's if nessisary |
|
||||
// | keep |
|
||||
//
|
||||
// - if the input is denormalized then we dont shift... so the "- (ZeroCnt+1)" is just leftovers from other options
|
||||
// int -> fp : largest bias + XLEN - Largest bias + new bias - 1 - ZeroCnt = XLEN + NewBias - 1 - ZeroCnt
|
||||
// - if the input is denormalized then we dont shift... so the "- (LeadingZeros+1)" is just leftovers from other options
|
||||
// int -> fp : largest bias + XLEN - Largest bias + new bias - 1 - LeadingZeros = XLEN + NewBias - 1 - LeadingZeros
|
||||
// Process:
|
||||
// - shifted right by XLEN (XLEN)
|
||||
// - shift left to normilize (-1-ZeroCnt)
|
||||
// - shift left to normilize (-1-LeadingZeros)
|
||||
// - newBias to make the biased exponent
|
||||
// oldexp - biasold +newbias - (ZeroCnt+1)&(XDenormE|IntToFp)
|
||||
assign CvtCalcExpE = {1'b0, OldExp} - (`NE+1)'(`BIAS) + {2'b0, NewBias} - {{`NE{1'b0}}, XDenormE|IntToFp} - {{`NE-`LOGCVTLEN+1{1'b0}}, (ZeroCnt&{`LOGCVTLEN{XDenormE|IntToFp}})};
|
||||
// oldexp - biasold +newbias - (LeadingZeros+1)&(XDenorm|IntToFp)
|
||||
assign Ce = {1'b0, OldExp} - (`NE+1)'(`BIAS) + {2'b0, NewBias} - {{`NE{1'b0}}, XDenorm|IntToFp} - {{`NE-`LOGCVTLEN+1{1'b0}}, (LeadingZeros&{`LOGCVTLEN{XDenorm|IntToFp}})};
|
||||
// find if the result is dnormal or underflows
|
||||
// - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0)
|
||||
// - can't underflow an integer to Fp conversion
|
||||
assign CvtResDenormUfE = (~|CvtCalcExpE | CvtCalcExpE[`NE])&~XZeroE&~IntToFp;
|
||||
assign ResDenormUf = (~|Ce | Ce[`NE])&~XZero&~IntToFp;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -225,7 +220,7 @@ module fcvt (
|
||||
// - if 64-bit : check the msb of the 64-bit integer input and if it's signed
|
||||
// - if 32-bit : check the msb of the 32-bit integer input and if it's signed
|
||||
// - otherwise: the floating point input's sign
|
||||
assign CvtResSgnE = IntToFp ? Int64 ? ForwardedSrcAE[`XLEN-1]&Signed : ForwardedSrcAE[31]&Signed : XSgnE;
|
||||
assign Cs = IntToFp ? Int64 ? Int[`XLEN-1]&Signed : Int[31]&Signed : Xs;
|
||||
|
||||
endmodule
|
||||
|
||||
|
@ -30,12 +30,12 @@
|
||||
|
||||
module flags(
|
||||
input logic Xs,
|
||||
input logic XSNaNM, YSNaNM, ZSNaNM, // inputs are signaling NaNs
|
||||
input logic XInfM, YInfM, ZInfM, // inputs are infinity
|
||||
input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
|
||||
input logic XInf, YInf, ZInf, // inputs are infinity
|
||||
input logic Plus1,
|
||||
input logic InfIn, // is a Inf input being used
|
||||
input logic XZero, YZero, // inputs are zero
|
||||
input logic XNaNM, YNaNM, // inputs are NaN
|
||||
input logic XNaN, YNaN, // inputs are NaN
|
||||
input logic NaNIn, // is a NaN input being used
|
||||
input logic Sqrt, // Sqrt?
|
||||
input logic ToInt, // convert to integer
|
||||
@ -43,18 +43,18 @@ module flags(
|
||||
input logic Int64, // convert to 64 bit integer
|
||||
input logic Signed, // convert to a signed integer
|
||||
input logic [`FMTBITS-1:0] OutFmt, // output format
|
||||
input logic [`NE:0] CvtCalcExpM, // the calculated expoent - Cvt
|
||||
input logic [`NE:0] CvtCe, // the calculated expoent - Cvt
|
||||
input logic CvtOp, // conversion opperation?
|
||||
input logic DivOp, // conversion opperation?
|
||||
input logic FmaOp, // Fma opperation?
|
||||
input logic [`NE+1:0] FullResExp, // ResExp with bits to determine sign and overflow
|
||||
input logic [`NE+1:0] RoundExp, // exponent of the normalized sum
|
||||
input logic [1:0] NegResMSBS, // the negitive integer result's most significant bits
|
||||
input logic ZSgnEffM, PSgnM, // the product and modified Z signs
|
||||
input logic Round, UfLSBRes, Sticky, UfPlus1, // bits used to determine rounding
|
||||
input logic [`NE+1:0] FullResExp, // Re with bits to determine sign and overflow
|
||||
input logic [`NE+1:0] Nexp, // exponent of the normalized sum
|
||||
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 R, UfLSBRes, S, UfPlus1, // bits used to determine rounding
|
||||
output logic DivByZero,
|
||||
output logic IntInvalid, Invalid, Overflow, // flags used to select the res
|
||||
output logic [4:0] PostProcFlgM // flags
|
||||
output logic [4:0] PostProcFlg // flags
|
||||
);
|
||||
logic SigNaN; // is an input a signaling NaN
|
||||
logic Inexact; // inexact flag
|
||||
@ -64,7 +64,7 @@ module flags(
|
||||
logic DivInvalid; // integer invalid flag
|
||||
logic Underflow; // Underflow flag
|
||||
logic ResExpGteMax; // is the result greater than or equal to the maximum floating point expoent
|
||||
logic ShiftGtIntSz; // is the shift greater than the the integer size (use ResExp to account for possible roundning "shift")
|
||||
logic ShiftGtIntSz; // is the shift greater than the the integer size (use Re to account for possible roundning "shift")
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Flags
|
||||
@ -127,16 +127,16 @@ module flags(
|
||||
// | | | | and if the result is not exact
|
||||
// | | | | | and if the input isnt infinity or NaN
|
||||
// | | | | | |
|
||||
assign Underflow = ((FullResExp[`NE+1] | (FullResExp == 0) | ((FullResExp == 1) & (RoundExp == 0) & ~(UfPlus1&UfLSBRes)))&(Round|Sticky))&~(InfIn|NaNIn|DivByZero);
|
||||
assign Underflow = ((FullResExp[`NE+1] | (FullResExp == 0) | ((FullResExp == 1) & (Nexp == 0) & ~(UfPlus1&UfLSBRes)))&(R|S))&~(InfIn|NaNIn|DivByZero);
|
||||
|
||||
// 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
|
||||
assign FpInexact = (Sticky|Overflow|Round|Underflow)&~(InfIn|NaNIn|DivByZero);
|
||||
assign FpInexact = (S|Overflow|R|Underflow)&~(InfIn|NaNIn|DivByZero);
|
||||
|
||||
// if the res is too small to be represented and not 0
|
||||
// | and if the res is not invalid (outside the integer bounds)
|
||||
// | |
|
||||
assign IntInexact = ((CvtCalcExpM[`NE]&~XZero)|Sticky|Round)&~IntInvalid;
|
||||
assign IntInexact = ((CvtCe[`NE]&~XZero)|S|R)&~IntInvalid;
|
||||
|
||||
// select the inexact flag to output
|
||||
assign Inexact = ToInt ? IntInexact : FpInexact;
|
||||
@ -153,12 +153,12 @@ module flags(
|
||||
// | | | | or the res rounds up out of bounds
|
||||
// | | | | and the res didn't underflow
|
||||
// | | | | |
|
||||
assign IntInvalid = XNaNM|XInfM|(ShiftGtIntSz&~FullResExp[`NE+1])|((Xs&~Signed)&(~((CvtCalcExpM[`NE]|(~|CvtCalcExpM))&~Plus1)))|(NegResMSBS[1]^NegResMSBS[0]);
|
||||
assign IntInvalid = XNaN|XInf|(ShiftGtIntSz&~FullResExp[`NE+1])|((Xs&~Signed)&(~((CvtCe[`NE]|(~|CvtCe))&~Plus1)))|(CvtNegResMsbs[1]^CvtNegResMsbs[0]);
|
||||
// |
|
||||
// or when the positive res rounds up out of range
|
||||
assign SigNaN = (XSNaNM&~(IntToFp&CvtOp)) | (YSNaNM&~CvtOp) | (ZSNaNM&FmaOp);
|
||||
assign FmaInvalid = ((XInfM | YInfM) & ZInfM & (PSgnM ^ ZSgnEffM) & ~XNaNM & ~YNaNM) | (XZero & YInfM) | (YZero & XInfM);
|
||||
assign DivInvalid = ((XInfM & YInfM) | (XZero & YZero))&~Sqrt | (Xs&Sqrt);
|
||||
assign SigNaN = (XSNaN&~(IntToFp&CvtOp)) | (YSNaN&~CvtOp) | (ZSNaN&FmaOp);
|
||||
assign FmaInvalid = ((XInf | YInf) & ZInf & (FmaPs ^ FmaAs) & ~XNaN & ~YNaN) | (XZero & YInf) | (YZero & XInf);
|
||||
assign DivInvalid = ((XInf & YInf) | (XZero & YZero))&~Sqrt | (Xs&Sqrt);
|
||||
|
||||
assign Invalid = SigNaN | (FmaInvalid&FmaOp) | (DivInvalid&DivOp);
|
||||
|
||||
@ -168,7 +168,7 @@ module flags(
|
||||
|
||||
// Combine flags
|
||||
// - to integer results do not set the underflow or overflow flags
|
||||
assign PostProcFlgM = {Invalid|(IntInvalid&CvtOp&ToInt), DivByZero, Overflow&~(ToInt&CvtOp), Underflow&~(ToInt&CvtOp), Inexact};
|
||||
assign PostProcFlg = {Invalid|(IntInvalid&CvtOp&ToInt), DivByZero, Overflow&~(ToInt&CvtOp), Underflow&~(ToInt&CvtOp), Inexact};
|
||||
|
||||
endmodule
|
||||
|
||||
|
@ -29,16 +29,16 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module fmashiftcalc(
|
||||
input logic [3*`NF+5:0] SumM, // the positive sum
|
||||
input logic [3*`NF+5:0] FmaSm, // the positive sum
|
||||
input logic [`NE-1:0] Ze, // exponent of Z
|
||||
input logic [`NE+1:0] ProdExpM, // X exponent + Y exponent - bias
|
||||
input logic [$clog2(3*`NF+7)-1:0] FmaNormCntM, // normalization shift count
|
||||
input logic [`NE+1:0] FmaPe, // X exponent + Y exponent - bias
|
||||
input logic [$clog2(3*`NF+7)-1:0] FmaNCnt, // normalization shift count
|
||||
input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
|
||||
input logic KillProdM, // is the product set to zero
|
||||
input logic ZDenormM,
|
||||
output logic [`NE+1:0] ConvNormSumExp, // exponent of the normalized sum not taking into account denormal or zero results
|
||||
output logic SumZero, // is the result denormalized - calculated before LZA corection
|
||||
output logic PreResultDenorm, // is the result denormalized - calculated before LZA corection
|
||||
input logic FmaKillProd, // is the product set to zero
|
||||
input logic ZDenorm,
|
||||
output logic [`NE+1:0] FmaConvNormSumExp, // exponent of the normalized sum not taking into account denormal or zero results
|
||||
output logic FmaSmZero, // is the result denormalized - calculated before LZA corection
|
||||
output logic FmaPreResultDenorm, // is the result denormalized - calculated before LZA corection
|
||||
output logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt, // normalization shift count
|
||||
output logic [3*`NF+8:0] FmaShiftIn // is the sum zero
|
||||
);
|
||||
@ -50,35 +50,35 @@ module fmashiftcalc(
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//*** insert bias-bias simplification in fcvt.sv/phone pictures
|
||||
// Determine if the sum is zero
|
||||
assign SumZero = ~(|SumM);
|
||||
assign FmaSmZero = ~(|FmaSm);
|
||||
|
||||
// calculate the sum's exponent
|
||||
assign NormSumExp = KillProdM ? {2'b0, Ze[`NE-1:1], Ze[0]&~ZDenormM} : ProdExpM + -{{`NE+2-$unsigned($clog2(3*`NF+7)){1'b0}}, FmaNormCntM} - 1 + (`NE+2)'(`NF+4);
|
||||
assign NormSumExp = FmaKillProd ? {2'b0, Ze[`NE-1:1], Ze[0]&~ZDenorm} : FmaPe + -{{`NE+2-$unsigned($clog2(3*`NF+7)){1'b0}}, FmaNCnt} - 1 + (`NE+2)'(`NF+4);
|
||||
|
||||
//convert the sum's exponent into the proper percision
|
||||
if (`FPSIZES == 1) begin
|
||||
assign ConvNormSumExp = NormSumExp;
|
||||
assign FmaConvNormSumExp = NormSumExp;
|
||||
|
||||
end else if (`FPSIZES == 2) begin
|
||||
assign ConvNormSumExp = Fmt ? NormSumExp : (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS1))&{`NE+2{|NormSumExp}};
|
||||
assign FmaConvNormSumExp = Fmt ? NormSumExp : (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS1))&{`NE+2{|NormSumExp}};
|
||||
|
||||
end else if (`FPSIZES == 3) begin
|
||||
always_comb begin
|
||||
case (Fmt)
|
||||
`FMT: ConvNormSumExp = NormSumExp;
|
||||
`FMT1: ConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS1))&{`NE+2{|NormSumExp}};
|
||||
`FMT2: ConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS2))&{`NE+2{|NormSumExp}};
|
||||
default: ConvNormSumExp = {`NE+2{1'bx}};
|
||||
`FMT: FmaConvNormSumExp = NormSumExp;
|
||||
`FMT1: FmaConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS1))&{`NE+2{|NormSumExp}};
|
||||
`FMT2: FmaConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS2))&{`NE+2{|NormSumExp}};
|
||||
default: FmaConvNormSumExp = {`NE+2{1'bx}};
|
||||
endcase
|
||||
end
|
||||
|
||||
end else if (`FPSIZES == 4) begin
|
||||
always_comb begin
|
||||
case (Fmt)
|
||||
2'h3: ConvNormSumExp = NormSumExp;
|
||||
2'h1: ConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`D_BIAS))&{`NE+2{|NormSumExp}};
|
||||
2'h0: ConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`S_BIAS))&{`NE+2{|NormSumExp}};
|
||||
2'h2: ConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`H_BIAS))&{`NE+2{|NormSumExp}};
|
||||
2'h3: FmaConvNormSumExp = NormSumExp;
|
||||
2'h1: FmaConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`D_BIAS))&{`NE+2{|NormSumExp}};
|
||||
2'h0: FmaConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`S_BIAS))&{`NE+2{|NormSumExp}};
|
||||
2'h2: FmaConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`H_BIAS))&{`NE+2{|NormSumExp}};
|
||||
endcase
|
||||
end
|
||||
|
||||
@ -90,7 +90,7 @@ module fmashiftcalc(
|
||||
logic Sum0LEZ, Sum0GEFL;
|
||||
assign Sum0LEZ = NormSumExp[`NE+1] | ~|NormSumExp;
|
||||
assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2));
|
||||
assign PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero;
|
||||
assign FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSmZero;
|
||||
|
||||
end else if (`FPSIZES == 2) begin
|
||||
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL;
|
||||
@ -98,7 +98,7 @@ module fmashiftcalc(
|
||||
assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2));
|
||||
assign Sum1LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1));
|
||||
assign Sum1GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF1+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)) | ~|NormSumExp;
|
||||
assign PreResultDenorm = (Fmt ? Sum0LEZ : Sum1LEZ) & (Fmt ? Sum0GEFL : Sum1GEFL) & ~SumZero;
|
||||
assign FmaPreResultDenorm = (Fmt ? Sum0LEZ : Sum1LEZ) & (Fmt ? Sum0GEFL : Sum1GEFL) & ~FmaSmZero;
|
||||
|
||||
end else if (`FPSIZES == 3) begin
|
||||
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL;
|
||||
@ -110,10 +110,10 @@ module fmashiftcalc(
|
||||
assign Sum2GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF2+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS2)) | ~|NormSumExp;
|
||||
always_comb begin
|
||||
case (Fmt)
|
||||
`FMT: PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero;
|
||||
`FMT1: PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero;
|
||||
`FMT2: PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero;
|
||||
default: PreResultDenorm = 1'bx;
|
||||
`FMT: FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSmZero;
|
||||
`FMT1: FmaPreResultDenorm = Sum1LEZ & Sum1GEFL & ~FmaSmZero;
|
||||
`FMT2: FmaPreResultDenorm = Sum2LEZ & Sum2GEFL & ~FmaSmZero;
|
||||
default: FmaPreResultDenorm = 1'bx;
|
||||
endcase
|
||||
end
|
||||
|
||||
@ -129,10 +129,10 @@ module fmashiftcalc(
|
||||
assign Sum3GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`H_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`H_BIAS)) | ~|NormSumExp;
|
||||
always_comb begin
|
||||
case (Fmt)
|
||||
2'h3: PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero;
|
||||
2'h1: PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero;
|
||||
2'h0: PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero;
|
||||
2'h2: PreResultDenorm = Sum3LEZ & Sum3GEFL & ~SumZero;
|
||||
2'h3: FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSmZero;
|
||||
2'h1: FmaPreResultDenorm = Sum1LEZ & Sum1GEFL & ~FmaSmZero;
|
||||
2'h0: FmaPreResultDenorm = Sum2LEZ & Sum2GEFL & ~FmaSmZero;
|
||||
2'h2: FmaPreResultDenorm = Sum3LEZ & Sum3GEFL & ~FmaSmZero;
|
||||
endcase // *** remove checking to see if it's underflowed and only check for less than zero for denorm checking
|
||||
end
|
||||
|
||||
@ -144,13 +144,13 @@ module fmashiftcalc(
|
||||
// - if kill prod dont add to exp
|
||||
|
||||
// Determine if the result is denormal
|
||||
// assign PreResultDenorm = $signed(ConvNormSumExp)<=0 & ($signed(ConvNormSumExp)>=$signed(-FracLen)) & ~SumZero;
|
||||
// assign FmaPreResultDenorm = $signed(FmaConvNormSumExp)<=0 & ($signed(FmaConvNormSumExp)>=$signed(-FracLen)) & ~FmaSmZero;
|
||||
|
||||
// Determine the shift needed for denormal results
|
||||
// - if not denorm add 1 to shift out the leading 1
|
||||
assign DenormShift = PreResultDenorm&~KillProdM ? ConvNormSumExp[$clog2(3*`NF+7)-1:0] : 1;
|
||||
assign DenormShift = FmaPreResultDenorm&~FmaKillProd ? FmaConvNormSumExp[$clog2(3*`NF+7)-1:0] : 1;
|
||||
// set and calculate the shift input and amount
|
||||
// - shift once if killing a product and the result is denormalized
|
||||
assign FmaShiftIn = {3'b0, SumM};
|
||||
assign FmaShiftAmt = (FmaNormCntM&{$clog2(3*`NF+7){~KillProdM}})+DenormShift;
|
||||
assign FmaShiftIn = {3'b0, FmaSm};
|
||||
assign FmaShiftAmt = (FmaNCnt&{$clog2(3*`NF+7){~FmaKillProd}})+DenormShift;
|
||||
endmodule
|
||||
|
@ -296,10 +296,10 @@ module fpu (
|
||||
fsgninj fsgninj(.SgnOpCodeE(FOpCtrlE[1:0]), .XSgnE, .YSgnE, .FSrcXE, .FmtE, .SgnResE);
|
||||
fclassify fclassify (.XSgnE, .XDenormE, .XZeroE, .XNaNE, .XInfE, .XSNaNE, .ClassResE);
|
||||
|
||||
fcvt fcvt (.XSgnE, .XExpE, .XManE, .ForwardedSrcAE, .FOpCtrlE,
|
||||
.FWriteIntE, .XZeroE, .XDenormE, .FmtE, .CvtCalcExpE,
|
||||
.CvtShiftAmtE, .CvtResDenormUfE, .CvtResSgnE, .IntZeroE,
|
||||
.CvtLzcInE);
|
||||
fcvt fcvt (.Xs(XSgnE), .Xe(XExpE), .Xm(XManE), .Int(ForwardedSrcAE), .FOpCtrl(FOpCtrlE),
|
||||
.ToInt(FWriteIntE), .XZero(XZeroE), .XDenorm(XDenormE), .Fmt(FmtE), .Ce(CvtCalcExpE),
|
||||
.ShiftAmt(CvtShiftAmtE), .ResDenormUf(CvtResDenormUfE), .Cs(CvtResSgnE), .IntZero(IntZeroE),
|
||||
.LzcIn(CvtLzcInE));
|
||||
|
||||
// data to be stored in memory - to IEU
|
||||
// - FP uses NaN-blocking format
|
||||
@ -381,12 +381,12 @@ module fpu (
|
||||
|
||||
assign FpLoadStoreM = FResSelM[1];
|
||||
|
||||
postprocess postprocess(.Xs(XSgnM), .Ys(YSgnM), .Ze(ZExpM), .Xm(XManM), .Ym(YManM), .Zm(ZManM), .Frm(FrmM), .Fmt(FmtM), .ProdExpM, .EarlyTermShiftDiv2M,
|
||||
.AddendStickyM, .KillProdM, .XZero(XZeroM), .YZero(YZeroM), .ZZero(ZZeroM), .XInfM, .YInfM, .Quot(QuotM),
|
||||
.ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM, .SumM, .DivCalcExpM, .DivDone(DivDoneM),
|
||||
.NegSumM, .InvZM(InvAM), .ZDenormM, .ZSgnEffM, .PSgnM, .FOpCtrl(FOpCtrlM), .FmaNormCntM, .DivNegStickyM,
|
||||
.CvtCalcExpM, .CvtResDenormUfM,.CvtShiftAmtM, .CvtResSgnM, .FWriteIntM, .DivStickyM,
|
||||
.CvtLzcInM, .IntZeroM, .PostProcSelM, .PostProcResM, .PostProcFlgM, .FCvtIntResM);
|
||||
postprocess postprocess(.Xs(XSgnM), .Ys(YSgnM), .Ze(ZExpM), .Xm(XManM), .Ym(YManM), .Zm(ZManM), .Frm(FrmM), .Fmt(FmtM), .FmaPe(ProdExpM), .DivEarlyTermShiftDiv2(EarlyTermShiftDiv2M),
|
||||
.FmaZmSticky(AddendStickyM), .FmaKillProd(KillProdM), .XZero(XZeroM), .YZero(YZeroM), .ZZero(ZZeroM), .XInf(XInfM), .YInf(YInfM), .Quot(QuotM),
|
||||
.ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM), .FmaSm(SumM), .DivCalcExp(DivCalcExpM), .DivDone(DivDoneM),
|
||||
.FmaNegSum(NegSumM), .FmaInvA(InvAM), .ZDenorm(ZDenormM), .FmaAs(ZSgnEffM), .FmaPs(PSgnM), .FOpCtrl(FOpCtrlM), .FmaNCnt(FmaNormCntM), .DivNegSticky(DivNegStickyM),
|
||||
.CvtCe(CvtCalcExpM), .CvtResDenormUf(CvtResDenormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CvtResSgnM), .ToInt(FWriteIntM), .DivSticky(DivStickyM),
|
||||
.CvtLzcIn(CvtLzcInM), .IntZero(IntZeroM), .PostProcSel(PostProcSelM), .W(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM));
|
||||
|
||||
// FPU flag selection - to privileged
|
||||
mux2 #(5) FPUFlgMux ({PreNVM&~FResSelM[1], 4'b0}, PostProcFlgM, ~FResSelM[1]&FResSelM[0], SetFflagsM);
|
||||
|
@ -33,15 +33,15 @@ module lzacorrection(
|
||||
input logic FmaOp,
|
||||
input logic DivOp,
|
||||
input logic DivResDenorm,
|
||||
input logic [`NE+1:0] DivCalcExpM,
|
||||
input logic [`NE+1:0] DivCalcExp,
|
||||
input logic [`NE+1:0] DivDenormShift,
|
||||
input logic [`NE+1:0] ConvNormSumExp, // exponent of the normalized sum not taking into account denormal or zero results
|
||||
input logic PreResultDenorm, // is the result denormalized - calculated before LZA corection
|
||||
input logic KillProdM, // is the product set to zero
|
||||
input logic SumZero,
|
||||
output logic [`CORRSHIFTSZ-1:0] CorrShifted, // the shifted sum before LZA correction
|
||||
output logic [`NE+1:0] CorrDivExp,
|
||||
output logic [`NE+1:0] SumExp // exponent of the normalized sum
|
||||
input logic [`NE+1:0] FmaConvNormSumExp, // exponent of the normalized sum not taking into account denormal or zero results
|
||||
input logic FmaPreResultDenorm, // is the result denormalized - calculated before LZA corection
|
||||
input logic FmaKillProd, // is the product set to zero
|
||||
input logic FmaSmZero,
|
||||
output logic [`CORRSHIFTSZ-1:0] Nfrac, // the shifted sum before LZA correction
|
||||
output logic [`NE+1:0] DivCorrExp,
|
||||
output logic [`NE+1:0] FmaSe // exponent of the normalized sum
|
||||
);
|
||||
logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction
|
||||
logic [`CORRSHIFTSZ:0] CorrQuotShifted;
|
||||
@ -54,16 +54,16 @@ module lzacorrection(
|
||||
// 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-3:1] : Shifted[`NORMSHIFTSZ-4:0];
|
||||
// if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Denorm)
|
||||
assign CorrQuotShifted = {LZAPlus2|(DivCalcExpM==1&~LZAPlus2) ? Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ] : {Shifted[`NORMSHIFTSZ-2:`NORMSHIFTSZ-`CORRSHIFTSZ], 1'b0}, 1'b0};
|
||||
assign CorrQuotShifted = {LZAPlus2|(DivCalcExp==1&~LZAPlus2) ? Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ] : {Shifted[`NORMSHIFTSZ-2:`NORMSHIFTSZ-`CORRSHIFTSZ], 1'b0}, 1'b0};
|
||||
// if the result of the divider was calculated to be denormalized, then the result was correctly normalized, so select the top shifted bits
|
||||
assign CorrShifted = FmaOp ? {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+6){1'b0}}} : DivOp&~DivResDenorm ? CorrQuotShifted[`CORRSHIFTSZ-1:0] : Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ];
|
||||
assign Nfrac = FmaOp ? {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+6){1'b0}}} : DivOp&~DivResDenorm ? CorrQuotShifted[`CORRSHIFTSZ-1:0] : Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ];
|
||||
// Determine sum's exponent
|
||||
// if plus1 If plus2 if said denorm but norm plus 1 if said denorm but norm plus 2
|
||||
assign SumExp = (ConvNormSumExp+{{`NE+1{1'b0}}, LZAPlus1&~KillProdM}+{{`NE{1'b0}}, LZAPlus2&~KillProdM, 1'b0}+{{`NE+1{1'b0}}, ~ResDenorm&PreResultDenorm&~KillProdM}+{{`NE+1{1'b0}}, &ConvNormSumExp&Shifted[3*`NF+6]&~KillProdM}) & {`NE+2{~(SumZero|ResDenorm)}};
|
||||
assign FmaSe = (FmaConvNormSumExp+{{`NE+1{1'b0}}, LZAPlus1&~FmaKillProd}+{{`NE{1'b0}}, LZAPlus2&~FmaKillProd, 1'b0}+{{`NE+1{1'b0}}, ~ResDenorm&FmaPreResultDenorm&~FmaKillProd}+{{`NE+1{1'b0}}, &FmaConvNormSumExp&Shifted[3*`NF+6]&~FmaKillProd}) & {`NE+2{~(FmaSmZero|ResDenorm)}};
|
||||
// recalculate if the result is denormalized
|
||||
assign ResDenorm = PreResultDenorm&~Shifted[`NORMSHIFTSZ-3]&~Shifted[`NORMSHIFTSZ-2];
|
||||
assign ResDenorm = FmaPreResultDenorm&~Shifted[`NORMSHIFTSZ-3]&~Shifted[`NORMSHIFTSZ-2];
|
||||
|
||||
// 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
|
||||
assign CorrDivExp = ((DivResDenorm)&~DivDenormShift[`NE+1]) ? (`NE+2)'(0) : DivCalcExpM - {(`NE+1)'(0), ~LZAPlus2};
|
||||
assign DivCorrExp = ((DivResDenorm)&~DivDenormShift[`NE+1]) ? (`NE+2)'(0) : DivCalcExp - {(`NE+1)'(0), ~LZAPlus2};
|
||||
endmodule
|
@ -34,15 +34,15 @@ module negateintres(
|
||||
input logic Signed,
|
||||
input logic Int64,
|
||||
input logic Plus1,
|
||||
output logic [1:0] NegResMSBS,
|
||||
output logic [`XLEN+1:0] NegRes
|
||||
output logic [1:0] CvtNegResMsbs,
|
||||
output logic [`XLEN+1:0] CvtNegRes
|
||||
);
|
||||
|
||||
|
||||
// round and negate the positive res if needed
|
||||
assign NegRes = Xs ? -({2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1}) : {2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1};
|
||||
assign CvtNegRes = Xs ? -({2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1}) : {2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1};
|
||||
|
||||
assign NegResMSBS = Signed ? Int64 ? NegRes[`XLEN:`XLEN-1] : NegRes[32:31] :
|
||||
Int64 ? NegRes[`XLEN+1:`XLEN] : NegRes[33:32];
|
||||
assign CvtNegResMsbs = Signed ? Int64 ? CvtNegRes[`XLEN:`XLEN-1] : CvtNegRes[32:31] :
|
||||
Int64 ? CvtNegRes[`XLEN+1:`XLEN] : CvtNegRes[33:32];
|
||||
|
||||
endmodule
|
@ -38,86 +38,85 @@ module postprocess(
|
||||
input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
|
||||
input logic [2:0] FOpCtrl, // choose which opperation (look below for values)
|
||||
input logic XZero, YZero, ZZero, // inputs are zero
|
||||
input logic XInfM, YInfM, ZInfM, // inputs are infinity
|
||||
input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN
|
||||
input logic XSNaNM, YSNaNM, ZSNaNM, // inputs are signaling NaNs
|
||||
input logic ZDenormM, // is the original precision denormalized
|
||||
input logic [1:0] PostProcSelM, // select result to be written to fp register
|
||||
input logic XInf, YInf, ZInf, // inputs are infinity
|
||||
input logic XNaN, YNaN, ZNaN, // inputs are NaN
|
||||
input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
|
||||
input logic ZDenorm, // is the original precision denormalized
|
||||
input logic [1:0] PostProcSel, // select result to be written to fp register
|
||||
//fma signals
|
||||
input logic [`NE+1:0] ProdExpM, // X exponent + Y exponent - bias
|
||||
input logic AddendStickyM, // sticky bit that is calculated during alignment
|
||||
input logic KillProdM, // set the product to zero before addition if the product is too small to matter
|
||||
input logic [3*`NF+5:0] SumM, // the positive sum
|
||||
input logic NegSumM, // was the sum negitive
|
||||
input logic InvZM, // do you invert Z
|
||||
input logic ZSgnEffM, // the modified Z sign - depends on instruction
|
||||
input logic PSgnM, // the product's sign
|
||||
input logic [$clog2(3*`NF+7)-1:0] FmaNormCntM, // the normalization shift count
|
||||
input logic FmaAs, // the modified Z sign - depends on instruction
|
||||
input logic FmaPs, // the product's sign
|
||||
input logic [`NE+1:0] FmaPe, // Product exponent
|
||||
input logic [3*`NF+5:0] FmaSm, // the positive sum
|
||||
input logic FmaZmSticky, // sticky bit that is calculated during alignment
|
||||
input logic FmaKillProd, // set the product to zero before addition if the product is too small to matter
|
||||
input logic FmaNegSum, // was the sum negitive
|
||||
input logic FmaInvA, // do you invert Z
|
||||
input logic [$clog2(3*`NF+7)-1:0] FmaNCnt, // the normalization shift count
|
||||
//divide signals
|
||||
input logic [$clog2(`DIVLEN/2+3)-1:0] EarlyTermShiftDiv2M,
|
||||
input logic DivStickyM,
|
||||
input logic DivNegStickyM,
|
||||
input logic [$clog2(`DIVLEN/2+3)-1:0] DivEarlyTermShiftDiv2,
|
||||
input logic DivSticky,
|
||||
input logic DivNegSticky,
|
||||
input logic DivDone,
|
||||
input logic [`NE+1:0] DivCalcExpM,
|
||||
input logic [`NE+1:0] DivCalcExp,
|
||||
input logic [`DIVLEN+2:0] Quot,
|
||||
// conversion signals
|
||||
input logic [`NE:0] CvtCalcExpM, // the calculated expoent
|
||||
input logic CvtResDenormUfM,
|
||||
input logic [`LOGCVTLEN-1:0] CvtShiftAmtM, // how much to shift by
|
||||
input logic CvtResSgnM, // the result's sign
|
||||
input logic FWriteIntM, // is fp->int (since it's writting to the integer register)
|
||||
input logic [`CVTLEN-1:0] CvtLzcInM, // input to the Leading Zero Counter (priority encoder)
|
||||
input logic IntZeroM, // is the input zero
|
||||
input logic CvtCs, // the result's sign
|
||||
input logic [`NE:0] CvtCe, // the calculated expoent
|
||||
input logic CvtResDenormUf,
|
||||
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 [`CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (priority encoder)
|
||||
input logic IntZero, // is the input zero
|
||||
// final results
|
||||
output logic [`FLEN-1:0] PostProcResM, // FMA final result
|
||||
output logic [4:0] PostProcFlgM,
|
||||
output logic [`XLEN-1:0] FCvtIntResM // the int conversion result
|
||||
output logic [`FLEN-1:0] W, // FMA final result
|
||||
output logic [4:0] PostProcFlg,
|
||||
output logic [`XLEN-1:0] FCvtIntRes // the int conversion result
|
||||
);
|
||||
|
||||
// general signals
|
||||
logic [`NF-1:0] ResFrac; // Result fraction
|
||||
logic [`NE-1:0] ResExp; // Result exponent
|
||||
logic [`CORRSHIFTSZ-1:0] CorrShifted; // corectly shifted fraction
|
||||
logic [`NE+1:0] FullResExp; // ResExp with bits to determine sign and overflow
|
||||
logic Sticky; // Sticky bit
|
||||
logic Ws;
|
||||
logic [`NF-1:0] Rf; // Result fraction
|
||||
logic [`NE-1:0] Re; // Result exponent
|
||||
logic Nsgn;
|
||||
logic [`NE+1:0] Nexp;
|
||||
logic [`CORRSHIFTSZ-1:0] Nfrac; // corectly shifted fraction
|
||||
logic [`NE+1:0] FullResExp; // Re with bits to determine sign and overflow
|
||||
logic S; // S bit
|
||||
logic UfPlus1; // do you add one (for determining underflow flag)
|
||||
logic Round; // bits needed to determine rounding
|
||||
logic R; // bits needed to determine rounding
|
||||
logic [`FLEN:0] RoundAdd; // how much to add to the result
|
||||
logic [$clog2(`NORMSHIFTSZ)-1:0] ShiftAmt; // normalization shift count
|
||||
logic [`NORMSHIFTSZ-1:0] ShiftIn; // is the sum zero
|
||||
logic [`NORMSHIFTSZ-1:0] Shifted; // the shifted result
|
||||
logic Plus1; // add one to the final result?
|
||||
logic IntInvalid, Overflow, Invalid; // flags
|
||||
logic [`NE+1:0] RoundExp;
|
||||
logic ResSgn;
|
||||
logic RoundSgn;
|
||||
logic UfLSBRes;
|
||||
logic [`FMTBITS-1:0] OutFmt;
|
||||
// fma signals
|
||||
logic [`NE+1:0] SumExp; // exponent of the normalized sum
|
||||
logic SumZero; // is the sum zero
|
||||
logic [3*`NF+8:0] FmaShiftIn; // is the sum zero
|
||||
logic [`NE+1:0] ConvNormSumExp; // exponent of the normalized sum not taking into account denormal or zero results
|
||||
logic PreResultDenorm; // is the result denormalized - calculated before LZA corection
|
||||
logic [`NE+1:0] FmaSe; // exponent of the normalized sum
|
||||
logic FmaSmZero; // is the sum zero
|
||||
logic [3*`NF+8:0] FmaShiftIn; // shift input
|
||||
logic [`NE+1:0] FmaConvNormSumExp; // exponent of the normalized sum not taking into account denormal or zero results
|
||||
logic FmaPreResultDenorm; // is the result denormalized - calculated before LZA corection
|
||||
logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt; // normalization shift count
|
||||
// division singals
|
||||
logic [$clog2(`NORMSHIFTSZ)-1:0] DivShiftAmt;
|
||||
logic [`NORMSHIFTSZ-1:0] DivShiftIn;
|
||||
logic [`NE+1:0] CorrDivExp;
|
||||
logic [`NE+1:0] DivCorrExp;
|
||||
logic DivByZero;
|
||||
logic DivResDenorm;
|
||||
logic [`NE+1:0] DivDenormShift;
|
||||
// conversion signals
|
||||
logic [`CVTLEN+`NF:0] CvtShiftIn; // number to be shifted
|
||||
logic [1:0] NegResMSBS;
|
||||
logic [`XLEN+1:0] NegRes;
|
||||
logic [1:0] CvtNegResMsbs;
|
||||
logic [`XLEN+1:0] CvtNegRes;
|
||||
logic CvtResUf;
|
||||
// readability signals
|
||||
logic Mult; // multiply opperation
|
||||
logic Int64; // is the integer 64 bits?
|
||||
logic Signed; // is the opperation with a signed integer?
|
||||
logic IntToFp; // is the opperation an int->fp conversion?
|
||||
logic ToInt; // is the opperation an fp->int conversion?
|
||||
logic CvtOp;
|
||||
logic FmaOp;
|
||||
logic DivOp;
|
||||
@ -129,16 +128,15 @@ module postprocess(
|
||||
assign Signed = FOpCtrl[0];
|
||||
assign Int64 = FOpCtrl[1];
|
||||
assign IntToFp = FOpCtrl[2];
|
||||
assign ToInt = FWriteIntM;
|
||||
assign Mult = FOpCtrl[2]&~FOpCtrl[1]&~FOpCtrl[0];
|
||||
assign CvtOp = (PostProcSelM == 2'b00);
|
||||
assign FmaOp = (PostProcSelM == 2'b10);
|
||||
assign DivOp = (PostProcSelM == 2'b01)&DivDone;
|
||||
assign CvtOp = (PostProcSel == 2'b00);
|
||||
assign FmaOp = (PostProcSel == 2'b10);
|
||||
assign DivOp = (PostProcSel == 2'b01)&DivDone;
|
||||
assign Sqrt = FOpCtrl[0];
|
||||
|
||||
// is there an input of infinity or NaN being used
|
||||
assign InfIn = (XInfM&~(IntToFp&CvtOp))|(YInfM&~CvtOp)|(ZInfM&FmaOp);
|
||||
assign NaNIn = (XNaNM&~(IntToFp&CvtOp))|(YNaNM&~CvtOp)|(ZNaNM&FmaOp);
|
||||
assign InfIn = (XInf&~(IntToFp&CvtOp))|(YInf&~CvtOp)|(ZInf&FmaOp);
|
||||
assign NaNIn = (XNaN&~(IntToFp&CvtOp))|(YNaN&~CvtOp)|(ZNaN&FmaOp);
|
||||
|
||||
// choose the ouptut format depending on the opperation
|
||||
// - fp -> fp: OpCtrl contains the percision of the output
|
||||
@ -152,20 +150,20 @@ module postprocess(
|
||||
// Normalization
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
cvtshiftcalc cvtshiftcalc(.ToInt, .CvtCalcExpM, .CvtResDenormUfM, .Xm, .CvtLzcInM,
|
||||
cvtshiftcalc cvtshiftcalc(.ToInt, .CvtCe, .CvtResDenormUf, .Xm, .CvtLzcIn,
|
||||
.XZero, .IntToFp, .OutFmt, .CvtResUf, .CvtShiftIn);
|
||||
fmashiftcalc fmashiftcalc(.SumM, .Ze, .ProdExpM, .FmaNormCntM, .Fmt, .KillProdM, .ConvNormSumExp,
|
||||
.ZDenormM, .SumZero, .PreResultDenorm, .FmaShiftAmt, .FmaShiftIn);
|
||||
divshiftcalc divshiftcalc(.Fmt, .DivCalcExpM, .Quot, .EarlyTermShiftDiv2M, .DivResDenorm, .DivDenormShift, .DivShiftAmt, .DivShiftIn);
|
||||
fmashiftcalc fmashiftcalc(.FmaSm, .Ze, .FmaPe, .FmaNCnt, .Fmt, .FmaKillProd, .FmaConvNormSumExp,
|
||||
.ZDenorm, .FmaSmZero, .FmaPreResultDenorm, .FmaShiftAmt, .FmaShiftIn);
|
||||
divshiftcalc divshiftcalc(.Fmt, .DivCalcExp, .Quot, .DivEarlyTermShiftDiv2, .DivResDenorm, .DivDenormShift, .DivShiftAmt, .DivShiftIn);
|
||||
|
||||
always_comb
|
||||
case(PostProcSelM)
|
||||
case(PostProcSel)
|
||||
2'b10: begin // fma
|
||||
ShiftAmt = {{$clog2(`NORMSHIFTSZ)-$clog2(3*`NF+7){1'b0}}, FmaShiftAmt};
|
||||
ShiftIn = {FmaShiftIn, {`NORMSHIFTSZ-(3*`NF+9){1'b0}}};
|
||||
end
|
||||
2'b00: begin // cvt
|
||||
ShiftAmt = {{$clog2(`NORMSHIFTSZ)-$clog2(`CVTLEN+1){1'b0}}, CvtShiftAmtM};
|
||||
ShiftAmt = {{$clog2(`NORMSHIFTSZ)-$clog2(`CVTLEN+1){1'b0}}, CvtShiftAmt};
|
||||
ShiftIn = {CvtShiftIn, {`NORMSHIFTSZ-`CVTLEN-`NF-1{1'b0}}};
|
||||
end
|
||||
2'b01: begin //div
|
||||
@ -185,9 +183,9 @@ module postprocess(
|
||||
|
||||
normshift normshift (.ShiftIn, .ShiftAmt, .Shifted);
|
||||
|
||||
lzacorrection lzacorrection(.FmaOp, .KillProdM, .PreResultDenorm, .ConvNormSumExp,
|
||||
.DivResDenorm, .DivDenormShift, .DivOp, .DivCalcExpM,
|
||||
.CorrDivExp, .SumZero, .Shifted, .SumExp, .CorrShifted);
|
||||
lzacorrection lzacorrection(.FmaOp, .FmaKillProd, .FmaPreResultDenorm, .FmaConvNormSumExp,
|
||||
.DivResDenorm, .DivDenormShift, .DivOp, .DivCalcExp,
|
||||
.DivCorrExp, .FmaSmZero, .Shifted, .FmaSe, .Nfrac);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Rounding
|
||||
@ -200,40 +198,40 @@ module postprocess(
|
||||
// round to nearest max magnitude
|
||||
|
||||
|
||||
roundsign roundsign(.PSgnM, .ZSgnEffM, .InvZM, .FmaOp, .DivOp, .CvtOp, .NegSumM,
|
||||
.Xs, .Ys, .CvtResSgnM, .RoundSgn);
|
||||
roundsign roundsign(.FmaPs, .FmaAs, .FmaInvA, .FmaOp, .DivOp, .CvtOp, .FmaNegSum,
|
||||
.Xs, .Ys, .CvtCs, .Nsgn);
|
||||
|
||||
round round(.OutFmt, .Frm, .Sticky, .AddendStickyM, .ZZero, .Plus1, .PostProcSelM, .CvtCalcExpM, .CorrDivExp,
|
||||
.InvZM, .RoundSgn, .SumExp, .FmaOp, .CvtOp, .CvtResDenormUfM, .CorrShifted, .ToInt, .CvtResUf,
|
||||
.DivStickyM, .DivNegStickyM, .DivDone,
|
||||
.DivOp, .UfPlus1, .FullResExp, .ResFrac, .ResExp, .Round, .RoundAdd, .UfLSBRes, .RoundExp);
|
||||
round round(.OutFmt, .Frm, .S, .FmaZmSticky, .ZZero, .Plus1, .PostProcSel, .CvtCe, .DivCorrExp,
|
||||
.FmaInvA, .Nsgn, .FmaSe, .FmaOp, .CvtOp, .CvtResDenormUf, .Nfrac, .ToInt, .CvtResUf,
|
||||
.DivSticky, .DivNegSticky, .DivDone,
|
||||
.DivOp, .UfPlus1, .FullResExp, .Rf, .Re, .R, .RoundAdd, .UfLSBRes, .Nexp);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Sign calculation
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
resultsign resultsign(.Frm, .PSgnM, .ZSgnEffM, .SumExp, .Round, .Sticky,
|
||||
.FmaOp, .ZInfM, .InfIn, .SumZero, .Mult, .RoundSgn, .ResSgn);
|
||||
resultsign resultsign(.Frm, .FmaPs, .FmaAs, .FmaSe, .R, .S,
|
||||
.FmaOp, .ZInf, .InfIn, .FmaSmZero, .Mult, .Nsgn, .Ws);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Flags
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
flags flags(.XSNaNM, .YSNaNM, .ZSNaNM, .XInfM, .YInfM, .ZInfM, .InfIn, .XZero, .YZero,
|
||||
.Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCalcExpM,
|
||||
.XNaNM, .YNaNM, .NaNIn, .ZSgnEffM, .PSgnM, .Round, .IntInvalid, .DivByZero,
|
||||
.UfLSBRes, .Sticky, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullResExp, .Plus1,
|
||||
.RoundExp, .NegResMSBS, .Invalid, .Overflow, .PostProcFlgM);
|
||||
flags flags(.XSNaN, .YSNaN, .ZSNaN, .XInf, .YInf, .ZInf, .InfIn, .XZero, .YZero,
|
||||
.Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCe,
|
||||
.XNaN, .YNaN, .NaNIn, .FmaAs, .FmaPs, .R, .IntInvalid, .DivByZero,
|
||||
.UfLSBRes, .S, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullResExp, .Plus1,
|
||||
.Nexp, .CvtNegResMsbs, .Invalid, .Overflow, .PostProcFlg);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Select the result
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
negateintres negateintres(.Xs, .Shifted, .Signed, .Int64, .Plus1, .NegResMSBS, .NegRes);
|
||||
negateintres negateintres(.Xs, .Shifted, .Signed, .Int64, .Plus1, .CvtNegResMsbs, .CvtNegRes);
|
||||
resultselect resultselect(.Xs, .Xm, .Ym, .Zm, .XZero, .IntInvalid,
|
||||
.IntZeroM, .Frm, .OutFmt, .XNaNM, .YNaNM, .ZNaNM, .CvtResUf,
|
||||
.NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .NegRes,
|
||||
.XInfM, .YInfM, .DivOp,
|
||||
.DivByZero, .FullResExp, .CvtCalcExpM, .ResSgn, .ResExp, .ResFrac, .PostProcResM, .FCvtIntResM);
|
||||
.IntZero, .Frm, .OutFmt, .XNaN, .YNaN, .ZNaN, .CvtResUf,
|
||||
.NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .CvtNegRes,
|
||||
.XInf, .YInf, .DivOp,
|
||||
.DivByZero, .FullResExp, .CvtCe, .Ws, .Re, .Rf, .W, .FCvtIntRes);
|
||||
|
||||
endmodule
|
||||
|
@ -32,13 +32,13 @@
|
||||
module resultselect(
|
||||
input logic Xs, // input signs
|
||||
input logic [`NF:0] Xm, Ym, Zm, // input mantissas
|
||||
input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN
|
||||
input logic XNaN, YNaN, ZNaN, // inputs are NaN
|
||||
input logic [2:0] Frm, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
|
||||
input logic [`FMTBITS-1:0] OutFmt, // output format
|
||||
input logic InfIn,
|
||||
input logic XInfM, YInfM,
|
||||
input logic XInf, YInf,
|
||||
input logic XZero,
|
||||
input logic IntZeroM,
|
||||
input logic IntZero,
|
||||
input logic NaNIn,
|
||||
input logic IntToFp,
|
||||
input logic Int64,
|
||||
@ -48,16 +48,16 @@ module resultselect(
|
||||
input logic FmaOp,
|
||||
input logic Plus1,
|
||||
input logic DivByZero,
|
||||
input logic [`NE:0] CvtCalcExpM, // the calculated expoent
|
||||
input logic ResSgn, // the res's sign
|
||||
input logic [`NE:0] CvtCe, // the calculated expoent
|
||||
input logic Ws, // the res's sign
|
||||
input logic IntInvalid, Invalid, Overflow, // flags
|
||||
input logic CvtResUf,
|
||||
input logic [`NE-1:0] ResExp, // Res exponent
|
||||
input logic [`NE-1:0] Re, // Res exponent
|
||||
input logic [`NE+1:0] FullResExp, // Res exponent
|
||||
input logic [`NF-1:0] ResFrac, // Res fraction
|
||||
input logic [`XLEN+1:0] NegRes, // the negation of the result
|
||||
output logic [`FLEN-1:0] PostProcResM, // final res
|
||||
output logic [`XLEN-1:0] FCvtIntResM // final res
|
||||
input logic [`NF-1:0] Rf, // Res fraction
|
||||
input logic [`XLEN+1:0] CvtNegRes, // the negation of the result
|
||||
output logic [`FLEN-1:0] W, // final res
|
||||
output logic [`XLEN-1:0] FCvtIntRes // final res
|
||||
);
|
||||
logic [`FLEN-1:0] XNaNRes, YNaNRes, ZNaNRes, InvalidRes, OfRes, UfRes, NormRes; // possible results
|
||||
logic OfResMax;
|
||||
@ -68,7 +68,7 @@ module resultselect(
|
||||
|
||||
// does the overflow result output the maximum normalized floating point number
|
||||
// output infinity if the input is infinity
|
||||
assign OfResMax = (~InfIn|(IntToFp&CvtOp))&~DivByZero&((Frm[1:0]==2'b01) | (Frm[1:0]==2'b10&~ResSgn) | (Frm[1:0]==2'b11&ResSgn));
|
||||
assign OfResMax = (~InfIn|(IntToFp&CvtOp))&~DivByZero&((Frm[1:0]==2'b01) | (Frm[1:0]==2'b10&~Ws) | (Frm[1:0]==2'b11&Ws));
|
||||
|
||||
if (`FPSIZES == 1) begin
|
||||
|
||||
@ -82,9 +82,9 @@ module resultselect(
|
||||
assign InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
|
||||
end
|
||||
|
||||
assign OfRes = OfResMax ? {ResSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResSgn, {`NE{1'b1}}, {`NF{1'b0}}};
|
||||
assign UfRes = {ResSgn, {`FLEN-2{1'b0}}, Plus1&Frm[1]&~(DivOp&YInfM)};
|
||||
assign NormRes = {ResSgn, ResExp, ResFrac};
|
||||
assign OfRes = OfResMax ? {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Ws, {`NE{1'b1}}, {`NF{1'b0}}};
|
||||
assign UfRes = {Ws, {`FLEN-2{1'b0}}, Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
assign NormRes = {Ws, Re, Rf};
|
||||
|
||||
end else if (`FPSIZES == 2) begin //will the format conversion in killprod work in other conversions?
|
||||
if(`IEEE754) begin
|
||||
@ -96,10 +96,10 @@ module resultselect(
|
||||
assign InvalidRes = OutFmt ? {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)};
|
||||
end
|
||||
|
||||
assign OfRes = OutFmt ? OfResMax ? {ResSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResSgn, {`NE{1'b1}}, {`NF{1'b0}}} :
|
||||
OfResMax ? {{`FLEN-`LEN1{1'b1}}, ResSgn, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : {{`FLEN-`LEN1{1'b1}}, ResSgn, {`NE1{1'b1}}, (`NF1)'(0)};
|
||||
assign UfRes = OutFmt ? {ResSgn, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)} : {{`FLEN-`LEN1{1'b1}}, ResSgn, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)};
|
||||
assign NormRes = OutFmt ? {ResSgn, ResExp, ResFrac} : {{`FLEN-`LEN1{1'b1}}, ResSgn, ResExp[`NE1-1:0], ResFrac[`NF-1:`NF-`NF1]};
|
||||
assign OfRes = OutFmt ? OfResMax ? {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Ws, {`NE{1'b1}}, {`NF{1'b0}}} :
|
||||
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)};
|
||||
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 NormRes = OutFmt ? {Ws, Re, Rf} : {{`FLEN-`LEN1{1'b1}}, Ws, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]};
|
||||
|
||||
end else if (`FPSIZES == 3) begin
|
||||
always_comb
|
||||
@ -114,9 +114,9 @@ module resultselect(
|
||||
InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
|
||||
end
|
||||
|
||||
OfRes = OfResMax ? {ResSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResSgn, {`NE{1'b1}}, {`NF{1'b0}}};
|
||||
UfRes = {ResSgn, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)};
|
||||
NormRes = {ResSgn, ResExp, ResFrac};
|
||||
OfRes = OfResMax ? {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Ws, {`NE{1'b1}}, {`NF{1'b0}}};
|
||||
UfRes = {Ws, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {Ws, Re, Rf};
|
||||
end
|
||||
`FMT1: begin
|
||||
if(`IEEE754) begin
|
||||
@ -127,9 +127,9 @@ module resultselect(
|
||||
end else begin
|
||||
InvalidRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)};
|
||||
end
|
||||
OfRes = OfResMax ? {{`FLEN-`LEN1{1'b1}}, ResSgn, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : {{`FLEN-`LEN1{1'b1}}, ResSgn, {`NE1{1'b1}}, (`NF1)'(0)};
|
||||
UfRes = {{`FLEN-`LEN1{1'b1}}, ResSgn, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)};
|
||||
NormRes = {{`FLEN-`LEN1{1'b1}}, ResSgn, ResExp[`NE1-1:0], ResFrac[`NF-1:`NF-`NF1]};
|
||||
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)};
|
||||
UfRes = {{`FLEN-`LEN1{1'b1}}, Ws, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {{`FLEN-`LEN1{1'b1}}, Ws, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]};
|
||||
end
|
||||
`FMT2: begin
|
||||
if(`IEEE754) begin
|
||||
@ -141,9 +141,9 @@ module resultselect(
|
||||
InvalidRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)};
|
||||
end
|
||||
|
||||
OfRes = OfResMax ? {{`FLEN-`LEN2{1'b1}}, ResSgn, {`NE2-1{1'b1}}, 1'b0, {`NF2{1'b1}}} : {{`FLEN-`LEN2{1'b1}}, ResSgn, {`NE2{1'b1}}, (`NF2)'(0)};
|
||||
UfRes = {{`FLEN-`LEN2{1'b1}}, ResSgn, (`LEN2-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)};
|
||||
NormRes = {{`FLEN-`LEN2{1'b1}}, ResSgn, ResExp[`NE2-1:0], ResFrac[`NF-1:`NF-`NF2]};
|
||||
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)};
|
||||
UfRes = {{`FLEN-`LEN2{1'b1}}, Ws, (`LEN2-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {{`FLEN-`LEN2{1'b1}}, Ws, Re[`NE2-1:0], Rf[`NF-1:`NF-`NF2]};
|
||||
end
|
||||
default: begin
|
||||
if(`IEEE754) begin
|
||||
@ -173,9 +173,9 @@ module resultselect(
|
||||
InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
|
||||
end
|
||||
|
||||
OfRes = OfResMax ? {ResSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResSgn, {`NE{1'b1}}, {`NF{1'b0}}};
|
||||
UfRes = {ResSgn, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)};
|
||||
NormRes = {ResSgn, ResExp, ResFrac};
|
||||
OfRes = OfResMax ? {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Ws, {`NE{1'b1}}, {`NF{1'b0}}};
|
||||
UfRes = {Ws, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {Ws, Re, Rf};
|
||||
end
|
||||
2'h1: begin
|
||||
if(`IEEE754) begin
|
||||
@ -186,9 +186,9 @@ module resultselect(
|
||||
end else begin
|
||||
InvalidRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)};
|
||||
end
|
||||
OfRes = OfResMax ? {{`FLEN-`D_LEN{1'b1}}, ResSgn, {`D_NE-1{1'b1}}, 1'b0, {`D_NF{1'b1}}} : {{`FLEN-`D_LEN{1'b1}}, ResSgn, {`D_NE{1'b1}}, (`D_NF)'(0)};
|
||||
UfRes = {{`FLEN-`D_LEN{1'b1}}, ResSgn, (`D_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)};
|
||||
NormRes = {{`FLEN-`D_LEN{1'b1}}, ResSgn, ResExp[`D_NE-1:0], ResFrac[`NF-1:`NF-`D_NF]};
|
||||
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)};
|
||||
UfRes = {{`FLEN-`D_LEN{1'b1}}, Ws, (`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]};
|
||||
end
|
||||
2'h0: begin
|
||||
if(`IEEE754) begin
|
||||
@ -200,9 +200,9 @@ module resultselect(
|
||||
InvalidRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)};
|
||||
end
|
||||
|
||||
OfRes = OfResMax ? {{`FLEN-`S_LEN{1'b1}}, ResSgn, {`S_NE-1{1'b1}}, 1'b0, {`S_NF{1'b1}}} : {{`FLEN-`S_LEN{1'b1}}, ResSgn, {`S_NE{1'b1}}, (`S_NF)'(0)};
|
||||
UfRes = {{`FLEN-`S_LEN{1'b1}}, ResSgn, (`S_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)};
|
||||
NormRes = {{`FLEN-`S_LEN{1'b1}}, ResSgn, ResExp[`S_NE-1:0], ResFrac[`NF-1:`NF-`S_NF]};
|
||||
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)};
|
||||
UfRes = {{`FLEN-`S_LEN{1'b1}}, Ws, (`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]};
|
||||
end
|
||||
2'h2: begin
|
||||
if(`IEEE754) begin
|
||||
@ -214,10 +214,10 @@ module resultselect(
|
||||
InvalidRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)};
|
||||
end
|
||||
|
||||
OfRes = OfResMax ? {{`FLEN-`H_LEN{1'b1}}, ResSgn, {`H_NE-1{1'b1}}, 1'b0, {`H_NF{1'b1}}} : {{`FLEN-`H_LEN{1'b1}}, ResSgn, {`H_NE{1'b1}}, (`H_NF)'(0)};
|
||||
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)};
|
||||
// zero is exact fi dividing by infinity so don't add 1
|
||||
UfRes = {{`FLEN-`H_LEN{1'b1}}, ResSgn, (`H_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)};
|
||||
NormRes = {{`FLEN-`H_LEN{1'b1}}, ResSgn, ResExp[`H_NE-1:0], ResFrac[`NF-1:`NF-`H_NF]};
|
||||
UfRes = {{`FLEN-`H_LEN{1'b1}}, Ws, (`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]};
|
||||
end
|
||||
endcase
|
||||
|
||||
@ -231,19 +231,19 @@ module resultselect(
|
||||
// - 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 int input is zero but not using the int input
|
||||
assign KillRes = CvtOp ? (CvtResUf|(XZero&~IntToFp)|(IntZeroM&IntToFp)) : FullResExp[`NE+1] | (((YInfM&~XInfM)|XZero)&DivOp);//Underflow & ~ResDenorm & (ResExp!=1);
|
||||
assign SelOfRes = Overflow|DivByZero|(InfIn&~(YInfM&DivOp));
|
||||
assign KillRes = CvtOp ? (CvtResUf|(XZero&~IntToFp)|(IntZero&IntToFp)) : FullResExp[`NE+1] | (((YInf&~XInf)|XZero)&DivOp);//Underflow & ~ResDenorm & (Re!=1);
|
||||
assign SelOfRes = Overflow|DivByZero|(InfIn&~(YInf&DivOp));
|
||||
// output infinity with result sign if divide by zero
|
||||
if(`IEEE754) begin
|
||||
assign PostProcResM = XNaNM&~(IntToFp&CvtOp) ? XNaNRes :
|
||||
YNaNM&~CvtOp ? YNaNRes :
|
||||
ZNaNM&FmaOp ? ZNaNRes :
|
||||
assign W = XNaN&~(IntToFp&CvtOp) ? XNaNRes :
|
||||
YNaN&~CvtOp ? YNaNRes :
|
||||
ZNaN&FmaOp ? ZNaNRes :
|
||||
Invalid ? InvalidRes :
|
||||
SelOfRes ? OfRes :
|
||||
KillRes ? UfRes :
|
||||
NormRes;
|
||||
end else begin
|
||||
assign PostProcResM = NaNIn|Invalid ? InvalidRes :
|
||||
assign W = NaNIn|Invalid ? InvalidRes :
|
||||
SelOfRes ? OfRes :
|
||||
KillRes ? UfRes :
|
||||
NormRes;
|
||||
@ -272,9 +272,9 @@ module resultselect(
|
||||
// unsigned | 2^32-1 | 2^64-1 |
|
||||
//
|
||||
// other: 32 bit unsinged res should be sign extended as if it were a signed number
|
||||
assign OfIntRes = Signed ? Xs&~XNaNM ? Int64 ? {1'b1, {`XLEN-1{1'b0}}} : {{`XLEN-32{1'b1}}, 1'b1, {31{1'b0}}} : // signed negitive
|
||||
assign OfIntRes = Signed ? Xs&~XNaN ? Int64 ? {1'b1, {`XLEN-1{1'b0}}} : {{`XLEN-32{1'b1}}, 1'b1, {31{1'b0}}} : // signed negitive
|
||||
Int64 ? {1'b0, {`XLEN-1{1'b1}}} : {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}} : // signed positive
|
||||
Xs&~XNaNM ? {`XLEN{1'b0}} : // unsigned negitive
|
||||
Xs&~XNaN ? {`XLEN{1'b0}} : // unsigned negitive
|
||||
{`XLEN{1'b1}};// unsigned positive
|
||||
|
||||
|
||||
@ -284,7 +284,7 @@ module resultselect(
|
||||
// - if rounding and signed opperation and negitive input, output -1
|
||||
// - otherwise output a rounded 0
|
||||
// - otherwise output the normal res (trmined and sign extended if nessisary)
|
||||
assign FCvtIntResM = IntInvalid ? OfIntRes :
|
||||
CvtCalcExpM[`NE] ? Xs&Signed&Plus1 ? {{`XLEN{1'b1}}} : {{`XLEN-1{1'b0}}, Plus1} : //CalcExp has to come after invalid ***swap to actual mux at some point??
|
||||
Int64 ? NegRes[`XLEN-1:0] : {{`XLEN-32{NegRes[31]}}, NegRes[31:0]};
|
||||
assign FCvtIntRes = IntInvalid ? OfIntRes :
|
||||
CvtCe[`NE] ? Xs&Signed&Plus1 ? {{`XLEN{1'b1}}} : {{`XLEN-1{1'b0}}, Plus1} : //CalcExp has to come after invalid ***swap to actual mux at some point??
|
||||
Int64 ? CvtNegRes[`XLEN-1:0] : {{`XLEN-32{CvtNegRes[31]}}, CvtNegRes[31:0]};
|
||||
endmodule
|
@ -30,17 +30,17 @@
|
||||
|
||||
module resultsign(
|
||||
input logic [2:0] Frm,
|
||||
input logic PSgnM, ZSgnEffM,
|
||||
input logic ZInfM,
|
||||
input logic FmaPs, FmaAs,
|
||||
input logic ZInf,
|
||||
input logic InfIn,
|
||||
input logic FmaOp,
|
||||
input logic [`NE+1:0] SumExp,
|
||||
input logic SumZero,
|
||||
input logic [`NE+1:0] FmaSe,
|
||||
input logic FmaSmZero,
|
||||
input logic Mult,
|
||||
input logic Round,
|
||||
input logic Sticky,
|
||||
input logic RoundSgn,
|
||||
output logic ResSgn
|
||||
input logic R,
|
||||
input logic S,
|
||||
input logic Nsgn,
|
||||
output logic Ws
|
||||
);
|
||||
|
||||
logic ZeroSgn;
|
||||
@ -52,15 +52,15 @@ module resultsign(
|
||||
// if cancelation then 0 unless round to -infinity
|
||||
// if multiply then Psgn
|
||||
// otherwise psign
|
||||
assign Underflow = SumExp[`NE+1] | ((SumExp == 0) & (Round|Sticky));
|
||||
assign ZeroSgn = (PSgnM^ZSgnEffM)&~Underflow&~Mult ? Frm[1:0] == 2'b10 : PSgnM;
|
||||
assign Underflow = FmaSe[`NE+1] | ((FmaSe == 0) & (R|S));
|
||||
assign ZeroSgn = (FmaPs^FmaAs)&~Underflow&~Mult ? Frm[1:0] == 2'b10 : FmaPs;
|
||||
|
||||
|
||||
// is the result negitive
|
||||
// if p - z is the Sum negitive
|
||||
// if -p + z is the Sum positive
|
||||
// if -p - z then the Sum is negitive
|
||||
assign InfSgn = ZInfM ? ZSgnEffM : PSgnM;
|
||||
assign ResSgn = InfIn&FmaOp ? InfSgn : SumZero&FmaOp ? ZeroSgn : RoundSgn;
|
||||
assign InfSgn = ZInf ? FmaAs : FmaPs;
|
||||
assign Ws = InfIn&FmaOp ? InfSgn : FmaSmZero&FmaOp ? ZeroSgn : Nsgn;
|
||||
|
||||
endmodule
|
@ -43,28 +43,28 @@ module round(
|
||||
input logic CvtOp,
|
||||
input logic ToInt,
|
||||
input logic DivDone,
|
||||
input logic [1:0] PostProcSelM,
|
||||
input logic CvtResDenormUfM,
|
||||
input logic [1:0] PostProcSel,
|
||||
input logic CvtResDenormUf,
|
||||
input logic CvtResUf,
|
||||
input logic [`CORRSHIFTSZ-1:0] CorrShifted,
|
||||
input logic AddendStickyM, // addend's sticky bit
|
||||
input logic [`CORRSHIFTSZ-1:0] Nfrac,
|
||||
input logic FmaZmSticky, // addend's sticky bit
|
||||
input logic ZZero, // is Z zero
|
||||
input logic InvZM, // invert Z
|
||||
input logic [`NE+1:0] SumExp, // exponent of the normalized sum
|
||||
input logic RoundSgn, // the result's sign
|
||||
input logic [`NE:0] CvtCalcExpM, // the calculated expoent
|
||||
input logic [`NE+1:0] CorrDivExp, // the calculated expoent
|
||||
input logic DivStickyM, // sticky bit
|
||||
input logic DivNegStickyM,
|
||||
input logic FmaInvA, // invert Z
|
||||
input logic [`NE+1:0] FmaSe, // exponent of the normalized sum
|
||||
input logic Nsgn, // the result's sign
|
||||
input logic [`NE:0] CvtCe, // the calculated expoent
|
||||
input logic [`NE+1:0] DivCorrExp, // the calculated expoent
|
||||
input logic DivSticky, // sticky bit
|
||||
input logic DivNegSticky,
|
||||
output logic UfPlus1, // do you add or subtract on from the result
|
||||
output logic [`NE+1:0] FullResExp, // ResExp with bits to determine sign and overflow
|
||||
output logic [`NF-1:0] ResFrac, // Result fraction
|
||||
output logic [`NE-1:0] ResExp, // Result exponent
|
||||
output logic Sticky, // sticky bit
|
||||
output logic [`NE+1:0] RoundExp,
|
||||
output logic [`NE+1:0] FullResExp, // Re with bits to determine sign and overflow
|
||||
output logic [`NF-1:0] Rf, // Result fraction
|
||||
output logic [`NE-1:0] Re, // Result exponent
|
||||
output logic S, // sticky bit
|
||||
output logic [`NE+1:0] Nexp,
|
||||
output logic Plus1,
|
||||
output logic [`FLEN:0] RoundAdd, // how much to add to the result
|
||||
output logic Round, UfLSBRes // bits needed to calculate rounding
|
||||
output logic R, UfLSBRes // bits needed to calculate rounding
|
||||
);
|
||||
logic LSBRes; // bit used for rounding - least significant bit of the normalized sum
|
||||
logic SubBySmallNum, UfSubBySmallNum; // was there supposed to be a subtraction by a small number
|
||||
@ -82,7 +82,7 @@ module round(
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// round to nearest even
|
||||
// {Round, Sticky}
|
||||
// {R, S}
|
||||
// 0x - do nothing
|
||||
// 10 - tie - Plus1 if result is odd (LSBNormSum = 1)
|
||||
// - don't add 1 if a small number was supposed to be subtracted
|
||||
@ -100,7 +100,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
|
||||
|
||||
// round to nearest max magnitude
|
||||
// {Guard, Round, Sticky}
|
||||
// {Guard, R, S}
|
||||
// 0x - do nothing
|
||||
// 10 - tie - Plus1
|
||||
// - don't add 1 if a small number was supposed to be subtracted
|
||||
@ -118,61 +118,61 @@ module round(
|
||||
// | NF |1|1|
|
||||
// ^ ^ if floating point result
|
||||
// ^ if not an FMA result
|
||||
if (`XLENPOS == 1)assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:0]);
|
||||
if (`XLENPOS == 1)assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`XLEN-2:0]);
|
||||
// 2: NF > XLEN
|
||||
if (`XLENPOS == 2)assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&IntRes) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]);
|
||||
if (`XLENPOS == 2)assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&IntRes) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`NF-2:0]);
|
||||
|
||||
end else if (`FPSIZES == 2) begin
|
||||
// XLEN is either 64 or 32
|
||||
// so half and single are always smaller then XLEN
|
||||
|
||||
// 1: XLEN > NF > NF1
|
||||
if (`XLENPOS == 1) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~OutFmt) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:0]);
|
||||
if (`XLENPOS == 1) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~OutFmt) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`XLEN-2:0]);
|
||||
// 2: NF > XLEN > NF1
|
||||
if (`XLENPOS == 2) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~OutFmt) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~OutFmt)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]);
|
||||
if (`XLENPOS == 2) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~OutFmt) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~OutFmt)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`NF-2:0]);
|
||||
// 3: NF > NF1 > XLEN
|
||||
if (`XLENPOS == 3) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&IntRes) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~OutFmt|IntRes)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]);
|
||||
if (`XLENPOS == 3) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&IntRes) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~OutFmt|IntRes)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`NF-2:0]);
|
||||
|
||||
end else if (`FPSIZES == 3) begin
|
||||
// 1: XLEN > NF > NF1
|
||||
if (`XLENPOS == 1) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~(OutFmt==`FMT)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:0]);
|
||||
if (`XLENPOS == 1) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~(OutFmt==`FMT)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`XLEN-2:0]);
|
||||
// 2: NF > XLEN > NF1
|
||||
if (`XLENPOS == 2) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`FMT)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~(OutFmt==`FMT))) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]);
|
||||
if (`XLENPOS == 2) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`FMT)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~(OutFmt==`FMT))) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`NF-2:0]);
|
||||
// 3: NF > NF1 > XLEN
|
||||
if (`XLENPOS == 3) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&(OutFmt==`FMT1)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&((OutFmt==`FMT1)|IntRes)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~(OutFmt==`FMT)|IntRes)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]);
|
||||
if (`XLENPOS == 3) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&(OutFmt==`FMT1)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&((OutFmt==`FMT1)|IntRes)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~(OutFmt==`FMT)|IntRes)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`NF-2:0]);
|
||||
|
||||
end else if (`FPSIZES == 4) begin
|
||||
// Quad precision will always be greater than XLEN
|
||||
// 2: NF > XLEN > NF1
|
||||
if (`XLENPOS == 2) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`H_NF-2:`CORRSHIFTSZ-`S_NF-1]&FpRes&(OutFmt==`H_FMT)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`S_NF-2:`CORRSHIFTSZ-`D_NF-1]&FpRes&((OutFmt==`S_FMT)|(OutFmt==`H_FMT))) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`D_NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`Q_FMT)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`Q_NF-2:0]);
|
||||
if (`XLENPOS == 2) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`H_NF-2:`CORRSHIFTSZ-`S_NF-1]&FpRes&(OutFmt==`H_FMT)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`S_NF-2:`CORRSHIFTSZ-`D_NF-1]&FpRes&((OutFmt==`S_FMT)|(OutFmt==`H_FMT))) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`D_NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`Q_FMT)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`Q_NF-2:0]);
|
||||
// 3: NF > NF1 > XLEN
|
||||
// The extra XLEN bit will be ored later when caculating the final sticky bit - the ufplus1 not needed for integer
|
||||
if (`XLENPOS == 3) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`H_NF-2:`CORRSHIFTSZ-`S_NF-1]&FpRes&(OutFmt==`H_FMT)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`S_NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&((OutFmt==`S_FMT)|(OutFmt==`H_FMT))) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`D_NF-1]&((OutFmt==`S_FMT)|(OutFmt==`H_FMT)|IntRes)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`D_NF-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) |
|
||||
(|CorrShifted[`CORRSHIFTSZ-`Q_NF-2:0]);
|
||||
if (`XLENPOS == 3) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`H_NF-2:`CORRSHIFTSZ-`S_NF-1]&FpRes&(OutFmt==`H_FMT)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`S_NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&((OutFmt==`S_FMT)|(OutFmt==`H_FMT))) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`D_NF-1]&((OutFmt==`S_FMT)|(OutFmt==`H_FMT)|IntRes)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`D_NF-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) |
|
||||
(|Nfrac[`CORRSHIFTSZ-`Q_NF-2:0]);
|
||||
|
||||
end
|
||||
|
||||
@ -180,37 +180,37 @@ module round(
|
||||
|
||||
// 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)
|
||||
assign UfSticky = AddendStickyM&FmaOp | NormSumSticky | CvtResUf&CvtOp | SumExp[`NE+1]&FmaOp | DivStickyM&DivOp;
|
||||
assign UfSticky = FmaZmSticky&FmaOp | NormSumSticky | CvtResUf&CvtOp | FmaSe[`NE+1]&FmaOp | DivSticky&DivOp;
|
||||
|
||||
// determine round and LSB of the rounded value
|
||||
// - underflow round bit is used to determint the underflow flag
|
||||
if (`FPSIZES == 1) begin
|
||||
assign FpRound = CorrShifted[`CORRSHIFTSZ-`NF-1];
|
||||
assign FpLSBRes = CorrShifted[`CORRSHIFTSZ-`NF];
|
||||
assign FpUfRound = CorrShifted[`CORRSHIFTSZ-`NF-2];
|
||||
assign FpRound = Nfrac[`CORRSHIFTSZ-`NF-1];
|
||||
assign FpLSBRes = Nfrac[`CORRSHIFTSZ-`NF];
|
||||
assign FpUfRound = Nfrac[`CORRSHIFTSZ-`NF-2];
|
||||
|
||||
end else if (`FPSIZES == 2) begin
|
||||
assign FpRound = OutFmt ? CorrShifted[`CORRSHIFTSZ-`NF-1] : CorrShifted[`CORRSHIFTSZ-`NF1-1];
|
||||
assign FpLSBRes = OutFmt ? CorrShifted[`CORRSHIFTSZ-`NF] : CorrShifted[`CORRSHIFTSZ-`NF1];
|
||||
assign FpUfRound = OutFmt ? CorrShifted[`CORRSHIFTSZ-`NF-2] : CorrShifted[`CORRSHIFTSZ-`NF1-2];
|
||||
assign FpRound = OutFmt ? Nfrac[`CORRSHIFTSZ-`NF-1] : Nfrac[`CORRSHIFTSZ-`NF1-1];
|
||||
assign FpLSBRes = OutFmt ? Nfrac[`CORRSHIFTSZ-`NF] : Nfrac[`CORRSHIFTSZ-`NF1];
|
||||
assign FpUfRound = OutFmt ? Nfrac[`CORRSHIFTSZ-`NF-2] : Nfrac[`CORRSHIFTSZ-`NF1-2];
|
||||
|
||||
end else if (`FPSIZES == 3) begin
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
`FMT: begin
|
||||
FpRound = CorrShifted[`CORRSHIFTSZ-`NF-1];
|
||||
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`NF];
|
||||
FpUfRound = CorrShifted[`CORRSHIFTSZ-`NF-2];
|
||||
FpRound = Nfrac[`CORRSHIFTSZ-`NF-1];
|
||||
FpLSBRes = Nfrac[`CORRSHIFTSZ-`NF];
|
||||
FpUfRound = Nfrac[`CORRSHIFTSZ-`NF-2];
|
||||
end
|
||||
`FMT1: begin
|
||||
FpRound = CorrShifted[`CORRSHIFTSZ-`NF1-1];
|
||||
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`NF1];
|
||||
FpUfRound = CorrShifted[`CORRSHIFTSZ-`NF1-2];
|
||||
FpRound = Nfrac[`CORRSHIFTSZ-`NF1-1];
|
||||
FpLSBRes = Nfrac[`CORRSHIFTSZ-`NF1];
|
||||
FpUfRound = Nfrac[`CORRSHIFTSZ-`NF1-2];
|
||||
end
|
||||
`FMT2: begin
|
||||
FpRound = CorrShifted[`CORRSHIFTSZ-`NF2-1];
|
||||
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`NF2];
|
||||
FpUfRound = CorrShifted[`CORRSHIFTSZ-`NF2-2];
|
||||
FpRound = Nfrac[`CORRSHIFTSZ-`NF2-1];
|
||||
FpLSBRes = Nfrac[`CORRSHIFTSZ-`NF2];
|
||||
FpUfRound = Nfrac[`CORRSHIFTSZ-`NF2-2];
|
||||
end
|
||||
default: begin
|
||||
FpRound = 1'bx;
|
||||
@ -222,69 +222,69 @@ module round(
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
2'h3: begin
|
||||
FpRound = CorrShifted[`CORRSHIFTSZ-`Q_NF-1];
|
||||
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`Q_NF];
|
||||
FpUfRound = CorrShifted[`CORRSHIFTSZ-`Q_NF-2];
|
||||
FpRound = Nfrac[`CORRSHIFTSZ-`Q_NF-1];
|
||||
FpLSBRes = Nfrac[`CORRSHIFTSZ-`Q_NF];
|
||||
FpUfRound = Nfrac[`CORRSHIFTSZ-`Q_NF-2];
|
||||
end
|
||||
2'h1: begin
|
||||
FpRound = CorrShifted[`CORRSHIFTSZ-`D_NF-1];
|
||||
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`D_NF];
|
||||
FpUfRound = CorrShifted[`CORRSHIFTSZ-`D_NF-2];
|
||||
FpRound = Nfrac[`CORRSHIFTSZ-`D_NF-1];
|
||||
FpLSBRes = Nfrac[`CORRSHIFTSZ-`D_NF];
|
||||
FpUfRound = Nfrac[`CORRSHIFTSZ-`D_NF-2];
|
||||
end
|
||||
2'h0: begin
|
||||
FpRound = CorrShifted[`CORRSHIFTSZ-`S_NF-1];
|
||||
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`S_NF];
|
||||
FpUfRound = CorrShifted[`CORRSHIFTSZ-`S_NF-2];
|
||||
FpRound = Nfrac[`CORRSHIFTSZ-`S_NF-1];
|
||||
FpLSBRes = Nfrac[`CORRSHIFTSZ-`S_NF];
|
||||
FpUfRound = Nfrac[`CORRSHIFTSZ-`S_NF-2];
|
||||
end
|
||||
2'h2: begin
|
||||
FpRound = CorrShifted[`CORRSHIFTSZ-`H_NF-1];
|
||||
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`H_NF];
|
||||
FpUfRound = CorrShifted[`CORRSHIFTSZ-`H_NF-2];
|
||||
FpRound = Nfrac[`CORRSHIFTSZ-`H_NF-1];
|
||||
FpLSBRes = Nfrac[`CORRSHIFTSZ-`H_NF];
|
||||
FpUfRound = Nfrac[`CORRSHIFTSZ-`H_NF-2];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
assign Round = ToInt&CvtOp ? CorrShifted[`CORRSHIFTSZ-`XLEN-1] : FpRound;
|
||||
assign LSBRes = ToInt&CvtOp ? CorrShifted[`CORRSHIFTSZ-`XLEN] : FpLSBRes;
|
||||
assign UfRound = ToInt&CvtOp ? CorrShifted[`CORRSHIFTSZ-`XLEN-2] : FpUfRound;
|
||||
assign R = ToInt&CvtOp ? Nfrac[`CORRSHIFTSZ-`XLEN-1] : FpRound;
|
||||
assign LSBRes = ToInt&CvtOp ? Nfrac[`CORRSHIFTSZ-`XLEN] : FpLSBRes;
|
||||
assign UfRound = ToInt&CvtOp ? Nfrac[`CORRSHIFTSZ-`XLEN-2] : FpUfRound;
|
||||
|
||||
// used to determine underflow flag
|
||||
assign UfLSBRes = FpRound;
|
||||
// determine sticky
|
||||
assign Sticky = UfSticky | UfRound;
|
||||
assign S = UfSticky | UfRound;
|
||||
|
||||
|
||||
// Deterimine if a small number was supposed to be subtrated
|
||||
// - for FMA or if division has a negitive sticky bit
|
||||
assign SubBySmallNum = ((AddendStickyM&FmaOp&~ZZero&InvZM) | (DivNegStickyM&DivOp)) & ~(NormSumSticky|UfRound);
|
||||
assign UfSubBySmallNum = ((AddendStickyM&FmaOp&~ZZero&InvZM) | (DivNegStickyM&DivOp)) & ~NormSumSticky;
|
||||
assign SubBySmallNum = ((FmaZmSticky&FmaOp&~ZZero&FmaInvA) | (DivNegSticky&DivOp)) & ~(NormSumSticky|UfRound);
|
||||
assign UfSubBySmallNum = ((FmaZmSticky&FmaOp&~ZZero&FmaInvA) | (DivNegSticky&DivOp)) & ~NormSumSticky;
|
||||
|
||||
|
||||
always_comb begin
|
||||
// Determine if you add 1
|
||||
case (Frm)
|
||||
3'b000: CalcPlus1 = Round & ((Sticky| LSBRes)&~SubBySmallNum);//round to nearest even
|
||||
3'b000: CalcPlus1 = R & ((S| LSBRes)&~SubBySmallNum);//round to nearest even
|
||||
3'b001: CalcPlus1 = 0;//round to zero
|
||||
3'b010: CalcPlus1 = RoundSgn & ~(SubBySmallNum & ~Round);//round down
|
||||
3'b011: CalcPlus1 = ~RoundSgn & ~(SubBySmallNum & ~Round);//round up
|
||||
3'b100: CalcPlus1 = Round & ~SubBySmallNum;//round to nearest max magnitude
|
||||
3'b010: CalcPlus1 = Nsgn & ~(SubBySmallNum & ~R);//round down
|
||||
3'b011: CalcPlus1 = ~Nsgn & ~(SubBySmallNum & ~R);//round up
|
||||
3'b100: CalcPlus1 = R & ~SubBySmallNum;//round to nearest max magnitude
|
||||
default: CalcPlus1 = 1'bx;
|
||||
endcase
|
||||
// Determine if you add 1 (for underflow flag)
|
||||
case (Frm)
|
||||
3'b000: UfCalcPlus1 = UfRound & ((UfSticky| UfLSBRes)&~UfSubBySmallNum);//round to nearest even
|
||||
3'b001: UfCalcPlus1 = 0;//round to zero
|
||||
3'b010: UfCalcPlus1 = RoundSgn & ~(UfSubBySmallNum & ~UfRound);//round down
|
||||
3'b011: UfCalcPlus1 = ~RoundSgn & ~(UfSubBySmallNum & ~UfRound);//round up
|
||||
3'b010: UfCalcPlus1 = Nsgn & ~(UfSubBySmallNum & ~UfRound);//round down
|
||||
3'b011: UfCalcPlus1 = ~Nsgn & ~(UfSubBySmallNum & ~UfRound);//round up
|
||||
3'b100: UfCalcPlus1 = UfRound & ~UfSubBySmallNum;//round to nearest max magnitude
|
||||
default: UfCalcPlus1 = 1'bx;
|
||||
endcase
|
||||
// Determine if you subtract 1
|
||||
case (Frm)
|
||||
3'b000: CalcMinus1 = 0;//round to nearest even
|
||||
3'b001: CalcMinus1 = SubBySmallNum & ~Round;//round to zero
|
||||
3'b010: CalcMinus1 = ~RoundSgn & ~Round & SubBySmallNum;//round down
|
||||
3'b011: CalcMinus1 = RoundSgn & ~Round & SubBySmallNum;//round up
|
||||
3'b001: CalcMinus1 = SubBySmallNum & ~R;//round to zero
|
||||
3'b010: CalcMinus1 = ~Nsgn & ~R & SubBySmallNum;//round down
|
||||
3'b011: CalcMinus1 = Nsgn & ~R & SubBySmallNum;//round up
|
||||
3'b100: CalcMinus1 = 0;//round to nearest max magnitude
|
||||
default: CalcMinus1 = 1'bx;
|
||||
endcase
|
||||
@ -292,10 +292,10 @@ module round(
|
||||
end
|
||||
|
||||
// If an answer is exact don't round
|
||||
assign Plus1 = CalcPlus1 & (Sticky | Round);
|
||||
assign Plus1 = CalcPlus1 & (S | R);
|
||||
assign FpPlus1 = Plus1&~(ToInt&CvtOp);
|
||||
assign UfPlus1 = UfCalcPlus1 & Sticky; // UfRound is part of sticky
|
||||
assign Minus1 = CalcMinus1 & (Sticky | Round);
|
||||
assign UfPlus1 = UfCalcPlus1 & S; // UfRound is part of sticky
|
||||
assign Minus1 = CalcMinus1 & (S | R);
|
||||
|
||||
// Compute rounded result
|
||||
if (`FPSIZES == 1) begin
|
||||
@ -332,20 +332,20 @@ module round(
|
||||
end
|
||||
|
||||
// determine the result to be roundned
|
||||
assign RoundFrac = CorrShifted[`CORRSHIFTSZ-1:`CORRSHIFTSZ-`NF];
|
||||
assign RoundFrac = Nfrac[`CORRSHIFTSZ-1:`CORRSHIFTSZ-`NF];
|
||||
|
||||
always_comb
|
||||
case(PostProcSelM)
|
||||
2'b10: RoundExp = SumExp; // fma
|
||||
2'b00: RoundExp = {CvtCalcExpM[`NE], CvtCalcExpM}&{`NE+2{~CvtResDenormUfM|CvtResUf}}; // cvt
|
||||
2'b01: RoundExp = DivDone ? CorrDivExp : '0; // divide
|
||||
default: RoundExp = '0;
|
||||
case(PostProcSel)
|
||||
2'b10: Nexp = FmaSe; // fma
|
||||
2'b00: Nexp = {CvtCe[`NE], CvtCe}&{`NE+2{~CvtResDenormUf|CvtResUf}}; // cvt
|
||||
2'b01: Nexp = DivDone ? DivCorrExp : '0; // divide
|
||||
default: Nexp = '0;
|
||||
endcase
|
||||
|
||||
// round the result
|
||||
// - if the fraction overflows one should be added to the exponent
|
||||
assign {FullResExp, ResFrac} = {RoundExp, RoundFrac} + RoundAdd;
|
||||
assign ResExp = FullResExp[`NE-1:0];
|
||||
assign {FullResExp, Rf} = {Nexp, RoundFrac} + RoundAdd;
|
||||
assign Re = FullResExp[`NE-1:0];
|
||||
|
||||
|
||||
endmodule
|
@ -29,16 +29,16 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module roundsign(
|
||||
input logic PSgnM, ZSgnEffM,
|
||||
input logic InvZM,
|
||||
input logic FmaPs, FmaAs,
|
||||
input logic FmaInvA,
|
||||
input logic Xs,
|
||||
input logic Ys,
|
||||
input logic NegSumM,
|
||||
input logic FmaNegSum,
|
||||
input logic FmaOp,
|
||||
input logic DivOp,
|
||||
input logic CvtOp,
|
||||
input logic CvtResSgnM,
|
||||
output logic RoundSgn
|
||||
input logic CvtCs,
|
||||
output logic Nsgn
|
||||
);
|
||||
|
||||
logic FmaResSgnTmp;
|
||||
@ -48,13 +48,13 @@ module roundsign(
|
||||
// if p - z is the Sum negitive
|
||||
// if -p + z is the Sum positive
|
||||
// if -p - z then the Sum is negitive
|
||||
assign FmaResSgnTmp = NegSumM^PSgnM; //*** move to execute stage
|
||||
assign FmaResSgnTmp = FmaNegSum^FmaPs; //*** move to execute stage
|
||||
|
||||
// assign FmaResSgnTmp = InvZM&(ZSgnEffM)&NegSumM | InvZM&PSgnM&~NegSumM | (ZSgnEffM&PSgnM);
|
||||
// assign FmaResSgnTmp = FmaInvA&(FmaAs)&FmaNegSum | FmaInvA&FmaPs&~FmaNegSum | (FmaAs&FmaPs);
|
||||
|
||||
assign DivSgn = Xs^Ys;
|
||||
|
||||
// Sign for rounding calulation
|
||||
assign RoundSgn = (FmaResSgnTmp&FmaOp) | (CvtResSgnM&CvtOp) | (DivSgn&DivOp);
|
||||
assign Nsgn = (FmaResSgnTmp&FmaOp) | (CvtCs&CvtOp) | (DivSgn&DivOp);
|
||||
|
||||
endmodule
|
@ -76,7 +76,7 @@ module testbenchfp;
|
||||
logic XZero, YZero, ZZero; // is the input zero
|
||||
logic XExpMax, YExpMax, ZExpMax; // is the input's exponent all ones
|
||||
logic [`CVTLEN-1:0] CvtLzcInE; // input to the Leading Zero Counter (priority encoder)
|
||||
logic IntZeroE;
|
||||
logic IntZero;
|
||||
logic CvtResSgnE;
|
||||
logic [`NE:0] CvtCalcExpE; // the calculated expoent
|
||||
logic [`LOGCVTLEN-1:0] CvtShiftAmtE; // how much to shift by
|
||||
@ -104,6 +104,7 @@ module testbenchfp;
|
||||
logic As;
|
||||
logic Ps;
|
||||
logic DivSticky;
|
||||
logic DivDone;
|
||||
logic DivNegSticky;
|
||||
logic [`NE+1:0] DivCalcExp;
|
||||
|
||||
@ -677,25 +678,25 @@ module testbenchfp;
|
||||
.FOpCtrl(OpCtrlVal), .Fmt(ModFmt), .Sm, .NegSum, .InvA, .NCnt, .As, .Ps,
|
||||
.Pe, .ZmSticky, .KillProd);
|
||||
|
||||
postprocess postprocess(.Xs(XSgn), .Ys(YSgn), .PostProcSelM(UnitVal[1:0]),
|
||||
.Ze(ZExp), .ZDenormM(ZDenorm), .FOpCtrlM(OpCtrlVal), .Quot, .DivCalcExpM(DivCalcExp),
|
||||
.Xm(XMan), .Ym(YMan), .Zm(ZMan), .CvtCalcExpM(CvtCalcExpE), .DivStickyM(DivSticky),
|
||||
.XNaNM(XNaN), .YNaNM(YNaN), .ZNaNM(ZNaN), .CvtResDenormUfM(CvtResDenormUfE), .DivNegStickyM(DivNegSticky),
|
||||
.XZeroM(XZero), .YZeroM(YZero), .ZZeroM(ZZero), .CvtShiftAmtM(CvtShiftAmtE),
|
||||
.XInfM(XInf), .YInfM(YInf), .ZInfM(ZInf), .CvtResSgnM(CvtResSgnE), .FWriteIntM(WriteIntVal),
|
||||
.XSNaNM(XSNaN), .YSNaNM(YSNaN), .ZSNaNM(ZSNaN), .CvtLzcInM(CvtLzcInE), .IntZeroM(IntZeroE),
|
||||
.KillProdM(KillProd), .AddendStickyM(ZmSticky), .ProdExpM(Pe),
|
||||
.SumM(Sm), .NegSumM(NegSum), .InvZM(InvA), .FmaNormCntM(NCnt), .EarlyTermShiftDiv2M(EarlyTermShiftDiv2), .ZSgnEffM(As), .PSgnM(Ps), .Fmt(ModFmt), .Frm(FrmVal),
|
||||
.PostProcFlgM(Flg), .PostProcResM(FpRes), .FCvtIntResM(IntRes));
|
||||
postprocess postprocess(.Xs(XSgn), .Ys(YSgn), .PostProcSel(UnitVal[1:0]),
|
||||
.Ze(ZExp), .ZDenorm(ZDenorm), .FOpCtrl(OpCtrlVal), .Quot, .DivCalcExp(DivCalcExp),
|
||||
.Xm(XMan), .Ym(YMan), .Zm(ZMan), .CvtCe(CvtCalcExpE), .DivSticky(DivSticky),
|
||||
.XNaN(XNaN), .YNaN(YNaN), .ZNaN(ZNaN), .CvtResDenormUf(CvtResDenormUfE), .DivNegSticky,
|
||||
.XZero(XZero), .YZero(YZero), .ZZero(ZZero), .CvtShiftAmt(CvtShiftAmtE),
|
||||
.XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal),
|
||||
.XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero,
|
||||
.FmaKillProd(KillProd), .FmaZmSticky(ZmSticky), .FmaPe(Pe), .DivDone,
|
||||
.FmaSm(Sm), .FmaNegSum(NegSum), .FmaInvA(InvA), .FmaNCnt(NCnt), .DivEarlyTermShiftDiv2(EarlyTermShiftDiv2), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal),
|
||||
.PostProcFlg(Flg), .W(FpRes), .FCvtIntRes(IntRes));
|
||||
|
||||
fcvt fcvt (.XSgnE(XSgn), .XExpE(XExp), .XManE(XMan), .ForwardedSrcAE(SrcA), .FWriteIntE(WriteIntVal),
|
||||
.XZeroE(XZero), .XDenormE(XDenorm), .FOpCtrlE(OpCtrlVal), .IntZeroE,
|
||||
.FmtE(ModFmt), .CvtCalcExpE, .CvtShiftAmtE, .CvtResDenormUfE, .CvtResSgnE, .CvtLzcInE);
|
||||
fcvt fcvt (.Xs(XSgn), .Xe(XExp), .Xm(XMan), .Int(SrcA), .ToInt(WriteIntVal),
|
||||
.XZero(XZero), .XDenorm(XDenorm), .FOpCtrl(OpCtrlVal), .IntZero,
|
||||
.Fmt(ModFmt), .Ce(CvtCalcExpE), .ShiftAmt(CvtShiftAmtE), .ResDenormUf(CvtResDenormUfE), .Cs(CvtResSgnE), .LzcIn(CvtLzcInE));
|
||||
fcmp fcmp (.FmtE(ModFmt), .FOpCtrlE(OpCtrlVal), .XSgnE(XSgn), .YSgnE(YSgn), .XExpE(XExp), .YExpE(YExp),
|
||||
.XManE(XMan), .YManE(YMan), .XZeroE(XZero), .YZeroE(YZero), .CmpIntResE(CmpRes),
|
||||
.XNaNE(XNaN), .YNaNE(YNaN), .XSNaNE(XSNaN), .YSNaNE(YSNaN), .FSrcXE(X), .FSrcYE(Y), .CmpNVE(CmpFlg[4]), .CmpFpResE(FpCmpRes));
|
||||
srtpreproc srtpreproc(.XManE(XMan), .Dur, .YManE(YMan),.X(DivX),.Dpreproc, .XZeroCnt, .YZeroCnt);
|
||||
srtfsm srtfsm(.reset, .WSN, .WCN, .WS, .WC, .Dur, .DivBusy, .clk, .DivStart, .StallM(1'b0), .StallE(1'b0), .XZeroE(XZero), .YZeroE(YZero), .DivStickyE(DivSticky), .XNaNE(XNaN), .YNaNE(YNaN),
|
||||
srtfsm srtfsm(.reset, .WSN, .WCN, .WS, .WC, .Dur, .DivBusy, .DivDone, .clk, .DivStart, .StallM(1'b0), .StallE(1'b0), .XZeroE(XZero), .YZeroE(YZero), .DivStickyE(DivSticky), .XNaNE(XNaN), .YNaNE(YNaN),
|
||||
.XInfE(XInf), .YInfE(YInf), .DivNegStickyE(DivNegSticky), .EarlyTermShiftDiv2E(EarlyTermShiftDiv2));
|
||||
srtradix4 srtradix4(.clk, .FmtE(ModFmt), .X(DivX),.Dpreproc, .DivBusy, .XZeroCnt, .YZeroCnt, .WS, .WC, .WSN, .WCN, .DivStart, .XExpE(XExp), .YExpE(YExp), .XZeroE(XZero), .YZeroE(YZero),
|
||||
.Quot, .Rem(), .DivCalcExpM(DivCalcExp));
|
||||
|
@ -1,29 +0,0 @@
|
||||
#!/usr/bin/bash
|
||||
# Madeleine Masser-Frye mmasserfrye@hmc.edu July 2022
|
||||
|
||||
helpFunction()
|
||||
{ echo ""
|
||||
echo "Usage: $0 "
|
||||
echo -e "\t--configs Synthesizes wally with configurations 32e, 32ic, 64ic, 32gc, and 64gc"
|
||||
echo -e "\t--freqs NUM Synthesizes rv32e with target frequencies at NUM MHz and +/- 2, 4, 6, 8 %"
|
||||
echo -e "\t--features Synthesizes rv64gc versions FPUoff, noMulDiv, noPriv, PMP0, PMP16"
|
||||
exit 1 # Exit script after printing help
|
||||
}
|
||||
|
||||
VALID_ARGS=$(getopt -o cft: --long configs,features,freqs: -- "$@")
|
||||
|
||||
eval set -- "$VALID_ARGS"
|
||||
unset VALID_ARGS
|
||||
|
||||
if [[ $1 == "--" ]];
|
||||
then helpFunction
|
||||
elif [[ $1 == "--freqs" ]] && [[ ! $2 =~ ^[[:digit:]]+$ ]]
|
||||
then echo "Argument must be an integer, target frequnecy is in MHz"
|
||||
else
|
||||
make clean
|
||||
make del
|
||||
make copy
|
||||
make configs
|
||||
./wallySynth.py $1 $2
|
||||
./extractSummary.py
|
||||
fi
|
@ -3,44 +3,62 @@
|
||||
|
||||
import subprocess
|
||||
from multiprocessing import Pool
|
||||
import time
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
def runSynth(config, tech, freq):
|
||||
def runSynth(config, tech, freq, maxopt):
|
||||
global pool
|
||||
command = "make synth DESIGN=wallypipelinedcore CONFIG={} TECH={} DRIVE=FLOP FREQ={} MAXOPT=1 MAXCORES=1".format(config, tech, freq)
|
||||
command = "make synth DESIGN=wallypipelinedcore CONFIG={} TECH={} DRIVE=FLOP FREQ={} MAXOPT={} MAXCORES=1".format(config, tech, freq, maxopt)
|
||||
pool.map(mask, [command])
|
||||
|
||||
def mask(command):
|
||||
subprocess.Popen(command, shell=True)
|
||||
|
||||
testFreq = [3000, 10000]
|
||||
def freshStart():
|
||||
out = subprocess.check_output(['bash','-c', 'make clean'])
|
||||
for x in out.decode("utf-8").split('\n')[:-1]:
|
||||
print(x)
|
||||
return
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
i = 0
|
||||
|
||||
techs = ['sky90', 'tsmc28']
|
||||
synthsToRun = []
|
||||
tech = techs[i]
|
||||
freq = testFreq[i]
|
||||
arr = [-8, -6, -4, -2, 0, 2, 4, 6, 8]
|
||||
allConfigs = ['rv32gc', 'rv32ic', 'rv64gc', 'rv64ic', 'rv32e', 'rv32i', 'rv64i']
|
||||
freqVaryPct = [-20, -12, -8, -6, -4, -2, 0, 2, 4, 6, 8, 12, 20]
|
||||
|
||||
pool = Pool()
|
||||
staggerPeriod = 60 #seconds
|
||||
|
||||
typeToRun = sys.argv[1]
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
if 'configs' in typeToRun:
|
||||
parser.add_argument("-s", "--freqsweep", type=int, help = "Synthesize wally with target frequencies at given MHz and +/- 2, 4, 6, 8 %%")
|
||||
parser.add_argument("-c", "--configsweep", action='store_true', help = "Synthesize wally with configurations 32e, 32ic, 64ic, 32gc, and 64gc")
|
||||
parser.add_argument("-f", "--featuresweep", action='store_true', help = "Synthesize wally with features turned off progressively to visualize critical path")
|
||||
|
||||
parser.add_argument("-v", "--version", choices=allConfigs, help = "Configuration of wally")
|
||||
parser.add_argument("-t", "--targetfreq", type=int, help = "Target frequncy")
|
||||
parser.add_argument("-e", "--tech", choices=techs, help = "Technology")
|
||||
parser.add_argument("-o", "--maxopt", action='store_true', help = "Turn on MAXOPT")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
freq = args.targetfreq if args.targetfreq else 3000
|
||||
tech = args.tech if args.tech else 'sky90'
|
||||
maxopt = int(args.maxopt)
|
||||
|
||||
if args.freqsweep:
|
||||
sc = args.freqsweep
|
||||
config = args.version if args.version else 'rv32e'
|
||||
freshStart()
|
||||
for freq in [round(sc+sc*x/100) for x in freqVaryPct]: # rv32e freq sweep
|
||||
runSynth(config, tech, freq, maxopt)
|
||||
if args.configsweep:
|
||||
freshStart()
|
||||
for config in ['rv32gc', 'rv32ic', 'rv64gc', 'rv64ic', 'rv32e']: # configs
|
||||
config = config + '_orig' # until memory integrated
|
||||
runSynth(config, tech, freq)
|
||||
time.sleep(staggerPeriod)
|
||||
elif 'features' in typeToRun:
|
||||
runSynth(config, tech, freq, maxopt)
|
||||
if args.featuresweep:
|
||||
freshStart()
|
||||
v = args.version if args.version else 'rv64gc'
|
||||
for mod in ['FPUoff', 'noMulDiv', 'noPriv', 'PMP0', 'PMP16']: # rv64gc path variations
|
||||
config = 'rv64gc_' + mod
|
||||
runSynth(config, tech, freq)
|
||||
time.sleep(staggerPeriod)
|
||||
elif 'freqs' in typeToRun:
|
||||
sc = int(sys.argv[2])
|
||||
config = 'rv32e'
|
||||
for freq in [round(sc+sc*x/100) for x in arr]: # rv32e freq sweep
|
||||
runSynth(config, tech, freq)
|
||||
config = v + '_' + mod
|
||||
runSynth(config, tech, freq, maxopt)
|
||||
|
Loading…
Reference in New Issue
Block a user