forked from Github_Repos/cvw
		
	some commenting fixes, converter optimizations, and moves normshift into postproc
This commit is contained in:
		
							parent
							
								
									43f45c62a6
								
							
						
					
					
						commit
						95a1ddd636
					
				@ -32,21 +32,21 @@
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module fcvt (
 | 
			
		||||
    input logic             Xs,          // input's sign
 | 
			
		||||
    input logic [`NE-1:0]   Xe,          // input's exponent
 | 
			
		||||
    input logic [`NF:0]     Xm,          // input's fraction
 | 
			
		||||
    input logic [`XLEN-1:0] Int, // integer input - from IEU
 | 
			
		||||
    input logic [2:0]       OpCtrl,       // choose which opperation (look below for values)
 | 
			
		||||
    input logic             ToInt,     // is fp->int (since it's writting to the integer register)
 | 
			
		||||
    input logic             XZero,         // is the input zero
 | 
			
		||||
    input logic             XDenorm,   // is the input denormalized
 | 
			
		||||
    input logic [`FMTBITS-1:0] Fmt,        // the input's precision (11=quad 01=double 00=single 10=half)
 | 
			
		||||
    output logic [`NE:0]           Ce,    // the calculated expoent
 | 
			
		||||
	output logic [`LOGCVTLEN-1:0] ShiftAmt,  // how much to shift by
 | 
			
		||||
    output logic                   ResDenormUf,// does the result underflow or is denormalized
 | 
			
		||||
    output logic                   Cs,     // the result's sign
 | 
			
		||||
    output logic                   IntZero,      // is the integer zero?
 | 
			
		||||
    output logic [`CVTLEN-1:0]      LzcIn      // input to the Leading Zero Counter (priority encoder)
 | 
			
		||||
    input logic                     Xs,         // input's sign
 | 
			
		||||
    input logic [`NE-1:0]           Xe,         // input's exponent
 | 
			
		||||
    input logic [`NF:0]             Xm,         // input's fraction
 | 
			
		||||
    input logic [`XLEN-1:0]         Int,        // integer input - from IEU
 | 
			
		||||
    input logic [2:0]               OpCtrl,     // choose which opperation (look below for values)
 | 
			
		||||
    input logic                     ToInt,      // is fp->int (since it's writting to the integer register)
 | 
			
		||||
    input logic                     XZero,      // is the input zero
 | 
			
		||||
    input logic                     XDenorm,    // is the input denormalized
 | 
			
		||||
    input logic [`FMTBITS-1:0]      Fmt,        // the input's precision (11=quad 01=double 00=single 10=half)
 | 
			
		||||
    output logic [`NE:0]            Ce,         // the calculated expoent
 | 
			
		||||
	output logic [`LOGCVTLEN-1:0]   ShiftAmt,   // how much to shift by
 | 
			
		||||
    output logic                    ResDenormUf,// does the result underflow or is denormalized
 | 
			
		||||
    output logic                    Cs,         // the result's sign
 | 
			
		||||
    output logic                    IntZero,    // is the integer zero?
 | 
			
		||||
    output logic [`CVTLEN-1:0]      LzcIn       // input to the Leading Zero Counter (priority encoder)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // OpCtrls:
 | 
			
		||||
@ -68,15 +68,15 @@ module fcvt (
 | 
			
		||||
    logic [`NE-1:0]	        OldExp;     // the old exponent
 | 
			
		||||
    logic                   Signed;     // is the opperation with a signed integer?
 | 
			
		||||
    logic                   Int64;      // is the integer 64 bits?
 | 
			
		||||
    logic                   IntToFp;       // is the opperation an int->fp conversion?
 | 
			
		||||
    logic [`CVTLEN:0]       LzcInFull;      // input to the Leading Zero Counter (priority encoder)
 | 
			
		||||
    logic                   IntToFp;    // is the opperation an int->fp conversion?
 | 
			
		||||
    logic [`CVTLEN:0]       LzcInFull;  // input to the Leading Zero Counter (priority encoder)
 | 
			
		||||
    logic [`LOGCVTLEN-1:0]  LeadingZeros; // output from the LZC
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // seperate OpCtrl for code readability
 | 
			
		||||
    assign Signed = OpCtrl[0];
 | 
			
		||||
    assign Int64 =  OpCtrl[1];
 | 
			
		||||
    assign IntToFp =   OpCtrl[2];
 | 
			
		||||
    assign Signed =  OpCtrl[0];
 | 
			
		||||
    assign Int64 =   OpCtrl[1];
 | 
			
		||||
    assign IntToFp = OpCtrl[2];
 | 
			
		||||
 | 
			
		||||
    // choose the ouptut format depending on the opperation
 | 
			
		||||
    //      - fp -> fp: OpCtrl contains the percision of the output
 | 
			
		||||
@ -109,27 +109,6 @@ module fcvt (
 | 
			
		||||
    assign LzcIn = LzcInFull[`CVTLEN-1:0];
 | 
			
		||||
    
 | 
			
		||||
    lzc #(`CVTLEN+1) lzc (.num(LzcInFull), .ZeroCnt(LeadingZeros));
 | 
			
		||||
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // shifter
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // kill the shift if it's negitive
 | 
			
		||||
    // select the amount to shift by
 | 
			
		||||
    //      fp -> int: 
 | 
			
		||||
    //          - shift left by CalcExp - essentially shifting until the unbiased exponent = 0
 | 
			
		||||
    //              - don't shift if supposed to shift right (underflowed or denorm input)
 | 
			
		||||
    //      denormalized/undeflowed result fp -> fp:
 | 
			
		||||
    //          - shift left by NF-1+CalcExp - to shift till the biased expoenent is 0
 | 
			
		||||
    //      ??? -> fp: 
 | 
			
		||||
    //          - shift left by LeadingZeros - to shift till the result is normalized
 | 
			
		||||
    //              - only shift fp -> fp if the intital value is denormalized
 | 
			
		||||
    //                  - this is a problem because the input to the lzc was the fraction rather than the mantissa
 | 
			
		||||
    //                  - rather have a few and-gates than an extra bit in the priority encoder??? *** is this true?
 | 
			
		||||
    always_comb
 | 
			
		||||
        if(ToInt)                       ShiftAmt = Ce[`LOGCVTLEN-1:0]&{`LOGCVTLEN{~Ce[`NE]}};
 | 
			
		||||
        else if (ResDenormUf&~IntToFp)  ShiftAmt = (`LOGCVTLEN)'(`NF-1)+Ce[`LOGCVTLEN-1:0];
 | 
			
		||||
        else                            ShiftAmt = LeadingZeros;
 | 
			
		||||
    
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // exp calculations
 | 
			
		||||
@ -179,7 +158,7 @@ module fcvt (
 | 
			
		||||
        assign NewBias = ToInt ? (`NE-1)'(1) : NewBiasToFp; 
 | 
			
		||||
    end
 | 
			
		||||
    // select the old exponent
 | 
			
		||||
    //      int -> fp : largest bias + XLEN
 | 
			
		||||
    //      int -> fp : largest bias + XLEN-1
 | 
			
		||||
    //      fp -> ??? : XExp
 | 
			
		||||
    assign OldExp = IntToFp ? (`NE)'(`BIAS)+(`NE)'(`XLEN-1) : Xe;
 | 
			
		||||
    
 | 
			
		||||
@ -189,6 +168,7 @@ module fcvt (
 | 
			
		||||
    //                                          only do ^ if the input was denormalized
 | 
			
		||||
    //              - convert the expoenent to the final preciaion (Exp - oldBias + newBias)
 | 
			
		||||
    //              - correct the expoent when there is a normalization shift ( + LeadingZeros+1) 
 | 
			
		||||
    //              - the plus 1 is built into the leading zeros by counting the leading zeroes in the mantissa rather than the fraction
 | 
			
		||||
    //      fp -> int : XExp - Largest Bias + 1 - (LeadingZeros+1)
 | 
			
		||||
    //          |  `XLEN  zeros |     Mantissa      | 0's if nessisary | << CalcExp
 | 
			
		||||
    //          process:
 | 
			
		||||
@ -204,19 +184,45 @@ module fcvt (
 | 
			
		||||
    //                  |     keep        |
 | 
			
		||||
    //
 | 
			
		||||
    //              - if the input is denormalized then we dont shift... so the  "- LeadingZeros" is just leftovers from other options
 | 
			
		||||
    //      int -> fp : largest bias +  XLEN - Largest bias + new bias - LeadingZeros = XLEN + NewBias - LeadingZeros
 | 
			
		||||
    //      int -> fp : largest bias +  XLEN-1 - Largest bias + new bias - LeadingZeros = XLEN-1 + NewBias - LeadingZeros
 | 
			
		||||
    //              Process:
 | 
			
		||||
    //                      |XLEN|.0000
 | 
			
		||||
    //                  - shifted right by XLEN (XLEN)
 | 
			
		||||
    //                      000000.|XLEN|
 | 
			
		||||
    //                  - shift left to normilize (-LeadingZeros)
 | 
			
		||||
    //                      000000.1...
 | 
			
		||||
    //                  - shift left 1 to normalize
 | 
			
		||||
    //                      000001.stuff
 | 
			
		||||
    //                  - newBias to make the biased exponent
 | 
			
		||||
    //          oldexp - biasold +newbias - LeadingZeros&(XDenorm|IntToFp)
 | 
			
		||||
    assign Ce = {1'b0, OldExp} - (`NE+1)'(`BIAS) + {2'b0, NewBias} - {{`NE-`LOGCVTLEN+1{1'b0}}, (LeadingZeros&{`LOGCVTLEN{XDenorm|IntToFp}})};
 | 
			
		||||
    //
 | 
			
		||||
    //          oldexp         - biasold         - LeadingZeros                               + newbias
 | 
			
		||||
    assign Ce = {1'b0, OldExp} - (`NE+1)'(`BIAS) - {{`NE-`LOGCVTLEN+1{1'b0}}, (LeadingZeros)} + {2'b0, NewBias};
 | 
			
		||||
    // find if the result is dnormal or underflows
 | 
			
		||||
    //      - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0)
 | 
			
		||||
    //      - can't underflow an integer to Fp conversion
 | 
			
		||||
    assign ResDenormUf = (~|Ce | Ce[`NE])&~XZero&~IntToFp;
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // shifter
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // kill the shift if it's negitive
 | 
			
		||||
    // select the amount to shift by
 | 
			
		||||
    //      fp -> int: 
 | 
			
		||||
    //          - shift left by CalcExp - essentially shifting until the unbiased exponent = 0
 | 
			
		||||
    //              - don't shift if supposed to shift right (underflowed or denorm input)
 | 
			
		||||
    //      denormalized/undeflowed result fp -> fp:
 | 
			
		||||
    //          - shift left by NF-1+CalcExp - to shift till the biased expoenent is 0
 | 
			
		||||
    //      ??? -> fp: 
 | 
			
		||||
    //          - shift left by LeadingZeros - to shift till the result is normalized
 | 
			
		||||
    //              - only shift fp -> fp if the intital value is denormalized
 | 
			
		||||
    //                  - this is a problem because the input to the lzc was the fraction rather than the mantissa
 | 
			
		||||
    //                  - rather have a few and-gates than an extra bit in the priority encoder??? *** is this true?
 | 
			
		||||
    always_comb//***change denorm to subnorm
 | 
			
		||||
        if(ToInt)                       ShiftAmt = Ce[`LOGCVTLEN-1:0]&{`LOGCVTLEN{~Ce[`NE]}};
 | 
			
		||||
        else if (ResDenormUf)  ShiftAmt = (`LOGCVTLEN)'(`NF-1)+Ce[`LOGCVTLEN-1:0];
 | 
			
		||||
        else                            ShiftAmt = LeadingZeros;
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // sign
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
@ -1,75 +0,0 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// normshift.sv
 | 
			
		||||
//
 | 
			
		||||
// Written: me@KatherineParry.com
 | 
			
		||||
// Modified: 7/5/2022
 | 
			
		||||
//
 | 
			
		||||
// Purpose: normalization shifter
 | 
			
		||||
// 
 | 
			
		||||
// A component of the Wally configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
 | 
			
		||||
//
 | 
			
		||||
// MIT LICENSE
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this 
 | 
			
		||||
// software and associated documentation files (the "Software"), to deal in the Software 
 | 
			
		||||
// without restriction, including without limitation the rights to use, copy, modify, merge, 
 | 
			
		||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons 
 | 
			
		||||
// to whom the Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
//   The above copyright notice and this permission notice shall be included in all copies or 
 | 
			
		||||
//   substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 | 
			
		||||
//   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 | 
			
		||||
//   PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
 | 
			
		||||
//   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 | 
			
		||||
//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 
 | 
			
		||||
//   OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 // convert shift
 | 
			
		||||
    //      fp -> int: |  `XLEN  zeros |     Mantissa      | 0's if nessisary | << CalcExp
 | 
			
		||||
    //          process:
 | 
			
		||||
    //              - start - CalcExp = 1 + XExp - Largest Bias
 | 
			
		||||
    //                  |  `XLEN  zeros     |     Mantissa      | 0's if nessisary |
 | 
			
		||||
    //
 | 
			
		||||
    //              - shift left 1 (1)
 | 
			
		||||
    //                  | `XLEN-1 zeros |bit|     frac      | 0's if nessisary |
 | 
			
		||||
    //                                      . <- binary point
 | 
			
		||||
    //
 | 
			
		||||
    //              - shift left till unbiased exponent is 0 (XExp - Largest Bias)
 | 
			
		||||
    //                  |  0's |     Mantissa      |      0's if nessisary     |
 | 
			
		||||
    //                  |     keep          |
 | 
			
		||||
    //
 | 
			
		||||
    //      fp -> fp:
 | 
			
		||||
    //          - if result is denormalized or underflowed:
 | 
			
		||||
    //              |  `NF-1  zeros   |     Mantissa      | 0's if nessisary | << NF+CalcExp-1
 | 
			
		||||
    //          process:
 | 
			
		||||
    //             - start
 | 
			
		||||
    //                 |     mantissa      | 0's |
 | 
			
		||||
    //
 | 
			
		||||
    //             - shift right by NF-1 (NF-1)
 | 
			
		||||
    //                 |  `NF-1  zeros   |     mantissa      | 0's |
 | 
			
		||||
    //
 | 
			
		||||
    //             - shift left by CalcExp = XExp - Largest bias + new bias
 | 
			
		||||
    //                 |   0's  |     mantissa      |     0's      |
 | 
			
		||||
    //                 |       keep      |
 | 
			
		||||
    //
 | 
			
		||||
    //          - if the input is denormalized:
 | 
			
		||||
    //              |     lzcIn      | 0's if nessisary | << ZeroCnt+1
 | 
			
		||||
    //              - plus 1 to shift out the first 1
 | 
			
		||||
    //
 | 
			
		||||
    //      int -> fp: |     lzcIn      | 0's if nessisary | << ZeroCnt+1
 | 
			
		||||
    //              - plus 1 to shift out the first 1
 | 
			
		||||
 | 
			
		||||
module normshift(
 | 
			
		||||
    input logic  [`LOGNORMSHIFTSZ-1:0]      ShiftAmt,   // normalization shift count
 | 
			
		||||
    input logic  [`NORMSHIFTSZ-1:0]              ShiftIn,        // is the sum zero
 | 
			
		||||
    output logic [`NORMSHIFTSZ-1:0]             Shifted        // is the sum zero
 | 
			
		||||
);
 | 
			
		||||
    assign Shifted = ShiftIn << ShiftAmt;
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
@ -30,16 +30,16 @@
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module cvtshiftcalc(
 | 
			
		||||
    input logic                    XZero,
 | 
			
		||||
    input logic                    ToInt,
 | 
			
		||||
    input logic                    IntToFp,
 | 
			
		||||
    input logic  [`NE:0]           CvtCe,    // the calculated expoent
 | 
			
		||||
    input logic  [`NF:0]           Xm,          // input mantissas
 | 
			
		||||
    input logic     [`FMTBITS-1:0]  OutFmt,       // output format
 | 
			
		||||
    input logic  [`CVTLEN-1:0]      CvtLzcIn,      // input to the Leading Zero Counter (priority encoder)
 | 
			
		||||
    input logic CvtResDenormUf,
 | 
			
		||||
    output logic CvtResUf,
 | 
			
		||||
    output logic [`CVTLEN+`NF:0]    CvtShiftIn    // number to be shifted
 | 
			
		||||
    input logic                     XZero,      // is the input zero?
 | 
			
		||||
    input logic                     ToInt,      // to integer conversion?
 | 
			
		||||
    input logic                     IntToFp,    // interger to floating point conversion?
 | 
			
		||||
    input logic  [`NE:0]            CvtCe,      // the calculated expoent
 | 
			
		||||
    input logic  [`NF:0]            Xm,         // input mantissas
 | 
			
		||||
    input logic  [`FMTBITS-1:0]     OutFmt,     // output format
 | 
			
		||||
    input logic  [`CVTLEN-1:0]      CvtLzcIn,   // input to the Leading Zero Counter (priority encoder)
 | 
			
		||||
    input logic                     CvtResDenormUf, // is the conversion result subnormal or underlows
 | 
			
		||||
    output logic                    CvtResUf,       // does the cvt result unerflow
 | 
			
		||||
    output logic [`CVTLEN+`NF:0]    CvtShiftIn      // number to be shifted
 | 
			
		||||
);
 | 
			
		||||
    logic [$clog2(`NF):0]	ResNegNF;   // the result's fraction length negated (-NF)
 | 
			
		||||
 | 
			
		||||
@ -51,6 +51,7 @@ module cvtshiftcalc(
 | 
			
		||||
    // seclect the input to the shifter
 | 
			
		||||
    //      fp  -> int:
 | 
			
		||||
    //          |  `XLEN  zeros |     Mantissa      | 0's if nessisary |
 | 
			
		||||
    //                          .
 | 
			
		||||
    //          Other problems:
 | 
			
		||||
    //              - if shifting to the right (neg CalcExp) then don't a 1 in the round bit (to prevent an incorrect plus 1 later durring rounding)
 | 
			
		||||
    //              - we do however want to keep the one in the sticky bit so set one of bits in the sticky bit area to 1
 | 
			
		||||
@ -58,11 +59,14 @@ module cvtshiftcalc(
 | 
			
		||||
    //      ??? -> fp:
 | 
			
		||||
    //          - if result is denormalized or underflowed then we want to shift right i.e. shift right then shift left:
 | 
			
		||||
    //              |  `NF-1  zeros   |     Mantissa      | 0's if nessisary | 
 | 
			
		||||
    //              .
 | 
			
		||||
    //          - otherwise:
 | 
			
		||||
    //              |     LzcInM      | 0's if nessisary | 
 | 
			
		||||
    //              .
 | 
			
		||||
    // change to int shift to the left one
 | 
			
		||||
 | 
			
		||||
    always_comb
 | 
			
		||||
    always_comb //                                            get rid of round bit if needed
 | 
			
		||||
    //                                                        |                    add sticky bit if needed
 | 
			
		||||
        if (ToInt)               CvtShiftIn = {{`XLEN{1'b0}}, Xm[`NF]&~CvtCe[`NE], Xm[`NF-1]|(CvtCe[`NE]&Xm[`NF]), Xm[`NF-2:0], {`CVTLEN-`XLEN{1'b0}}};
 | 
			
		||||
        else if (CvtResDenormUf) CvtShiftIn = {{`NF-1{1'b0}}, Xm, {`CVTLEN-`NF+1{1'b0}}};
 | 
			
		||||
        else                     CvtShiftIn = {CvtLzcIn, {`NF+1{1'b0}}};
 | 
			
		||||
 | 
			
		||||
@ -241,6 +241,7 @@ module unpackinput (
 | 
			
		||||
        // also need to take into account possible zero/denorm/inf/NaN values
 | 
			
		||||
        
 | 
			
		||||
        // convert the double precsion exponent into quad precsion
 | 
			
		||||
        // 1 is added to the exponent if the input is zero or subnormal
 | 
			
		||||
        always_comb
 | 
			
		||||
            case (Fmt)
 | 
			
		||||
                2'b11: Exp = {In[`Q_LEN-2:`Q_NF+1], In[`Q_NF]|~ExpNonZero};
 | 
			
		||||
 | 
			
		||||
@ -700,7 +700,7 @@ module testbenchfp;
 | 
			
		||||
              .XZero(XZero), .YZero(YZero), .ZZero(ZZero), .CvtShiftAmt(CvtShiftAmtE),
 | 
			
		||||
              .XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal),
 | 
			
		||||
              .XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero,
 | 
			
		||||
              .FmaZmS(ASticky), .FmaSe(Se),
 | 
			
		||||
              .FmaASticky(ASticky), .FmaSe(Se),
 | 
			
		||||
              .FmaSm(Sm), .FmaSCnt(SCnt), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal), 
 | 
			
		||||
              .PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes));
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user