diff options
-rw-r--r-- | Makefile | 11 | ||||
-rw-r--r-- | model/riscv_fdext_regs.sail | 4 | ||||
-rw-r--r-- | model/riscv_insts_fext.sail | 83 | ||||
-rw-r--r-- | model/riscv_sys_control.sail | 10 |
4 files changed, 72 insertions, 36 deletions
@@ -7,21 +7,24 @@ else ifeq ($(ARCH),64) override ARCH := RV64 endif +# Currently, we only have F with RV32, and both F and D with RV64. ifeq ($(ARCH),RV32) SAIL_XLEN := riscv_xlen32.sail + SAIL_FLEN := riscv_flen_F.sail else ifeq ($(ARCH),RV64) SAIL_XLEN := riscv_xlen64.sail + SAIL_FLEN := riscv_flen_D.sail else $(error '$(ARCH)' is not a valid architecture, must be one of: RV32, RV64) endif -# For now, F and D extensions cannot be separated, and are only available in RV64. -SAIL_FLEN := riscv_flen_D.sail - # Instruction sources, depending on target SAIL_CHECK_SRCS = riscv_addr_checks_common.sail riscv_addr_checks.sail riscv_misa_ext.sail SAIL_DEFAULT_INST = riscv_insts_base.sail riscv_insts_aext.sail riscv_insts_cext.sail riscv_insts_mext.sail riscv_insts_zicsr.sail riscv_insts_next.sail -SAIL_DEFAULT_INST += riscv_softfloat_interface.sail riscv_insts_fext.sail riscv_insts_dext.sail +SAIL_DEFAULT_INST += riscv_softfloat_interface.sail riscv_insts_fext.sail +ifeq ($(ARCH),RV64) +SAIL_DEFAULT_INST +=riscv_insts_dext.sail +endif SAIL_SEQ_INST = $(SAIL_DEFAULT_INST) riscv_jalr_seq.sail SAIL_RMEM_INST = $(SAIL_DEFAULT_INST) riscv_jalr_rmem.sail riscv_insts_rmem.sail diff --git a/model/riscv_fdext_regs.sail b/model/riscv_fdext_regs.sail index 28f4395..0cda7f2 100644 --- a/model/riscv_fdext_regs.sail +++ b/model/riscv_fdext_regs.sail @@ -129,9 +129,9 @@ function wF (r, in_v) = { print_reg("f" ^ string_of_int(r) ^ " <- " ^ FRegStr(v)); } -function rF_bits(i: bits(5)) -> xlenbits = rF(unsigned(i)) +function rF_bits(i: bits(5)) -> flenbits = rF(unsigned(i)) -function wF_bits(i: bits(5), data: xlenbits) -> unit = { +function wF_bits(i: bits(5), data: flenbits) -> unit = { wF(unsigned(i)) = data } diff --git a/model/riscv_insts_fext.sail b/model/riscv_insts_fext.sail index 8fadbdf..1a1d40d 100644 --- a/model/riscv_insts_fext.sail +++ b/model/riscv_insts_fext.sail @@ -306,9 +306,14 @@ mapping clause encdec = LOAD_FP(imm, rs1, rd, DOUBLE) if is_RV32D_or_RV64 val process_fload64 : (regidx, xlenbits, MemoryOpResult(bits(64))) -> Retired effect {escape, rreg, wreg} function process_fload64(rd, addr, value) = - match value { - MemValue(result) => { F(rd) = result; RETIRE_SUCCESS }, - MemException(e) => { handle_mem_exception(addr, e); RETIRE_FAIL } + if sizeof(flen) == 64 + then match value { + MemValue(result) => { F(rd) = result; RETIRE_SUCCESS }, + MemException(e) => { handle_mem_exception(addr, e); RETIRE_FAIL } + } + else { + /* should not get here */ + RETIRE_FAIL } val process_fload32 : (regidx, xlenbits, MemoryOpResult(bits(32))) @@ -648,47 +653,71 @@ function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_WU)) = { } function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_L_S)) = { - let rs1_val_S = nan_unbox (F(rs1)); - let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm)); + if sizeof(flen) == 64 + then { + let rs1_val_S = nan_unbox (F(rs1)); + let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm)); - let (fflags, rd_val_L) = riscv_f32ToI64 (rm_3b, rs1_val_S); + let (fflags, rd_val_L) = riscv_f32ToI64 (rm_3b, rs1_val_S); - writeCSR (csr_name_map ("fflags"), EXTZ (fflags)); - X(rd) = rd_val_L; - RETIRE_SUCCESS + writeCSR (csr_name_map ("fflags"), EXTZ (fflags)); + X(rd) = rd_val_L; + RETIRE_SUCCESS + } else { + /* this would not decode on RV32 */ + RETIRE_FAIL + } } function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_LU_S)) = { - let rs1_val_S = nan_unbox (F(rs1)); - let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm)); + if sizeof(flen) == 64 + then { + let rs1_val_S = nan_unbox (F(rs1)); + let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm)); - let (fflags, rd_val_LU) = riscv_f32ToUi64 (rm_3b, rs1_val_S); + let (fflags, rd_val_LU) = riscv_f32ToUi64 (rm_3b, rs1_val_S); - writeCSR (csr_name_map ("fflags"), EXTZ (fflags)); - X(rd) = rd_val_LU; - RETIRE_SUCCESS + writeCSR (csr_name_map ("fflags"), EXTZ (fflags)); + X(rd) = rd_val_LU; + RETIRE_SUCCESS + } else { + /* this would not decode on RV32 */ + RETIRE_FAIL + } } function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_L)) = { - let rs1_val_L = X(rs1); - let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm)); + if sizeof(flen) == 64 + then { + let rs1_val_L = X(rs1); + let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm)); - let (fflags, rd_val_S) = riscv_i64ToF32 (rm_3b, rs1_val_L); + let (fflags, rd_val_S) = riscv_i64ToF32 (rm_3b, rs1_val_L); - writeCSR (csr_name_map ("fflags"), EXTZ (fflags)); - F(rd) = nan_box (rd_val_S); - RETIRE_SUCCESS + writeCSR (csr_name_map ("fflags"), EXTZ (fflags)); + F(rd) = nan_box (rd_val_S); + RETIRE_SUCCESS + } else { + /* this would not decode on RV32 */ + RETIRE_FAIL + } } function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_LU)) = { - let rs1_val_LU = X(rs1); - let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm)); + if sizeof(flen) == 64 + then { + let rs1_val_LU = X(rs1); + let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm)); - let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU); + let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU); - writeCSR (csr_name_map ("fflags"), EXTZ (fflags)); - F(rd) = nan_box (rd_val_S); - RETIRE_SUCCESS + writeCSR (csr_name_map ("fflags"), EXTZ (fflags)); + F(rd) = nan_box (rd_val_S); + RETIRE_SUCCESS + } else { + /* this would not decode on RV32 */ + RETIRE_FAIL + } } /* AST -> Assembly notation ================================ */ diff --git a/model/riscv_sys_control.sail b/model/riscv_sys_control.sail index a642d85..0227cae 100644 --- a/model/riscv_sys_control.sail +++ b/model/riscv_sys_control.sail @@ -454,9 +454,13 @@ function init_sys() -> unit = { misa->U() = 0b1; /* user-mode */ misa->S() = 0b1; /* supervisor-mode */ - /* we currently support either both F and D, or neither */ - misa->F() = bool_to_bits(sys_enable_fdext()); /* single-precision */ - misa->D() = bool_to_bits(sys_enable_fdext()); /* double-precision */ + /* On RV64, we currently support either both F and D, or neither. + * On RV32, we currently only support F. + */ + misa->F() = bool_to_bits(sys_enable_fdext()); /* single-precision */ + misa->D() = if sizeof(xlen) == 64 + then bool_to_bits(sys_enable_fdext()) /* double-precision */ + else 0b0; mstatus = set_mstatus_SXL(mstatus, misa.MXL()); mstatus = set_mstatus_UXL(mstatus, misa.MXL()); |