香山处理器产生的前因后果就不介绍了,有兴趣的读者可以查看香山的官方文档,其中已经有详细的介绍。另外本文也不是从零开始搭建香山的开发环境,官方文档‘前端开发环境’已经体贴的给我们做好了一键实现环境搭建的repo。
先描述下我的工作环境:
vmware:32G物理内存,50G disk,4核CPU
OS:ubuntu 18.04
环境不同的仅做参考。第一次写博,有错误和不成熟的地方还请各位大牛批评指正,小弟拜谢了。
先按照官方文档中下载xs-env
>> git clone https://github.com/OpenXiangShan/xs-env
>> cd xs-env
>> sudo -s ./setup-tools.sh # use apt to install dependencies, you may modify it to use different pkg manager
setup-tools.sh中完成了编译香山核所需的工具安装,其中会下载并编译verilator,一个开源仿真工具,也是香山核官方支持的开源仿真工具,当前香山核也支持vcs仿真,但貌似支持力度不是特别好;此脚本的另一个主要功能就是下载mill,mill是scala的构建工具,类似于sbt,貌似很多人都从sbt迁移到了mill,在github下载速度实现让人无法忍受,经过无数次失败后终于下载下来,为了让小伙伴们不在经历这个过程,已将mill-0.9.8放到了gitee上,下载后放到~/.cache/mill/download/0.9.8即可使用,注意/usr/bin/mill其实是个脚本,用于检查~/.cache/mill/download/0.9.8文件是否存在,不存在时会从https://github.com/lihaoyi/mill/releases/download/0.9.8/0.9.8-assembly下载mill可执行文件,然后调用~/.cache/mill/download/0.9.8运行chisel代码构建。
完成上面的工具下载安装后,开始下载香山核编译运行所需的代码仓
>> source setup.sh
在这步,会下载XiangShan,NEMU,nexus-am和nutshell。NEMU是一个款类似spike的risc-v指令模拟器,nexus-am是香山所使用的应用开发框架,nutshell是另一款开源risc-v核,可能是前期做对比或开发使用。香山使用了difftest测试框架,会比较每条指令在程序运行的过程中的正确与否,NEMU就是difftest的golden model。
下载完上面的代码后,setup.sh中会自动编译NEMU和nexus-am中的coremark,这里还需要说下NEMU有两种工作模式:作为单独可执行程序的工作模式和golden model模式。两种模式的编译目标不同,单独可执行程序编译时指定riscv64-xs_defconfig,生成的文件是buidl/riscv64-nemu-interpreter;golden model模式编译时指定riscv64-xs-ref_defconfig,生成文件是riscv64-nemu-interpreter-so。
编译NEMU时又报错了
xs-env/NEMU/include/checkpoint/path_manager.h:24:10: fatal error: filesystem: No such file or directory
#include <filesystem>
NEMU中用到了C++17的特性,需要将gcc/g++升级到8.x版本以上(想升级到9.x也不行啊,ubuntu 18.04中没有gcc9.x的版本),通过使用apt安装gcc-8并配置update-alternatives:
>> sudo apt install gcc-8
>> sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8
>> sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 700 --slave /user/bin/g++ g++ /usr/bin/g++-7
>> sudo update-alternatives --config gcc
There are 2 choices for the alternative gcc (providing /usr/bin/gcc).
Selection Path Priority Status
------------------------------------------------------------
0 /usr/bin/gcc-8 800 auto mode
* 1 /usr/bin/gcc-7 700 manual mode
2 /usr/bin/gcc-8 800 manual mode
Press <enter> to keep the current choice[*], or type selection number: 0
update-alternatives: using /usr/bin/gcc-8 to provide /usr/bin/gcc (gcc) in auto mode
在编译过程中还出现了一次cmake版本太低的错误,编译需要cmake 3.14以上,但ubuntu apt中最高只能到3.10,cmake官网下载速度实在让人泪目,还好在gitee上找到了3.19版本的镜像仓:
cmake-release: cmake release repo
下载后解压缩,然后将其中的bin目录加到PATH中即可。
OK,现在代码都已经准备好了,开始编译香山核。
>> cd xs-env/XiangShan
>> make init
>> make emu CONFIG=MinimalConfig EMU_TRACE=1 -j4
make init会下载香山代码仓所用到的子模块,make emu的参数请参考官方文档说明,-j4这里选择4是因为我的vmware中只有4个虚拟CPU核。
编译过程中出现错误。。。
Connection:[logTimestamp] type:[func] source location:[SimTop] sink location:[BusPerfMonitor_1]
Connection:[XSPERF_CLEAN] type:[func] source location:[SimTop] sink location:[BusPerfMonitor_1]
Connection:[XSPERF_DUMP] type:[func] source location:[SimTop] sink location:[BusPerfMonitor_1]
Connection:[DISPLAY_LOG_ENABLE] type:[func] source location:[SimTop] sink location:[BusPerfMonitor_1]
1 targets failed
XiangShan.test.runMain subprocess failed
Makefile:102: recipe for target 'build/SimTop.v' failed
没啥提示就直接failed,郁闷了一阵,根据文档中所讲,到troubleshoot中查找了下,应该是内存不够导致的,香山核编译时在MinimalConfig配置下需要至少32G内存,标准配置最少需要64G内存,通过如下方法修改:
1. 修改XiangShan/build.sc中的参数
override def forkArgs = Seq("-Xmx64G", "-Xss256m")
改成
override def forkArgs = Seq("-Xmx24G", "-Xss256m")
我的虚拟机有32G内存,为了保险这里设置为24G内存,请大家根据自己的PC配置自行确定此参数。
2. 物理内存不能满足需求而又不想在加钱买内存,使用swap来补充,这里我在vmware中新增了一块100G的虚拟硬盘,专门作为swap,即便是标准配置的香山核也可以编译了:)。关闭虚拟机新增scsi接口硬盘后再启动,然后在终端中操作
>> sudo mkswap -f /dev/sdb
>> sudo swapon /dev/sdb
新增的硬盘在我的vmware中显示的/dev/sdb。
重新执行make emu CONFIG=MinimalConfig EMU_TRACE=1 -j4,经过漫长的等待终于编译完成了,迫不及待的跑个仿真:
>> ./build/emu -i ready-to-run/coremark-2-iteration.bin
运行成功!
Emu compiled at Dec 4 2022, 19:33:27
Using simulated 32768B flash
[warning]no valid flash bin path, use preset flash instead
The image is ready-to-run/coremark-2-iteration.bin
Using simulated 8192MB RAM
--diff is not given, try to use $(NEMU_HOME)/build/riscv64-nemu-interpreter-so by default
NemuProxy using /home/fenghang/xs-env/NEMU/build/riscv64-nemu-interpreter-so
The first instruction of core 0 has commited. Difftest enabled.
[NEMU] Can not find flash image: (null)
[NEMU] Use built-in image instead
[src/device/io/mmio.c:39,add_mmio_map] Add mmio map 'flash' at [0x0000000010000000, 0x00000000100fffff]
Running CoreMark for 2 iterations
2K performance run parameters for coremark.
CoreMark Size : 666
Total time (ms) : 5210
Iterations : 2
Compiler version : GCC10.2.0
seedcrc : 0xe9f5
[0]crclist : 0xe714
[0]crcmatrix : 0x1fd7
[0]crcstate : 0x8e3a
[0]crcfinal : 0x72be
Finised in 5210 ms.
==================================================
CoreMark Iterations/Sec 383
Core 0: HIT GOOD TRAP at pc = 0x800026ba
total guest instructions = 626,872
instrCnt = 626,872, cycleCnt = 587,010, IPC = 1.067907
[PERF ][time= 587011] TOP.SimTop.l_soc.core_with_l2.core.frontend.icache.missUnit.prefEntries_0: PrefetchEntryReq2, 0
[PERF ][time= 587011] TOP.SimTop.l_soc.core_with_l2.core.frontend.icache.missUnit.prefEntries_1: PrefetchEntryReq2, 0
[PERF ][time= 587011] TOP.SimTop.l_soc.core_with_l2.core.exuBlocks.scheduler.fpBusyTable: busy_count, 0
[PERF ][time= 587011] TOP.SimTop.l_soc.core_with_l2.core.exuBlocks_1.scheduler.fpBusyTable: busy_count, 0
[PERF ][time= 587011] TOP.SimTop.l_soc.core_with_l2.core.exuBlocks.scheduler.intBusyTable: busy_count, 3289028