Skip to content

Commit

Permalink
Merge pull request #541 from eleanorLYJ/add-rv32e
Browse files Browse the repository at this point in the history
Add support for the RV32E variant
  • Loading branch information
jserv authored Jan 27, 2025
2 parents 82a85ae + 64ea138 commit 418a9e6
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 23 deletions.
4 changes: 4 additions & 0 deletions .ci/riscv-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ make ENABLE_EXT_M=1 ENABLE_EXT_A=1 ENABLE_EXT_F=1 ENABLE_EXT_C=1 \
make arch-test RISCV_DEVICE=IMAFCZicsrZifencei $PARALLEL || exit 1
make arch-test RISCV_DEVICE=FCZicsr $PARALLEL || exit 1
make arch-test RISCV_DEVICE=IMZbaZbbZbcZbs $PARALLEL || exit 1

make distclean
make ENABLE_RV32E=1 ENABLE_FULL4G=1 $PARALLEL
make arch-test RISCV_DEVICE=E $PARALLEL || exit 1
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ endif
ENABLE_EXT_C ?= 1
$(call set-feature, EXT_C)

# RV32E Base Integer Instruction Set
ENABLE_RV32E ?= 0
$(call set-feature, RV32E)

# Control and Status Register (CSR)
ENABLE_Zicsr ?= 1
$(call set-feature, Zicsr)
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ a focus on efficiency and readability.

Features:
* Fast interpreter for executing the RV32 ISA
* Comprehensive support for RV32I and M, A, F, C, Zba, Zbb, Zbc, Zbs extensions
* Comprehensive support for RV32I, RV32E and M, A, F, C, Zba, Zbb, Zbc, Zbs extensions
* Memory-efficient design
* Built-in ELF loader
* Implementation of commonly used newlib system calls
Expand Down Expand Up @@ -116,6 +116,7 @@ The image containing all the necessary tools for development and testing can be
### Customization

`rv32emu` is configurable, and you can override the below variable(s) to fit your expectations:
* `ENABLE_RV32E`: RV32E Base Integer Instruction Set
* `ENABLE_EXT_M`: Standard Extension for Integer Multiplication and Division
* `ENABLE_EXT_A`: Standard Extension for Atomic Instructions
* `ENABLE_EXT_F`: Standard Extension for Single-Precision Floating Point Instructions
Expand Down Expand Up @@ -187,6 +188,7 @@ $ make arch-test RISCV_DEVICE=I
Current progress of this emulator in riscv-arch-test (RV32):
* Passed Tests
- `I`: Base Integer Instruction Set
- `E`: RV32E Base Integer Instruction Set
- `M`: Standard Extension for Integer Multiplication and Division
- `A`: Standard Extension for Atomic Instructions
- `F`: Standard Extension for Single-Precision Floating-Point
Expand Down
5 changes: 5 additions & 0 deletions src/feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
#define RV32_FEATURE_EXT_C 1
#endif

/* RV32E Base Integer Instruction Set */
#ifndef RV32_FEATURE_RV32E
#define RV32_FEATURE_RV32E 0
#endif

