From b8d1fa5366ba6c98de41579628d90b17e76a5631 Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Thu, 31 Oct 2024 06:18:03 -0700 Subject: [PATCH] Add Zfhmin support Per section 24.6 of the unprivileged ISA manual: > The Zfhmin extension includes the following instructions from the Zfh extension: FLH, FSH, FMV.X.H, FMV.H.X, FCVT.S.H, and FCVT.H.S. If the D extension is present, the FCVT.D.H and FCVT.H.D instructions are also included. If the Q extension is present, the FCVT.Q.H and FCVT.H.Q instructions are additionally included. We already supported Zfh, so this is just a modification of some of the guards to enable only the supported instructions for Zfhmin. For now I have Zfhmin enabled whenever Zfh is enabled, but later it can be updated so that it can be enabled independently once we have better model configuration. --- README.md | 2 +- model/riscv_insts_fext.sail | 13 +++++++++---- model/riscv_insts_zfh.sail | 29 ++++++++++++++++------------- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 5be6cf929..09614c51f 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ Supported RISC-V ISA features - Zaamo extension for atomic memory operations, v1.0 - Zabha extension for byte and halfword atomic memory operations, v1.0 - F and D extensions for single and double-precision floating-point, v2.2 -- Zfh extension half-precision floating-point, v1.0 +- Zfh and Zfhmin extensions for half-precision floating-point, v1.0 - Zfa extension for additional floating-point instructions, v1.0 - Zfinx, Zdinx, and Zhinx extensions for floating-point in integer registers, v1.0 - C extension for compressed instructions, v2.0 diff --git a/model/riscv_insts_fext.sail b/model/riscv_insts_fext.sail index d74e8217a..e42fed4c7 100644 --- a/model/riscv_insts_fext.sail +++ b/model/riscv_insts_fext.sail @@ -25,9 +25,14 @@ /* **************************************************************** */ +// TODO: Add config flags to control Zfh and Zfhmin enum clause extension = Ext_Zfh function clause extensionEnabled(Ext_Zfh) = (misa[F] == 0b1) & (mstatus[FS] != 0b00) +enum clause extension = Ext_Zfhmin +// Zfhmin is a subset of Zfh. This can be changed to extensionEnabled(Ext_Zfh) | sys_enable_zfhmin() when more configuration is implemented. +function clause extensionEnabled(Ext_Zfhmin) = extensionEnabled(Ext_Zfh) + mapping encdec_rounding_mode : rounding_mode <-> bits(3) = { RM_RNE <-> 0b000, RM_RTZ <-> 0b001, @@ -274,8 +279,8 @@ union clause ast = LOAD_FP : (bits(12), regidx, regidx, word_width) /* AST <-> Binary encoding ================================ */ -mapping clause encdec = LOAD_FP(imm, rs1, rd, HALF) if extensionEnabled(Ext_Zfh) - <-> imm @ rs1 @ 0b001 @ rd @ 0b000_0111 if extensionEnabled(Ext_Zfh) +mapping clause encdec = LOAD_FP(imm, rs1, rd, HALF) if extensionEnabled(Ext_Zfhmin) + <-> imm @ rs1 @ 0b001 @ rd @ 0b000_0111 if extensionEnabled(Ext_Zfhmin) mapping clause encdec = LOAD_FP(imm, rs1, rd, WORD) if extensionEnabled(Ext_F) <-> imm @ rs1 @ 0b010 @ rd @ 0b000_0111 if extensionEnabled(Ext_F) @@ -360,8 +365,8 @@ union clause ast = STORE_FP : (bits(12), regidx, regidx, word_width) /* AST <-> Binary encoding ================================ */ -mapping clause encdec = STORE_FP(imm7 @ imm5, rs2, rs1, HALF) if extensionEnabled(Ext_Zfh) - <-> imm7 : bits(7) @ rs2 @ rs1 @ 0b001 @ imm5 : bits(5) @ 0b010_0111 if extensionEnabled(Ext_Zfh) +mapping clause encdec = STORE_FP(imm7 @ imm5, rs2, rs1, HALF) if extensionEnabled(Ext_Zfhmin) + <-> imm7 : bits(7) @ rs2 @ rs1 @ 0b001 @ imm5 : bits(5) @ 0b010_0111 if extensionEnabled(Ext_Zfhmin) mapping clause encdec = STORE_FP(imm7 @ imm5, rs2, rs1, WORD) if extensionEnabled(Ext_F) <-> imm7 : bits(7) @ rs2 @ rs1 @ 0b010 @ imm5 : bits(5) @ 0b010_0111 if extensionEnabled(Ext_F) diff --git a/model/riscv_insts_zfh.sail b/model/riscv_insts_zfh.sail index e484b4577..c9a84e05f 100644 --- a/model/riscv_insts_zfh.sail +++ b/model/riscv_insts_zfh.sail @@ -164,8 +164,11 @@ function fle_H (v1, v2, is_quiet) = { /* **************************************************************** */ /* Helper functions for 'encdec()' */ - +// Full half support. function haveHalfFPU() -> bool = extensionEnabled(Ext_Zfh) | extensionEnabled(Ext_Zhinx) +// Support for conversion of halves to/from single & double, but no actual +// calculations with halves. +function haveHalfMin() -> bool = haveHalfFPU() | extensionEnabled(Ext_Zfhmin) /* ****************************************************************** */ /* Floating-point loads */ @@ -538,20 +541,20 @@ mapping clause encdec = <-> 0b110_1010 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveHalfFPU() mapping clause encdec = - F_UN_RM_TYPE_H(rs1, rm, rd, FCVT_H_S) if haveHalfFPU() -<-> 0b010_0010 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveHalfFPU() + F_UN_RM_TYPE_H(rs1, rm, rd, FCVT_H_S) if haveHalfMin() +<-> 0b010_0010 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveHalfMin() mapping clause encdec = - F_UN_RM_TYPE_H(rs1, rm, rd, FCVT_H_D) if haveHalfFPU() -<-> 0b010_0010 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveHalfFPU() + F_UN_RM_TYPE_H(rs1, rm, rd, FCVT_H_D) if haveHalfMin() & (haveDoubleFPU() & validDoubleRegs([rs1])) +<-> 0b010_0010 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveHalfMin() & (haveDoubleFPU() & validDoubleRegs([rs1])) mapping clause encdec = - F_UN_RM_TYPE_H(rs1, rm, rd, FCVT_S_H) if haveHalfFPU() -<-> 0b010_0000 @ 0b00010 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveHalfFPU() + F_UN_RM_TYPE_H(rs1, rm, rd, FCVT_S_H) if haveHalfMin() +<-> 0b010_0000 @ 0b00010 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveHalfMin() mapping clause encdec = - F_UN_RM_TYPE_H(rs1, rm, rd, FCVT_D_H) if haveHalfFPU() -<-> 0b010_0001 @ 0b00010 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveHalfFPU() + F_UN_RM_TYPE_H(rs1, rm, rd, FCVT_D_H) if haveHalfMin() & (haveDoubleFPU() & validDoubleRegs([rd])) +<-> 0b010_0001 @ 0b00010 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveHalfMin() & (haveDoubleFPU() & validDoubleRegs([rd])) // TODO: /* FCVT_H_Q, FCVT_Q_H : Will be added with Q Extension */ @@ -884,11 +887,11 @@ union clause ast = F_UN_TYPE_H : (regidx, regidx, f_un_op_H) mapping clause encdec = F_UN_TYPE_H(rs1, rd, FCLASS_H) if haveHalfFPU() <-> 0b111_0010 @ 0b00000 @ rs1 @ 0b001 @ rd @ 0b101_0011 if haveHalfFPU() -mapping clause encdec = F_UN_TYPE_H(rs1, rd, FMV_X_H) if extensionEnabled(Ext_Zfh) - <-> 0b111_0010 @ 0b00000 @ rs1 @ 0b000 @ rd @ 0b101_0011 if extensionEnabled(Ext_Zfh) +mapping clause encdec = F_UN_TYPE_H(rs1, rd, FMV_X_H) if extensionEnabled(Ext_Zfhmin) + <-> 0b111_0010 @ 0b00000 @ rs1 @ 0b000 @ rd @ 0b101_0011 if extensionEnabled(Ext_Zfhmin) -mapping clause encdec = F_UN_TYPE_H(rs1, rd, FMV_H_X) if extensionEnabled(Ext_Zfh) - <-> 0b111_1010 @ 0b00000 @ rs1 @ 0b000 @ rd @ 0b101_0011 if extensionEnabled(Ext_Zfh) +mapping clause encdec = F_UN_TYPE_H(rs1, rd, FMV_H_X) if extensionEnabled(Ext_Zfhmin) + <-> 0b111_1010 @ 0b00000 @ rs1 @ 0b000 @ rd @ 0b101_0011 if extensionEnabled(Ext_Zfhmin) /* Execution semantics ================================ */