aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile11
-rw-r--r--model/riscv_fdext_regs.sail4
-rw-r--r--model/riscv_insts_fext.sail83
-rw-r--r--model/riscv_sys_control.sail10
4 files changed, 72 insertions, 36 deletions
diff --git a/Makefile b/Makefile
index 7fbbf34..70bef02 100644
--- a/Makefile
+++ b/Makefile
@@ -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());