From 1459d840eda2d4672a977d017ac33496e3aa6c5c Mon Sep 17 00:00:00 2001 From: Katherine Parry Date: Thu, 27 May 2021 15:23:28 -0400 Subject: [PATCH] All compare instructions pass imperas tests --- wally-pipelined/src/fpu/fctrl.sv | 2 +- wally-pipelined/src/fpu/fpu.sv | 9 +-- wally-pipelined/src/fpu/fpucmp2.sv | 64 +++++++++++-------- wally-pipelined/src/hazard/hazard.sv | 4 +- wally-pipelined/src/ieu/forward.sv | 5 +- wally-pipelined/src/ieu/ieu.sv | 3 +- .../src/wally/wallypipelinedhart.sv | 4 +- .../testbench/testbench-imperas.sv | 18 +++--- 8 files changed, 63 insertions(+), 46 deletions(-) diff --git a/wally-pipelined/src/fpu/fctrl.sv b/wally-pipelined/src/fpu/fctrl.sv index e925ad13..220ccd8f 100755 --- a/wally-pipelined/src/fpu/fctrl.sv +++ b/wally-pipelined/src/fpu/fctrl.sv @@ -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 diff --git a/wally-pipelined/src/fpu/fpu.sv b/wally-pipelined/src/fpu/fpu.sv index 34db50e7..aa1039be 100755 --- a/wally-pipelined/src/fpu/fpu.sv +++ b/wally-pipelined/src/fpu/fpu.sv @@ -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 diff --git a/wally-pipelined/src/fpu/fpucmp2.sv b/wally-pipelined/src/fpu/fpucmp2.sv index 766f7f57..e2820688 100755 --- a/wally-pipelined/src/fpu/fpucmp2.sv +++ b/wally-pipelined/src/fpu/fpucmp2.sv @@ -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 diff --git a/wally-pipelined/src/hazard/hazard.sv b/wally-pipelined/src/hazard/hazard.sv index 7bd59286..35aa9835 100644 --- a/wally-pipelined/src/hazard/hazard.sv +++ b/wally-pipelined/src/hazard/hazard.sv @@ -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; diff --git a/wally-pipelined/src/ieu/forward.sv b/wally-pipelined/src/ieu/forward.sv index f00a6ecb..cdc6d270 100644 --- a/wally-pipelined/src/ieu/forward.sv +++ b/wally-pipelined/src/ieu/forward.sv @@ -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)); diff --git a/wally-pipelined/src/ieu/ieu.sv b/wally-pipelined/src/ieu/ieu.sv index 8b1993be..a4ab9b06 100644 --- a/wally-pipelined/src/ieu/ieu.sv +++ b/wally-pipelined/src/ieu/ieu.sv @@ -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, diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index eab0885d..e49cc6c6 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -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; diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 5636455b..b8f97b26 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -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" };