fpu compare simplification, minor cleanup

This commit is contained in:
David Harris 2022-03-29 17:11:28 +00:00
parent ad106e7130
commit 049c55769a
10 changed files with 76 additions and 48 deletions

@ -1 +1 @@
Subproject commit 261a65e0a2d3e8d62d81b1d8fe7e309a096bc6a9 Subproject commit 2d2aaa7b85c60219c591555b647dfa1785ffe1b3

@ -1 +1 @@
Subproject commit be67c99bd461742aa1c100bcc0732657faae2230 Subproject commit effd553a6a91ed9b0ba251796a8a44505a45174f

@ -1 +1 @@
Subproject commit a7e27bc046405f0dbcde091be99f5a5d564e2172 Subproject commit cb4295f9ce5da2881d7746015a6105adb8f09071

@ -1 +1 @@
Subproject commit cf04274f50621fd9ef9147793cca6dd1657985c7 Subproject commit 3e2bf06b071a77ae62c09bf07c5229d1f9397d94

View File

@ -23,40 +23,32 @@ module fcmp (
output logic [`FLEN-1:0] CmpResE // compare resilt output logic [`FLEN-1:0] CmpResE // compare resilt
); );
logic LT, EQ; // is X < or > or = Y logic LTabs, LT, EQ; // is X < or > or = Y
logic BothZeroE, EitherNaNE, EitherSNaNE;
// X is less than Y: assign LTabs= {1'b0, XExpE, XManE} < {1'b0, YExpE, YManE}; // unsigned comparison, treating FP as integers
// Signs: assign LT = (XSgnE & ~YSgnE) | (XSgnE & YSgnE & ~LTabs & ~EQ) | (~XSgnE & ~YSgnE & LTabs);
// X Y answer //assign LT = $signed({XSgnE, XExpE, XManE[`NF-1:0]}) < $signed({YSgnE, YExpE, YManE[`NF-1:0]});
// pos pos idk - keep checking //assign LT = XInt < YInt;
// pos neg no // assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE<YManE)^XSgnE)&~EQ : (XExpE<YExpE)^XSgnE;
// neg pos yes
// neg neg idk - keep checking
// Exponent
// - if XExp < YExp
// - if negitive - no
// - if positive - yes
// - otherwise keep checking
// Mantissa
// - XMan < YMan then
// - if negitive - no
// - if positive - yes
// note: LT does -0 < 0
//*** compare Exp and Man together
assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE<YManE)^XSgnE)&~EQ : (XExpE<YExpE)^XSgnE;
assign EQ = (FSrcXE == FSrcYE); assign EQ = (FSrcXE == FSrcYE);
assign BothZeroE = XZeroE&YZeroE;
assign EitherNaNE = XNaNE|YNaNE;
assign EitherSNaNE = XSNaNE|YSNaNE;
// flags // flags
// Min/Max - if an input is a signaling NaN set invalid flag // Min/Max - if an input is a signaling NaN set invalid flag
// LT/LE - signaling - sets invalid if NaN input // LT/LE - signaling - sets invalid if NaN input
// EQ - quiet - sets invalid if signaling NaN input // EQ - quiet - sets invalid if signaling NaN input
always_comb begin always_comb begin
case (FOpCtrlE[2:0]) case (FOpCtrlE[2:0])
3'b111: CmpNVE = XSNaNE|YSNaNE;//min 3'b111: CmpNVE = EitherSNaNE;//min
3'b101: CmpNVE = XSNaNE|YSNaNE;//max 3'b101: CmpNVE = EitherSNaNE;//max
3'b010: CmpNVE = XSNaNE|YSNaNE;//equal 3'b010: CmpNVE = EitherSNaNE;//equal
3'b001: CmpNVE = XNaNE|YNaNE;//less than 3'b001: CmpNVE = EitherNaNE;//less than
3'b011: CmpNVE = XNaNE|YNaNE;//less than or equal 3'b011: CmpNVE = EitherNaNE;//less than or equal
default: CmpNVE = 1'b0; default: CmpNVE = 1'b0;
endcase endcase
end end
@ -71,24 +63,22 @@ module fcmp (
// - inf = inf and -inf = -inf // - inf = inf and -inf = -inf
// - return 0 if comparison with NaN (unordered) // - return 0 if comparison with NaN (unordered)
logic [`FLEN-1:0] QNaNX, QNaNY; logic [`FLEN-1:0] QNaN;
if(`IEEE754) begin // fmin/fmax of two NaNs returns a quiet NaN of the appropriate size
assign QNaNX = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]}; // for IEEE, return the payload of X
assign QNaNY = FmtE ? {YSgnE, YExpE, 1'b1, YManE[`NF-2:0]} : {{32{1'b1}}, YSgnE, YExpE[7:0], 1'b1, YManE[50:29]}; // for RISC-V, return the canonical NaN
end else begin if(`IEEE754) assign QNaN = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]};
assign QNaNX = FmtE ? {1'b0, XExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpE[7:0], 1'b1, 22'b0}; else assign QNaN = FmtE ? {1'b0, XExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpE[7:0], 1'b1, 22'b0};
assign QNaNY = FmtE ? {1'b0, YExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, YExpE[7:0], 1'b1, 22'b0};
end
always_comb begin always_comb begin
case (FOpCtrlE[2:0]) case (FOpCtrlE[2:0])
3'b111: CmpResE = XNaNE ? YNaNE ? QNaNX : FSrcYE // Min 3'b111: CmpResE = XNaNE ? YNaNE ? QNaN : FSrcYE // Min
: YNaNE ? FSrcXE : LT ? FSrcXE : FSrcYE; : YNaNE ? FSrcXE : LT ? FSrcXE : FSrcYE;
3'b101: CmpResE = XNaNE ? YNaNE ? QNaNX : FSrcYE // Max 3'b101: CmpResE = XNaNE ? YNaNE ? QNaN : FSrcYE // Max
: YNaNE ? FSrcXE : LT ? FSrcYE : FSrcXE; : YNaNE ? FSrcXE : LT ? FSrcYE : FSrcXE;
3'b010: CmpResE = {63'b0, (EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Equal 3'b010: CmpResE = {63'b0, (EQ|BothZeroE) & ~EitherNaNE}; // Equal
3'b001: CmpResE = {63'b0, LT&~(XZeroE&YZeroE)&~(XNaNE|YNaNE)}; // Less than 3'b001: CmpResE = {63'b0, LT & ~BothZeroE & ~EitherNaNE}; // Less than
3'b011: CmpResE = {63'b0, (LT|EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Less than or equal 3'b011: CmpResE = {63'b0, (LT|EQ|BothZeroE) & ~EitherNaNE}; // Less than or equal
default: CmpResE = 64'b0; default: CmpResE = 64'b0;
endcase endcase
end end

View File

@ -102,6 +102,7 @@ module BTBPredictor
// Another optimization may be using a PC relative address. // Another optimization may be using a PC relative address.
// *** need to add forwarding. // *** need to add forwarding.
// *** optimize for byte write enables
SRAM2P1R1W #(Depth, `XLEN+5) memory(.clk(clk), SRAM2P1R1W #(Depth, `XLEN+5) memory(.clk(clk),
.reset(reset), .reset(reset),
.RA1(LookUpPCIndex), .RA1(LookUpPCIndex),

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ram.sv // swbytemask.sv
// //
// Written: David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu 9 January 2021
// Modified: // Modified:

View File

@ -102,7 +102,7 @@ module trap (
if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec
always_comb always_comb
if (PrivilegedTrapVector[1:0] == 2'b01 & CauseM[`XLEN-1] == 1) if (PrivilegedTrapVector[1:0] == 2'b01 & CauseM[`XLEN-1] == 1)
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2] + CauseM[`XLEN-5:0], 2'b00}; PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2] + CauseM[`XLEN-3:0], 2'b00};
else else
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00}; PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00};
end end

View File

@ -50,10 +50,47 @@
// Number of 64 bit PMP Configuration Register entries (or pairs of 32 bit entries) // Number of 64 bit PMP Configuration Register entries (or pairs of 32 bit entries)
`define PMPCFG_ENTRIES (`PMP_ENTRIES/8) `define PMPCFG_ENTRIES (`PMP_ENTRIES/8)
// Floating-point half-precision
`define ZFH_SUPPORTED 0
// Floating point constants for Quad, Double, Single, and Half precisions
`define Q_LEN 128
`define Q_NE 15
`define Q_NF 112
`define Q_BIAS 16383
`define D_LEN 64
`define D_NE 11
`define D_NF 52
`define D_BIAS 1023
`define S_LEN 32
`define S_NE 8
`define S_NF 23
`define S_BIAS 127
`define H_LEN 16
`define H_NE 5
`define H_NF 10
`define H_BIAS 15
// Floating point length FLEN and number of exponent (NE) and fraction (NF) bits // Floating point length FLEN and number of exponent (NE) and fraction (NF) bits
`define FLEN 64//(`Q_SUPPORTED ? 128 : `D_SUPPORTED ? 64 : 32) `define FLEN (`Q_SUPPORTED ? `Q_LEN : `D_SUPPORTED ? `D_LEN : `F_SUPPORTED ? `S_LEN : `H_LEN)
`define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8) `define NE (`Q_SUPPORTED ? `Q_NE : `D_SUPPORTED ? `D_NE : `F_SUPPORTED ? `S_NE : `H_NE)
`define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23) `define NF (`Q_SUPPORTED ? `Q_NF : `D_SUPPORTED ? `D_NF : `F_SUPPORTED ? `S_NF : `H_NF)
`define FMT (`Q_SUPPORTED ? 3 : `D_SUPPORTED ? 1 : `F_SUPPORTED ? 0 : 2)
`define BIAS (`Q_SUPPORTED ? `Q_BIAS : `D_SUPPORTED ? `D_BIAS : `F_SUPPORTED ? `S_BIAS : `H_BIAS)
// Floating point constants needed for FPU paramerterization
`define FPSIZES (`Q_SUPPORTED+`D_SUPPORTED+`F_SUPPORTED+`ZFH_SUPPORTED)
`define LEN1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_LEN : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_LEN : `H_LEN)
`define NE1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_NE : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_NE : `H_NE)
`define NF1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_NF : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_NF : `H_NF)
`define FMT1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? 1 : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? 0 : 2)
`define BIAS1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_BIAS : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_BIAS : `H_BIAS)
`define LEN2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_LEN : `H_LEN)
`define NE2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_NE : `H_NE)
`define NF2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_NF : `H_NF)
`define FMT2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? 0 : 2)
`define BIAS2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_BIAS : `H_BIAS)
// Disable spurious Verilator warnings // Disable spurious Verilator warnings