Zfa fli support working for F and D

This commit is contained in:
David Harris 2024-01-16 17:27:40 -08:00
parent 29eba93bfa
commit 0588d611ea
3 changed files with 18 additions and 4 deletions

View File

@ -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 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) 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 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) 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) 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) 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) ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q)
// coverage off // 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) 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) 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) 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) ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d)
// coverage on // 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 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu
endcase endcase
// coverage off // coverage off
// Not covered in testing because rv64gc does not support half or quad precision
7'b1101010: case(Rs2D) 7'b1101010: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h 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 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'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 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h h->lu
endcase endcase
// Not covered in testing because rv64gc does not support quad precision
7'b1101011: case(Rs2D) 7'b1101011: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.q.w w->q 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 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 // 011 - mv to fp 01
// 110 - min 10 // 110 - min 10
// 101 - max 10 // 101 - max 10
// 111 - fli 11
// OpCtrl: // OpCtrl:
// Fma: {not multiply-add?, negate prod?, negate Z?} // Fma: {not multiply-add?, negate prod?, negate Z?}

View File

@ -160,6 +160,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt
logic [P.FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer logic [P.FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer
logic mvsgn; // sign bit for extending move 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 // 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), .ToInt(FWriteIntE), .XZero(XZeroE), .Fmt(FmtE), .Ce(CeE), .ShiftAmt(CvtShiftAmtE),
.ResSubnormUf(CvtResSubnormUfE), .Cs(CsE), .IntZero(IntZeroE), .LzcIn(CvtLzcInE)); .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 // 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}; if(P.FPSIZES == 1) assign AlignedSrcAE = {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE};
else if(P.FPSIZES == 2) else if(P.FPSIZES == 2)
@ -276,7 +285,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
end end
// select a result that may be written to the FP register // 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); assign PreNVE = CmpNVE&(OpCtrlE[2]|FWriteIntE);
// select the result that may be written to the integer register with fmv.x.* // select the result that may be written to the integer register with fmv.x.*

View File

@ -128,7 +128,8 @@ module testbench;
"arch64zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch64zicboz; "arch64zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch64zicboz;
"arch64zcb": if (P.ZCB_SUPPORTED) tests = arch64zcb; "arch64zcb": if (P.ZCB_SUPPORTED) tests = arch64zcb;
"arch64zfh": if (P.ZFH_SUPPORTED) tests = arch64zfh; "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 endcase
end else begin // RV32 end else begin // RV32
case (TEST) case (TEST)
@ -165,6 +166,7 @@ module testbench;
"arch32zcb": if (P.ZCB_SUPPORTED) tests = arch32zcb; "arch32zcb": if (P.ZCB_SUPPORTED) tests = arch32zcb;
"arch32zfh": if (P.ZFH_SUPPORTED) tests = arch32zfh; "arch32zfh": if (P.ZFH_SUPPORTED) tests = arch32zfh;
"arch32zfaf": if (P.ZFA_SUPPORTED) tests = arch32zfaf; "arch32zfaf": if (P.ZFA_SUPPORTED) tests = arch32zfaf;
"arch32zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch32zfad;
endcase endcase
end end
if (tests.size() == 0) begin if (tests.size() == 0) begin