All compare instructions pass imperas tests

This commit is contained in:
Katherine Parry 2021-05-27 15:23:28 -04:00
parent 309e6c3dc1
commit 1459d840ed
8 changed files with 63 additions and 46 deletions

View File

@ -158,7 +158,7 @@ module fctrl (
// fsqrt = ???1
3'b000 : begin FOpCtrlD = {3'b0, Funct7D[5]}; FInput2UsedD = ~Funct7D[5]; end
// cmp
// fmin = ?100
// fmin = ?111
// fmax = ?101
// feq = ?010
// flt = ?001

View File

@ -40,7 +40,7 @@ module fpu (
output logic [31:0] FSROutW,
output logic [1:0] FMemRWM,
output logic FStallD,
output logic FWriteIntM, FWriteIntW,
output logic FWriteIntE, FWriteIntM, FWriteIntW,
output logic [`XLEN-1:0] FWriteDataM,
output logic FDivSqrtDoneM,
output logic IllegalFPUInstrD,
@ -55,7 +55,7 @@ module fpu (
logic [2:0] FrmD, FrmE, FrmM, FrmW; // FP rounding mode
logic FmtD, FmtE, FmtM, FmtW; // FP precision 0-single 1-double
logic FDivStartD, FDivStartE; // Start division
logic FWriteIntD, FWriteIntE; // Write to integer register
logic FWriteIntD; // Write to integer register
logic FOutputInput2D, FOutputInput2E; // Put Input2 in Input1 if a store instruction
logic [1:0] FMemRWD, FMemRWE; // Read and write enable for memory
logic [1:0] FForwardInput1D, FForwardInput1E; // Input1 forwarding mux control signal
@ -151,7 +151,7 @@ module fpu (
logic BzeroE, BzeroM;
logic CmpInvalidM, CmpInvalidW;
logic [1:0] CmpFCCM, CmpFCCW;
logic [63:0] FCmpResultW;
logic [63:0] FCmpResultM, FCmpResultW;
// fsgn signals
logic [63:0] SgnResultE, SgnResultM, SgnResultW;
@ -415,7 +415,7 @@ module fpu (
fpuaddcvt2 fpadd2 (.*);
//second instance of two-stage floating-point comparator
fpucmp2 fpcmp2 (CmpInvalidM, CmpFCCM, ANaNM, BNaNM, AzeroM, BzeroM, WM, XM, {1'b0, FmtM}, FInput1M, FInput2M);
fpucmp2 fpcmp2 (.Invalid(CmpInvalidM), .FCC(CmpFCCM), .ANaN(ANaNM), .BNaN(BNaNM), .Azero(AzeroM), .Bzero(BzeroM), .w(WM), .x(XM), .Sel({1'b0, FmtM}), .op1(FInput1M), .op2(FInput2M), .*);
@ -451,6 +451,7 @@ module fpu (
//*****************
flopenrc #(1) MWRegCmp1(clk, reset, PipeClearMW, PipeEnableMW, CmpInvalidM, CmpInvalidW);
flopenrc #(2) MWRegCmp2(clk, reset, PipeClearMW, PipeEnableMW, CmpFCCM, CmpFCCW);
flopenrc #(64) MWRegCmp3(clk, reset, PipeClearMW, PipeEnableMW, FCmpResultM, FCmpResultW);
//*****************
//fpsgn M/W pipe registers

View File

@ -37,17 +37,18 @@
// It also produces an invalid operation flag, which is one
// if either of the input operands is a signaling NaN per 754
module fpucmp2 (Invalid, FCC, ANaN, BNaN, Azero, Bzero, w, x, Sel, op1, op2);
module fpucmp2 (
input logic [63:0] op1,
input logic [63:0] op2,
input logic [1:0] Sel,
input logic [7:0] w, x,
input logic ANaN, BNaN,
input logic Azero, Bzero,
input logic [3:0] FOpCtrlM,
input logic [63:0] op1;
input logic [63:0] op2;
input logic [1:0] Sel;
input logic [7:0] w, x;
input logic ANaN, BNaN;
input logic Azero, Bzero;
output logic Invalid; // Invalid Operation
output logic [1:0] FCC; // Condition Codes
output logic Invalid, // Invalid Operation
output logic [1:0] FCC, // Condition Codes
output logic [63:0] FCmpResultM);
logic LT; // magnitude op1 < magnitude op2
logic EQ; // magnitude op1 = magnitude op2
@ -59,7 +60,7 @@ module fpucmp2 (Invalid, FCC, ANaN, BNaN, Azero, Bzero, w, x, Sel, op1, op2);
// 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(ANaN), .BNaN(BNaN), .Azero(Azero), .Bzero(Bzero), .Sel(Sel), .A(op1), .B(op2));
exception_cmp_2 exc2 (.invalid(Invalid), .fcc(FCC), .LT_mag(LT), .EQ_mag(EQ), .ANaN(ANaN), .BNaN(BNaN), .Azero(Azero), .Bzero(Bzero), .Sel(Sel), .A(op1), .B(op2), .*);
endmodule // fpcomp
@ -156,24 +157,26 @@ endmodule // magcompare64b
// It also produces a invalid operation flag, which is one
// if either of the input operands is a signaling NaN.
module exception_cmp_2 (invalid, fcc, LT_mag, EQ_mag, ANaN, BNaN, Azero, Bzero, Sel, A, B);
input logic [63:0] A;
input logic [63:0] B;
input logic LT_mag;
input logic EQ_mag;
input logic [1:0] Sel;
module exception_cmp_2 (
input logic [63:0] A,
input logic [63:0] B,
input logic LT_mag,
input logic EQ_mag,
input logic [1:0] Sel,
input logic [3:0] FOpCtrlM,
output logic invalid;
output logic [1:0] fcc;
output logic invalid,
output logic [1:0] fcc,
output logic [63:0] FCmpResultM,
input logic Azero,
input logic Bzero,
input logic ANaN,
input logic BNaN);
logic dp;
logic sp;
logic hp;
input logic Azero;
input logic Bzero;
input logic ANaN;
input logic BNaN;
logic ASNaN;
logic BSNaN;
logic UO;
@ -221,6 +224,17 @@ module exception_cmp_2 (invalid, fcc, LT_mag, EQ_mag, ANaN, BNaN, Azero, Bzero,
// Set the bits of fcc based on LT, GT, EQ, and UO
assign fcc[0] = LT | UO;
assign fcc[1] = GT | UO;
assign fcc[1] = GT | UO;
always_comb begin
case (FOpCtrlM[2:0])
3'b111: FCmpResultM = LT ? A : B;//min
3'b101: FCmpResultM = GT ? A : B;//max
3'b010: FCmpResultM = {63'b0, EQ};//equal
3'b001: FCmpResultM = {63'b0, LT};//less than
3'b011: FCmpResultM = {63'b0, LT | EQ};//less than or equal
default: FCmpResultM = 64'b0;
endcase
end
endmodule // exception_cmp

View File

@ -30,7 +30,7 @@ module hazard(
input logic reset,
// Detect hazards
input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
input logic LoadStallD, MulDivStallD, CSRRdStallD,
input logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD,
input logic DataStall, ICacheStallF,
input logic FStallD,
input logic DivBusyE,
@ -59,7 +59,7 @@ module hazard(
assign BranchFlushDE = BPPredWrongE | RetM | TrapM;
assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE);
assign StallDCause = (LoadStallD | MulDivStallD | CSRRdStallD | FStallD) & ~(BranchFlushDE); // stall in decode if instruction is a load/mul/csr dependent on previous
assign StallDCause = (FPUStallD | LoadStallD | MulDivStallD | CSRRdStallD | FStallD) & ~(BranchFlushDE); // stall in decode if instruction is a load/mul/csr dependent on previous
// assign StallDCause = LoadStallD | MulDivStallD | CSRRdStallD; // stall in decode if instruction is a load/mul/csr dependent on previous
assign StallECause = DivBusyE;
assign StallMCause = 0;

View File

@ -31,10 +31,10 @@ module forward(
input logic MemReadE, MulDivE, CSRReadE,
input logic RegWriteM, RegWriteW,
input logic DivDoneE, DivBusyE,
input logic FWriteIntM, FWriteIntW,
input logic FWriteIntE, FWriteIntM, FWriteIntW,
// Forwarding controls
output logic [1:0] ForwardAE, ForwardBE,
output logic LoadStallD, MulDivStallD, CSRRdStallD
output logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD
);
always_comb begin
@ -52,6 +52,7 @@ module forward(
end
// Stall on dependent operations that finish in Mem Stage and can't bypass in time
assign FPUStallD = FWriteIntE & ((Rs1D == RdE) | (Rs2D == RdE));
assign LoadStallD = MemReadE & ((Rs1D == RdE) | (Rs2D == RdE));
assign MulDivStallD = MulDivE & ((Rs1D == RdE) | (Rs2D == RdE)) | MulDivE | DivBusyE; // *** extend with stalls for divide
assign CSRRdStallD = CSRReadE & ((Rs1D == RdE) | (Rs2D == RdE));

View File

@ -35,6 +35,7 @@ module ieu (
// Execute Stage interface
input logic [`XLEN-1:0] PCE,
input logic [`XLEN-1:0] PCLinkE,
input logic FWriteIntE,
output logic [`XLEN-1:0] PCTargetE,
output logic MulDivE, W64E,
output logic [2:0] Funct3E,
@ -59,7 +60,7 @@ module ieu (
// hazards
input logic StallE, StallM, StallW,
input logic FlushE, FlushM, FlushW,
output logic LoadStallD, MulDivStallD, CSRRdStallD,
output logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD,
output logic PCSrcE,
input logic DivDoneE,
input logic DivBusyE,

View File

@ -86,7 +86,7 @@ module wallypipelinedhart (
logic PCSrcE;
logic CSRWritePendingDEM;
logic LoadStallD, MulDivStallD, CSRRdStallD;
logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD;
logic DivDoneE;
logic DivBusyE;
logic DivDoneW;
@ -98,7 +98,7 @@ module wallypipelinedhart (
logic [`XLEN-1:0] FWriteDataM;
logic SquashSCW;
logic FStallD;
logic FWriteIntW, FWriteIntM;
logic FWriteIntE, FWriteIntW, FWriteIntM;
logic [31:0] FSROutW;
logic FDivSqrtDoneM;
logic IllegalFPUInstrD, IllegalFPUInstrE;

View File

@ -118,6 +118,11 @@ string tests32f[] = '{
};
string tests64d[] = '{
"rv64d/I-FMAX-D-01", "2000",
"rv64d/I-FMIN-D-01", "2000",
"rv64d/I-FLE-D-01", "2000",
"rv64d/I-FLT-D-01", "2000",
"rv64d/I-FEQ-D-01", "2000",
"rv64d/I-FADD-D-01", "2000",
// "rv64d/I-FCLASS-D-01", "2000",
// "rv64d/I-FCVT-D-L-01", "2000",
@ -131,23 +136,18 @@ string tests32f[] = '{
// "rv64d/I-FCVT-W-D-01", "2000",
// "rv64d/I-FCVT-WU-D-01", "2000",
// "rv64d/I-FDIV-D-01", "2000",
// "rv64d/I-FEQ-D-01", "2000",
"rv64d/I-FSD-01", "2000",
"rv64d/I-FLD-01", "2420",
// "rv64d/I-FLE-D-01", "2000",
// "rv64d/I-FLT-D-01", "2000",
// "rv64d/I-FMADD-D-01", "2000",
// "rv64d/I-FMAX-D-01", "2000",
// "rv64d/I-FMIN-D-01", "2000",
"rv64d/I-FMADD-D-01", "2000",
// "rv64d/I-FMSUB-D-01", "2000",
// "rv64d/I-FMUL-D-01", "2000",
"rv64d/I-FMV-D-X-01", "2000",
"rv64d/I-FMV-X-D-01", "2000",
// "rv64d/I-FNMADD-D-01", "2000",
// "rv64d/I-FNMSUB-D-01", "2000",
// "rv64d/I-FSGNJ-D-01", "2000",
// "rv64d/I-FSGNJN-D-01", "2000",
// "rv64d/I-FSGNJX-D-01", "2000",
"rv64d/I-FSGNJ-D-01", "2000",
"rv64d/I-FSGNJN-D-01", "2000",
"rv64d/I-FSGNJX-D-01", "2000",
// "rv64d/I-FSQRTD-01", "2000",
"rv64d/I-FSUB-D-01", "2000"
};