mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
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:
commit
6ff2b0cc2c
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -33,4 +33,3 @@ module fmamult import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
assign Pm = Xm * Ym;
|
||||
endmodule
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user