Merge pull request #373 from harshinisrinath1001/main

Improved testing of pmd in priv, fixed bugs, and attempted to reset menvcfg and fixed spacing in fpu/fma and fpu/postprocessing
This commit is contained in:
David Harris 2023-07-30 22:46:44 -07:00 committed by GitHub
commit 6ff2b0cc2c
18 changed files with 438 additions and 437 deletions

View File

@ -67,7 +67,6 @@ module fma import cvw::*; #(parameter cvw_t P) (
// - Multiply the mantissas // - Multiply the mantissas
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// calculate the product's exponent // calculate the product's exponent
fmaexpadd #(P) expadd(.Xe, .Ye, .XZero, .YZero, .Pe); fmaexpadd #(P) expadd(.Xe, .Ye, .XZero, .YZero, .Pe);
@ -80,6 +79,7 @@ module fma import cvw::*; #(parameter cvw_t P) (
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Alignment shifter // Alignment shifter
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
fmaalign #(P) align(.Ze, .Zm, .XZero, .YZero, .ZZero, .Xe, .Ye, .Am, .ASticky, .KillProd); fmaalign #(P) align(.Ze, .Zm, .XZero, .YZero, .ZZero, .Xe, .Ye, .Am, .ASticky, .KillProd);
// /////////////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////////
@ -91,5 +91,3 @@ module fma import cvw::*; #(parameter cvw_t P) (
fmalza #(3*P.NF+4, P.NF) lza(.A(AmInv), .Pm(PmKilled), .Cin(InvA & (~ASticky | KillProd)), .sub(InvA), .SCnt); fmalza #(3*P.NF+4, P.NF) lza(.A(AmInv), .Pm(PmKilled), .Cin(InvA & (~ASticky | KillProd)), .sub(InvA), .SCnt);
endmodule endmodule

View File

@ -1,4 +1,3 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// fmaalign.sv // fmaalign.sv
// //
@ -51,18 +50,16 @@ module fmaalign import cvw::*; #(parameter cvw_t P) (
// This could have been done using Pe, but ACnt is on the critical path so we replicate logic for speed // This could have been done using Pe, but ACnt is on the critical path so we replicate logic for speed
assign ACnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)} + (P.NE+2)'(P.NF+2) - {2'b0, Ze}; assign ACnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)} + (P.NE+2)'(P.NF+2) - {2'b0, Ze};
// Defualt Addition with only inital left shift // Default Addition with only inital left shift
// | 53'b0 | 106'b(product) | 1'b0 | // | 53'b0 | 106'b(product) | 1'b0 |
// | addnend | // | addnend |
assign ZmPreshifted = {Zm,(3*P.NF+3)'(0)}; assign ZmPreshifted = {Zm,(3*P.NF+3)'(0)};
assign KillProd = (ACnt[P.NE+1]&~ZZero)|XZero|YZero; assign KillProd = (ACnt[P.NE+1]&~ZZero)|XZero|YZero;
assign KillZ = $signed(ACnt)>$signed((P.NE+2)'(3)*(P.NE+2)'(P.NF)+(P.NE+2)'(3)); assign KillZ = $signed(ACnt)>$signed((P.NE+2)'(3)*(P.NE+2)'(P.NF)+(P.NE+2)'(3));
always_comb begin always_comb begin
// If the product is too small to effect the sum, kill the product // If the product is too small to effect the sum, kill the product
// | 53'b0 | 106'b(product) | 1'b0 | // | 53'b0 | 106'b(product) | 1'b0 |
// | addnend | // | addnend |
if (KillProd) begin if (KillProd) begin
@ -85,11 +82,9 @@ module fmaalign import cvw::*; #(parameter cvw_t P) (
end else begin end else begin
ZmShifted = ZmPreshifted >> ACnt; ZmShifted = ZmPreshifted >> ACnt;
ASticky = |(ZmShifted[P.NF-1:0]); ASticky = |(ZmShifted[P.NF-1:0]);
end end
end end
assign Am = ZmShifted[4*P.NF+3:P.NF]; assign Am = ZmShifted[4*P.NF+3:P.NF];
endmodule endmodule

View File

@ -33,4 +33,3 @@ module fmamult import cvw::*; #(parameter cvw_t P) (
assign Pm = Xm * Ym; assign Pm = Xm * Ym;
endmodule endmodule

View File

@ -47,7 +47,7 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
// seclect the input to the shifter // seclect the input to the shifter
// fp -> int: // fp -> int:
// | P.XLEN zeros | mantissa | 0's if nessisary | // | P.XLEN zeros | mantissa | 0's if necessary |
// . // .
// Other problems: // 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) // - 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)
@ -58,7 +58,7 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
// | P.NF-1 zeros | mantissa | 0's if nessisary | // | P.NF-1 zeros | mantissa | 0's if nessisary |
// . // .
// - otherwise: // - otherwise:
// | LzcInM | 0's if nessisary | // | LzcInM | 0's if necessary |
// . // .
// change to int shift to the left one // change to int shift to the left one
always_comb always_comb
@ -95,8 +95,6 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
endcase endcase
end end
// 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

