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 XZero,
input logic ToInt, input logic ToInt,
input logic IntToFp, 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 [`NF:0] Xm, // input mantissas
input logic [`FMTBITS-1:0] OutFmt, // output format input logic [`FMTBITS-1:0] OutFmt, // output format
input logic [`CVTLEN-1:0] CvtLzcInM, // input to the Leading Zero Counter (priority encoder) input logic [`CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (priority encoder)
input logic CvtResDenormUfM, input logic CvtResDenormUf,
output logic CvtResUf, output logic CvtResUf,
output logic [`CVTLEN+`NF:0] CvtShiftIn // number to be shifted output logic [`CVTLEN+`NF:0] CvtShiftIn // number to be shifted
); );
@ -60,9 +60,9 @@ module cvtshiftcalc(
// - otherwise: // - otherwise:
// | LzcInM | 0's if nessisary | // | LzcInM | 0's if nessisary |
// change to int shift to the left one // 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}}} : 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}}} :
CvtResDenormUfM ? {{`NF-1{1'b0}}, Xm, {`CVTLEN-`NF+1{1'b0}}} : CvtResDenormUf ? {{`NF-1{1'b0}}, Xm, {`CVTLEN-`NF+1{1'b0}}} :
{CvtLzcInM, {`NF+1{1'b0}}}; {CvtLzcIn, {`NF+1{1'b0}}};
// choose the negative of the fraction size // choose the negative of the fraction size
@ -93,6 +93,6 @@ module cvtshiftcalc(
// determine if the result underflows ??? -> fp // determine if the result underflows ??? -> fp
// - if the first 1 is shifted out of the result then the result underflows // - if the first 1 is shifted out of the result then the result underflows
// - can't underflow an integer to fp conversions // - 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 endmodule

View File

@ -3,60 +3,36 @@
module divshiftcalc( module divshiftcalc(
input logic [`DIVLEN+2:0] Quot, input logic [`DIVLEN+2:0] Quot,
input logic [`FMTBITS-1:0] Fmt, input logic [`FMTBITS-1:0] Fmt,
input logic [$clog2(`DIVLEN/2+3)-1:0] EarlyTermShiftDiv2M, input logic [$clog2(`DIVLEN/2+3)-1:0] DivEarlyTermShiftDiv2,
input logic [`NE+1:0] DivCalcExpM, input logic [`NE+1:0] DivCalcExp,
output logic [$clog2(`NORMSHIFTSZ)-1:0] DivShiftAmt, output logic [$clog2(`NORMSHIFTSZ)-1:0] DivShiftAmt,
output logic [`NORMSHIFTSZ-1:0] DivShiftIn, output logic [`NORMSHIFTSZ-1:0] DivShiftIn,
output logic DivResDenorm, output logic DivResDenorm,
output logic [`NE+1:0] DivDenormShift output logic [`NE+1:0] DivDenormShift
); );
logic [`NE+1:0] NormShift; logic [`NE+1:0] NormShift;
logic [`NE+1:0] Nf;
// is the result denromalized // is the result denromalized
// if the exponent is 1 then the result needs to be normalized then the result is denormalizes // if the exponent is 1 then the result needs to be normalized then the result is denormalizes
assign DivResDenorm = DivCalcExpM[`NE+1]|(~|DivCalcExpM[`NE+1:0]); assign DivResDenorm = DivCalcExp[`NE+1]|(~|DivCalcExp[`NE+1:0]);
// select the proper fraction lengnth
// if (`FPSIZES == 1) begin
// assign Nf = (`NE+2)'(`NF);
// 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 // if the result is denormalized
// 00000000x.xxxxxx... Exp = DivCalcExpM // 00000000x.xxxxxx... Exp = DivCalcExp
// .00000000xxxxxxx... >> NF+1 Exp = DivCalcExpM+NF+1 // .00000000xxxxxxx... >> NF+1 Exp = DivCalcExp+NF+1
// .00xxxxxxxxxxxxx... << DivCalcExpM+NF+1 Exp = +1 // .00xxxxxxxxxxxxx... << DivCalcExp+NF+1 Exp = +1
// .0000xxxxxxxxxxx... >> 1 Exp = 1 // .0000xxxxxxxxxxx... >> 1 Exp = 1
// Left shift amount = DivCalcExpM+NF+1-1 // Left shift amount = DivCalcExp+NF+1-1
assign DivDenormShift = (`NE+2)'(`NF)+DivCalcExpM; assign DivDenormShift = (`NE+2)'(`NF)+DivCalcExp;
// if the result is normalized // if the result is normalized
// 00000000x.xxxxxx... Exp = DivCalcExpM // 00000000x.xxxxxx... Exp = DivCalcExp
// .00000000xxxxxxx... >> NF+1 Exp = DivCalcExpM+NF+1 // .00000000xxxxxxx... >> NF+1 Exp = DivCalcExp+NF+1
// 00000000.xxxxxxx... << NF Exp = DivCalcExpM+1 // 00000000.xxxxxxx... << NF Exp = DivCalcExp+1
// 00000000x.xxxxxx... << NF Exp = DivCalcExpM (extra shift done afterwards) // 00000000x.xxxxxx... << NF Exp = DivCalcExp (extra shift done afterwards)
// 00000000xx.xxxxx... << 1? Exp = DivCalcExpM-1 (determined after) // 00000000xx.xxxxx... << 1? Exp = DivCalcExp-1 (determined after)
// inital Left shift amount = NF // inital Left shift amount = NF
assign NormShift = (`NE+2)'(`NF); assign NormShift = (`NE+2)'(`NF);
// if the shift amount is negitive then dont shift (keep sticky bit) // 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 // *** may be able to reduce shifter size
assign DivShiftIn = {{`NF{1'b0}}, Quot[`DIVLEN+2:0], {`NORMSHIFTSZ-`DIVLEN-3-`NF{1'b0}}}; 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 // 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 // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
@ -21,7 +21,7 @@
// substantial portions of the Software. // substantial portions of the Software.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // 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 // 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, // 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 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
@ -31,21 +31,21 @@
`include "wally-config.vh" `include "wally-config.vh"
module fcvt ( module fcvt (
input logic XSgnE, // input's sign input logic Xs, // input's sign
input logic [`NE-1:0] XExpE, // input's exponent input logic [`NE-1:0] Xe, // input's exponent
input logic [`NF:0] XManE, // input's fraction input logic [`NF:0] Xm, // input's fraction
input logic [`XLEN-1:0] ForwardedSrcAE, // integer input - from IEU input logic [`XLEN-1:0] Int, // integer input - from IEU
input logic [2:0] FOpCtrlE, // choose which opperation (look below for values) input logic [2:0] FOpCtrl, // choose which opperation (look below for values)
input logic FWriteIntE, // is fp->int (since it's writting to the integer register) input logic ToInt, // is fp->int (since it's writting to the integer register)
input logic XZeroE, // is the input zero input logic XZero, // is the input zero
input logic XDenormE, // is the input denormalized input logic XDenorm, // is the input denormalized
input logic [`FMTBITS-1:0] FmtE, // the input's precision (11=quad 01=double 00=single 10=half) input logic [`FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half)
output logic [`NE:0] CvtCalcExpE, // the calculated expoent output logic [`NE:0] Ce, // the calculated expoent
output logic [`LOGCVTLEN-1:0] CvtShiftAmtE, // how much to shift by output logic [`LOGCVTLEN-1:0] ShiftAmt, // how much to shift by
output logic CvtResDenormUfE,// does the result underflow or is denormalized output logic ResDenormUf,// does the result underflow or is denormalized
output logic CvtResSgnE, // the result's sign output logic Cs, // the result's sign
output logic IntZeroE, // is the integer zero? output logic IntZero, // is the integer zero?
output logic [`CVTLEN-1:0] CvtLzcInE // input to the Leading Zero Counter (priority encoder) output logic [`CVTLEN-1:0] LzcIn // input to the Leading Zero Counter (priority encoder)
); );
// OpCtrls: // OpCtrls:
@ -58,9 +58,6 @@ module fcvt (
// bit 2 bit 1 bit 0 // bit 2 bit 1 bit 0
// for example: signed long -> single floating point has the OpCode 101 // 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 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 Signed; // is the opperation with a signed integer?
logic Int64; // is the integer 64 bits? logic Int64; // is the integer 64 bits?
logic IntToFp; // is the opperation an int->fp conversion? logic IntToFp; // is the opperation an int->fp conversion?
logic ToInt; // is the opperation an fp->int conversion? logic [`LOGCVTLEN-1:0] LeadingZeros; // output from the LZC
logic [`LOGCVTLEN-1:0] ZeroCnt; // output from the LZC
// seperate OpCtrl for code readability // seperate OpCtrl for code readability
assign Signed = FOpCtrlE[0]; assign Signed = FOpCtrl[0];
assign Int64 = FOpCtrlE[1]; assign Int64 = FOpCtrl[1];
assign IntToFp = FOpCtrlE[2]; assign IntToFp = FOpCtrl[2];
assign ToInt = FWriteIntE;
// choose the ouptut format depending on the opperation // choose the ouptut format depending on the opperation
// - fp -> fp: OpCtrl contains the percision of the output // - 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) 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) 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 // 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) // 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 TrimInt = {{`XLEN-32{Int64}}, {32{1'b1}}} & PosInt;
assign IntZeroE = ~|TrimInt; assign IntZero = ~|TrimInt;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// lzc // lzc
@ -107,10 +102,10 @@ module fcvt (
// choose the input to the leading zero counter i.e. priority encoder // choose the input to the leading zero counter i.e. priority encoder
// int -> fp : | positive integer | 00000... (if needed) | // int -> fp : | positive integer | 00000... (if needed) |
// fp -> fp : | fraction | 00000... (if needed) | // fp -> fp : | fraction | 00000... (if needed) |
assign CvtLzcInE = IntToFp ? {TrimInt, {`CVTLEN-`XLEN{1'b0}}} : assign LzcIn = IntToFp ? {TrimInt, {`CVTLEN-`XLEN{1'b0}}} :
{XManE[`NF-1:0], {`CVTLEN-`NF{1'b0}}}; {Xm[`NF-1:0], {`CVTLEN-`NF{1'b0}}};
lzc #(`CVTLEN) lzc (.num(CvtLzcInE), .ZeroCnt); lzc #(`CVTLEN) lzc (.num(LzcIn), .ZeroCnt(LeadingZeros));
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// shifter // shifter
@ -124,13 +119,13 @@ module fcvt (
// denormalized/undeflowed result fp -> fp: // denormalized/undeflowed result fp -> fp:
// - shift left by NF-1+CalcExp - to shift till the biased expoenent is 0 // - shift left by NF-1+CalcExp - to shift till the biased expoenent is 0
// ??? -> fp: // ??? -> fp:
// - shift left by 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 // - 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 // - this is a problem because the input to the lzc was the fraction rather than the mantissa
// - rather have a few and-gates than an extra bit in the priority encoder??? *** is this true? // - rather have a few and-gates than an extra bit in the priority encoder??? *** is this true?
assign CvtShiftAmtE = ToInt ? CvtCalcExpE[`LOGCVTLEN-1:0]&{`LOGCVTLEN{~CvtCalcExpE[`NE]}} : assign ShiftAmt = ToInt ? Ce[`LOGCVTLEN-1:0]&{`LOGCVTLEN{~Ce[`NE]}} :
CvtResDenormUfE&~IntToFp ? (`LOGCVTLEN)'(`NF-1)+CvtCalcExpE[`LOGCVTLEN-1:0] : ResDenormUf&~IntToFp ? (`LOGCVTLEN)'(`NF-1)+Ce[`LOGCVTLEN-1:0] :
(ZeroCnt+1)&{`LOGCVTLEN{XDenormE|IntToFp}}; (LeadingZeros+1)&{`LOGCVTLEN{XDenorm|IntToFp}};
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// exp calculations // exp calculations
@ -180,15 +175,15 @@ module fcvt (
// select the old exponent // select the old exponent
// int -> fp : largest bias + XLEN // int -> fp : largest bias + XLEN
// fp -> ??? : XExp // fp -> ??? : XExp
assign OldExp = IntToFp ? (`NE)'(`BIAS)+(`NE)'(`XLEN) : XExpE; assign OldExp = IntToFp ? (`NE)'(`BIAS)+(`NE)'(`XLEN) : Xe;
// calculate CalcExp // calculate CalcExp
// fp -> fp : // fp -> fp :
// - XExp - Largest bias + new bias - (ZeroCnt+1) // - XExp - Largest bias + new bias - (LeadingZeros+1)
// only do ^ if the input was denormalized // only do ^ if the input was denormalized
// - convert the expoenent to the final preciaion (Exp - oldBias + newBias) // - convert the expoenent to the final preciaion (Exp - oldBias + newBias)
// - correct the expoent when there is a normalization shift ( + ZeroCnt+1) // - correct the expoent when there is a normalization shift ( + LeadingZeros+1)
// fp -> int : XExp - Largest Bias + 1 - (ZeroCnt+1) // fp -> int : XExp - Largest Bias + 1 - (LeadingZeros+1)
// | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp // | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp
// process: // process:
// - start // - start
@ -202,18 +197,18 @@ module fcvt (
// | 0's | Mantissa | 0's if nessisary | // | 0's | Mantissa | 0's if nessisary |
// | keep | // | keep |
// //
// - if the input is denormalized then we dont shift... so the "- (ZeroCnt+1)" is just leftovers from other options // - 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 - ZeroCnt = XLEN + NewBias - 1 - ZeroCnt // int -> fp : largest bias + XLEN - Largest bias + new bias - 1 - LeadingZeros = XLEN + NewBias - 1 - LeadingZeros
// Process: // Process:
// - shifted right by XLEN (XLEN) // - shifted right by XLEN (XLEN)
// - shift left to normilize (-1-ZeroCnt) // - shift left to normilize (-1-LeadingZeros)
// - newBias to make the biased exponent // - newBias to make the biased exponent
// oldexp - biasold +newbias - (ZeroCnt+1)&(XDenormE|IntToFp) // oldexp - biasold +newbias - (LeadingZeros+1)&(XDenorm|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}})}; 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 // find if the result is dnormal or underflows
// - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0) // - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0)
// - can't underflow an integer to Fp conversion // - can't underflow an integer to Fp conversion
assign 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 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 // - if 32-bit : check the msb of the 32-bit integer input and if it's signed
// - otherwise: the floating point input's sign // - 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 endmodule

View File

@ -30,12 +30,12 @@
module flags( module flags(
input logic Xs, input logic Xs,
input logic XSNaNM, YSNaNM, ZSNaNM, // inputs are signaling NaNs input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
input logic XInfM, YInfM, ZInfM, // inputs are infinity input logic XInf, YInf, ZInf, // inputs are infinity
input logic Plus1, input logic Plus1,
input logic InfIn, // is a Inf input being used input logic InfIn, // is a Inf input being used
input logic XZero, YZero, // inputs are zero 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 NaNIn, // is a NaN input being used
input logic Sqrt, // Sqrt? input logic Sqrt, // Sqrt?
input logic ToInt, // convert to integer input logic ToInt, // convert to integer
@ -43,18 +43,18 @@ module flags(
input logic Int64, // convert to 64 bit integer input logic Int64, // convert to 64 bit integer
input logic Signed, // convert to a signed integer input logic Signed, // convert to a signed integer
input logic [`FMTBITS-1:0] OutFmt, // output format 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 CvtOp, // conversion opperation?
input logic DivOp, // conversion opperation? input logic DivOp, // conversion opperation?
input logic FmaOp, // Fma 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] FullResExp, // Re with bits to determine sign and overflow
input logic [`NE+1:0] RoundExp, // exponent of the normalized sum input logic [`NE+1:0] Nexp, // exponent of the normalized sum
input logic [1:0] NegResMSBS, // the negitive integer result's most significant bits input logic [1:0] CvtNegResMsbs, // the negitive integer result's most significant bits
input logic ZSgnEffM, PSgnM, // the product and modified Z signs input logic FmaAs, FmaPs, // the product and modified Z signs
input logic Round, UfLSBRes, Sticky, UfPlus1, // bits used to determine rounding input logic R, UfLSBRes, S, UfPlus1, // bits used to determine rounding
output logic DivByZero, output logic DivByZero,
output logic IntInvalid, Invalid, Overflow, // flags used to select the res output logic IntInvalid, Invalid, Overflow, // flags used to select the res
output logic [4:0] PostProcFlgM // flags output logic [4:0] PostProcFlg // flags
); );
logic SigNaN; // is an input a signaling NaN logic SigNaN; // is an input a signaling NaN
logic Inexact; // inexact flag logic Inexact; // inexact flag
@ -64,7 +64,7 @@ module flags(
logic DivInvalid; // integer invalid flag logic DivInvalid; // integer invalid flag
logic Underflow; // Underflow flag logic Underflow; // Underflow flag
logic ResExpGteMax; // is the result greater than or equal to the maximum floating point expoent 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 // Flags
@ -127,16 +127,16 @@ module flags(
// | | | | and if the result is not exact // | | | | and if the result is not exact
// | | | | | and if the input isnt infinity or NaN // | | | | | and if the input isnt infinity or NaN
// | | | | | | // | | | | | |
assign Underflow = ((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 // Set Inexact flag if the res is diffrent from what would be outputed given infinite precision
// - Don't set the underflow flag if an underflowed res isn't outputed // - Don't set the underflow flag if an underflowed res isn't outputed
assign FpInexact = (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 // if the res is too small to be represented and not 0
// | and if the res is not invalid (outside the integer bounds) // | and if the res is not invalid (outside the integer bounds)
// | | // | |
assign IntInexact = ((CvtCalcExpM[`NE]&~XZero)|Sticky|Round)&~IntInvalid; assign IntInexact = ((CvtCe[`NE]&~XZero)|S|R)&~IntInvalid;
// select the inexact flag to output // select the inexact flag to output
assign Inexact = ToInt ? IntInexact : FpInexact; assign Inexact = ToInt ? IntInexact : FpInexact;
@ -153,12 +153,12 @@ module flags(
// | | | | or the res rounds up out of bounds // | | | | or the res rounds up out of bounds
// | | | | and the res didn't underflow // | | | | 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 // or when the positive res rounds up out of range
assign SigNaN = (XSNaNM&~(IntToFp&CvtOp)) | (YSNaNM&~CvtOp) | (ZSNaNM&FmaOp); assign SigNaN = (XSNaN&~(IntToFp&CvtOp)) | (YSNaN&~CvtOp) | (ZSNaN&FmaOp);
assign FmaInvalid = ((XInfM | YInfM) & ZInfM & (PSgnM ^ ZSgnEffM) & ~XNaNM & ~YNaNM) | (XZero & YInfM) | (YZero & XInfM); assign FmaInvalid = ((XInf | YInf) & ZInf & (FmaPs ^ FmaAs) & ~XNaN & ~YNaN) | (XZero & YInf) | (YZero & XInf);
assign DivInvalid = ((XInfM & YInfM) | (XZero & YZero))&~Sqrt | (Xs&Sqrt); assign DivInvalid = ((XInf & YInf) | (XZero & YZero))&~Sqrt | (Xs&Sqrt);
assign Invalid = SigNaN | (FmaInvalid&FmaOp) | (DivInvalid&DivOp); assign Invalid = SigNaN | (FmaInvalid&FmaOp) | (DivInvalid&DivOp);
@ -168,7 +168,7 @@ module flags(
// Combine flags // Combine flags
// - to integer results do not set the underflow or overflow 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 endmodule

View File

@ -29,16 +29,16 @@
`include "wally-config.vh" `include "wally-config.vh"
module fmashiftcalc( 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] Ze, // exponent of Z
input logic [`NE+1:0] ProdExpM, // X exponent + Y exponent - bias input logic [`NE+1:0] FmaPe, // X exponent + Y exponent - bias
input logic [$clog2(3*`NF+7)-1:0] FmaNormCntM, // normalization shift count 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 [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
input logic KillProdM, // is the product set to zero input logic FmaKillProd, // is the product set to zero
input logic ZDenormM, input logic ZDenorm,
output logic [`NE+1:0] ConvNormSumExp, // exponent of the normalized sum not taking into account denormal or zero results output logic [`NE+1:0] FmaConvNormSumExp, // 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 FmaSmZero, // is the result denormalized - calculated before LZA corection
output logic PreResultDenorm, // 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 [$clog2(3*`NF+7)-1:0] FmaShiftAmt, // normalization shift count
output logic [3*`NF+8:0] FmaShiftIn // is the sum zero 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 //*** insert bias-bias simplification in fcvt.sv/phone pictures
// Determine if the sum is zero // Determine if the sum is zero
assign SumZero = ~(|SumM); assign FmaSmZero = ~(|FmaSm);
// calculate the sum's exponent // 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 //convert the sum's exponent into the proper percision
if (`FPSIZES == 1) begin if (`FPSIZES == 1) begin
assign ConvNormSumExp = NormSumExp; assign FmaConvNormSumExp = NormSumExp;
end else if (`FPSIZES == 2) begin 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 end else if (`FPSIZES == 3) begin
always_comb begin always_comb begin
case (Fmt) case (Fmt)
`FMT: ConvNormSumExp = NormSumExp; `FMT: FmaConvNormSumExp = NormSumExp;
`FMT1: ConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS1))&{`NE+2{|NormSumExp}}; `FMT1: FmaConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS1))&{`NE+2{|NormSumExp}};
`FMT2: ConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS2))&{`NE+2{|NormSumExp}}; `FMT2: FmaConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS2))&{`NE+2{|NormSumExp}};
default: ConvNormSumExp = {`NE+2{1'bx}}; default: FmaConvNormSumExp = {`NE+2{1'bx}};
endcase endcase
end end
end else if (`FPSIZES == 4) begin end else if (`FPSIZES == 4) begin
always_comb begin always_comb begin
case (Fmt) case (Fmt)
2'h3: ConvNormSumExp = NormSumExp; 2'h3: FmaConvNormSumExp = NormSumExp;
2'h1: ConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`D_BIAS))&{`NE+2{|NormSumExp}}; 2'h1: FmaConvNormSumExp = (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'h0: FmaConvNormSumExp = (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'h2: FmaConvNormSumExp = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`H_BIAS))&{`NE+2{|NormSumExp}};
endcase endcase
end end
@ -90,7 +90,7 @@ module fmashiftcalc(
logic Sum0LEZ, Sum0GEFL; logic Sum0LEZ, Sum0GEFL;
assign Sum0LEZ = NormSumExp[`NE+1] | ~|NormSumExp; assign Sum0LEZ = NormSumExp[`NE+1] | ~|NormSumExp;
assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2)); 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 end else if (`FPSIZES == 2) begin
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL; logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL;
@ -98,7 +98,7 @@ module fmashiftcalc(
assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2)); assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2));
assign Sum1LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)); 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 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 end else if (`FPSIZES == 3) begin
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL; 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; assign Sum2GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF2+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS2)) | ~|NormSumExp;
always_comb begin always_comb begin
case (Fmt) case (Fmt)
`FMT: PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; `FMT: FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSmZero;
`FMT1: PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; `FMT1: FmaPreResultDenorm = Sum1LEZ & Sum1GEFL & ~FmaSmZero;
`FMT2: PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; `FMT2: FmaPreResultDenorm = Sum2LEZ & Sum2GEFL & ~FmaSmZero;
default: PreResultDenorm = 1'bx; default: FmaPreResultDenorm = 1'bx;
endcase endcase
end 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; assign Sum3GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`H_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`H_BIAS)) | ~|NormSumExp;
always_comb begin always_comb begin
case (Fmt) case (Fmt)
2'h3: PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; 2'h3: FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSmZero;
2'h1: PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; 2'h1: FmaPreResultDenorm = Sum1LEZ & Sum1GEFL & ~FmaSmZero;
2'h0: PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; 2'h0: FmaPreResultDenorm = Sum2LEZ & Sum2GEFL & ~FmaSmZero;
2'h2: PreResultDenorm = Sum3LEZ & Sum3GEFL & ~SumZero; 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 endcase // *** remove checking to see if it's underflowed and only check for less than zero for denorm checking
end end
@ -144,13 +144,13 @@ module fmashiftcalc(
// - if kill prod dont add to exp // - if kill prod dont add to exp
// Determine if the result is denormal // Determine if the result is 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 // Determine the shift needed for denormal results
// - if not denorm add 1 to shift out the leading 1 // - if not denorm add 1 to shift out the leading 1
assign DenormShift = 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 // set and calculate the shift input and amount
// - shift once if killing a product and the result is denormalized // - shift once if killing a product and the result is denormalized
assign FmaShiftIn = {3'b0, SumM}; assign FmaShiftIn = {3'b0, FmaSm};
assign FmaShiftAmt = (FmaNormCntM&{$clog2(3*`NF+7){~KillProdM}})+DenormShift; assign FmaShiftAmt = (FmaNCnt&{$clog2(3*`NF+7){~FmaKillProd}})+DenormShift;
endmodule endmodule

View File

@ -296,10 +296,10 @@ module fpu (
fsgninj fsgninj(.SgnOpCodeE(FOpCtrlE[1:0]), .XSgnE, .YSgnE, .FSrcXE, .FmtE, .SgnResE); fsgninj fsgninj(.SgnOpCodeE(FOpCtrlE[1:0]), .XSgnE, .YSgnE, .FSrcXE, .FmtE, .SgnResE);
fclassify fclassify (.XSgnE, .XDenormE, .XZeroE, .XNaNE, .XInfE, .XSNaNE, .ClassResE); fclassify fclassify (.XSgnE, .XDenormE, .XZeroE, .XNaNE, .XInfE, .XSNaNE, .ClassResE);
fcvt fcvt (.XSgnE, .XExpE, .XManE, .ForwardedSrcAE, .FOpCtrlE, fcvt fcvt (.Xs(XSgnE), .Xe(XExpE), .Xm(XManE), .Int(ForwardedSrcAE), .FOpCtrl(FOpCtrlE),
.FWriteIntE, .XZeroE, .XDenormE, .FmtE, .CvtCalcExpE, .ToInt(FWriteIntE), .XZero(XZeroE), .XDenorm(XDenormE), .Fmt(FmtE), .Ce(CvtCalcExpE),
.CvtShiftAmtE, .CvtResDenormUfE, .CvtResSgnE, .IntZeroE, .ShiftAmt(CvtShiftAmtE), .ResDenormUf(CvtResDenormUfE), .Cs(CvtResSgnE), .IntZero(IntZeroE),
.CvtLzcInE); .LzcIn(CvtLzcInE));
// data to be stored in memory - to IEU // data to be stored in memory - to IEU
// - FP uses NaN-blocking format // - FP uses NaN-blocking format
@ -381,12 +381,12 @@ module fpu (
assign FpLoadStoreM = FResSelM[1]; assign FpLoadStoreM = FResSelM[1];
postprocess postprocess(.Xs(XSgnM), .Ys(YSgnM), .Ze(ZExpM), .Xm(XManM), .Ym(YManM), .Zm(ZManM), .Frm(FrmM), .Fmt(FmtM), .ProdExpM, .EarlyTermShiftDiv2M, postprocess postprocess(.Xs(XSgnM), .Ys(YSgnM), .Ze(ZExpM), .Xm(XManM), .Ym(YManM), .Zm(ZManM), .Frm(FrmM), .Fmt(FmtM), .FmaPe(ProdExpM), .DivEarlyTermShiftDiv2(EarlyTermShiftDiv2M),
.AddendStickyM, .KillProdM, .XZero(XZeroM), .YZero(YZeroM), .ZZero(ZZeroM), .XInfM, .YInfM, .Quot(QuotM), .FmaZmSticky(AddendStickyM), .FmaKillProd(KillProdM), .XZero(XZeroM), .YZero(YZeroM), .ZZero(ZZeroM), .XInf(XInfM), .YInf(YInfM), .Quot(QuotM),
.ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM, .SumM, .DivCalcExpM, .DivDone(DivDoneM), .ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM), .FmaSm(SumM), .DivCalcExp(DivCalcExpM), .DivDone(DivDoneM),
.NegSumM, .InvZM(InvAM), .ZDenormM, .ZSgnEffM, .PSgnM, .FOpCtrl(FOpCtrlM), .FmaNormCntM, .DivNegStickyM, .FmaNegSum(NegSumM), .FmaInvA(InvAM), .ZDenorm(ZDenormM), .FmaAs(ZSgnEffM), .FmaPs(PSgnM), .FOpCtrl(FOpCtrlM), .FmaNCnt(FmaNormCntM), .DivNegSticky(DivNegStickyM),
.CvtCalcExpM, .CvtResDenormUfM,.CvtShiftAmtM, .CvtResSgnM, .FWriteIntM, .DivStickyM, .CvtCe(CvtCalcExpM), .CvtResDenormUf(CvtResDenormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CvtResSgnM), .ToInt(FWriteIntM), .DivSticky(DivStickyM),
.CvtLzcInM, .IntZeroM, .PostProcSelM, .PostProcResM, .PostProcFlgM, .FCvtIntResM); .CvtLzcIn(CvtLzcInM), .IntZero(IntZeroM), .PostProcSel(PostProcSelM), .W(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM));
// FPU flag selection - to privileged // FPU flag selection - to privileged
mux2 #(5) FPUFlgMux ({PreNVM&~FResSelM[1], 4'b0}, PostProcFlgM, ~FResSelM[1]&FResSelM[0], SetFflagsM); 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 FmaOp,
input logic DivOp, input logic DivOp,
input logic DivResDenorm, 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] DivDenormShift,
input logic [`NE+1:0] ConvNormSumExp, // exponent of the normalized sum not taking into account denormal or zero results input logic [`NE+1:0] FmaConvNormSumExp, // 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 FmaPreResultDenorm, // is the result denormalized - calculated before LZA corection
input logic KillProdM, // is the product set to zero input logic FmaKillProd, // is the product set to zero
input logic SumZero, input logic FmaSmZero,
output logic [`CORRSHIFTSZ-1:0] CorrShifted, // the shifted sum before LZA correction output logic [`CORRSHIFTSZ-1:0] Nfrac, // the shifted sum before LZA correction
output logic [`NE+1:0] CorrDivExp, output logic [`NE+1:0] DivCorrExp,
output logic [`NE+1:0] SumExp // exponent of the normalized sum output logic [`NE+1:0] FmaSe // exponent of the normalized sum
); );
logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction
logic [`CORRSHIFTSZ:0] CorrQuotShifted; 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 // 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]; 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) // 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 // 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 // Determine sum's exponent
// if plus1 If plus2 if said denorm but norm plus 1 if said denorm but norm plus 2 // if plus1 If plus2 if said 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 // 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 // the quotent is in the range [.5,2) if there is no early termination
// if the quotent < 1 and not denormal then subtract 1 to account for the normalization shift // if the quotent < 1 and not 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 endmodule

View File

@ -34,15 +34,15 @@ module negateintres(
input logic Signed, input logic Signed,
input logic Int64, input logic Int64,
input logic Plus1, input logic Plus1,
output logic [1:0] NegResMSBS, output logic [1:0] CvtNegResMsbs,
output logic [`XLEN+1:0] NegRes output logic [`XLEN+1:0] CvtNegRes
); );
// round and negate the positive res if needed // 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] : assign CvtNegResMsbs = Signed ? Int64 ? CvtNegRes[`XLEN:`XLEN-1] : CvtNegRes[32:31] :
Int64 ? NegRes[`XLEN+1:`XLEN] : NegRes[33:32]; Int64 ? CvtNegRes[`XLEN+1:`XLEN] : CvtNegRes[33:32];
endmodule endmodule

View File

@ -38,86 +38,85 @@ module postprocess(
input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single 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 [2:0] FOpCtrl, // choose which opperation (look below for values)
input logic XZero, YZero, ZZero, // inputs are zero input logic XZero, YZero, ZZero, // inputs are zero
input logic XInfM, YInfM, ZInfM, // inputs are infinity input logic XInf, YInf, ZInf, // inputs are infinity
input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN input logic XNaN, YNaN, ZNaN, // inputs are NaN
input logic XSNaNM, YSNaNM, ZSNaNM, // inputs are signaling NaNs input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
input logic ZDenormM, // is the original precision denormalized input logic ZDenorm, // is the original precision denormalized
input logic [1:0] PostProcSelM, // select result to be written to fp register input logic [1:0] PostProcSel, // select result to be written to fp register
//fma signals //fma signals
input logic [`NE+1:0] ProdExpM, // X exponent + Y exponent - bias input logic FmaAs, // the modified Z sign - depends on instruction
input logic AddendStickyM, // sticky bit that is calculated during alignment input logic FmaPs, // the product's sign
input logic KillProdM, // set the product to zero before addition if the product is too small to matter input logic [`NE+1:0] FmaPe, // Product exponent
input logic [3*`NF+5:0] SumM, // the positive sum input logic [3*`NF+5:0] FmaSm, // the positive sum
input logic NegSumM, // was the sum negitive input logic FmaZmSticky, // sticky bit that is calculated during alignment
input logic InvZM, // do you invert Z input logic FmaKillProd, // set the product to zero before addition if the product is too small to matter
input logic ZSgnEffM, // the modified Z sign - depends on instruction input logic FmaNegSum, // was the sum negitive
input logic PSgnM, // the product's sign input logic FmaInvA, // do you invert Z
input logic [$clog2(3*`NF+7)-1:0] FmaNormCntM, // the normalization shift count input logic [$clog2(3*`NF+7)-1:0] FmaNCnt, // the normalization shift count
//divide signals //divide signals
input logic [$clog2(`DIVLEN/2+3)-1:0] EarlyTermShiftDiv2M, input logic [$clog2(`DIVLEN/2+3)-1:0] DivEarlyTermShiftDiv2,
input logic DivStickyM, input logic DivSticky,
input logic DivNegStickyM, input logic DivNegSticky,
input logic DivDone, input logic DivDone,
input logic [`NE+1:0] DivCalcExpM, input logic [`NE+1:0] DivCalcExp,
input logic [`DIVLEN+2:0] Quot, input logic [`DIVLEN+2:0] Quot,
// conversion signals // conversion signals
input logic [`NE:0] CvtCalcExpM, // the calculated expoent input logic CvtCs, // the result's sign
input logic CvtResDenormUfM, input logic [`NE:0] CvtCe, // the calculated expoent
input logic [`LOGCVTLEN-1:0] CvtShiftAmtM, // how much to shift by input logic CvtResDenormUf,
input logic CvtResSgnM, // the result's sign input logic [`LOGCVTLEN-1:0] CvtShiftAmt, // how much to shift by
input logic FWriteIntM, // is fp->int (since it's writting to the integer register) input logic ToInt, // is fp->int (since it's writting to the integer register)
input logic [`CVTLEN-1:0] CvtLzcInM, // input to the Leading Zero Counter (priority encoder) input logic [`CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (priority encoder)
input logic IntZeroM, // is the input zero input logic IntZero, // is the input zero
// final results // final results
output logic [`FLEN-1:0] PostProcResM, // FMA final result output logic [`FLEN-1:0] W, // FMA final result
output logic [4:0] PostProcFlgM, output logic [4:0] PostProcFlg,
output logic [`XLEN-1:0] FCvtIntResM // the int conversion result output logic [`XLEN-1:0] FCvtIntRes // the int conversion result
); );
// general signals // general signals
logic [`NF-1:0] ResFrac; // Result fraction logic Ws;
logic [`NE-1:0] ResExp; // Result exponent logic [`NF-1:0] Rf; // Result fraction
logic [`CORRSHIFTSZ-1:0] CorrShifted; // corectly shifted fraction logic [`NE-1:0] Re; // Result exponent
logic [`NE+1:0] FullResExp; // ResExp with bits to determine sign and overflow logic Nsgn;
logic Sticky; // Sticky bit 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 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 [`FLEN:0] RoundAdd; // how much to add to the result
logic [$clog2(`NORMSHIFTSZ)-1:0] ShiftAmt; // normalization shift count logic [$clog2(`NORMSHIFTSZ)-1:0] ShiftAmt; // normalization shift count
logic [`NORMSHIFTSZ-1:0] ShiftIn; // is the sum zero logic [`NORMSHIFTSZ-1:0] ShiftIn; // is the sum zero
logic [`NORMSHIFTSZ-1:0] Shifted; // the shifted result logic [`NORMSHIFTSZ-1:0] Shifted; // the shifted result
logic Plus1; // add one to the final result? logic Plus1; // add one to the final result?
logic IntInvalid, Overflow, Invalid; // flags logic IntInvalid, Overflow, Invalid; // flags
logic [`NE+1:0] RoundExp;
logic ResSgn;
logic RoundSgn;
logic UfLSBRes; logic UfLSBRes;
logic [`FMTBITS-1:0] OutFmt; logic [`FMTBITS-1:0] OutFmt;
// fma signals // fma signals
logic [`NE+1:0] SumExp; // exponent of the normalized sum logic [`NE+1:0] FmaSe; // exponent of the normalized sum
logic SumZero; // is the sum zero logic FmaSmZero; // is the sum zero
logic [3*`NF+8:0] FmaShiftIn; // is the sum zero logic [3*`NF+8:0] FmaShiftIn; // shift input
logic [`NE+1:0] ConvNormSumExp; // exponent of the normalized sum not taking into account denormal or zero results logic [`NE+1:0] FmaConvNormSumExp; // exponent of the normalized sum not taking into account denormal or zero results
logic PreResultDenorm; // is the result denormalized - calculated before LZA corection logic FmaPreResultDenorm; // is the result denormalized - calculated before LZA corection
logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt; // normalization shift count logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt; // normalization shift count
// division singals // division singals
logic [$clog2(`NORMSHIFTSZ)-1:0] DivShiftAmt; logic [$clog2(`NORMSHIFTSZ)-1:0] DivShiftAmt;
logic [`NORMSHIFTSZ-1:0] DivShiftIn; logic [`NORMSHIFTSZ-1:0] DivShiftIn;
logic [`NE+1:0] CorrDivExp; logic [`NE+1:0] DivCorrExp;
logic DivByZero; logic DivByZero;
logic DivResDenorm; logic DivResDenorm;
logic [`NE+1:0] DivDenormShift; logic [`NE+1:0] DivDenormShift;
// conversion signals // conversion signals
logic [`CVTLEN+`NF:0] CvtShiftIn; // number to be shifted logic [`CVTLEN+`NF:0] CvtShiftIn; // number to be shifted
logic [1:0] NegResMSBS; logic [1:0] CvtNegResMsbs;
logic [`XLEN+1:0] NegRes; logic [`XLEN+1:0] CvtNegRes;
logic CvtResUf; logic CvtResUf;
// readability signals // readability signals
logic Mult; // multiply opperation logic Mult; // multiply opperation
logic Int64; // is the integer 64 bits? logic Int64; // is the integer 64 bits?
logic Signed; // is the opperation with a signed integer? logic Signed; // is the opperation with a signed integer?
logic IntToFp; // is the opperation an int->fp conversion? logic IntToFp; // is the opperation an int->fp conversion?
logic ToInt; // is the opperation an fp->int conversion?
logic CvtOp; logic CvtOp;
logic FmaOp; logic FmaOp;
logic DivOp; logic DivOp;
@ -129,16 +128,15 @@ module postprocess(
assign Signed = FOpCtrl[0]; assign Signed = FOpCtrl[0];
assign Int64 = FOpCtrl[1]; assign Int64 = FOpCtrl[1];
assign IntToFp = FOpCtrl[2]; assign IntToFp = FOpCtrl[2];
assign ToInt = FWriteIntM;
assign Mult = FOpCtrl[2]&~FOpCtrl[1]&~FOpCtrl[0]; assign Mult = FOpCtrl[2]&~FOpCtrl[1]&~FOpCtrl[0];
assign CvtOp = (PostProcSelM == 2'b00); assign CvtOp = (PostProcSel == 2'b00);
assign FmaOp = (PostProcSelM == 2'b10); assign FmaOp = (PostProcSel == 2'b10);
assign DivOp = (PostProcSelM == 2'b01)&DivDone; assign DivOp = (PostProcSel == 2'b01)&DivDone;
assign Sqrt = FOpCtrl[0]; assign Sqrt = FOpCtrl[0];
// is there an input of infinity or NaN being used // is there an input of infinity or NaN being used
assign InfIn = (XInfM&~(IntToFp&CvtOp))|(YInfM&~CvtOp)|(ZInfM&FmaOp); assign InfIn = (XInf&~(IntToFp&CvtOp))|(YInf&~CvtOp)|(ZInf&FmaOp);
assign NaNIn = (XNaNM&~(IntToFp&CvtOp))|(YNaNM&~CvtOp)|(ZNaNM&FmaOp); assign NaNIn = (XNaN&~(IntToFp&CvtOp))|(YNaN&~CvtOp)|(ZNaN&FmaOp);
// choose the ouptut format depending on the opperation // choose the ouptut format depending on the opperation
// - fp -> fp: OpCtrl contains the percision of the output // - fp -> fp: OpCtrl contains the percision of the output
@ -152,20 +150,20 @@ module postprocess(
// Normalization // Normalization
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
cvtshiftcalc cvtshiftcalc(.ToInt, .CvtCalcExpM, .CvtResDenormUfM, .Xm, .CvtLzcInM, cvtshiftcalc cvtshiftcalc(.ToInt, .CvtCe, .CvtResDenormUf, .Xm, .CvtLzcIn,
.XZero, .IntToFp, .OutFmt, .CvtResUf, .CvtShiftIn); .XZero, .IntToFp, .OutFmt, .CvtResUf, .CvtShiftIn);
fmashiftcalc fmashiftcalc(.SumM, .Ze, .ProdExpM, .FmaNormCntM, .Fmt, .KillProdM, .ConvNormSumExp, fmashiftcalc fmashiftcalc(.FmaSm, .Ze, .FmaPe, .FmaNCnt, .Fmt, .FmaKillProd, .FmaConvNormSumExp,
.ZDenormM, .SumZero, .PreResultDenorm, .FmaShiftAmt, .FmaShiftIn); .ZDenorm, .FmaSmZero, .FmaPreResultDenorm, .FmaShiftAmt, .FmaShiftIn);
divshiftcalc divshiftcalc(.Fmt, .DivCalcExpM, .Quot, .EarlyTermShiftDiv2M, .DivResDenorm, .DivDenormShift, .DivShiftAmt, .DivShiftIn); divshiftcalc divshiftcalc(.Fmt, .DivCalcExp, .Quot, .DivEarlyTermShiftDiv2, .DivResDenorm, .DivDenormShift, .DivShiftAmt, .DivShiftIn);
always_comb always_comb
case(PostProcSelM) case(PostProcSel)
2'b10: begin // fma 2'b10: begin // fma
ShiftAmt = {{$clog2(`NORMSHIFTSZ)-$clog2(3*`NF+7){1'b0}}, FmaShiftAmt}; ShiftAmt = {{$clog2(`NORMSHIFTSZ)-$clog2(3*`NF+7){1'b0}}, FmaShiftAmt};
ShiftIn = {FmaShiftIn, {`NORMSHIFTSZ-(3*`NF+9){1'b0}}}; ShiftIn = {FmaShiftIn, {`NORMSHIFTSZ-(3*`NF+9){1'b0}}};
end end
2'b00: begin // cvt 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}}}; ShiftIn = {CvtShiftIn, {`NORMSHIFTSZ-`CVTLEN-`NF-1{1'b0}}};
end end
2'b01: begin //div 2'b01: begin //div
@ -185,9 +183,9 @@ module postprocess(
normshift normshift (.ShiftIn, .ShiftAmt, .Shifted); normshift normshift (.ShiftIn, .ShiftAmt, .Shifted);
lzacorrection lzacorrection(.FmaOp, .KillProdM, .PreResultDenorm, .ConvNormSumExp, lzacorrection lzacorrection(.FmaOp, .FmaKillProd, .FmaPreResultDenorm, .FmaConvNormSumExp,
.DivResDenorm, .DivDenormShift, .DivOp, .DivCalcExpM, .DivResDenorm, .DivDenormShift, .DivOp, .DivCalcExp,
.CorrDivExp, .SumZero, .Shifted, .SumExp, .CorrShifted); .DivCorrExp, .FmaSmZero, .Shifted, .FmaSe, .Nfrac);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Rounding // Rounding
@ -200,40 +198,40 @@ module postprocess(
// round to nearest max magnitude // round to nearest max magnitude
roundsign roundsign(.PSgnM, .ZSgnEffM, .InvZM, .FmaOp, .DivOp, .CvtOp, .NegSumM, roundsign roundsign(.FmaPs, .FmaAs, .FmaInvA, .FmaOp, .DivOp, .CvtOp, .FmaNegSum,
.Xs, .Ys, .CvtResSgnM, .RoundSgn); .Xs, .Ys, .CvtCs, .Nsgn);
round round(.OutFmt, .Frm, .Sticky, .AddendStickyM, .ZZero, .Plus1, .PostProcSelM, .CvtCalcExpM, .CorrDivExp, round round(.OutFmt, .Frm, .S, .FmaZmSticky, .ZZero, .Plus1, .PostProcSel, .CvtCe, .DivCorrExp,
.InvZM, .RoundSgn, .SumExp, .FmaOp, .CvtOp, .CvtResDenormUfM, .CorrShifted, .ToInt, .CvtResUf, .FmaInvA, .Nsgn, .FmaSe, .FmaOp, .CvtOp, .CvtResDenormUf, .Nfrac, .ToInt, .CvtResUf,
.DivStickyM, .DivNegStickyM, .DivDone, .DivSticky, .DivNegSticky, .DivDone,
.DivOp, .UfPlus1, .FullResExp, .ResFrac, .ResExp, .Round, .RoundAdd, .UfLSBRes, .RoundExp); .DivOp, .UfPlus1, .FullResExp, .Rf, .Re, .R, .RoundAdd, .UfLSBRes, .Nexp);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Sign calculation // Sign calculation
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
resultsign resultsign(.Frm, .PSgnM, .ZSgnEffM, .SumExp, .Round, .Sticky, resultsign resultsign(.Frm, .FmaPs, .FmaAs, .FmaSe, .R, .S,
.FmaOp, .ZInfM, .InfIn, .SumZero, .Mult, .RoundSgn, .ResSgn); .FmaOp, .ZInf, .InfIn, .FmaSmZero, .Mult, .Nsgn, .Ws);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Flags // Flags
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
flags flags(.XSNaNM, .YSNaNM, .ZSNaNM, .XInfM, .YInfM, .ZInfM, .InfIn, .XZero, .YZero, flags flags(.XSNaN, .YSNaN, .ZSNaN, .XInf, .YInf, .ZInf, .InfIn, .XZero, .YZero,
.Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCalcExpM, .Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCe,
.XNaNM, .YNaNM, .NaNIn, .ZSgnEffM, .PSgnM, .Round, .IntInvalid, .DivByZero, .XNaN, .YNaN, .NaNIn, .FmaAs, .FmaPs, .R, .IntInvalid, .DivByZero,
.UfLSBRes, .Sticky, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullResExp, .Plus1, .UfLSBRes, .S, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullResExp, .Plus1,
.RoundExp, .NegResMSBS, .Invalid, .Overflow, .PostProcFlgM); .Nexp, .CvtNegResMsbs, .Invalid, .Overflow, .PostProcFlg);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Select the result // 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, resultselect resultselect(.Xs, .Xm, .Ym, .Zm, .XZero, .IntInvalid,
.IntZeroM, .Frm, .OutFmt, .XNaNM, .YNaNM, .ZNaNM, .CvtResUf, .IntZero, .Frm, .OutFmt, .XNaN, .YNaN, .ZNaN, .CvtResUf,
.NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .NegRes, .NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .CvtNegRes,
.XInfM, .YInfM, .DivOp, .XInf, .YInf, .DivOp,
.DivByZero, .FullResExp, .CvtCalcExpM, .ResSgn, .ResExp, .ResFrac, .PostProcResM, .FCvtIntResM); .DivByZero, .FullResExp, .CvtCe, .Ws, .Re, .Rf, .W, .FCvtIntRes);
endmodule endmodule

View File

@ -32,13 +32,13 @@
module resultselect( module resultselect(
input logic Xs, // input signs input logic Xs, // input signs
input logic [`NF:0] Xm, Ym, Zm, // input mantissas 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 [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 [`FMTBITS-1:0] OutFmt, // output format
input logic InfIn, input logic InfIn,
input logic XInfM, YInfM, input logic XInf, YInf,
input logic XZero, input logic XZero,
input logic IntZeroM, input logic IntZero,
input logic NaNIn, input logic NaNIn,
input logic IntToFp, input logic IntToFp,
input logic Int64, input logic Int64,
@ -48,16 +48,16 @@ module resultselect(
input logic FmaOp, input logic FmaOp,
input logic Plus1, input logic Plus1,
input logic DivByZero, input logic DivByZero,
input logic [`NE:0] CvtCalcExpM, // the calculated expoent input logic [`NE:0] CvtCe, // the calculated expoent
input logic ResSgn, // the res's sign input logic Ws, // the res's sign
input logic IntInvalid, Invalid, Overflow, // flags input logic IntInvalid, Invalid, Overflow, // flags
input logic CvtResUf, input logic CvtResUf,
input logic [`NE-1:0] ResExp, // Res exponent input logic [`NE-1:0] Re, // Res exponent
input logic [`NE+1:0] FullResExp, // Res exponent input logic [`NE+1:0] FullResExp, // Res exponent
input logic [`NF-1:0] ResFrac, // Res fraction input logic [`NF-1:0] Rf, // Res fraction
input logic [`XLEN+1:0] NegRes, // the negation of the result input logic [`XLEN+1:0] CvtNegRes, // the negation of the result
output logic [`FLEN-1:0] PostProcResM, // final res output logic [`FLEN-1:0] W, // final res
output logic [`XLEN-1:0] FCvtIntResM // final res output logic [`XLEN-1:0] FCvtIntRes // final res
); );
logic [`FLEN-1:0] XNaNRes, YNaNRes, ZNaNRes, InvalidRes, OfRes, UfRes, NormRes; // possible results logic [`FLEN-1:0] XNaNRes, YNaNRes, ZNaNRes, InvalidRes, OfRes, UfRes, NormRes; // possible results
logic OfResMax; logic OfResMax;
@ -68,7 +68,7 @@ module resultselect(
// does the overflow result output the maximum normalized floating point number // does the overflow result output the maximum normalized floating point number
// output infinity if the input is infinity // output infinity if the input is infinity
assign OfResMax = (~InfIn|(IntToFp&CvtOp))&~DivByZero&((Frm[1:0]==2'b01) | (Frm[1:0]==2'b10&~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 if (`FPSIZES == 1) begin
@ -82,9 +82,9 @@ module resultselect(
assign InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; assign InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
end end
assign OfRes = OfResMax ? {ResSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResSgn, {`NE{1'b1}}, {`NF{1'b0}}}; assign OfRes = OfResMax ? {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Ws, {`NE{1'b1}}, {`NF{1'b0}}};
assign UfRes = {ResSgn, {`FLEN-2{1'b0}}, Plus1&Frm[1]&~(DivOp&YInfM)}; assign UfRes = {Ws, {`FLEN-2{1'b0}}, Plus1&Frm[1]&~(DivOp&YInf)};
assign NormRes = {ResSgn, ResExp, ResFrac}; assign NormRes = {Ws, Re, Rf};
end else if (`FPSIZES == 2) begin //will the format conversion in killprod work in other conversions? end else if (`FPSIZES == 2) begin //will the format conversion in killprod work in other conversions?
if(`IEEE754) begin if(`IEEE754) begin
@ -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)}; 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 end
assign OfRes = OutFmt ? OfResMax ? {ResSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResSgn, {`NE{1'b1}}, {`NF{1'b0}}} : 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}}, ResSgn, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : {{`FLEN-`LEN1{1'b1}}, ResSgn, {`NE1{1'b1}}, (`NF1)'(0)}; 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 ? {ResSgn, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)} : {{`FLEN-`LEN1{1'b1}}, ResSgn, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)}; 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 ? {ResSgn, ResExp, ResFrac} : {{`FLEN-`LEN1{1'b1}}, ResSgn, ResExp[`NE1-1:0], ResFrac[`NF-1:`NF-`NF1]}; 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 end else if (`FPSIZES == 3) begin
always_comb always_comb
@ -114,9 +114,9 @@ module resultselect(
InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
end end
OfRes = OfResMax ? {ResSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResSgn, {`NE{1'b1}}, {`NF{1'b0}}}; OfRes = OfResMax ? {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Ws, {`NE{1'b1}}, {`NF{1'b0}}};
UfRes = {ResSgn, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)}; UfRes = {Ws, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {ResSgn, ResExp, ResFrac}; NormRes = {Ws, Re, Rf};
end end
`FMT1: begin `FMT1: begin
if(`IEEE754) begin if(`IEEE754) begin
@ -127,9 +127,9 @@ module resultselect(
end else begin end else begin
InvalidRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; InvalidRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`LEN1{1'b1}}, ResSgn, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : {{`FLEN-`LEN1{1'b1}}, ResSgn, {`NE1{1'b1}}, (`NF1)'(0)}; 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}}, ResSgn, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)}; UfRes = {{`FLEN-`LEN1{1'b1}}, Ws, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`LEN1{1'b1}}, ResSgn, ResExp[`NE1-1:0], ResFrac[`NF-1:`NF-`NF1]}; NormRes = {{`FLEN-`LEN1{1'b1}}, Ws, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]};
end end
`FMT2: begin `FMT2: begin
if(`IEEE754) 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)}; InvalidRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)};
end 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)}; 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}}, ResSgn, (`LEN2-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)}; UfRes = {{`FLEN-`LEN2{1'b1}}, Ws, (`LEN2-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`LEN2{1'b1}}, ResSgn, ResExp[`NE2-1:0], ResFrac[`NF-1:`NF-`NF2]}; NormRes = {{`FLEN-`LEN2{1'b1}}, Ws, Re[`NE2-1:0], Rf[`NF-1:`NF-`NF2]};
end end
default: begin default: begin
if(`IEEE754) begin if(`IEEE754) begin
@ -173,9 +173,9 @@ module resultselect(
InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
end end
OfRes = OfResMax ? {ResSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResSgn, {`NE{1'b1}}, {`NF{1'b0}}}; OfRes = OfResMax ? {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Ws, {`NE{1'b1}}, {`NF{1'b0}}};
UfRes = {ResSgn, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)}; UfRes = {Ws, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {ResSgn, ResExp, ResFrac}; NormRes = {Ws, Re, Rf};
end end
2'h1: begin 2'h1: begin
if(`IEEE754) begin if(`IEEE754) begin
@ -186,9 +186,9 @@ module resultselect(
end else begin end else begin
InvalidRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; InvalidRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`D_LEN{1'b1}}, 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)}; 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}}, ResSgn, (`D_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)}; UfRes = {{`FLEN-`D_LEN{1'b1}}, Ws, (`D_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`D_LEN{1'b1}}, ResSgn, ResExp[`D_NE-1:0], ResFrac[`NF-1:`NF-`D_NF]}; NormRes = {{`FLEN-`D_LEN{1'b1}}, Ws, Re[`D_NE-1:0], Rf[`NF-1:`NF-`D_NF]};
end end
2'h0: begin 2'h0: begin
if(`IEEE754) begin if(`IEEE754) begin
@ -200,9 +200,9 @@ module resultselect(
InvalidRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; InvalidRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`S_LEN{1'b1}}, 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)}; 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}}, ResSgn, (`S_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInfM)}; UfRes = {{`FLEN-`S_LEN{1'b1}}, Ws, (`S_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`S_LEN{1'b1}}, ResSgn, ResExp[`S_NE-1:0], ResFrac[`NF-1:`NF-`S_NF]}; NormRes = {{`FLEN-`S_LEN{1'b1}}, Ws, Re[`S_NE-1:0], Rf[`NF-1:`NF-`S_NF]};
end end
2'h2: begin 2'h2: begin
if(`IEEE754) begin if(`IEEE754) begin
@ -214,10 +214,10 @@ module resultselect(
InvalidRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; InvalidRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`H_LEN{1'b1}}, 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 // 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)}; UfRes = {{`FLEN-`H_LEN{1'b1}}, Ws, (`H_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`H_LEN{1'b1}}, ResSgn, ResExp[`H_NE-1:0], ResFrac[`NF-1:`NF-`H_NF]}; NormRes = {{`FLEN-`H_LEN{1'b1}}, Ws, Re[`H_NE-1:0], Rf[`NF-1:`NF-`H_NF]};
end end
endcase 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 // - do so if the res underflows, is zero (the exp doesnt calculate correctly). or the integer input is 0
// - dont set to zero if fp input is zero but not using the fp input // - dont set to zero if fp input is zero but not using the fp input
// - dont set to zero if int input is zero but not using the int input // - dont set to zero if int input is zero but not using the int input
assign KillRes = CvtOp ? (CvtResUf|(XZero&~IntToFp)|(IntZeroM&IntToFp)) : FullResExp[`NE+1] | (((YInfM&~XInfM)|XZero)&DivOp);//Underflow & ~ResDenorm & (ResExp!=1); assign KillRes = CvtOp ? (CvtResUf|(XZero&~IntToFp)|(IntZero&IntToFp)) : FullResExp[`NE+1] | (((YInf&~XInf)|XZero)&DivOp);//Underflow & ~ResDenorm & (Re!=1);
assign SelOfRes = Overflow|DivByZero|(InfIn&~(YInfM&DivOp)); assign SelOfRes = Overflow|DivByZero|(InfIn&~(YInf&DivOp));
// output infinity with result sign if divide by zero // output infinity with result sign if divide by zero
if(`IEEE754) begin if(`IEEE754) begin
assign PostProcResM = XNaNM&~(IntToFp&CvtOp) ? XNaNRes : assign W = XNaN&~(IntToFp&CvtOp) ? XNaNRes :
YNaNM&~CvtOp ? YNaNRes : YNaN&~CvtOp ? YNaNRes :
ZNaNM&FmaOp ? ZNaNRes : ZNaN&FmaOp ? ZNaNRes :
Invalid ? InvalidRes : Invalid ? InvalidRes :
SelOfRes ? OfRes : SelOfRes ? OfRes :
KillRes ? UfRes : KillRes ? UfRes :
NormRes; NormRes;
end else begin end else begin
assign PostProcResM = NaNIn|Invalid ? InvalidRes : assign W = NaNIn|Invalid ? InvalidRes :
SelOfRes ? OfRes : SelOfRes ? OfRes :
KillRes ? UfRes : KillRes ? UfRes :
NormRes; NormRes;
@ -272,9 +272,9 @@ module resultselect(
// unsigned | 2^32-1 | 2^64-1 | // unsigned | 2^32-1 | 2^64-1 |
// //
// other: 32 bit unsinged res should be sign extended as if it were a signed number // 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 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 {`XLEN{1'b1}};// unsigned positive
@ -284,7 +284,7 @@ module resultselect(
// - if rounding and signed opperation and negitive input, output -1 // - if rounding and signed opperation and negitive input, output -1
// - otherwise output a rounded 0 // - otherwise output a rounded 0
// - otherwise output the normal res (trmined and sign extended if nessisary) // - otherwise output the normal res (trmined and sign extended if nessisary)
assign FCvtIntResM = IntInvalid ? OfIntRes : assign FCvtIntRes = 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?? 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 ? NegRes[`XLEN-1:0] : {{`XLEN-32{NegRes[31]}}, NegRes[31:0]}; Int64 ? CvtNegRes[`XLEN-1:0] : {{`XLEN-32{CvtNegRes[31]}}, CvtNegRes[31:0]};
endmodule endmodule

View File

@ -30,17 +30,17 @@
module resultsign( module resultsign(
input logic [2:0] Frm, input logic [2:0] Frm,
input logic PSgnM, ZSgnEffM, input logic FmaPs, FmaAs,
input logic ZInfM, input logic ZInf,
input logic InfIn, input logic InfIn,
input logic FmaOp, input logic FmaOp,
input logic [`NE+1:0] SumExp, input logic [`NE+1:0] FmaSe,
input logic SumZero, input logic FmaSmZero,
input logic Mult, input logic Mult,
input logic Round, input logic R,
input logic Sticky, input logic S,
input logic RoundSgn, input logic Nsgn,
output logic ResSgn output logic Ws
); );
logic ZeroSgn; logic ZeroSgn;
@ -52,15 +52,15 @@ module resultsign(
// if cancelation then 0 unless round to -infinity // if cancelation then 0 unless round to -infinity
// if multiply then Psgn // if multiply then Psgn
// otherwise psign // otherwise psign
assign Underflow = SumExp[`NE+1] | ((SumExp == 0) & (Round|Sticky)); assign Underflow = FmaSe[`NE+1] | ((FmaSe == 0) & (R|S));
assign ZeroSgn = (PSgnM^ZSgnEffM)&~Underflow&~Mult ? Frm[1:0] == 2'b10 : PSgnM; assign ZeroSgn = (FmaPs^FmaAs)&~Underflow&~Mult ? Frm[1:0] == 2'b10 : FmaPs;
// is the result negitive // is the result negitive
// if p - z is the Sum negitive // if p - z is the Sum negitive
// if -p + z is the Sum positive // if -p + z is the Sum positive
// if -p - z then the Sum is negitive // if -p - z then the Sum is negitive
assign InfSgn = ZInfM ? ZSgnEffM : PSgnM; assign InfSgn = ZInf ? FmaAs : FmaPs;
assign ResSgn = InfIn&FmaOp ? InfSgn : SumZero&FmaOp ? ZeroSgn : RoundSgn; assign Ws = InfIn&FmaOp ? InfSgn : FmaSmZero&FmaOp ? ZeroSgn : Nsgn;
endmodule endmodule

View File

@ -43,28 +43,28 @@ module round(
input logic CvtOp, input logic CvtOp,
input logic ToInt, input logic ToInt,
input logic DivDone, input logic DivDone,
input logic [1:0] PostProcSelM, input logic [1:0] PostProcSel,
input logic CvtResDenormUfM, input logic CvtResDenormUf,
input logic CvtResUf, input logic CvtResUf,
input logic [`CORRSHIFTSZ-1:0] CorrShifted, input logic [`CORRSHIFTSZ-1:0] Nfrac,
input logic AddendStickyM, // addend's sticky bit input logic FmaZmSticky, // addend's sticky bit
input logic ZZero, // is Z zero input logic ZZero, // is Z zero
input logic InvZM, // invert Z input logic FmaInvA, // invert Z
input logic [`NE+1:0] SumExp, // exponent of the normalized sum input logic [`NE+1:0] FmaSe, // exponent of the normalized sum
input logic RoundSgn, // the result's sign input logic Nsgn, // the result's sign
input logic [`NE:0] CvtCalcExpM, // the calculated expoent input logic [`NE:0] CvtCe, // the calculated expoent
input logic [`NE+1:0] CorrDivExp, // the calculated expoent input logic [`NE+1:0] DivCorrExp, // the calculated expoent
input logic DivStickyM, // sticky bit input logic DivSticky, // sticky bit
input logic DivNegStickyM, input logic DivNegSticky,
output logic UfPlus1, // do you add or subtract on from the result 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 [`NE+1:0] FullResExp, // Re with bits to determine sign and overflow
output logic [`NF-1:0] ResFrac, // Result fraction output logic [`NF-1:0] Rf, // Result fraction
output logic [`NE-1:0] ResExp, // Result exponent output logic [`NE-1:0] Re, // Result exponent
output logic Sticky, // sticky bit output logic S, // sticky bit
output logic [`NE+1:0] RoundExp, output logic [`NE+1:0] Nexp,
output logic Plus1, output logic Plus1,
output logic [`FLEN:0] RoundAdd, // how much to add to the result 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 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 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 to nearest even
// {Round, Sticky} // {R, S}
// 0x - do nothing // 0x - do nothing
// 10 - tie - Plus1 if result is odd (LSBNormSum = 1) // 10 - tie - Plus1 if result is odd (LSBNormSum = 1)
// - don't add 1 if a small number was supposed to be subtracted // - don't add 1 if a small number was supposed to be subtracted
@ -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 // - subtract 1 if a small number was supposed to be subtracted from a negative result with guard and round bits of 0
// round to nearest max magnitude // round to nearest max magnitude
// {Guard, Round, Sticky} // {Guard, R, S}
// 0x - do nothing // 0x - do nothing
// 10 - tie - Plus1 // 10 - tie - Plus1
// - don't add 1 if a small number was supposed to be subtracted // - don't add 1 if a small number was supposed to be subtracted
@ -118,61 +118,61 @@ module round(
// | NF |1|1| // | NF |1|1|
// ^ ^ if floating point result // ^ ^ if floating point result
// ^ if not an FMA result // ^ if not an FMA result
if (`XLENPOS == 1)assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) | if (`XLENPOS == 1)assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:0]); (|Nfrac[`CORRSHIFTSZ-`XLEN-2:0]);
// 2: NF > XLEN // 2: NF > XLEN
if (`XLENPOS == 2)assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&IntRes) | if (`XLENPOS == 2)assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&IntRes) |
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]); (|Nfrac[`CORRSHIFTSZ-`NF-2:0]);
end else if (`FPSIZES == 2) begin end else if (`FPSIZES == 2) begin
// XLEN is either 64 or 32 // XLEN is either 64 or 32
// so half and single are always smaller then XLEN // so half and single are always smaller then XLEN
// 1: XLEN > NF > NF1 // 1: XLEN > NF > NF1
if (`XLENPOS == 1) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~OutFmt) | if (`XLENPOS == 1) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~OutFmt) |
(|CorrShifted[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) | (|Nfrac[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:0]); (|Nfrac[`CORRSHIFTSZ-`XLEN-2:0]);
// 2: NF > XLEN > NF1 // 2: NF > XLEN > NF1
if (`XLENPOS == 2) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~OutFmt) | if (`XLENPOS == 2) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~OutFmt) |
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~OutFmt)) | (|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~OutFmt)) |
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]); (|Nfrac[`CORRSHIFTSZ-`NF-2:0]);
// 3: NF > NF1 > XLEN // 3: NF > NF1 > XLEN
if (`XLENPOS == 3) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&IntRes) | if (`XLENPOS == 3) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&IntRes) |
(|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~OutFmt|IntRes)) | (|Nfrac[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~OutFmt|IntRes)) |
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]); (|Nfrac[`CORRSHIFTSZ-`NF-2:0]);
end else if (`FPSIZES == 3) begin end else if (`FPSIZES == 3) begin
// 1: XLEN > NF > NF1 // 1: XLEN > NF > NF1
if (`XLENPOS == 1) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) | if (`XLENPOS == 1) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) |
(|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~(OutFmt==`FMT)) | (|Nfrac[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~(OutFmt==`FMT)) |
(|CorrShifted[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) | (|Nfrac[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:0]); (|Nfrac[`CORRSHIFTSZ-`XLEN-2:0]);
// 2: NF > XLEN > NF1 // 2: NF > XLEN > NF1
if (`XLENPOS == 2) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) | if (`XLENPOS == 2) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) |
(|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`FMT)) | (|Nfrac[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`FMT)) |
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~(OutFmt==`FMT))) | (|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~(OutFmt==`FMT))) |
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]); (|Nfrac[`CORRSHIFTSZ-`NF-2:0]);
// 3: NF > NF1 > XLEN // 3: NF > NF1 > XLEN
if (`XLENPOS == 3) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&(OutFmt==`FMT1)) | if (`XLENPOS == 3) assign NormSumSticky = (|Nfrac[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&(OutFmt==`FMT1)) |
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&((OutFmt==`FMT1)|IntRes)) | (|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&((OutFmt==`FMT1)|IntRes)) |
(|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~(OutFmt==`FMT)|IntRes)) | (|Nfrac[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~(OutFmt==`FMT)|IntRes)) |
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]); (|Nfrac[`CORRSHIFTSZ-`NF-2:0]);
end else if (`FPSIZES == 4) begin end else if (`FPSIZES == 4) begin
// Quad precision will always be greater than XLEN // Quad precision will always be greater than XLEN
// 2: NF > XLEN > NF1 // 2: NF > XLEN > NF1
if (`XLENPOS == 2) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`H_NF-2:`CORRSHIFTSZ-`S_NF-1]&FpRes&(OutFmt==`H_FMT)) | if (`XLENPOS == 2) assign NormSumSticky = (|Nfrac[`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))) | (|Nfrac[`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)) | (|Nfrac[`CORRSHIFTSZ-`D_NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`Q_FMT)) |
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) | (|Nfrac[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) |
(|CorrShifted[`CORRSHIFTSZ-`Q_NF-2:0]); (|Nfrac[`CORRSHIFTSZ-`Q_NF-2:0]);
// 3: NF > NF1 > XLEN // 3: NF > NF1 > XLEN
// The extra XLEN bit will be ored later when caculating the final sticky bit - the ufplus1 not needed for integer // 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)) | if (`XLENPOS == 3) assign NormSumSticky = (|Nfrac[`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))) | (|Nfrac[`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)) | (|Nfrac[`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)) | (|Nfrac[`CORRSHIFTSZ-`D_NF-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) |
(|CorrShifted[`CORRSHIFTSZ-`Q_NF-2:0]); (|Nfrac[`CORRSHIFTSZ-`Q_NF-2:0]);
end end
@ -180,37 +180,37 @@ module round(
// only add the Addend sticky if doing an FMA opperation // only add the Addend sticky if doing an FMA opperation
// - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits) // - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits)
assign 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 // determine round and LSB of the rounded value
// - underflow round bit is used to determint the underflow flag // - underflow round bit is used to determint the underflow flag
if (`FPSIZES == 1) begin if (`FPSIZES == 1) begin
assign FpRound = CorrShifted[`CORRSHIFTSZ-`NF-1]; assign FpRound = Nfrac[`CORRSHIFTSZ-`NF-1];
assign FpLSBRes = CorrShifted[`CORRSHIFTSZ-`NF]; assign FpLSBRes = Nfrac[`CORRSHIFTSZ-`NF];
assign FpUfRound = CorrShifted[`CORRSHIFTSZ-`NF-2]; assign FpUfRound = Nfrac[`CORRSHIFTSZ-`NF-2];
end else if (`FPSIZES == 2) begin end else if (`FPSIZES == 2) begin
assign FpRound = OutFmt ? CorrShifted[`CORRSHIFTSZ-`NF-1] : CorrShifted[`CORRSHIFTSZ-`NF1-1]; assign FpRound = OutFmt ? Nfrac[`CORRSHIFTSZ-`NF-1] : Nfrac[`CORRSHIFTSZ-`NF1-1];
assign FpLSBRes = OutFmt ? CorrShifted[`CORRSHIFTSZ-`NF] : CorrShifted[`CORRSHIFTSZ-`NF1]; assign FpLSBRes = OutFmt ? Nfrac[`CORRSHIFTSZ-`NF] : Nfrac[`CORRSHIFTSZ-`NF1];
assign FpUfRound = OutFmt ? CorrShifted[`CORRSHIFTSZ-`NF-2] : CorrShifted[`CORRSHIFTSZ-`NF1-2]; assign FpUfRound = OutFmt ? Nfrac[`CORRSHIFTSZ-`NF-2] : Nfrac[`CORRSHIFTSZ-`NF1-2];
end else if (`FPSIZES == 3) begin end else if (`FPSIZES == 3) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
`FMT: begin `FMT: begin
FpRound = CorrShifted[`CORRSHIFTSZ-`NF-1]; FpRound = Nfrac[`CORRSHIFTSZ-`NF-1];
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`NF]; FpLSBRes = Nfrac[`CORRSHIFTSZ-`NF];
FpUfRound = CorrShifted[`CORRSHIFTSZ-`NF-2]; FpUfRound = Nfrac[`CORRSHIFTSZ-`NF-2];
end end
`FMT1: begin `FMT1: begin
FpRound = CorrShifted[`CORRSHIFTSZ-`NF1-1]; FpRound = Nfrac[`CORRSHIFTSZ-`NF1-1];
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`NF1]; FpLSBRes = Nfrac[`CORRSHIFTSZ-`NF1];
FpUfRound = CorrShifted[`CORRSHIFTSZ-`NF1-2]; FpUfRound = Nfrac[`CORRSHIFTSZ-`NF1-2];
end end
`FMT2: begin `FMT2: begin
FpRound = CorrShifted[`CORRSHIFTSZ-`NF2-1]; FpRound = Nfrac[`CORRSHIFTSZ-`NF2-1];
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`NF2]; FpLSBRes = Nfrac[`CORRSHIFTSZ-`NF2];
FpUfRound = CorrShifted[`CORRSHIFTSZ-`NF2-2]; FpUfRound = Nfrac[`CORRSHIFTSZ-`NF2-2];
end end
default: begin default: begin
FpRound = 1'bx; FpRound = 1'bx;
@ -222,69 +222,69 @@ module round(
always_comb always_comb
case (OutFmt) case (OutFmt)
2'h3: begin 2'h3: begin
FpRound = CorrShifted[`CORRSHIFTSZ-`Q_NF-1]; FpRound = Nfrac[`CORRSHIFTSZ-`Q_NF-1];
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`Q_NF]; FpLSBRes = Nfrac[`CORRSHIFTSZ-`Q_NF];
FpUfRound = CorrShifted[`CORRSHIFTSZ-`Q_NF-2]; FpUfRound = Nfrac[`CORRSHIFTSZ-`Q_NF-2];
end end
2'h1: begin 2'h1: begin
FpRound = CorrShifted[`CORRSHIFTSZ-`D_NF-1]; FpRound = Nfrac[`CORRSHIFTSZ-`D_NF-1];
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`D_NF]; FpLSBRes = Nfrac[`CORRSHIFTSZ-`D_NF];
FpUfRound = CorrShifted[`CORRSHIFTSZ-`D_NF-2]; FpUfRound = Nfrac[`CORRSHIFTSZ-`D_NF-2];
end end
2'h0: begin 2'h0: begin
FpRound = CorrShifted[`CORRSHIFTSZ-`S_NF-1]; FpRound = Nfrac[`CORRSHIFTSZ-`S_NF-1];
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`S_NF]; FpLSBRes = Nfrac[`CORRSHIFTSZ-`S_NF];
FpUfRound = CorrShifted[`CORRSHIFTSZ-`S_NF-2]; FpUfRound = Nfrac[`CORRSHIFTSZ-`S_NF-2];
end end
2'h2: begin 2'h2: begin
FpRound = CorrShifted[`CORRSHIFTSZ-`H_NF-1]; FpRound = Nfrac[`CORRSHIFTSZ-`H_NF-1];
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`H_NF]; FpLSBRes = Nfrac[`CORRSHIFTSZ-`H_NF];
FpUfRound = CorrShifted[`CORRSHIFTSZ-`H_NF-2]; FpUfRound = Nfrac[`CORRSHIFTSZ-`H_NF-2];
end end
endcase endcase
end end
assign Round = ToInt&CvtOp ? CorrShifted[`CORRSHIFTSZ-`XLEN-1] : FpRound; assign R = ToInt&CvtOp ? Nfrac[`CORRSHIFTSZ-`XLEN-1] : FpRound;
assign LSBRes = ToInt&CvtOp ? CorrShifted[`CORRSHIFTSZ-`XLEN] : FpLSBRes; assign LSBRes = ToInt&CvtOp ? Nfrac[`CORRSHIFTSZ-`XLEN] : FpLSBRes;
assign UfRound = ToInt&CvtOp ? CorrShifted[`CORRSHIFTSZ-`XLEN-2] : FpUfRound; assign UfRound = ToInt&CvtOp ? Nfrac[`CORRSHIFTSZ-`XLEN-2] : FpUfRound;
// used to determine underflow flag // used to determine underflow flag
assign UfLSBRes = FpRound; assign UfLSBRes = FpRound;
// determine sticky // determine sticky
assign Sticky = UfSticky | UfRound; assign S = UfSticky | UfRound;
// Deterimine if a small number was supposed to be subtrated // Deterimine if a small number was supposed to be subtrated
// - for FMA or if division has a negitive sticky bit // - for FMA or if division has a negitive sticky bit
assign SubBySmallNum = ((AddendStickyM&FmaOp&~ZZero&InvZM) | (DivNegStickyM&DivOp)) & ~(NormSumSticky|UfRound); assign SubBySmallNum = ((FmaZmSticky&FmaOp&~ZZero&FmaInvA) | (DivNegSticky&DivOp)) & ~(NormSumSticky|UfRound);
assign UfSubBySmallNum = ((AddendStickyM&FmaOp&~ZZero&InvZM) | (DivNegStickyM&DivOp)) & ~NormSumSticky; assign UfSubBySmallNum = ((FmaZmSticky&FmaOp&~ZZero&FmaInvA) | (DivNegSticky&DivOp)) & ~NormSumSticky;
always_comb begin always_comb begin
// Determine if you add 1 // Determine if you add 1
case (Frm) 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'b001: CalcPlus1 = 0;//round to zero
3'b010: CalcPlus1 = RoundSgn & ~(SubBySmallNum & ~Round);//round down 3'b010: CalcPlus1 = Nsgn & ~(SubBySmallNum & ~R);//round down
3'b011: CalcPlus1 = ~RoundSgn & ~(SubBySmallNum & ~Round);//round up 3'b011: CalcPlus1 = ~Nsgn & ~(SubBySmallNum & ~R);//round up
3'b100: CalcPlus1 = Round & ~SubBySmallNum;//round to nearest max magnitude 3'b100: CalcPlus1 = R & ~SubBySmallNum;//round to nearest max magnitude
default: CalcPlus1 = 1'bx; default: CalcPlus1 = 1'bx;
endcase endcase
// Determine if you add 1 (for underflow flag) // Determine if you add 1 (for underflow flag)
case (Frm) case (Frm)
3'b000: UfCalcPlus1 = UfRound & ((UfSticky| UfLSBRes)&~UfSubBySmallNum);//round to nearest even 3'b000: UfCalcPlus1 = UfRound & ((UfSticky| UfLSBRes)&~UfSubBySmallNum);//round to nearest even
3'b001: UfCalcPlus1 = 0;//round to zero 3'b001: UfCalcPlus1 = 0;//round to zero
3'b010: UfCalcPlus1 = RoundSgn & ~(UfSubBySmallNum & ~UfRound);//round down 3'b010: UfCalcPlus1 = Nsgn & ~(UfSubBySmallNum & ~UfRound);//round down
3'b011: UfCalcPlus1 = ~RoundSgn & ~(UfSubBySmallNum & ~UfRound);//round up 3'b011: UfCalcPlus1 = ~Nsgn & ~(UfSubBySmallNum & ~UfRound);//round up
3'b100: UfCalcPlus1 = UfRound & ~UfSubBySmallNum;//round to nearest max magnitude 3'b100: UfCalcPlus1 = UfRound & ~UfSubBySmallNum;//round to nearest max magnitude
default: UfCalcPlus1 = 1'bx; default: UfCalcPlus1 = 1'bx;
endcase endcase
// Determine if you subtract 1 // Determine if you subtract 1
case (Frm) case (Frm)
3'b000: CalcMinus1 = 0;//round to nearest even 3'b000: CalcMinus1 = 0;//round to nearest even
3'b001: CalcMinus1 = SubBySmallNum & ~Round;//round to zero 3'b001: CalcMinus1 = SubBySmallNum & ~R;//round to zero
3'b010: CalcMinus1 = ~RoundSgn & ~Round & SubBySmallNum;//round down 3'b010: CalcMinus1 = ~Nsgn & ~R & SubBySmallNum;//round down
3'b011: CalcMinus1 = RoundSgn & ~Round & SubBySmallNum;//round up 3'b011: CalcMinus1 = Nsgn & ~R & SubBySmallNum;//round up
3'b100: CalcMinus1 = 0;//round to nearest max magnitude 3'b100: CalcMinus1 = 0;//round to nearest max magnitude
default: CalcMinus1 = 1'bx; default: CalcMinus1 = 1'bx;
endcase endcase
@ -292,10 +292,10 @@ module round(
end end
// If an answer is exact don't round // If an answer is exact don't round
assign Plus1 = CalcPlus1 & (Sticky | Round); assign Plus1 = CalcPlus1 & (S | R);
assign FpPlus1 = Plus1&~(ToInt&CvtOp); assign FpPlus1 = Plus1&~(ToInt&CvtOp);
assign UfPlus1 = UfCalcPlus1 & Sticky; // UfRound is part of sticky assign UfPlus1 = UfCalcPlus1 & S; // UfRound is part of sticky
assign Minus1 = CalcMinus1 & (Sticky | Round); assign Minus1 = CalcMinus1 & (S | R);
// Compute rounded result // Compute rounded result
if (`FPSIZES == 1) begin if (`FPSIZES == 1) begin
@ -332,20 +332,20 @@ module round(
end end
// determine the result to be roundned // determine the result to be roundned
assign RoundFrac = CorrShifted[`CORRSHIFTSZ-1:`CORRSHIFTSZ-`NF]; assign RoundFrac = Nfrac[`CORRSHIFTSZ-1:`CORRSHIFTSZ-`NF];
always_comb always_comb
case(PostProcSelM) case(PostProcSel)
2'b10: RoundExp = SumExp; // fma 2'b10: Nexp = FmaSe; // fma
2'b00: RoundExp = {CvtCalcExpM[`NE], CvtCalcExpM}&{`NE+2{~CvtResDenormUfM|CvtResUf}}; // cvt 2'b00: Nexp = {CvtCe[`NE], CvtCe}&{`NE+2{~CvtResDenormUf|CvtResUf}}; // cvt
2'b01: RoundExp = DivDone ? CorrDivExp : '0; // divide 2'b01: Nexp = DivDone ? DivCorrExp : '0; // divide
default: RoundExp = '0; default: Nexp = '0;
endcase endcase
// round the result // round the result
// - if the fraction overflows one should be added to the exponent // - if the fraction overflows one should be added to the exponent
assign {FullResExp, ResFrac} = {RoundExp, RoundFrac} + RoundAdd; assign {FullResExp, Rf} = {Nexp, RoundFrac} + RoundAdd;
assign ResExp = FullResExp[`NE-1:0]; assign Re = FullResExp[`NE-1:0];
endmodule endmodule

View File

@ -29,16 +29,16 @@
`include "wally-config.vh" `include "wally-config.vh"
module roundsign( module roundsign(
input logic PSgnM, ZSgnEffM, input logic FmaPs, FmaAs,
input logic InvZM, input logic FmaInvA,
input logic Xs, input logic Xs,
input logic Ys, input logic Ys,
input logic NegSumM, input logic FmaNegSum,
input logic FmaOp, input logic FmaOp,
input logic DivOp, input logic DivOp,
input logic CvtOp, input logic CvtOp,
input logic CvtResSgnM, input logic CvtCs,
output logic RoundSgn output logic Nsgn
); );
logic FmaResSgnTmp; logic FmaResSgnTmp;
@ -48,13 +48,13 @@ module roundsign(
// if p - z is the Sum negitive // if p - z is the Sum negitive
// if -p + z is the Sum positive // if -p + z is the Sum positive
// if -p - z then the Sum is negitive // 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; assign DivSgn = Xs^Ys;
// Sign for rounding calulation // Sign for rounding calulation
assign RoundSgn = (FmaResSgnTmp&FmaOp) | (CvtResSgnM&CvtOp) | (DivSgn&DivOp); assign Nsgn = (FmaResSgnTmp&FmaOp) | (CvtCs&CvtOp) | (DivSgn&DivOp);
endmodule endmodule

View File

@ -76,7 +76,7 @@ module testbenchfp;
logic XZero, YZero, ZZero; // is the input zero logic XZero, YZero, ZZero; // is the input zero
logic XExpMax, YExpMax, ZExpMax; // is the input's exponent all ones 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 [`CVTLEN-1:0] CvtLzcInE; // input to the Leading Zero Counter (priority encoder)
logic IntZeroE; logic IntZero;
logic CvtResSgnE; logic CvtResSgnE;
logic [`NE:0] CvtCalcExpE; // the calculated expoent logic [`NE:0] CvtCalcExpE; // the calculated expoent
logic [`LOGCVTLEN-1:0] CvtShiftAmtE; // how much to shift by logic [`LOGCVTLEN-1:0] CvtShiftAmtE; // how much to shift by
@ -104,6 +104,7 @@ module testbenchfp;
logic As; logic As;
logic Ps; logic Ps;
logic DivSticky; logic DivSticky;
logic DivDone;
logic DivNegSticky; logic DivNegSticky;
logic [`NE+1:0] DivCalcExp; logic [`NE+1:0] DivCalcExp;
@ -677,25 +678,25 @@ module testbenchfp;
.FOpCtrl(OpCtrlVal), .Fmt(ModFmt), .Sm, .NegSum, .InvA, .NCnt, .As, .Ps, .FOpCtrl(OpCtrlVal), .Fmt(ModFmt), .Sm, .NegSum, .InvA, .NCnt, .As, .Ps,
.Pe, .ZmSticky, .KillProd); .Pe, .ZmSticky, .KillProd);
postprocess postprocess(.Xs(XSgn), .Ys(YSgn), .PostProcSelM(UnitVal[1:0]), postprocess postprocess(.Xs(XSgn), .Ys(YSgn), .PostProcSel(UnitVal[1:0]),
.Ze(ZExp), .ZDenormM(ZDenorm), .FOpCtrlM(OpCtrlVal), .Quot, .DivCalcExpM(DivCalcExp), .Ze(ZExp), .ZDenorm(ZDenorm), .FOpCtrl(OpCtrlVal), .Quot, .DivCalcExp(DivCalcExp),
.Xm(XMan), .Ym(YMan), .Zm(ZMan), .CvtCalcExpM(CvtCalcExpE), .DivStickyM(DivSticky), .Xm(XMan), .Ym(YMan), .Zm(ZMan), .CvtCe(CvtCalcExpE), .DivSticky(DivSticky),
.XNaNM(XNaN), .YNaNM(YNaN), .ZNaNM(ZNaN), .CvtResDenormUfM(CvtResDenormUfE), .DivNegStickyM(DivNegSticky), .XNaN(XNaN), .YNaN(YNaN), .ZNaN(ZNaN), .CvtResDenormUf(CvtResDenormUfE), .DivNegSticky,
.XZeroM(XZero), .YZeroM(YZero), .ZZeroM(ZZero), .CvtShiftAmtM(CvtShiftAmtE), .XZero(XZero), .YZero(YZero), .ZZero(ZZero), .CvtShiftAmt(CvtShiftAmtE),
.XInfM(XInf), .YInfM(YInf), .ZInfM(ZInf), .CvtResSgnM(CvtResSgnE), .FWriteIntM(WriteIntVal), .XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal),
.XSNaNM(XSNaN), .YSNaNM(YSNaN), .ZSNaNM(ZSNaN), .CvtLzcInM(CvtLzcInE), .IntZeroM(IntZeroE), .XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero,
.KillProdM(KillProd), .AddendStickyM(ZmSticky), .ProdExpM(Pe), .FmaKillProd(KillProd), .FmaZmSticky(ZmSticky), .FmaPe(Pe), .DivDone,
.SumM(Sm), .NegSumM(NegSum), .InvZM(InvA), .FmaNormCntM(NCnt), .EarlyTermShiftDiv2M(EarlyTermShiftDiv2), .ZSgnEffM(As), .PSgnM(Ps), .Fmt(ModFmt), .Frm(FrmVal), .FmaSm(Sm), .FmaNegSum(NegSum), .FmaInvA(InvA), .FmaNCnt(NCnt), .DivEarlyTermShiftDiv2(EarlyTermShiftDiv2), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal),
.PostProcFlgM(Flg), .PostProcResM(FpRes), .FCvtIntResM(IntRes)); .PostProcFlg(Flg), .W(FpRes), .FCvtIntRes(IntRes));
fcvt fcvt (.XSgnE(XSgn), .XExpE(XExp), .XManE(XMan), .ForwardedSrcAE(SrcA), .FWriteIntE(WriteIntVal), fcvt fcvt (.Xs(XSgn), .Xe(XExp), .Xm(XMan), .Int(SrcA), .ToInt(WriteIntVal),
.XZeroE(XZero), .XDenormE(XDenorm), .FOpCtrlE(OpCtrlVal), .IntZeroE, .XZero(XZero), .XDenorm(XDenorm), .FOpCtrl(OpCtrlVal), .IntZero,
.FmtE(ModFmt), .CvtCalcExpE, .CvtShiftAmtE, .CvtResDenormUfE, .CvtResSgnE, .CvtLzcInE); .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), fcmp fcmp (.FmtE(ModFmt), .FOpCtrlE(OpCtrlVal), .XSgnE(XSgn), .YSgnE(YSgn), .XExpE(XExp), .YExpE(YExp),
.XManE(XMan), .YManE(YMan), .XZeroE(XZero), .YZeroE(YZero), .CmpIntResE(CmpRes), .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)); .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); 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)); .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), 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)); .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 import subprocess
from multiprocessing import Pool from multiprocessing import Pool
import time import argparse
import sys
def runSynth(config, tech, freq): def runSynth(config, tech, freq, maxopt):
global pool 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]) pool.map(mask, [command])
def mask(command): def mask(command):
subprocess.Popen(command, shell=True) 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__': if __name__ == '__main__':
i = 0
techs = ['sky90', 'tsmc28'] techs = ['sky90', 'tsmc28']
synthsToRun = [] allConfigs = ['rv32gc', 'rv32ic', 'rv64gc', 'rv64ic', 'rv32e', 'rv32i', 'rv64i']
tech = techs[i] freqVaryPct = [-20, -12, -8, -6, -4, -2, 0, 2, 4, 6, 8, 12, 20]
freq = testFreq[i]
arr = [-8, -6, -4, -2, 0, 2, 4, 6, 8]
pool = Pool() 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 for config in ['rv32gc', 'rv32ic', 'rv64gc', 'rv64ic', 'rv32e']: # configs
config = config + '_orig' # until memory integrated config = config + '_orig' # until memory integrated
runSynth(config, tech, freq) runSynth(config, tech, freq, maxopt)
time.sleep(staggerPeriod) if args.featuresweep:
elif 'features' in typeToRun: freshStart()
v = args.version if args.version else 'rv64gc'
for mod in ['FPUoff', 'noMulDiv', 'noPriv', 'PMP0', 'PMP16']: # rv64gc path variations for mod in ['FPUoff', 'noMulDiv', 'noPriv', 'PMP0', 'PMP16']: # rv64gc path variations
config = 'rv64gc_' + mod config = v + '_' + mod
runSynth(config, tech, freq) runSynth(config, tech, freq, maxopt)
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)