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
///////////////////////////////////////////////////////////////////////////////
// calculate the product's exponent
fmaexpadd #(P) expadd(.Xe, .Ye, .XZero, .YZero, .Pe);
@ -80,6 +79,7 @@ module fma import cvw::*; #(parameter cvw_t P) (
///////////////////////////////////////////////////////////////////////////////
// Alignment shifter
///////////////////////////////////////////////////////////////////////////////
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);
endmodule

View File

@ -1,4 +1,3 @@
///////////////////////////////////////////
// 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
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 |
// | addnend |
assign ZmPreshifted = {Zm,(3*P.NF+3)'(0)};
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));
always_comb begin
// If the product is too small to effect the sum, kill the product
// | 53'b0 | 106'b(product) | 1'b0 |
// | addnend |
if (KillProd) begin
@ -85,11 +82,9 @@ module fmaalign import cvw::*; #(parameter cvw_t P) (
end else begin
ZmShifted = ZmPreshifted >> ACnt;
ASticky = |(ZmShifted[P.NF-1:0]);
end
end
assign Am = ZmShifted[4*P.NF+3:P.NF];
endmodule

View File

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

View File

@ -47,7 +47,7 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
// seclect the input to the shifter
// fp -> int:
// | P.XLEN zeros | mantissa | 0's if nessisary |
// | P.XLEN zeros | mantissa | 0's if necessary |
// .
// 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)
@ -58,7 +58,7 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
// | P.NF-1 zeros | mantissa | 0's if nessisary |
// .
// - otherwise:
// | LzcInM | 0's if nessisary |
// | LzcInM | 0's if necessary |
// .
// change to int shift to the left one
always_comb
@ -95,8 +95,6 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
endcase
end
// determine if the result underflows ??? -> fp
// - if the first 1 is shifted out of the result then the result underflows
// - can't underflow an integer to fp conversions

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));
end
// calulate overflow flag:
// if the result is greater than or equal to the max exponent(not taking into account sign)
// | 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);
///////////////////////////////////////////////////////////////////////////////
// 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)
assign DivByZero = YZero&DivOp&~Sqrt&~(XZero|NaNIn|InfIn);
///////////////////////////////////////////////////////////////////////////////
// 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};
endmodule

View File

@ -27,22 +27,22 @@
////////////////////////////////////////////////////////////////////////////////////////////////
// convert shift
// fp -> int: | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp
// fp -> int: | `XLEN zeros | Mantissa | 0's if necessary | << CalcExp
// process:
// - start - CalcExp = 1 + XExp - Largest Bias
// | `XLEN zeros | Mantissa | 0's if nessisary |
// | `XLEN zeros | Mantissa | 0's if necessary |
//
// - shift left 1 (1)
// | `XLEN-1 zeros |bit| frac | 0's if nessisary |
// | `XLEN-1 zeros |bit| frac | 0's if necessary |
// . <- binary point
//
// - 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 |
//
// fp -> fp:
// - 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:
// - start
// | mantissa | 0's |
@ -55,10 +55,10 @@
// | keep |
//
// - 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
//
// 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
// 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)
// - Plus 1 otherwise
// determine what format the final result is in: int or fp
assign IntRes = ToInt;
assign FpRes = ~IntRes;
@ -179,15 +178,10 @@ module round import cvw::*; #(parameter cvw_t P) (
end
// only add the Addend sticky if doing an FMA opperation
// - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits)
assign Sticky = FmaASticky&FmaOp | NormSticky | CvtResUf&CvtOp | FmaMe[P.NE+1]&FmaOp | DivSticky&DivOp;
// determine round and LSB of the rounded value
// - underflow round bit is used to determint the underflow flag
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 Round = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound;
always_comb begin
// Determine if you add 1
case (Frm)
@ -282,9 +275,6 @@ module round import cvw::*; #(parameter cvw_t P) (
assign FpPlus1 = Plus1&~(ToInt&CvtOp);
assign UfPlus1 = UfCalcPlus1 & (Sticky|Round);
// place Plus1 into the proper position for the format
if (P.FPSIZES == 1) begin
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)
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
assign RoundFrac = Mf[P.CORRSHIFTSZ-1:P.CORRSHIFTSZ-P.NF];
// select the exponent
always_comb
case(PostProcSel)
@ -326,5 +312,4 @@ module round import cvw::*; #(parameter cvw_t P) (
assign {FullRe, Rf} = {Me, RoundFrac} + RoundAdd;
assign Re = FullRe[P.NE-1:0];
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
else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive
// select the integer output
// - if the input is invalid (out of bounds NaN or Inf) then output overflow res
// - if the input underflows

View File

@ -27,6 +27,18 @@
#include "WALLY-init-lib.h"
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
li a0, 1
@ -44,16 +56,38 @@ main:
csrw satp, zero
# 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
csrw stimecmp, zero
li t0, 3
li a0, 3
ecall # return to M-mode
csrsi mcounteren, 2 # mcounteren_tm = 1
li t0, 1
li a0, 1
ecall # supervisor mode again
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