View File

@ -120,7 +120,6 @@ module flags import cvw::*; #(parameter cvw_t P) (
assign ShiftGtIntSz = (|FullRe[P.Q_NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64)); assign ShiftGtIntSz = (|FullRe[P.Q_NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
end end
// calulate overflow flag: // calulate overflow flag:
// if the result is greater than or equal to the max exponent(not taking into account sign) // if the result is greater than or equal to the max exponent(not taking into account sign)
// | and the exponent isn't negitive // | and the exponent isn't negitive
@ -142,7 +141,6 @@ module flags import cvw::*; #(parameter cvw_t P) (
// | | | | | | // | | | | | |
assign Underflow = ((FullRe[P.NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&Guard)))&(Round|Sticky|Guard))&~(InfIn|NaNIn|DivByZero|Invalid); assign Underflow = ((FullRe[P.NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&Guard)))&(Round|Sticky|Guard))&~(InfIn|NaNIn|DivByZero|Invalid);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Inexact // Inexact
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -199,7 +197,6 @@ module flags import cvw::*; #(parameter cvw_t P) (
// - don't set flag if an input is NaN or Inf(IEEE says has to be a finite numerator) // - don't set flag if an input is NaN or Inf(IEEE says has to be a finite numerator)
assign DivByZero = YZero&DivOp&~Sqrt&~(XZero|NaNIn|InfIn); assign DivByZero = YZero&DivOp&~Sqrt&~(XZero|NaNIn|InfIn);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// final flags // final flags
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -209,7 +206,3 @@ module flags import cvw::*; #(parameter cvw_t P) (
assign PostProcFlg = {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

@ -27,22 +27,22 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// convert shift // convert shift
// fp -> int: | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp // fp -> int: | `XLEN zeros | Mantissa | 0's if necessary | << CalcExp
// process: // process:
// - start - CalcExp = 1 + XExp - Largest Bias // - start - CalcExp = 1 + XExp - Largest Bias
// | `XLEN zeros | Mantissa | 0's if nessisary | // | `XLEN zeros | Mantissa | 0's if necessary |
// //
// - shift left 1 (1) // - shift left 1 (1)
// | `XLEN-1 zeros |bit| frac | 0's if nessisary | // | `XLEN-1 zeros |bit| frac | 0's if necessary |
// . <- binary point // . <- binary point
// //
// - shift left till unbiased exponent is 0 (XExp - Largest Bias) // - shift left till unbiased exponent is 0 (XExp - Largest Bias)
// | 0's | Mantissa | 0's if nessisary | // | 0's | Mantissa | 0's if necessary |
// | keep | // | keep |
// //
// fp -> fp: // fp -> fp:
// - if result is subnormal or underflowed: // - if result is subnormal or underflowed:
// | `NF-1 zeros | Mantissa | 0's if nessisary | << NF+CalcExp-1 // | `NF-1 zeros | Mantissa | 0's if necessary | << NF+CalcExp-1
// process: // process:
// - start // - start
// | mantissa | 0's | // | mantissa | 0's |
@ -55,10 +55,10 @@
// | keep | // | keep |
// //
// - if the input is subnormal: // - if the input is subnormal:
// | lzcIn | 0's if nessisary | << ZeroCnt+1 // | lzcIn | 0's if necessary | << ZeroCnt+1
// - plus 1 to shift out the first 1 // - plus 1 to shift out the first 1
// //
// int -> fp: | lzcIn | 0's if nessisary | << ZeroCnt+1 // int -> fp: | lzcIn | 0's if necessary | << ZeroCnt+1
// - plus 1 to shift out the first 1 // - plus 1 to shift out the first 1
// fma shift // fma shift

View File

@ -108,7 +108,6 @@ module round import cvw::*; #(parameter cvw_t P) (
// 11 - do nothing if a small number was supposed to subtracted (the sticky bit was set by the small number) // 11 - do nothing if a small number was supposed to subtracted (the sticky bit was set by the small number)
// - Plus 1 otherwise // - Plus 1 otherwise
// determine what format the final result is in: int or fp // determine what format the final result is in: int or fp
assign IntRes = ToInt; assign IntRes = ToInt;
assign FpRes = ~IntRes; assign FpRes = ~IntRes;
@ -179,15 +178,10 @@ module round import cvw::*; #(parameter cvw_t P) (
end end
// 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 Sticky = FmaASticky&FmaOp | NormSticky | CvtResUf&CvtOp | FmaMe[P.NE+1]&FmaOp | DivSticky&DivOp; assign Sticky = FmaASticky&FmaOp | NormSticky | CvtResUf&CvtOp | FmaMe[P.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 (P.FPSIZES == 1) begin if (P.FPSIZES == 1) begin
@ -254,7 +248,6 @@ module round import cvw::*; #(parameter cvw_t P) (
assign LsbRes = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN] : FpLsbRes; assign LsbRes = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN] : FpLsbRes;
assign Round = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound; assign Round = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound;
always_comb begin always_comb begin
// Determine if you add 1 // Determine if you add 1
case (Frm) case (Frm)
@ -282,9 +275,6 @@ module round import cvw::*; #(parameter cvw_t P) (
assign FpPlus1 = Plus1&~(ToInt&CvtOp); assign FpPlus1 = Plus1&~(ToInt&CvtOp);
assign UfPlus1 = UfCalcPlus1 & (Sticky|Round); assign UfPlus1 = UfCalcPlus1 & (Sticky|Round);
// place Plus1 into the proper position for the format // place Plus1 into the proper position for the format
if (P.FPSIZES == 1) begin if (P.FPSIZES == 1) begin
assign RoundAdd = {{P.FLEN{1'b0}}, FpPlus1}; assign RoundAdd = {{P.FLEN{1'b0}}, FpPlus1};
@ -302,13 +292,9 @@ module round import cvw::*; #(parameter cvw_t P) (
end else if (P.FPSIZES == 4) end else if (P.FPSIZES == 4)
assign RoundAdd = {(P.Q_NE+1+P.H_NF)'(0), FpPlus1&(OutFmt==P.H_FMT), (P.S_NF-P.H_NF-1)'(0), FpPlus1&(OutFmt==P.S_FMT), (P.D_NF-P.S_NF-1)'(0), FpPlus1&(OutFmt==P.D_FMT), (P.Q_NF-P.D_NF-1)'(0), FpPlus1&(OutFmt==P.Q_FMT)}; assign RoundAdd = {(P.Q_NE+1+P.H_NF)'(0), FpPlus1&(OutFmt==P.H_FMT), (P.S_NF-P.H_NF-1)'(0), FpPlus1&(OutFmt==P.S_FMT), (P.D_NF-P.S_NF-1)'(0), FpPlus1&(OutFmt==P.D_FMT), (P.Q_NF-P.D_NF-1)'(0), FpPlus1&(OutFmt==P.Q_FMT)};
// trim unneeded bits from fraction // trim unneeded bits from fraction
assign RoundFrac = Mf[P.CORRSHIFTSZ-1:P.CORRSHIFTSZ-P.NF]; assign RoundFrac = Mf[P.CORRSHIFTSZ-1:P.CORRSHIFTSZ-P.NF];
// select the exponent // select the exponent
always_comb always_comb
case(PostProcSel) case(PostProcSel)
@ -326,5 +312,4 @@ module round import cvw::*; #(parameter cvw_t P) (
assign {FullRe, Rf} = {Me, RoundFrac} + RoundAdd; assign {FullRe, Rf} = {Me, RoundFrac} + RoundAdd;
assign Re = FullRe[P.NE-1:0]; assign Re = FullRe[P.NE-1:0];
endmodule endmodule

