This commit is contained in:
DTowersM 2022-07-08 21:25:58 +00:00
commit 3e19500fc8
16 changed files with 460 additions and 501 deletions

View File

@ -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

View File

@ -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}}};

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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));

View File

@ -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

View File

@ -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)