/* Control and Status Register (CSR) */
#ifndef RV32_FEATURE_Zicsr
#define RV32_FEATURE_Zicsr 1
Expand Down
7 changes: 6 additions & 1 deletion src/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -769,10 +769,15 @@ void rv_reset(riscv_t *rv, riscv_word_t pc)
rv->csr_mtvec = 0;
rv->csr_cycle = 0;
rv->csr_mstatus = 0;
rv->csr_misa |= MISA_SUPER | MISA_USER | MISA_I;
rv->csr_misa |= MISA_SUPER | MISA_USER;
rv->csr_mvendorid = RV_MVENDORID;
rv->csr_marchid = RV_MARCHID;
rv->csr_mimpid = RV_MIMPID;
#if !RV32_HAS(RV32E)
rv->csr_misa |= MISA_I;
#else
rv->csr_misa |= MISA_E;
#endif
#if RV32_HAS(EXT_A)
rv->csr_misa |= MISA_A;
#endif
Expand Down
37 changes: 21 additions & 16 deletions src/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
extern "C" {
#endif

/* clang-format off */
#define RV_REGS_LIST \
_(zero) /* hard-wired zero, ignoring any writes */ \
_(ra) /* return address */ \
Expand All @@ -50,22 +51,25 @@ extern "C" {
_(a3) \
_(a4) \
_(a5) \
_(a6) \
_(a7) \
_(s2) /* saved register */ \
_(s3) \
_(s4) \
_(s5) \
_(s6) \
_(s7) \
_(s8) \
_(s9) \
_(s10) \
_(s11) \
_(t3) /* temporary register */ \
_(t4) \
_(t5) \
_(t6)
IIF(RV32_HAS(RV32E))(, \
_(a6) \
_(a7) \
_(s2) /* saved register */ \
_(s3) \
_(s4) \
_(s5) \
_(s6) \
_(s7) \
_(s8) \
_(s9) \
_(s10) \
_(s11) \
_(t3) /* temporary register */ \
_(t4) \
_(t5) \
_(t6) \
)
/* clang-format on */

/* RISC-V registers (mnemonics, ABI names)
*
Expand Down Expand Up @@ -117,6 +121,7 @@ enum SV32_PTE_PERM {
#define MISA_SUPER (1 << ('S' - 'A'))
#define MISA_USER (1 << ('U' - 'A'))
#define MISA_I (1 << ('I' - 'A'))
#define MISA_E (1 << ('E' - 'A'))
#define MISA_M (1 << ('M' - 'A'))
#define MISA_A (1 << ('A' - 'A'))
#define MISA_F (1 << ('F' - 'A'))
Expand Down
6 changes: 5 additions & 1 deletion src/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,8 +466,12 @@ static void syscall_sbi_rst(riscv_t *rv)

void syscall_handler(riscv_t *rv)
{
/* get the syscall number */
/* get the syscall number */
#if !RV32_HAS(RV32E)
riscv_word_t syscall = rv_get_reg(rv, rv_reg_a7);
#else
riscv_word_t syscall = rv_get_reg(rv, rv_reg_t0);
#endif

switch (syscall) { /* dispatch system call */
#define _(name, number) \
Expand Down
2 changes: 2 additions & 0 deletions tests/arch-test-target/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

misa_A = (1 << 0)
misa_C = (1 << 2)
misa_E = (1 << 4)
misa_F = (1 << 5)
misa_I = (1 << 8)
misa_M = (1 << 12)

config_temp = '''[RISCOF]
Expand Down
7 changes: 7 additions & 0 deletions tests/arch-test-target/rv32emu/env/model_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,17 @@
/* clang-format on */

// RV_COMPLIANCE_HALT
#ifndef RV32E
#define RVMODEL_HALT \
add a7, x0, 93; \
add a0, x0, 0; \
ecall
#else
#define RVMODEL_HALT \
add t0, x0, 93; \
add a0, x0, 0; \
ecall
#endif

#define RVMODEL_BOOT

Expand Down
6 changes: 5 additions & 1 deletion tests/arch-test-target/rv32emu/riscof_rv32emu.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ def build(self, isa_yaml, platform_yaml):
# will be useful in setting integer value in the compiler string (if not already hardcoded);
self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32')

self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ')
if 'E' not in ispec['ISA']:
self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ')
else:
self.compile_cmd = self.compile_cmd+' -mabi='+('lp64e ' if 64 in ispec['supported_xlen'] else 'ilp32e ')
self.compile_cmd += '-D RV32E '

def runTests(self, testList):
# Delete Makefile if it already exists.
Expand Down
8 changes: 8 additions & 0 deletions tests/arch-test-target/sail_cSim/env/model_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,19 @@
/* clang-format on */

// RV_COMPLIANCE_HALT
#ifndef RV32E
#define RVMODEL_HALT \
li x1, 1; \
write_tohost: \
sw x1, tohost, t5; \
j write_tohost;
#else
#define RVMODEL_HALT \
li x1, 1; \
write_tohost: \
sw x1, tohost, x15; \
j write_tohost;
#endif

#define RVMODEL_BOOT

Expand Down
8 changes: 7 additions & 1 deletion tests/arch-test-target/sail_cSim/riscof_sail_cSim.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,15 @@ def build(self, isa_yaml, platform_yaml):
ispec = utils.load_yaml(isa_yaml)['hart0']
self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32')
self.isa = 'rv' + self.xlen
self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ')
if 'E' not in ispec['ISA']:
self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ')
else:
self.compile_cmd = self.compile_cmd+' -mabi='+('lp64e ' if 64 in ispec['supported_xlen'] else 'ilp32e ')
self.compile_cmd += "-D RV32E "
if "I" in ispec["ISA"]:
self.isa += 'i'
if "E" in ispec["ISA"]:
self.isa += 'e'
if "M" in ispec["ISA"]:
self.isa += 'm'
if "C" in ispec["ISA"]:
Expand Down
10 changes: 8 additions & 2 deletions tests/arch-test-target/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@
def setup_testlist(riscv_device):
# ISA config file path
ispec = constants.root + '/rv32emu/rv32emu_isa.yaml'
misa = 0x40000100
ISA = 'RV32I'
misa = 0x40000000
ISA = 'RV32'

if not riscv_device:
raise AssertionError('There is not any ISA.')

if 'E' in riscv_device:
misa |= constants.misa_E
ISA += 'E'
else:
misa |= constants.misa_I
ISA += 'I'
if 'M' in riscv_device:
misa |= constants.misa_M
ISA += 'M'
Expand Down

0 comments on commit 418a9e6

Please sign in to comment.