From 0588d611ead1deb5379be81a93b1f7ebb5859dfa Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 16 Jan 2024 17:27:40 -0800 Subject: [PATCH] Zfa fli support working for F and D --- src/fpu/fctrl.sv | 7 +++++-- src/fpu/fpu.sv | 11 ++++++++++- testbench/testbench.sv | 4 +++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index 999837889..d4cc60e87 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -143,14 +143,16 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0; // fmv.x.w/d/h/q fp to int register 7'b11110??: if (Funct3D == 3'b000 & Rs2D == 5'b00000) ControlsD = `FCTRLW'b1_0_00_00_011_0_0_0; // fmv.w/d/h/q.x int to fp reg + else if (P.ZFA_SUPPORTED & Funct3D == 3'b000 & Rs2D == 5'b00001) + ControlsD = `FCTRLW'b1_0_00_00_111_0_0_0; // fli 7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00) ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h) 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) // coverage off - // Not covered in testing because rv64gc does not support half or quad precision 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) + // Not covered in testing because rv64gc does not support quad precision 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) // coverage on @@ -179,7 +181,6 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu endcase // coverage off - // Not covered in testing because rv64gc does not support half or quad precision 7'b1101010: case(Rs2D) 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h @@ -192,6 +193,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.h h->l 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h h->lu endcase + // Not covered in testing because rv64gc does not support quad precision 7'b1101011: case(Rs2D) 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.q.w w->q 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.q.wu wu->q @@ -274,6 +276,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( // 011 - mv to fp 01 // 110 - min 10 // 101 - max 10 + // 111 - fli 11 // OpCtrl: // Fma: {not multiply-add?, negate prod?, negate Z?} diff --git a/src/fpu/fpu.sv b/src/fpu/fpu.sv index 45af38c0c..8be0e4488 100755 --- a/src/fpu/fpu.sv +++ b/src/fpu/fpu.sv @@ -160,6 +160,7 @@ module fpu import cvw::*; #(parameter cvw_t P) ( logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt logic [P.FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer logic mvsgn; // sign bit for extending move + logic [P.FLEN-1:0] FliResE; // Floating-point load immediate value ////////////////////////////////////////////////////////////////////////////////////////// // Decode Stage: fctrl decoder, read register file @@ -263,6 +264,14 @@ module fpu import cvw::*; #(parameter cvw_t P) ( .ToInt(FWriteIntE), .XZero(XZeroE), .Fmt(FmtE), .Ce(CeE), .ShiftAmt(CvtShiftAmtE), .ResSubnormUf(CvtResSubnormUfE), .Cs(CsE), .IntZero(IntZeroE), .LzcIn(CvtLzcInE)); + // floating-point load immediate: fli + if (P.ZFA_SUPPORTED) begin + logic [4:0] Rs1E; + + flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, InstrD[19:15], Rs1E); + fli #(P) fli(.Rs1(Rs1E), .Fmt(FmtE), .Imm(FliResE)); + end else assign FliResE = '0; + // NaN Box SrcA to convert integer to requested FP size for fmv.*.x if(P.FPSIZES == 1) assign AlignedSrcAE = {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE}; else if(P.FPSIZES == 2) @@ -276,7 +285,7 @@ module fpu import cvw::*; #(parameter cvw_t P) ( end // select a result that may be written to the FP register - mux3 #(P.FLEN) FResMux(SgnResE, AlignedSrcAE, CmpFpResE, {OpCtrlE[2], &OpCtrlE[1:0]}, PreFpResE); + mux4 #(P.FLEN) FResMux(SgnResE, AlignedSrcAE, CmpFpResE, FliResE, {OpCtrlE[2], &OpCtrlE[1:0]}, PreFpResE); assign PreNVE = CmpNVE&(OpCtrlE[2]|FWriteIntE); // select the result that may be written to the integer register with fmv.x.* diff --git a/testbench/testbench.sv b/testbench/testbench.sv index efd4ea637..87b603288 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -128,7 +128,8 @@ module testbench; "arch64zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch64zicboz; "arch64zcb": if (P.ZCB_SUPPORTED) tests = arch64zcb; "arch64zfh": if (P.ZFH_SUPPORTED) tests = arch64zfh; -// "arch64zfa": if (P.ZFA_SUPPORTED) tests = arch64zfa; + "arch64zfaf": if (P.ZFA_SUPPORTED) tests = arch64zfaf; + "arch64zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch64zfad; endcase end else begin // RV32 case (TEST) @@ -165,6 +166,7 @@ module testbench; "arch32zcb": if (P.ZCB_SUPPORTED) tests = arch32zcb; "arch32zfh": if (P.ZFH_SUPPORTED) tests = arch32zfh; "arch32zfaf": if (P.ZFA_SUPPORTED) tests = arch32zfaf; + "arch32zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch32zfad; endcase end if (tests.size() == 0) begin