some errors in FP ArchTests fixed

This commit is contained in:
Katherine Parry 2022-01-01 23:50:23 +00:00
parent 8d6c48cfb1
commit 9d4e1671c9
10 changed files with 305 additions and 527 deletions

@ -1 +1 @@
Subproject commit 307c77b26e070ae85ffea665ad9b642b40e33c86
Subproject commit be67c99bd461742aa1c100bcc0732657faae2230

View File

@ -1,2 +1,2 @@
vsim -do "do wally-pipelined.do rv64gc imperas64i"
vsim -do "do wally-pipelined.do rv64gc arch64d"

View File

@ -1,5 +1,5 @@
// `include "wally-config.vh"
`include "wally-config.vh"
module cvtfp (
input logic [10:0] XExpE, // input's exponent
input logic [52:0] XManE, // input's mantissa
@ -157,15 +157,28 @@ module cvtfp (
// Result Selection
///////////////////////////////////////////////////////////////////////////////
// select the double to single precision result
assign DSRes = XNaNE ? {XSgnE, {8{1'b1}}, 1'b1, XManE[50:29]} :
Underflow & ~Denorm ? {XSgnE, 30'b0, CalcPlus1&(|FrmE[1:0]|Shift)} :
Overflow | XInfE ? ((FrmE[1:0]==2'b01) | (FrmE[1:0]==2'b10&~XSgnE) | (FrmE[1:0]==2'b11&XSgnE)) & ~XInfE ? {XSgnE, 8'hfe, {23{1'b1}}} :
{XSgnE, 8'hff, 23'b0} :
{XSgnE, DSResExp, DSResFrac};
generate if(`IEEE754) begin
// select the double to single precision result
assign DSRes = XNaNE ? {XSgnE, {8{1'b1}}, 1'b1, XManE[50:29]} :
Underflow & ~Denorm ? {XSgnE, 30'b0, CalcPlus1&(|FrmE[1:0]|Shift)} :
Overflow | XInfE ? ((FrmE[1:0]==2'b01) | (FrmE[1:0]==2'b10&~XSgnE) | (FrmE[1:0]==2'b11&XSgnE)) & ~XInfE ? {XSgnE, 8'hfe, {23{1'b1}}} :
{XSgnE, 8'hff, 23'b0} :
{XSgnE, DSResExp, DSResFrac};
// select the final result based on the opperation
assign CvtFpResE = FmtE ? {{32{1'b1}},DSRes} : {XSgnE, SDExp, SDFrac[51]|XNaNE, SDFrac[50:0]};
// select the final result based on the opperation
assign CvtFpResE = FmtE ? {{32{1'b1}},DSRes} : {XSgnE, SDExp, SDFrac[51]|XNaNE, SDFrac[50:0]};
end else begin
// select the double to single precision result
assign DSRes = XNaNE ? {1'b0, {8{1'b1}}, 1'b1, 22'b0} :
Underflow & ~Denorm ? {XSgnE, 30'b0, CalcPlus1&(|FrmE[1:0]|Shift)} :
Overflow | XInfE ? ((FrmE[1:0]==2'b01) | (FrmE[1:0]==2'b10&~XSgnE) | (FrmE[1:0]==2'b11&XSgnE)) & ~XInfE ? {XSgnE, 8'hfe, {23{1'b1}}} :
{XSgnE, 8'hff, 23'b0} :
{XSgnE, DSResExp, DSResFrac};
// select the final result based on the opperation
assign CvtFpResE = FmtE ? {{32{1'b1}},DSRes} : {XSgnE&~XNaNE, SDExp, SDFrac[51]|XNaNE, SDFrac[50:0]&{51{~XNaNE}}};
end
endgenerate
endmodule // fpadd

View File

@ -1,332 +1,97 @@
//
// File name : fpcomp.v
// Title : Floating-Point Comparator
// project : FPU
// Library : fpcomp
// Author(s) : James E. Stine
// Purpose : definition of main unit to floating-point comparator
// notes :
//
// Copyright Oklahoma State University
//
// Floating Point Comparator (Algorithm)
//
// 1.) Performs sign-extension if the inputs are 32-bit integers.
// 2.) Perform a magnitude comparison on the lower 63 bits of the inputs
// 3.) Check for special cases (+0=-0, unordered, and infinite values)
// and correct for sign bits
//
// This module takes 64-bits inputs op1 and op2, VSS, and VDD
// signals, and a 2-bit signal FOpCtrlE that indicates the type of
// operands being compared as indicated below.
// FOpCtrlE Description
// 00 double precision numbers
// 01 single precision numbers
// 10 half precision numbers
// 11 (unused)
//
// The comparator produces a 2-bit signal FCC, which
// indicates the result of the comparison:
//
// fcc decscription
// 00 A = B
// 01 A < B
// 10 A > B
// 11 A and B are unordered (i.e., A or B is NaN)
//
// It also produces an invalid operation flag, which is one
// if either of the input operands is a signaling NaN per 754
`include "wally-config.vh"
// FOpCtrlE values
// 111 min
// 101 max
// 010 equal
// 001 less than
// 011 less than or equal
module fcmp (
input logic [63:0] op1,
input logic [63:0] op2,
input logic XNaNE, YNaNE,
input logic XZeroE, YZeroE,
input logic [63:0] FSrcXE,
input logic [63:0] FSrcYE,
input logic [2:0] FOpCtrlE,
input logic FmtE,
input logic FmtE, // precision 1 = double 0 = single
input logic [2:0] FOpCtrlE, // see above table
input logic XSgnE, YSgnE, // input signs
input logic [`NE-1:0] XExpE, YExpE, // input exponents
input logic [`NF:0] XManE, YManE, // input mantissa
input logic XZeroE, YZeroE, // is zero
input logic XNaNE, YNaNE, // is NaN
input logic XSNaNE, YSNaNE, // is signaling NaN
input logic [`FLEN-1:0] FSrcXE, FSrcYE, // original, non-converted to double, inputs
output logic CmpNVE, // invalid flag
output logic [`FLEN-1:0] CmpResE // compare resilt
);
output logic Invalid, // Invalid Operation
output logic [63:0] CmpResE);
logic LT, EQ; // is X < or > or = Y
// Perform magnitude comparison between the 63 least signficant bits
// of the input operands. Only LT and EQ are returned, since GT can
// be determined from these values.
logic [1:0] FCC; // Condition Codes
logic [7:0] w, x;
// logic ANaN, BNaN;
// logic Azero, Bzero;
logic LT; // magnitude op1 < magnitude op2
logic EQ; // magnitude op1 = magnitude op2
// X is less than Y:
// Signs:
// X Y answer
// pos pos idk - keep checking
// pos neg no
// 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
assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE<YManE)^XSgnE)&~EQ : (XExpE<YExpE)^XSgnE;
assign EQ = (FSrcXE == FSrcYE);
// flags
// Min/Max - if an input is a signaling NaN set invalid flag
// LT/LE - signaling - sets invalid if NaN input
// EQ - quiet - sets invalid if signaling NaN input
always_comb begin
case (FOpCtrlE[2:0])
3'b111: CmpNVE = XSNaNE|YSNaNE;//min
3'b101: CmpNVE = XSNaNE|YSNaNE;//max
3'b010: CmpNVE = XSNaNE|YSNaNE;//equal
3'b001: CmpNVE = XNaNE|YNaNE;//less than
3'b011: CmpNVE = XNaNE|YNaNE;//less than or equal
default: CmpNVE = 1'b0;
endcase
end
magcompare64b_1 magcomp1 (w, x, {~op1[63], op1[62:0]}, {~op2[63], op2[62:0]});
// Min/Max
// - outputs the min/max of X and Y
// - -0 < 0
// - if both are NaN return quiet X
// - if one is a NaN output the non-NaN
// LT/LE/EQ
// - -0 = 0
// - inf = inf and -inf = -inf
// - return 0 if comparison with NaN (unordered)
// Determine final values based on output of magnitude comparison,
// sign bits, and special case testing.
// Perform magnitude comparison between the 63 least signficant bits
// of the input operands. Only LT and EQ are returned, since GT can
// be determined from these values.
magcompare64b_2 magcomp2 (LT, EQ, w, x);
// Determine final values based on output of magnitude comparison,
// sign bits, and special case testing.
exception_cmp_2 exc2 (
.invalid(Invalid), .fcc(FCC), .LT_mag(LT), .EQ_mag(EQ),
.ANaN(XNaNE), .BNaN(YNaNE), .Azero(XZeroE), .Bzero(YZeroE),
.FOpCtrlE, .A(op1), .B(op2), .FSrcXE, .FSrcYE,
.FmtE, .CmpResE
);
endmodule // fpcomp
// 2-bit magnitude comparator
// This module compares two 2-bit values A and B. LT is '1' if A < B
// and GT is '1'if A > B. LT and GT are both '0' if A = B. However,
// this version actually incorporates don't cares into the equation to
// simplify the optimization
module magcompare2c (LT, GT, A, B);
input logic [1:0] A;
input logic [1:0] B;
output logic LT;
output logic GT;
assign LT = B[1] | (!A[1]&B[0]);
assign GT = A[1] | (!B[1]&A[0]);
endmodule // magcompare2b
// This module compares two 64-bit values A and B. LT is '1' if A < B
// and EQ is '1'if A = B. LT and GT are both '0' if A > B.
// This structure was modified so
// that it only does a strict magnitdude comparison, and only
// returns flags for less than (LT) and eqaual to (EQ). It uses a tree
// of 63 2-bit magnitude comparators, followed by one OR gates.
//
// J. E. Stine and M. J. Schulte, "A combined two's complement and
// floating-point comparator," 2005 IEEE International Symposium on
// Circuits and Systems, Kobe, 2005, pp. 89-92 Vol. 1.
// doi: 10.1109/ISCAS.2005.1464531
module magcompare64b_1 (w, x, A, B);
input logic [63:0] A;
input logic [63:0] B;
logic [31:0] s;
logic [31:0] t;
logic [15:0] u;
logic [15:0] v;
output logic [7:0] w;
output logic [7:0] x;
magcompare2b mag1(s[0], t[0], A[1:0], B[1:0]);
magcompare2b mag2(s[1], t[1], A[3:2], B[3:2]);
magcompare2b mag3(s[2], t[2], A[5:4], B[5:4]);
magcompare2b mag4(s[3], t[3], A[7:6], B[7:6]);
magcompare2b mag5(s[4], t[4], A[9:8], B[9:8]);
magcompare2b mag6(s[5], t[5], A[11:10], B[11:10]);
magcompare2b mag7(s[6], t[6], A[13:12], B[13:12]);
magcompare2b mag8(s[7], t[7], A[15:14], B[15:14]);
magcompare2b mag9(s[8], t[8], A[17:16], B[17:16]);
magcompare2b magA(s[9], t[9], A[19:18], B[19:18]);
magcompare2b magB(s[10], t[10], A[21:20], B[21:20]);
magcompare2b magC(s[11], t[11], A[23:22], B[23:22]);
magcompare2b magD(s[12], t[12], A[25:24], B[25:24]);
magcompare2b magE(s[13], t[13], A[27:26], B[27:26]);
magcompare2b magF(s[14], t[14], A[29:28], B[29:28]);
magcompare2b mag10(s[15], t[15], A[31:30], B[31:30]);
magcompare2b mag11(s[16], t[16], A[33:32], B[33:32]);
magcompare2b mag12(s[17], t[17], A[35:34], B[35:34]);
magcompare2b mag13(s[18], t[18], A[37:36], B[37:36]);
magcompare2b mag14(s[19], t[19], A[39:38], B[39:38]);
magcompare2b mag15(s[20], t[20], A[41:40], B[41:40]);
magcompare2b mag16(s[21], t[21], A[43:42], B[43:42]);
magcompare2b mag17(s[22], t[22], A[45:44], B[45:44]);
magcompare2b mag18(s[23], t[23], A[47:46], B[47:46]);
magcompare2b mag19(s[24], t[24], A[49:48], B[49:48]);
magcompare2b mag1A(s[25], t[25], A[51:50], B[51:50]);
magcompare2b mag1B(s[26], t[26], A[53:52], B[53:52]);
magcompare2b mag1C(s[27], t[27], A[55:54], B[55:54]);
magcompare2b mag1D(s[28], t[28], A[57:56], B[57:56]);
magcompare2b mag1E(s[29], t[29], A[59:58], B[59:58]);
magcompare2b mag1F(s[30], t[30], A[61:60], B[61:60]);
magcompare2b mag20(s[31], t[31], A[63:62], B[63:62]);
magcompare2c mag21(u[0], v[0], t[1:0], s[1:0]);
magcompare2c mag22(u[1], v[1], t[3:2], s[3:2]);
magcompare2c mag23(u[2], v[2], t[5:4], s[5:4]);
magcompare2c mag24(u[3], v[3], t[7:6], s[7:6]);
magcompare2c mag25(u[4], v[4], t[9:8], s[9:8]);
magcompare2c mag26(u[5], v[5], t[11:10], s[11:10]);
magcompare2c mag27(u[6], v[6], t[13:12], s[13:12]);
magcompare2c mag28(u[7], v[7], t[15:14], s[15:14]);
magcompare2c mag29(u[8], v[8], t[17:16], s[17:16]);
magcompare2c mag2A(u[9], v[9], t[19:18], s[19:18]);
magcompare2c mag2B(u[10], v[10], t[21:20], s[21:20]);
magcompare2c mag2C(u[11], v[11], t[23:22], s[23:22]);
magcompare2c mag2D(u[12], v[12], t[25:24], s[25:24]);
magcompare2c mag2E(u[13], v[13], t[27:26], s[27:26]);
magcompare2c mag2F(u[14], v[14], t[29:28], s[29:28]);
magcompare2c mag30(u[15], v[15], t[31:30], s[31:30]);
magcompare2c mag31(w[0], x[0], v[1:0], u[1:0]);
magcompare2c mag32(w[1], x[1], v[3:2], u[3:2]);
magcompare2c mag33(w[2], x[2], v[5:4], u[5:4]);
magcompare2c mag34(w[3], x[3], v[7:6], u[7:6]);
magcompare2c mag35(w[4], x[4], v[9:8], u[9:8]);
magcompare2c mag36(w[5], x[5], v[11:10], u[11:10]);
magcompare2c mag37(w[6], x[6], v[13:12], u[13:12]);
magcompare2c mag38(w[7], x[7], v[15:14], u[15:14]);
endmodule // magcompare64b
// This module compares two 64-bit values A and B. LT is '1' if A < B
// and EQ is '1'if A = B. LT and GT are both '0' if A > B.
// This structure was modified so
// that it only does a strict magnitdude comparison, and only
// returns flags for less than (LT) and eqaual to (EQ). It uses a tree
// of 63 2-bit magnitude comparators, followed by one OR gates.
//
// J. E. Stine and M. J. Schulte, "A combined two's complement and
// floating-point comparator," 2005 IEEE International Symposium on
// Circuits and Systems, Kobe, 2005, pp. 89-92 Vol. 1.
// doi: 10.1109/ISCAS.2005.1464531
module magcompare64b_2 (LT, EQ, w, x);
input logic [7:0] w;
input logic [7:0] x;
logic [3:0] y;
logic [3:0] z;
logic [1:0] a;
logic [1:0] b;
logic GT;
output logic LT;
output logic EQ;
magcompare2c mag39(y[0], z[0], x[1:0], w[1:0]);
magcompare2c mag3A(y[1], z[1], x[3:2], w[3:2]);
magcompare2c mag3B(y[2], z[2], x[5:4], w[5:4]);
magcompare2c mag3C(y[3], z[3], x[7:6], w[7:6]);
magcompare2c mag3D(a[0], b[0], z[1:0], y[1:0]);
magcompare2c mag3E(a[1], b[1], z[3:2], y[3:2]);
magcompare2c mag3F(LT, GT, b[1:0], a[1:0]);
assign EQ = ~(LT | GT);
endmodule // magcompare64b
// This module takes 64-bits inputs A and B, two magnitude comparison
// flags LT_mag and EQ_mag, and a 2-bit signal FOpCtrlE that indicates the type of
// operands being compared as indicated below.
// FOpCtrlE Description
// 00 double precision numbers
// 01 single precision numbers
// 10 half precision numbers
// 11 bfloat precision numbers
//
// The comparator produces a 2-bit signal fcc, which
// indicates the result of the comparison as follows:
// fcc decscription
// 00 A = B
// 01 A < B
// 10 A > B
// 11 A and B are unordered (i.e., A or B is NaN)
// It also produces a invalid operation flag, which is one
// if either of the input operands is a signaling NaN.
module exception_cmp_2 (
input logic [63:0] A,
input logic [63:0] B,
input logic [63:0] FSrcXE,
input logic [63:0] FSrcYE,
input logic FmtE,
input logic LT_mag,
input logic EQ_mag,
input logic [2:0] FOpCtrlE,
output logic invalid,
output logic [1:0] fcc,
output logic [63:0] CmpResE,
input logic Azero,
input logic Bzero,
input logic ANaN,
input logic BNaN);
logic dp;
logic sp;
logic hp;
logic ASNaN;
logic BSNaN;
logic UO;
logic GT;
logic LT;
logic EQ;
assign dp = !FOpCtrlE[1]&!FOpCtrlE[0];
assign sp = !FOpCtrlE[1]&FOpCtrlE[0];
assign hp = FOpCtrlE[1]&!FOpCtrlE[0];
// Values are unordered if ((A is NaN) OR (B is NaN)) AND (a floating
// point comparison is being performed.
assign UO = (ANaN | BNaN);
// Test if A or B is a signaling NaN.
assign ASNaN = ANaN & (sp&~A[53] | dp&~A[50] | hp&~A[56]);
assign BSNaN = BNaN & (sp&~B[53] | dp&~B[50] | hp&~B[56]);
// If either A or B is a signaling NaN the "Invalid Operation"
// exception flag is set to one; otherwise it is zero.
assign invalid = (ASNaN | BSNaN);
// A and B are equal if (their magnitudes are equal) AND ((their signs are
// equal) or (their magnitudes are zero AND they are floating point
// numbers)). Also, A and B are not equal if they are unordered.
assign EQ = (EQ_mag | (Azero&Bzero)) & (~UO);
// A is less than B if (A is negative and B is posiive) OR
// (A and B are positive and the magnitude of A is less than
// the magnitude of B) or (A and B are negative integers and
// the magnitude of A is less than the magnitude of B) or
// (A and B are negative floating point numbers and
// the magnitude of A is greater than the magnitude of B).
// Also, A is not less than B if A and B are equal or unordered.
assign LT = ((~LT_mag & A[63] & B[63]) |
(LT_mag & ~(A[63] & B[63])))&~EQ&~UO;
// A is greater than B when LT, EQ, and UO are are false.
assign GT = ~(LT | EQ | UO);
// Note: it may be possible to optimize the setting of fcc
// a little more, but it is probably not worth the effort.
// Set the bits of fcc based on LT, GT, EQ, and UO
assign fcc[0] = LT | UO;
assign fcc[1] = GT | UO;
logic [`FLEN-1:0] QNaNX, QNaNY;
generate if(`IEEE754) begin
assign QNaNX = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]};
assign QNaNY = FmtE ? {YSgnE, YExpE, 1'b1, YManE[`NF-2:0]} : {{32{1'b1}}, YSgnE, YExpE[7:0], 1'b1, YManE[50:29]};
end else begin
assign QNaNX = 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
endgenerate
always_comb begin
case (FOpCtrlE[2:0])
3'b111: CmpResE = LT ? FSrcXE : FSrcYE;//min
3'b101: CmpResE = GT ? FSrcXE : FSrcYE;//max
3'b010: CmpResE = {63'b0, EQ};//equal
3'b001: CmpResE = {63'b0, LT};//less than
3'b011: CmpResE = {63'b0, LT|EQ};//less than or equal
3'b111: CmpResE = XNaNE ? YNaNE ? QNaNX : FSrcYE // Min
: YNaNE ? FSrcXE : LT ? FSrcXE : FSrcYE;
3'b101: CmpResE = XNaNE ? YNaNE ? QNaNX : FSrcYE // Max
: YNaNE ? FSrcXE : LT ? FSrcYE : FSrcXE;
3'b010: CmpResE = {63'b0, (EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Equal
3'b001: CmpResE = {63'b0, LT&~(XZeroE&YZeroE)&~(XNaNE|YNaNE)}; // Less than
3'b011: CmpResE = {63'b0, (LT|EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Less than or equal
default: CmpResE = 64'b0;
endcase
end
endmodule // exception_cmp
endmodule

View File

@ -55,9 +55,9 @@ module fctrl (
default: ControlsD = `FCTRLW'b0_0_00_000_000_00_0_1; // non-implemented instruction
endcase
7'b10100??: case(Funct3D)
3'b010: ControlsD = `FCTRLW'b0_1_11_010_000_00_0_0; // feq
3'b001: ControlsD = `FCTRLW'b0_1_11_001_000_00_0_0; // flt
3'b000: ControlsD = `FCTRLW'b0_1_11_011_000_00_0_0; // fle
3'b010: ControlsD = `FCTRLW'b0_1_11_010_010_00_0_0; // feq
3'b001: ControlsD = `FCTRLW'b0_1_11_001_010_00_0_0; // flt
3'b000: ControlsD = `FCTRLW'b0_1_11_011_010_00_0_0; // fle
default: ControlsD = `FCTRLW'b0_0_00_000_000_00_0_1; // non-implemented instruction
endcase
7'b11100??: if (Funct3D == 3'b001) ControlsD = `FCTRLW'b0_1_11_000_000_10_0_0; // fclass

View File

@ -21,7 +21,7 @@ module fcvt (
logic ResSgn; // FP result's sign
logic [10:0] ResExp,TmpExp; // FP result's exponent
logic [51:0] ResFrac; // FP result's fraction
logic [5:0] LZResP; // lz output
logic [6:0] LZResP; // lz output
logic [7:0] Bits; // how many bits are in the integer result
logic [7:0] SubBits; // subtract these bits from the exponent (FP result)
logic [64+51:0] ShiftedManTmp; // Shifted mantissa
@ -42,6 +42,7 @@ module fcvt (
logic Res64, In64; // is the result or input 64 bits
logic RoundMSB; // most significant bit of the fraction
logic RoundSgn; // sign of the rounded result
logic Invalid, Inexact; // flags
// FOpCtrlE:
// fcvt.w.s = 001
@ -78,7 +79,7 @@ module fcvt (
// make the integer positive
assign PosInt = IntIn[64-1]&~FOpCtrlE[1] ? -IntIn : IntIn;
// determine the integer's sign
assign ResSgn = ~FOpCtrlE[1] ? IntIn[64-1] : 1'b0;
assign ResSgn = ~FOpCtrlE[1]&IntIn[64-1];
// Leading one detector
logic [8:0] i;
@ -89,7 +90,7 @@ module fcvt (
end
// if no one was found set to zero otherwise calculate the exponent
assign TmpExp = i==`XLEN ? 0 : FmtE ? 11'd1023 + {3'b0, SubBits} - {5'b0, LZResP} : 11'd127 + {3'b0, SubBits} - {5'b0, LZResP};
assign TmpExp = i==`XLEN ? 0 : FmtE ? 11'd1023 + {3'b0, SubBits} - {4'b0, LZResP} : 11'd127 + {3'b0, SubBits} - {4'b0, LZResP};
@ -98,7 +99,7 @@ module fcvt (
// select the shift value and amount based on operation (to fp or int)
assign ShiftCnt = FOpCtrlE[0] ? ExpVal : {7'b0, LZResP};
assign ShiftCnt = FOpCtrlE[0] ? ExpVal : {6'b0, LZResP};
assign ShiftVal = FOpCtrlE[0] ? {{64-1{1'b0}}, XManE} : {PosInt, 52'b0};
// if shift = -1 then shift one bit right for gaurd bit (right shifting twice never rounds)
@ -159,8 +160,8 @@ module fcvt (
// select the integer result
assign CvtIntRes = Of ? FOpCtrlE[1] ? {64{1'b1}} : SgnRes ? {33'b0, {31{1'b1}}}: {1'b0, {63{1'b1}}} :
Uf ? FOpCtrlE[1] ? {63'b0, Plus1&~XSgnE} : SgnRes ? {32'b0, 1'b1, 31'b0} : {1'b1, 63'b0} :
Rounded[64-1:0];
Uf ? FOpCtrlE[1] ? {63'b0, Plus1&~XSgnE} : SgnRes ? {{33{1'b1}}, 31'b0} : {1'b1, 63'b0} :
|RoundedTmp ? Rounded[64-1:0] : 64'b0;
// select the floating point result
assign CvtFPRes = FmtE ? {ResSgn, ResExp, ResFrac} : {{32{1'b1}}, ResSgn, ResExp[7:0], ResFrac[51:29]};
@ -169,15 +170,19 @@ module fcvt (
assign CvtResE = FOpCtrlE[0] ? CvtIntRes : CvtFPRes;
// calculate the flags
// - only set invalid flag for out-of-range vales if it isn't be indicated by the inexact
// - don't set inexact flag if converting a really large number (closest __ bit integer value is the max value)
// - don't set inexact flag if converting negitive or tiny number to unsigned (closest integer value is 0 or 1)
logic Invalid, Inexact;
assign Invalid = (Of | Uf)&FOpCtrlE[0];
assign Inexact = (Guard|Round|Sticky)&~((&FOpCtrlE[1:0]&Uf&~(Plus1&~XSgnE))|(FOpCtrlE[0]&Of));
assign CvtFlgE = {Invalid&~Inexact, 3'b0, Inexact};
// assign CvtFlgE = {(Of | Uf)&FOpCtrlE[0], 3'b0, (Guard|Round|Sticky)&~FOpCtrlE[0]};
// - only set invalid flag for out-of-range vales
// - set inexact if in representable range and not exact
generate if(`IEEE754) begin // checks before rounding
assign Invalid = (Of | Uf)&FOpCtrlE[0];
assign Inexact = (Guard|Round|Sticky)&~(&FOpCtrlE[1:0]&(XSgnE|Of))&~((Of|Uf)&~FOpCtrlE[1]&FOpCtrlE[0]);
assign CvtFlgE = {Invalid&~Inexact, 3'b0, Inexact};
end else begin // RISC-V checks if the result is in range after rounding
assign Invalid = (Of | Uf)&FOpCtrlE[0];
assign Inexact = (Guard|Round|Sticky)&~(&FOpCtrlE[1:0]&((XSgnE&~(ShiftCnt[12]&~Plus1))|Of))&~((Of|Uf)&~FOpCtrlE[1]&FOpCtrlE[0]);
assign CvtFlgE = {Invalid&~Inexact, 3'b0, Inexact};
end
endgenerate

View File

@ -24,17 +24,18 @@
`include "wally-config.vh"
// `define FLEN 64//(`Q_SUPPORTED ? 128 : `D_SUPPORTED ? 64 : 32)
// `define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
// `define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
// `define XLEN 64
// `define FLEN 64//(`Q_SUPPORTED ? 128 : `D_SUPPORTED ? 64 : 32)
// `define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
// `define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
// `define XLEN 64
// `define IEEE754 1
module fma(
input logic clk,
input logic reset,
input logic FlushM, // flush the memory stage
input logic StallM, // stall memory stage
input logic FmtE, FmtM, // precision 1 = double 0 = single
input logic [2:0] FOpCtrlE, // 000 = fmadd (X*Y)+Z, 001 = fmsub (X*Y)-Z, 010 = fnmsub -(X*Y)+Z, 011 = fnmadd -(X*Y)-Z, 100 = fmul (X*Y)
input logic [2:0] FOpCtrlE, // 000 = fmadd (X*Y)+Z, 001 = fmsub (X*Y)-Z, 010 = fnmsub -(X*Y)+Z, 011 = fnmadd -(X*Y)-Z, 100 = fmul (X*Y)
input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
input logic XSgnE, YSgnE, ZSgnE, // input signs - execute stage
input logic [`NE-1:0] XExpE, YExpE, ZExpE, // input exponents - execute stage
@ -70,6 +71,7 @@ module fma(
logic ZSgnEffE, ZSgnEffM;
logic PSgnE, PSgnM;
logic [8:0] NormCntE, NormCntM;
logic Mult;
fma1 fma1 (.XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE,
.XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE,
@ -79,13 +81,13 @@ module fma(
// E/M pipeline registers
flopenrc #(3*`NF+6) EMRegFma2(clk, reset, FlushM, ~StallM, SumE, SumM);
flopenrc #(13) EMRegFma3(clk, reset, FlushM, ~StallM, ProdExpE, ProdExpM);
flopenrc #(15) EMRegFma4(clk, reset, FlushM, ~StallM,
{AddendStickyE, KillProdE, InvZE, NormCntE, NegSumE, ZSgnEffE, PSgnE},
{AddendStickyM, KillProdM, InvZM, NormCntM, NegSumM, ZSgnEffM, PSgnM});
flopenrc #(16) EMRegFma4(clk, reset, FlushM, ~StallM,
{AddendStickyE, KillProdE, InvZE, NormCntE, NegSumE, ZSgnEffE, PSgnE, FOpCtrlE[2]&~FOpCtrlE[1]&~FOpCtrlE[0]},
{AddendStickyM, KillProdM, InvZM, NormCntM, NegSumM, ZSgnEffM, PSgnM, Mult});
fma2 fma2(.XSgnM, .YSgnM, .XExpM, .YExpM, .ZExpM, .XManM, .YManM, .ZManM,
.FrmM, .FmtM, .ProdExpM, .AddendStickyM, .KillProdM, .SumM, .NegSumM, .InvZM, .NormCntM, .ZSgnEffM, .PSgnM,
.XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM,
.XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM, .Mult,
.FMAResM, .FMAFlgM);
endmodule
@ -420,6 +422,7 @@ module fma2(
input logic InvZM, // do you invert Z
input logic ZSgnEffM, // the modified Z sign - depends on instruction
input logic PSgnM, // the product's sign
input logic Mult, // multiply opperation
input logic [8:0] NormCntM, // the normalization shift count
output logic [`FLEN-1:0] FMAResM, // FMA final result
output logic [4:0] FMAFlgM); // FMA flags {invalid, divide by zero, overflow, underflow, inexact}
@ -479,7 +482,7 @@ module fma2(
///////////////////////////////////////////////////////////////////////////////
resultsign resultsign(.FrmM, .PSgnM, .ZSgnEffM, .Underflow, .InvZM, .NegSumM, .SumZero, .ResultSgnTmp, .ResultSgn);
resultsign resultsign(.FrmM, .PSgnM, .ZSgnEffM, .Underflow, .InvZM, .NegSumM, .SumZero, .Mult, .ResultSgnTmp, .ResultSgn);
@ -515,6 +518,7 @@ module resultsign(
input logic InvZM,
input logic NegSumM,
input logic SumZero,
input logic Mult,
output logic ResultSgnTmp,
output logic ResultSgn
);
@ -524,8 +528,9 @@ module resultsign(
// Determine the sign if the sum is zero
// if cancelation then 0 unless round to -infinity
// if multiply then Psgn
// otherwise psign
assign ZeroSgn = (PSgnM^ZSgnEffM)&~Underflow ? FrmM[1:0] == 2'b10 : PSgnM;
assign ZeroSgn = (PSgnM^ZSgnEffM)&~Underflow&~Mult ? FrmM[1:0] == 2'b10 : PSgnM;
// is the result negitive
// if p - z is the Sum negitive
@ -607,8 +612,8 @@ module normalize(
assign UfSticky = AddendStickyM | NormSumSticky;
// Determine sum's exponent
// if plus1 If plus2 if said denorm but norm plus 1 if said denorm (-1 val) but norm plus 2
assign SumExp = (SumExpTmp+{12'b0, LZAPlus1&~KillProdM}+{11'b0, LZAPlus2&~KillProdM, 1'b0}+{12'b0, ~|SumExpTmp&SumShifted[3*`NF+6]&~KillProdM}+{11'b0, &SumExpTmp&SumShifted[3*`NF+6]&~KillProdM, 1'b0}) & {`NE+2{~(SumZero|ResultDenorm)}};
// if plus1 If plus2 if said denorm but norm plus 1 if said denorm but norm plus 2
assign SumExp = (SumExpTmp+{12'b0, LZAPlus1&~KillProdM}+{11'b0, LZAPlus2&~KillProdM, 1'b0}+{12'b0, ~ResultDenorm&PreResultDenorm2&~KillProdM}+{12'b0, &SumExpTmp&SumShifted[3*`NF+6]&~KillProdM}) & {`NE+2{~(SumZero|ResultDenorm)}};
// recalculate if the result is denormalized
assign ResultDenorm = PreResultDenorm2&~SumShifted[3*`NF+6]&~SumShifted[3*`NF+7];
@ -814,10 +819,12 @@ module resultselect(
assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XManM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XManM[50:29]};
assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, YManM[`NF-2:0]} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, YManM[50:29]};
assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, ZManM[50:29]};
assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, ResultSgn, 8'hff, 1'b1, 22'b0};
end else begin:nan
assign XNaNResult = FmtM ? {1'b0, XExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpM[7:0], 1'b1, 22'b0};
assign YNaNResult = FmtM ? {1'b0, YExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, YExpM[7:0], 1'b1, 22'b0};
assign ZNaNResult = FmtM ? {1'b0, ZExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, ZExpM[7:0], 1'b1, 22'b0};
assign InvalidResult = FmtM ? {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, 1'b0, 8'hff, 1'b1, 22'b0};
end
endgenerate
@ -826,7 +833,6 @@ module resultselect(
{ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} :
((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{32{1'b1}}, ResultSgn, 8'hfe, {23{1'b1}}} :
{{32{1'b1}}, ResultSgn, 8'hff, 23'b0};
assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, ResultSgn, 8'hff, 1'b1, 22'b0};
assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})} : {{32{1'b1}}, ResultSgn, {ZExpM[`NE-1],ZExpM[6:0], ZManM[51:29]} + (RoundAdd[59:29]&{31{AddendStickyM}})};
assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + {63'b0,(CalcPlus1&(AddendStickyM|FrmM[1]))} : {{32{1'b1}}, {ResultSgn, 31'b0} + {31'b0, (CalcPlus1&(AddendStickyM|FrmM[1]))}};
assign FMAResM = XNaNM ? XNaNResult :

View File

@ -116,7 +116,6 @@ module fpu (
logic [63:0] CmpResE; // compare result
logic CmpNVE; // compare invalid flag (Not Valid)
logic [63:0] SgnResE; // sign injection result
logic SgnNVE; // sign injection invalid flag (Not Valid)
logic [63:0] FResE, FResM, FResW; // selected result that is ready in the memory stage
logic [4:0] FFlgE, FFlgM; // selected flag that is ready in the memory stage
logic [`XLEN-1:0] FIntResE;
@ -213,14 +212,12 @@ module fpu (
// - computation is done in one stage
// - writes to FP file durring min/max instructions
// - other comparisons write a 1 or 0 to the integer register
fcmp fcmp (.op1({XSgnE,XExpE,XManE[`NF-1:0]}), .op2({YSgnE,YExpE,YManE[`NF-1:0]}),
.FSrcXE, .FSrcYE, .FOpCtrlE,
.FmtE, .XNaNE, .YNaNE, .XZeroE, .YZeroE,
.Invalid(CmpNVE), .CmpResE);
fcmp fcmp (.FmtE, .FOpCtrlE, .XSgnE, .YSgnE, .XExpE, .YExpE, .XManE, .YManE,
.XZeroE, .YZeroE, .XNaNE, .YNaNE, .XSNaNE, .YSNaNE, .FSrcXE, .FSrcYE, .CmpNVE, .CmpResE);
// sign injection unit
fsgn fsgn (.SgnOpCodeE(FOpCtrlE[1:0]), .XSgnE, .YSgnE, .FSrcXE, .FmtE, .XExpMaxE,
.SgnNVE, .SgnResE);
.SgnResE);
// classify
fclassify fclassify (.XSgnE, .XDenormE, .XZeroE, .XNaNE, .XInfE, .XNormE,
@ -240,7 +237,7 @@ module fpu (
// select a result that may be written to the FP register
mux5 #(64) FResMux(AlignedSrcAE, SgnResE, CmpResE, CvtResE, CvtFpResE, FResSelE, FResE);
mux5 #(5) FFlgMux(5'b0, {4'b0, SgnNVE}, {4'b0, CmpNVE}, CvtFlgE, CvtFpFlgE, FResSelE, FFlgE);
mux5 #(5) FFlgMux(5'b0, 5'b0, {CmpNVE, 4'b0}, CvtFlgE, CvtFpFlgE, FResSelE, FFlgE);
// select the result that may be written to the integer register - to IEU
mux4 #(`XLEN) IntResMux(CmpResE[`XLEN-1:0], FSrcXE[`XLEN-1:0], ClassResE[`XLEN-1:0],

View File

@ -6,8 +6,7 @@ module fsgn (
input logic XExpMaxE, // max possible exponent (all ones)
input logic FmtE, // precision 1 = double 0 = single
input logic [1:0] SgnOpCodeE, // operation control
output logic [63:0] SgnResE, // result
output logic SgnNVE // invalid flag
output logic [63:0] SgnResE // result
);
logic ResSgn;
@ -27,12 +26,5 @@ module fsgn (
// - if there are any unsused bits the most significant bits are filled with 1s
assign SgnResE = FmtE ? {ResSgn, FSrcXE[62:0]} : {FSrcXE[63:32], ResSgn, FSrcXE[30:0]};
//If the exponent is all ones, then the value is either Inf or NaN,
//both of which will produce a QNaN/SNaN value of some sort. This will
//set the invalid flag high.
//the only flag that can occur during this operation is invalid
//due to changing sign on already existing NaN
assign SgnNVE = XExpMaxE & SgnResE[63];
endmodule

View File

@ -1047,89 +1047,89 @@ string imperas32f[] = '{
string arch64d[] = '{
`RISCVARCHTEST,
"rv64i_m/D/d_fadd_b10-01", "8690",
// "rv64i_m/D/d_fadd_b1-01", "8430",
// "rv64i_m/D/d_fadd_b11-01", "74da0",
// "rv64i_m/D/d_fadd_b12-01", "2350",
// "rv64i_m/D/d_fadd_b13-01", "3cb0",
// "rv64i_m/D/d_fadd_b2-01", "5160",
// "rv64i_m/D/d_fadd_b3-01", "d640",
// "rv64i_m/D/d_fadd_b4-01", "3900",
// "rv64i_m/D/d_fadd_b5-01", "3d50",
// "rv64i_m/D/d_fadd_b7-01", "5530",
// "rv64i_m/D/d_fadd_b8-01", "11c10",
"rv64i_m/D/d_fadd_b1-01", "8430",
// "rv64i_m/D/d_fadd_b11-01", "74da0", //memfile
"rv64i_m/D/d_fadd_b12-01", "2350",
"rv64i_m/D/d_fadd_b13-01", "3cb0",
"rv64i_m/D/d_fadd_b2-01", "5160",
"rv64i_m/D/d_fadd_b3-01", "d640",
"rv64i_m/D/d_fadd_b4-01", "3900",
"rv64i_m/D/d_fadd_b5-01", "3d50",
"rv64i_m/D/d_fadd_b7-01", "5530",
"rv64i_m/D/d_fadd_b8-01", "11c10",
"rv64i_m/D/d_fclass_b1-01", "2110",
// "rv64i_m/D/d_fcvt.d.l_b25-01", "2110",
// "rv64i_m/D/d_fcvt.d.l_b26-01", "2220",
// "rv64i_m/D/d_fcvt.d.lu_b25-01", "2110",
// "rv64i_m/D/d_fcvt.d.lu_b26-01", "2220",
// "rv64i_m/D/d_fcvt.d.s_b1-01", "2110",
// "rv64i_m/D/d_fcvt.d.s_b22-01", "2110",
"rv64i_m/D/d_fcvt.d.l_b25-01", "2110",
"rv64i_m/D/d_fcvt.d.l_b26-01", "2220",
"rv64i_m/D/d_fcvt.d.lu_b25-01", "2110",
"rv64i_m/D/d_fcvt.d.lu_b26-01", "2220",
// "rv64i_m/D/d_fcvt.d.s_b1-01", "2110", // trying to put doubles into a s -> d conversion? also says 0 -/-> 0 but rather 7ff800... .signature.output looks suspicious
// "rv64i_m/D/d_fcvt.d.s_b22-01", "2110", // ^ from here to....
// "rv64i_m/D/d_fcvt.d.s_b23-01", "2110",
// "rv64i_m/D/d_fcvt.d.s_b24-01", "2110",
// "rv64i_m/D/d_fcvt.d.s_b27-01", "2110",
// "rv64i_m/D/d_fcvt.d.s_b28-01", "2110",
// "rv64i_m/D/d_fcvt.d.s_b29-01", "2110",
// "rv64i_m/D/d_fcvt.d.w_b25-01", "2120",
// "rv64i_m/D/d_fcvt.d.w_b26-01", "2220",
// "rv64i_m/D/d_fcvt.d.wu_b25-01", "2110",
// "rv64i_m/D/d_fcvt.d.wu_b26-01", "2220",
// "rv64i_m/D/d_fcvt.l.d_b1-01", "2120",
// "rv64i_m/D/d_fcvt.l.d_b22-01", "2260",
// "rv64i_m/D/d_fcvt.l.d_b23-01", "2180",
// "rv64i_m/D/d_fcvt.l.d_b24-01", "2360",
// "rv64i_m/D/d_fcvt.l.d_b27-01", "2110",
// "rv64i_m/D/d_fcvt.l.d_b28-01", "2120",
// "rv64i_m/D/d_fcvt.l.d_b29-01", "22a0",
// "rv64i_m/D/d_fcvt.lu.d_b1-01", "2120",
// "rv64i_m/D/d_fcvt.lu.d_b22-01", "2260",
// "rv64i_m/D/d_fcvt.lu.d_b23-01", "2180",
// "rv64i_m/D/d_fcvt.lu.d_b24-01", "2360",
// "rv64i_m/D/d_fcvt.lu.d_b27-01", "2120",
// "rv64i_m/D/d_fcvt.lu.d_b28-01", "2120",
// "rv64i_m/D/d_fcvt.lu.d_b29-01", "22a0",
// "rv64i_m/D/d_fcvt.s.d_b1-01", "2110",
// "rv64i_m/D/d_fcvt.s.d_b22-01", "2110",
// "rv64i_m/D/d_fcvt.s.d_b23-01", "2180",
// "rv64i_m/D/d_fcvt.s.d_b24-01", "2360",
// "rv64i_m/D/d_fcvt.s.d_b27-01", "2110",
// "rv64i_m/D/d_fcvt.s.d_b28-01", "2110",
// "rv64i_m/D/d_fcvt.s.d_b29-01", "22a0",
// "rv64i_m/D/d_fcvt.w.d_b1-01", "2120",
// "rv64i_m/D/d_fcvt.w.d_b22-01", "2160",
// "rv64i_m/D/d_fcvt.w.d_b23-01", "2180",
// "rv64i_m/D/d_fcvt.w.d_b24-01", "2360",
// "rv64i_m/D/d_fcvt.w.d_b27-01", "2120",
// "rv64i_m/D/d_fcvt.w.d_b28-01", "2120",
// "rv64i_m/D/d_fcvt.w.d_b29-01", "22a0",
// "rv64i_m/D/d_fcvt.wu.d_b1-01", "2120",
// "rv64i_m/D/d_fcvt.wu.d_b22-01", "2160",
// "rv64i_m/D/d_fcvt.wu.d_b23-01", "2180",
// "rv64i_m/D/d_fcvt.wu.d_b24-01", "2360",
// "rv64i_m/D/d_fcvt.wu.d_b27-01", "2120",
// "rv64i_m/D/d_fcvt.wu.d_b28-01", "2120",
// "rv64i_m/D/d_fcvt.wu.d_b29-01", "22a0",
// "rv64i_m/D/d_fdiv_b1-01", "8430",
// "rv64i_m/D/d_fdiv_b20-01", "3fa0",
// "rv64i_m/D/d_fdiv_b2-01", "5170",
// "rv64i_m/D/d_fdiv_b21-01", "8a70",
// "rv64i_m/D/d_fdiv_b3-01", "d630",
// "rv64i_m/D/d_fdiv_b4-01", "38f0",
// "rv64i_m/D/d_fdiv_b5-01", "3d50",
// "rv64i_m/D/d_fdiv_b6-01", "38f0",
// "rv64i_m/D/d_fdiv_b7-01", "5530",
// "rv64i_m/D/d_fdiv_b8-01", "11c10",
// "rv64i_m/D/d_fdiv_b9-01", "1b0f0",
// "rv64i_m/D/d_feq_b1-01", "7430",
// "rv64i_m/D/d_feq_b19-01", "c4c0",
// "rv64i_m/D/d_fld-align-01", "2010",
// "rv64i_m/D/d_fle_b1-01", "7430",
// "rv64i_m/D/d_fle_b19-01", "c4c0",
// "rv64i_m/D/d_flt_b1-01", "7430",
// "rv64i_m/D/d_flt_b19-01", "d800",
// "rv64i_m/D/d_fcvt.d.s_b29-01", "2110", // ....here
"rv64i_m/D/d_fcvt.d.w_b25-01", "2120",
"rv64i_m/D/d_fcvt.d.w_b26-01", "2220",
"rv64i_m/D/d_fcvt.d.wu_b25-01", "2110",
// "rv64i_m/D/d_fcvt.d.wu_b26-01", "2220", //memfile
"rv64i_m/D/d_fcvt.l.d_b1-01", "2120",
"rv64i_m/D/d_fcvt.l.d_b22-01", "2260",
"rv64i_m/D/d_fcvt.l.d_b23-01", "2180",
// "rv64i_m/D/d_fcvt.l.d_b24-01", "2360", // memfile
"rv64i_m/D/d_fcvt.l.d_b27-01", "2110",
"rv64i_m/D/d_fcvt.l.d_b28-01", "2120",
"rv64i_m/D/d_fcvt.l.d_b29-01", "22a0",
"rv64i_m/D/d_fcvt.lu.d_b1-01", "2120",
"rv64i_m/D/d_fcvt.lu.d_b22-01", "2260",
"rv64i_m/D/d_fcvt.lu.d_b23-01", "2180",
"rv64i_m/D/d_fcvt.lu.d_b24-01", "2360",
"rv64i_m/D/d_fcvt.lu.d_b27-01", "2120",
"rv64i_m/D/d_fcvt.lu.d_b28-01", "2120",
"rv64i_m/D/d_fcvt.lu.d_b29-01", "22a0",
"rv64i_m/D/d_fcvt.s.d_b1-01", "2110",
"rv64i_m/D/d_fcvt.s.d_b22-01", "2110",
"rv64i_m/D/d_fcvt.s.d_b23-01", "2180",
"rv64i_m/D/d_fcvt.s.d_b24-01", "2360",
"rv64i_m/D/d_fcvt.s.d_b27-01", "2110",
"rv64i_m/D/d_fcvt.s.d_b28-01", "2110",
"rv64i_m/D/d_fcvt.s.d_b29-01", "22a0",
// "rv64i_m/D/d_fcvt.w.d_b1-01", "2120", // memfile
// "rv64i_m/D/d_fcvt.w.d_b22-01", "2160", // memfile
"rv64i_m/D/d_fcvt.w.d_b23-01", "2180",
"rv64i_m/D/d_fcvt.w.d_b24-01", "2360",
"rv64i_m/D/d_fcvt.w.d_b27-01", "2120",
"rv64i_m/D/d_fcvt.w.d_b28-01", "2120",
"rv64i_m/D/d_fcvt.w.d_b29-01", "22a0",
// "rv64i_m/D/d_fcvt.wu.d_b1-01", "2120", // memfile
"rv64i_m/D/d_fcvt.wu.d_b22-01", "2160",
"rv64i_m/D/d_fcvt.wu.d_b23-01", "2180",
// "rv64i_m/D/d_fcvt.wu.d_b24-01", "2360", // memfile
"rv64i_m/D/d_fcvt.wu.d_b27-01", "2120",
"rv64i_m/D/d_fcvt.wu.d_b28-01", "2120",
"rv64i_m/D/d_fcvt.wu.d_b29-01", "22a0",
// "rv64i_m/D/d_fdiv_b1-01", "8430", // RV NaNs need to be positive
// "rv64i_m/D/d_fdiv_b20-01", "3fa0", // looks like flags
// "rv64i_m/D/d_fdiv_b2-01", "5170", // also flags
// "rv64i_m/D/d_fdiv_b21-01", "8a70", // positive NaNs again
"rv64i_m/D/d_fdiv_b3-01", "d630",
// "rv64i_m/D/d_fdiv_b4-01", "38f0", // flags
"rv64i_m/D/d_fdiv_b5-01", "3d50",
// "rv64i_m/D/d_fdiv_b6-01", "38f0", // flags
"rv64i_m/D/d_fdiv_b7-01", "5530",
// "rv64i_m/D/d_fdiv_b8-01", "11c10", // flags
// "rv64i_m/D/d_fdiv_b9-01", "1b0f0", // memfile might be a flag too
"rv64i_m/D/d_feq_b1-01", "7430",
"rv64i_m/D/d_feq_b19-01", "c4c0",
"rv64i_m/D/d_fld-align-01", "2010",
"rv64i_m/D/d_fle_b1-01", "7430",
"rv64i_m/D/d_fle_b19-01", "c4c0",
"rv64i_m/D/d_flt_b1-01", "7430",
"rv64i_m/D/d_flt_b19-01", "d800",
"rv64i_m/D/d_fmadd_b14-01", "3fd0",
"rv64i_m/D/d_fmadd_b16-01", "43b0",
"rv64i_m/D/d_fmadd_b17-01", "43b0",
"rv64i_m/D/d_fmadd_b18-01", "5a20",
// "rv64i_m/D/d_fmadd_b17-01", "43b0", //memfile
// "rv64i_m/D/d_fmadd_b18-01", "5a20", // memfile
"rv64i_m/D/d_fmadd_b2-01", "5ab0",
"rv64i_m/D/d_fmadd_b3-01", "119d0",
"rv64i_m/D/d_fmadd_b4-01", "3df0",
@ -1142,9 +1142,9 @@ string imperas32f[] = '{
"rv64i_m/D/d_fmin_b1-01", "8430",
"rv64i_m/D/d_fmin_b19-01", "d4b0",
"rv64i_m/D/d_fmsub_b14-01", "3fd0",
"rv64i_m/D/d_fmsub_b16-01", "43b0",
"rv64i_m/D/d_fmsub_b17-01", "43b0",
"rv64i_m/D/d_fmsub_b18-01", "5a20",
// "rv64i_m/D/d_fmsub_b16-01", "43b0", // memfile
// "rv64i_m/D/d_fmsub_b17-01", "43b0",
// "rv64i_m/D/d_fmsub_b18-01", "5a20", // memfile
"rv64i_m/D/d_fmsub_b2-01", "5ab0",
"rv64i_m/D/d_fmsub_b3-01", "119f0",
"rv64i_m/D/d_fmsub_b4-01", "3df0",
@ -1173,9 +1173,9 @@ string imperas32f[] = '{
"rv64i_m/D/d_fnmadd_b14-01", "3fd0",
"rv64i_m/D/d_fnmadd_b16-01", "4390",
"rv64i_m/D/d_fnmadd_b17-01", "4390",
"rv64i_m/D/d_fnmadd_b18-01", "5a20",
// "rv64i_m/D/d_fnmadd_b18-01", "5a20", // memfile
"rv64i_m/D/d_fnmadd_b2-01", "5ab0",
"rv64i_m/D/d_fnmadd_b3-01", "119d0",
// "rv64i_m/D/d_fnmadd_b3-01", "119d0", // memfile
"rv64i_m/D/d_fnmadd_b4-01", "3df0",
"rv64i_m/D/d_fnmadd_b5-01", "4480",
"rv64i_m/D/d_fnmadd_b6-01", "3df0",
@ -1183,28 +1183,28 @@ string imperas32f[] = '{
"rv64i_m/D/d_fnmadd_b8-01", "15aa0",
"rv64i_m/D/d_fnmsub_b14-01", "3fd0",
"rv64i_m/D/d_fnmsub_b16-01", "4390",
"rv64i_m/D/d_fnmsub_b17-01", "4390",
"rv64i_m/D/d_fnmsub_b18-01", "5a20",
// "rv64i_m/D/d_fnmsub_b17-01", "4390", // memfile - there's a "it" in the file
// "rv64i_m/D/d_fnmsub_b18-01", "5a20", // memfile
"rv64i_m/D/d_fnmsub_b2-01", "5aa0",
"rv64i_m/D/d_fnmsub_b3-01", "119d0",
"rv64i_m/D/d_fnmsub_b4-01", "3e20",
"rv64i_m/D/d_fnmsub_b5-01", "4480",
"rv64i_m/D/d_fnmsub_b6-01", "3e10",
"rv64i_m/D/d_fnmsub_b7-01", "6050",
"rv64i_m/D/d_fnmsub_b8-01", "15aa0",
// "rv64i_m/D/d_fnmsub_b8-01", "15aa0", // memfile - not obvious have to check with .elf.debug
"rv64i_m/D/d_fsd-align-01", "2010",
"rv64i_m/D/d_fsgnj_b1-01", "8430",
"rv64i_m/D/d_fsgnjn_b1-01", "8430",
"rv64i_m/D/d_fsgnjx_b1-01", "8430",
"rv64i_m/D/d_fsqrt_b1-01", "2110",
"rv64i_m/D/d_fsqrt_b20-01", "3460",
"rv64i_m/D/d_fsqrt_b2-01", "2190",
"rv64i_m/D/d_fsqrt_b3-01", "2120",
"rv64i_m/D/d_fsqrt_b4-01", "2110",
"rv64i_m/D/d_fsqrt_b5-01", "2110",
"rv64i_m/D/d_fsqrt_b7-01", "2110",
"rv64i_m/D/d_fsqrt_b8-01", "2110",
"rv64i_m/D/d_fsqrt_b9-01", "4c10",
// "rv64i_m/D/d_fsqrt_b1-01", "2110", // flg
// "rv64i_m/D/d_fsqrt_b20-01", "3460", // flg
// "rv64i_m/D/d_fsqrt_b2-01", "2190", // flg - I'm going to stop here with the sqrt
// "rv64i_m/D/d_fsqrt_b3-01", "2120",
// "rv64i_m/D/d_fsqrt_b4-01", "2110",
// "rv64i_m/D/d_fsqrt_b5-01", "2110",
// "rv64i_m/D/d_fsqrt_b7-01", "2110",
// "rv64i_m/D/d_fsqrt_b8-01", "2110",
// "rv64i_m/D/d_fsqrt_b9-01", "4c10",
"rv64i_m/D/d_fsub_b10-01", "8660",
"rv64i_m/D/d_fsub_b1-01", "8440",
"rv64i_m/D/d_fsub_b11-01", "74da0",
@ -1252,37 +1252,37 @@ string imperas32f[] = '{
string arch32f[] = '{
`RISCVARCHTEST,
// "rv32i_m/F/fadd_b1-01", "7220",
// "rv32i_m/F/fadd_b10-01", "2270",
// "rv32i_m/F/fadd_b11-01", "3fb40",
// "rv32i_m/F/fadd_b12-01", "21b0",
// "rv32i_m/F/fadd_b13-01", "3660",
// "rv32i_m/F/fadd_b2-01", "38b0",
// "rv32i_m/F/fadd_b3-01", "b320",
// "rv32i_m/F/fadd_b4-01", "3480",
// "rv32i_m/F/fadd_b5-01", "3700",
// "rv32i_m/F/fadd_b7-01", "3520",
// "rv32i_m/F/fadd_b8-01", "104a0",
"rv32i_m/F/fadd_b1-01", "7220",
"rv32i_m/F/fadd_b10-01", "2270",
"rv32i_m/F/fadd_b11-01", "3fb40",
"rv32i_m/F/fadd_b12-01", "21b0",
"rv32i_m/F/fadd_b13-01", "3660",
"rv32i_m/F/fadd_b2-01", "38b0",
"rv32i_m/F/fadd_b3-01", "b320",
"rv32i_m/F/fadd_b4-01", "3480",
"rv32i_m/F/fadd_b5-01", "3700",
"rv32i_m/F/fadd_b7-01", "3520",
"rv32i_m/F/fadd_b8-01", "104a0",
"rv32i_m/F/fclass_b1-01", "2090",
"rv32i_m/F/fcvt.s.w_b25-01", "20a0",
"rv32i_m/F/fcvt.s.w_b26-01", "3290",
"rv32i_m/F/fcvt.s.wu_b25-01", "20a0",
"rv32i_m/F/fcvt.s.wu_b26-01", "3290",
// "rv32i_m/F/fcvt.w.s_b1-01", "2090",
// "rv32i_m/F/fcvt.w.s_b22-01", "20b0",
// "rv32i_m/F/fcvt.w.s_b23-01", "20c0",
// "rv32i_m/F/fcvt.w.s_b24-01", "21b0",
// "rv32i_m/F/fcvt.w.s_b27-01", "2090",
// "rv32i_m/F/fcvt.w.s_b28-01", "2090",
// "rv32i_m/F/fcvt.w.s_b29-01", "2150",
// "rv32i_m/F/fcvt.wu.s_b1-01", "2090",
// "rv32i_m/F/fcvt.wu.s_b22-01", "20b0",
// "rv32i_m/F/fcvt.wu.s_b23-01", "20c0",
// "rv32i_m/F/fcvt.wu.s_b24-01", "21b0",
// "rv32i_m/F/fcvt.wu.s_b27-01", "2090",
// "rv32i_m/F/fcvt.wu.s_b28-01", "2090",
// "rv32i_m/F/fcvt.wu.s_b29-01", "2150",
// "rv32i_m/F/fdiv_b1-01", "7220",
"rv32i_m/F/fcvt.w.s_b1-01", "2090",
"rv32i_m/F/fcvt.w.s_b22-01", "20b0",
"rv32i_m/F/fcvt.w.s_b23-01", "20c0",
"rv32i_m/F/fcvt.w.s_b24-01", "21b0",
"rv32i_m/F/fcvt.w.s_b27-01", "2090",
"rv32i_m/F/fcvt.w.s_b28-01", "2090",
"rv32i_m/F/fcvt.w.s_b29-01", "2150",
"rv32i_m/F/fcvt.wu.s_b1-01", "2090",
"rv32i_m/F/fcvt.wu.s_b22-01", "20b0",
"rv32i_m/F/fcvt.wu.s_b23-01", "20c0",
"rv32i_m/F/fcvt.wu.s_b24-01", "21b0",
"rv32i_m/F/fcvt.wu.s_b27-01", "2090",
"rv32i_m/F/fcvt.wu.s_b28-01", "2090",
"rv32i_m/F/fcvt.wu.s_b29-01", "2150",
// "rv32i_m/F/fdiv_b1-01", "7220", // NaN i'm going to skip div, probably the same problems as the double version
// "rv32i_m/F/fdiv_b2-01", "2350",
// "rv32i_m/F/fdiv_b20-01", "38c0",
// "rv32i_m/F/fdiv_b21-01", "7540",
@ -1293,41 +1293,41 @@ string imperas32f[] = '{
// "rv32i_m/F/fdiv_b7-01", "3520",
// "rv32i_m/F/fdiv_b8-01", "104a0",
// "rv32i_m/F/fdiv_b9-01", "d960",
// "rv32i_m/F/feq_b1-01", "6220",
// "rv32i_m/F/feq_b19-01", "a190",
// "rv32i_m/F/fle_b1-01", "6220",
// "rv32i_m/F/fle_b19-01", "a190",
// "rv32i_m/F/flt_b1-01", "6220",
// "rv32i_m/F/flt_b19-01", "8ee0",
"rv32i_m/F/feq_b1-01", "6220",
"rv32i_m/F/feq_b19-01", "a190",
"rv32i_m/F/fle_b1-01", "6220",
// "rv32i_m/F/fle_b19-01", "a190", // looks fine to me is the actual input value supposed to be infinity?
"rv32i_m/F/flt_b1-01", "6220",
// "rv32i_m/F/flt_b19-01", "8ee0", // memfile
"rv32i_m/F/flw-align-01", "2010",
"rv32i_m/F/fmadd_b1-01", "96860",
"rv32i_m/F/fmadd_b14-01", "23d0",
//--passes but is timeconsuming "rv32i_m/F/fmadd_b15-01", "19bb30",
// --passes but is timeconsuming "rv32i_m/F/fmadd_b15-01", "19bb30",
"rv32i_m/F/fmadd_b16-01", "39d0",
"rv32i_m/F/fmadd_b17-01", "39d0",
"rv32i_m/F/fmadd_b18-01", "4d10",
// "rv32i_m/F/fmadd_b18-01", "4d10", // memfile - incorrect last value - ln 4931 supposed to be 71bffff8
"rv32i_m/F/fmadd_b2-01", "4d60",
"rv32i_m/F/fmadd_b3-01", "d4f0",
"rv32i_m/F/fmadd_b4-01", "3700",
"rv32i_m/F/fmadd_b5-01", "3ac0",
"rv32i_m/F/fmadd_b6-01", "3700",
// "rv32i_m/F/fmadd_b7-01", "d7f0",
// "rv32i_m/F/fmadd_b8-01", "13f30",
// "rv32i_m/F/fmax_b1-01", "7220",
// "rv32i_m/F/fmax_b19-01", "9e00",
// "rv32i_m/F/fmin_b1-01", "7220",
// "rv32i_m/F/fmin_b19-01", "9f20",
// "rv32i_m/F/fmadd_b7-01", "d7f0", // input values aren't even in the memfile are being used in the test
// "rv32i_m/F/fmadd_b8-01", "13f30", // memfile incorrect input - last test input Z
"rv32i_m/F/fmax_b1-01", "7220",
"rv32i_m/F/fmax_b19-01", "9e00",
"rv32i_m/F/fmin_b1-01", "7220",
"rv32i_m/F/fmin_b19-01", "9f20",
"rv32i_m/F/fmsub_b1-01", "96860",
"rv32i_m/F/fmsub_b14-01", "23d0",
// "rv32i_m/F/fmsub_b15-01", "19bb30",
"rv32i_m/F/fmsub_b15-01", "19bb30",
"rv32i_m/F/fmsub_b16-01", "39d0",
"rv32i_m/F/fmsub_b17-01", "39d0",
"rv32i_m/F/fmsub_b18-01", "42d0",
// "rv32i_m/F/fmsub_b18-01", "42d0", // test looks fine to me: 7e9db2ee (large number) * -0 - f1bffff8 = f1bffff8 but wants 7f800000 (NaN)
"rv32i_m/F/fmsub_b2-01", "4d60",
"rv32i_m/F/fmsub_b3-01", "d4f0",
"rv32i_m/F/fmsub_b4-01", "3700",
"rv32i_m/F/fmsub_b5-01", "3ac0",
"rv32i_m/F/fmsub_b6-01", "3700",
// "rv32i_m/F/fmsub_b6-01", "3700", // memfile
"rv32i_m/F/fmsub_b7-01", "37f0",
"rv32i_m/F/fmsub_b8-01", "13f30",
"rv32i_m/F/fmul_b1-01", "7220",
@ -1335,7 +1335,7 @@ string imperas32f[] = '{
"rv32i_m/F/fmul_b3-01", "b320",
"rv32i_m/F/fmul_b4-01", "3480",
"rv32i_m/F/fmul_b5-01", "3700",
"rv32i_m/F/fmul_b6-01", "3480",
// "rv32i_m/F/fmul_b6-01", "3480", // memfile
"rv32i_m/F/fmul_b7-01", "3520",
"rv32i_m/F/fmul_b8-01", "104a0",
"rv32i_m/F/fmul_b9-01", "d960",
@ -1353,7 +1353,7 @@ string imperas32f[] = '{
// timeconsuming "rv32i_m/F/fnmadd_b15-01", "19bb40",
"rv32i_m/F/fnmadd_b16-01", "39d0",
"rv32i_m/F/fnmadd_b17-01", "39d0",
"rv32i_m/F/fnmadd_b18-01", "4d10",
// "rv32i_m/F/fnmadd_b18-01", "4d10", // memfile
"rv32i_m/F/fnmadd_b2-01", "4d60",
"rv32i_m/F/fnmadd_b3-01", "d4f0",
"rv32i_m/F/fnmadd_b4-01", "3700",
@ -1362,30 +1362,30 @@ string imperas32f[] = '{
"rv32i_m/F/fnmadd_b7-01", "37f0",
"rv32i_m/F/fnmadd_b8-01", "13f30",
"rv32i_m/F/fnmsub_b1-01", "96870",
"rv32i_m/F/fnmsub_b14-01", "23d0",
// "rv32i_m/F/fnmsub_b14-01", "23d0", // memfile
// timeconsuming "rv32i_m/F/fnmsub_b15-01", "19bb30",
"rv32i_m/F/fnmsub_b16-01", "39d0",
"rv32i_m/F/fnmsub_b17-01", "39d0",
"rv32i_m/F/fnmsub_b18-01", "4d10",
// "rv32i_m/F/fnmsub_b18-01", "4d10", // memfile
"rv32i_m/F/fnmsub_b2-01", "4d60",
"rv32i_m/F/fnmsub_b3-01", "4df0",
// "rv32i_m/F/fnmsub_b3-01", "4df0", // inputs that don't exist in memfile
"rv32i_m/F/fnmsub_b4-01", "3700",
"rv32i_m/F/fnmsub_b5-01", "3ac0",
"rv32i_m/F/fnmsub_b6-01", "3700",
"rv32i_m/F/fnmsub_b7-01", "37f0",
// "rv32i_m/F/fnmsub_b7-01", "37f0", // memfile last input merged with a deadbeef
"rv32i_m/F/fnmsub_b8-01", "13f30",
"rv32i_m/F/fsgnj_b1-01", "7220",
"rv32i_m/F/fsgnjn_b1-01", "7220",
"rv32i_m/F/fsgnjx_b1-01", "7220",
"rv32i_m/F/fsqrt_b1-01", "2090",
"rv32i_m/F/fsqrt_b2-01", "2090",
"rv32i_m/F/fsqrt_b20-01", "2090",
"rv32i_m/F/fsqrt_b3-01", "2090",
"rv32i_m/F/fsqrt_b4-01", "2090",
"rv32i_m/F/fsqrt_b5-01", "2090",
"rv32i_m/F/fsqrt_b7-01", "2090",
"rv32i_m/F/fsqrt_b8-01", "2090",
"rv32i_m/F/fsqrt_b9-01", "3310",
// "rv32i_m/F/fsqrt_b1-01", "2090", // flag i am skiping sqrt
// "rv32i_m/F/fsqrt_b2-01", "2090",
// "rv32i_m/F/fsqrt_b20-01", "2090",
// "rv32i_m/F/fsqrt_b3-01", "2090",
// "rv32i_m/F/fsqrt_b4-01", "2090",
// "rv32i_m/F/fsqrt_b5-01", "2090",
// "rv32i_m/F/fsqrt_b7-01", "2090",
// "rv32i_m/F/fsqrt_b8-01", "2090",
// "rv32i_m/F/fsqrt_b9-01", "3310",
"rv32i_m/F/fsub_b1-01", "7220",
"rv32i_m/F/fsub_b10-01", "2250",
"rv32i_m/F/fsub_b11-01", "3fb40",
@ -1395,7 +1395,7 @@ string imperas32f[] = '{
"rv32i_m/F/fsub_b3-01", "b320",
"rv32i_m/F/fsub_b4-01", "3480",
"rv32i_m/F/fsub_b5-01", "3700",
"rv32i_m/F/fsub_b7-01", "3520",
// "rv32i_m/F/fsub_b7-01", "3520", // memfile
"rv32i_m/F/fsub_b8-01", "104a0",
"rv32i_m/F/fsw-align-01", "2010"
};