IBEX是一个开源的RISCV核,我们可以在Verilator下测试这个riscv核的相关功能。

编译IBEX系统

> cd ibex-master
> make build-all

或者

> make build-simple-system

或者

> fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_simple_system \
 --RV32E=0 --RV32M=ibex_pkg::RV32MFast --RV32B=ibex_pkg::RV32BNone --RegFile=ibex_pkg::RegFileFF \
 --BranchTargetALU=0 --WritebackStage=0 --ICache=0 --ICacheECC=0 --ICacheScramble=0 \
 --BranchPredictor=0 --DbgTriggerEn=0 --SecureIbex=0 --PMPEnable=1 --PMPGranularity=0 \
 --PMPNumRegions=4 --MHPMCounterNum=0 --MHPMCounterWidth=40

fusesoc会在"--cores-root"指定的目录下查找core文件,找到“lowrisc:ibex:ibex_simple_system”对应的examples/simple_system/ibex_simple_system.core文件。

这个core文件定义了一个包含ibex-core,ram,simctl的小系统。

最终编译成功后会在build目录下生成build/lowrisc_ibex_ibex_simple_system_0/sim-verilator/Vibex_simple_system,这是一个基于verilator的可执行文件。


编译应用程序

> make -C examples/sw/simple_system/pmp_smoke_test

必要的话需要在examples/sw/simple_system/common/common.mk中修改gcc

#CC = riscv64-unknown-elf-gcc
CC = /home/esxi/toolchain/riscv-elf-toolchain/bin/riscv64-unknown-elf-gcc

运行

> ./build/lowrisc_ibex_ibex_simple_system_0/sim-verilator/Vibex_simple_system \
-l ram,examples/sw/simple_system/pmp_smoke_test/pmp_smoke_test.elf

最终会在当前目录生成以下文件:
ibex_simple_system.log - 程序打印
trace_core_0000000.log - 指令执行记录
ibex_simple_system_pcount.csv - cycle统计

如果PMPEnable为0,则会在ibex_simple_system.log中看到exception

EXCEPTION!!!
============
MEPC:   0x001003E2
MCAUSE: 0x00000002
MTVAL:  0x3B069073

我们dump应用程序

> /home/esxi/toolchain/riscv-elf-toolchain/bin/riscv64-unknown-elf-objdump -D examples/sw/simple_system/pmp_smoke_test/pmp_smoke_test.elf 
001003d2 <main>: 
 1003d2: 00000797 auipc a5,0x0 
 1003d6: 06678793 add a5,a5,102 # 100438 <test_int>
 1003da: 0027d693 srl a3,a5,0x2
 1003de: 09100713 li a4,145
 1003e2: 3b069073 csrw pmpaddr0,a3
 1003e6: 3a071073 csrw pmpcfg0,a4
 1003ea: 4731 li a4,12
 1003ec: c398 sw a4,0(a5)
 1003ee: 4501 li a0,0
 1003f0: 8082 ret

可以看到1003e2这条指令“csrv pmpaddr0,a3”非法,那是因为PMPEnable=0,既然PMP没使能,那么写PMP寄存器肯定是非法的。
所以我们可以修改fusesoc的参数,加上“--PMPEnable=1 --PMPNumRegions=4”,从而使能PMP,并支持4个PMP条目,重新编译

再次运行,发现输出变为:

EXCEPTION!!!
============
MEPC:   0x001003EC
MCAUSE: 0x00000007
MTVAL:  0x00100438
~

1003ec对应的指令是“sw a4,0(a5)”,就是往设置成readonly的地址区域进行写操作,这个就会导致exception 7,即“Store/AMO access fault”。由此证明PMP在正确工作。