Spike 模拟器手把手教程:从装环境到加自定义指令的 6 个台阶
【免费下载链接】riscv-isa-simSpike, a RISC-V ISA Simulator项目地址: https://gitcode.com/GitHub_Trending/ri/riscv-isa-sim
如果你写过几行 RISC-V 汇编,却不知道一条指令执行完寄存器到底变成了什么,那 Spike 就是为你准备的。它是 RISC-V 指令集的功能模拟器(RV32I/RV64I 起步,A、F、D、V、加密和向量扩展都有),不用开发板、不用烧录,一条命令就能把程序指令级地跑起来。这篇文章按任务推进:装环境 → 跑通第一个程序 → 用内置控制台调 bug → GDB 联调 → 开多核 → 加自定义指令,每一步只给你刚好够用的命令。
台阶 1:3 条命令把 Spike 编译出来
先装依赖,再进 build 目录配置编译(--prefix指向你的 RISC-V 工具链安装路径,下文用$RISCV指代):
apt-get install device-tree-compiler libboost-regex-dev libboost-system-dev git clone https://gitcode.com/GitHub_Trending/ri/riscv-isa-sim && cd riscv-isa-sim mkdir build && cd build && ../configure --prefix=$RISCV && make -j$(nproc) && sudo make install装完跑spike --help能看到完整参数列表就说明 OK。💡 坑在这儿:如果 configure 阶段报 Boost 或 dtc 相关错误,九成是上面第一个命令没装全,别急着改源码。
台阶 2:跑通第一个程序
用 RISC-V 工具链把 C 程序编成 ELF,然后用代理内核pk在模拟环境里执行:
riscv64-unknown-elf-gcc -o hello hello.c spike pk hellopk会在 Spike 里起一个极简 Linux 环境,让你的用户态程序能直接printf、退出、返回状态码。想换 ISA 组合?加--isa=rv64gc;想给目标侧多划点内存?-m4096表示 4 GiB(默认 2048 MiB)。参数全貌可以直接翻 spike_main/spike.cc 里的help(),或者运行时的--help输出。
台阶 3:程序跑飞了,用-d控制台查现场
spike -d -l pk your_app.elf-d进交互式调试,-l同时记录执行日志。掉进控制台后是:开头的命令,常用的几个:
:reg 0 a0—— 看 0 号 hart 的 a0 寄存器:mem 2020—— 从地址0x2020起 dump 内存:until pc 0 2020—— 让 hart 0 一直跑到 PC 到0x2020再停下:insn/:pc/:priv—— 看当前指令、PC 和特权级:run—— 继续执行
排障套路是先:until跳到可疑位置,再:reg+:mem对照现场。全部命令实现都在 riscv/interactive.cc,找不到命令时直接搜源码最快。
台阶 4:GDB 联调 Spike 的正确姿势
不想在:控制台里手工单步的话,就让 Spike 先停下等调试器:
spike --halted --rbb-port=7878 pk your_app.elf--halted表示所有 hart 启动即暂停,--rbb-port打开远程调试监听端口;之后用 OpenOCD 对接这个端口,再让 GDB 连 OpenOCD,就能用熟悉的break/step/watch操作模拟器了。这条链路对写驱动、写 OS 内核的人特别实用。
台阶 5:开多核,把竞态复现出来
单核永远跑不出死锁,把-p改成核心数即可:
spike -p2 pk multi_thread_app想指定每个 hart 的入口地址用--pcs=H:A,H:A,指定 hartid 用--hartids=0,1。另外 Spike 自身是顺序一致的,同时满足 RVWMO 和 RVTSO 两种内存模型,所以你在上面观察到的是"最乐观"情况,弱序真实硬件上可能更糟——这点结论要记牢。
台阶 6:加一条自定义指令(RoCC)
打开 riscv/insns/ 你会发现 1500 多个指令文件,像add.h这种一行就能看懂:
WRITE_RD(sext_xlen(RS1 + RS2));但 Spike 真正的玩法是 RoCC 自定义扩展:仓库里 customext/ 带了完整示例,编出来得到两个共享库,运行时这样挂进去:
spike --extlib=libdummy_rocc.so --extension=dummy_rocc pk your_app--extlib加载库,--extension启用其中的扩展,两个参数都可以重复传。你的新指令只要占住自定义 opcode 空间,就不会和内置指令撞车。
下一步建议:把 ci-tests/ 里的hello.c、vector-sum.c拿过来在-d控制台里逐指令走一遍,比读十遍文档都管用;想深入调试命令实现,直接读riscv/interactive.cc。
【免费下载链接】riscv-isa-simSpike, a RISC-V ISA Simulator项目地址: https://gitcode.com/GitHub_Trending/ri/riscv-isa-sim
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考