View File

@ -290,7 +290,6 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negitive if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negitive
else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive
// select the integer output // select the integer output
// - if the input is invalid (out of bounds NaN or Inf) then output overflow res // - if the input is invalid (out of bounds NaN or Inf) then output overflow res
// - if the input underflows // - if the input underflows

View File

@ -27,6 +27,18 @@
#include "WALLY-init-lib.h" #include "WALLY-init-lib.h"
main: main:
# Tests sret in machine mode
la t1, sretdone
csrw sepc, t1
sret
sretdone:
addi t2, x0, 42
# switch to user mode
li a0, 0
ecall
sret #should be treated as illegal instruction
mret #mret in user mode and should be illegal
# switch to supervisor mode # switch to supervisor mode
li a0, 1 li a0, 1
@ -44,16 +56,38 @@ main:
csrw satp, zero csrw satp, zero
# STIMECMP from S mode # STIMECMP from S mode
li t0, 1 # 1st is when MENVCFG_STCE is cleared
li a0, 3
ecall # starts in M-mode
csrw menvcfg, x0
li a0, 1
ecall # enter S-mode ecall # enter S-mode
csrw stimecmp, zero csrw stimecmp, zero
li t0, 3 li a0, 3
ecall # return to M-mode ecall # return to M-mode
csrsi mcounteren, 2 # mcounteren_tm = 1 csrsi mcounteren, 2 # mcounteren_tm = 1
li t0, 1 li a0, 1
ecall # supervisor mode again ecall # supervisor mode again
csrw stimecmp, zero csrw stimecmp, zero
li t0, 3 li a0, 3
ecall # machine mode again
# STIMECMP from S mode
# 2nd is when MENVCFG_STCE is set
csrci mcounteren, 2 # mcounteren_tm = 0
li t0, 1
slli t0, t0, 63
csrw menvcfg, t0
li a0, 1
ecall # enter S-mode
csrw stimecmp, zero
li a0, 3
ecall # return to M-mode
csrsi mcounteren, 2 # mcounteren_tm = 1
li a0, 1
ecall # supervisor mode again
csrw stimecmp, zero
li a0, 3
ecall # machine mode again ecall # machine mode again