Cpu exper manual
本文档是专业阶段 CPU 方向的实验手册。
专业阶段 CPU 方向的实验围绕 Xg233ai 自定义指令扩展展开,你需要按照 G233 CPU 指令扩展手册 给出的指令规格,在 QEMU TCG 前端完成指令翻译与实现(Decodetree 译码 → Helper 实现 → 测试验证)。
环境搭建¶
第一步,以 Ubuntu 22.04 为例,介绍如何安装 QEMU 开发环境。
# 备份 sources.list 文件
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
# 启用 deb-src 源(将所有 deb 源对应的 deb-src 源解锁)
sudo sed -i '/^# deb-src /s/^# //' /etc/apt/sources.list
sudo apt-get update
sudo apt update && sudo apt build-dep qemu
# 创建工具链安装目录
sudo mkdir -p /opt/riscv
# 下载工具链压缩包
wget https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2025.09.28/riscv64-elf-ubuntu-22.04-gcc-nightly-2025.09.28-nightly.tar.xz -O riscv-toolchain.tar.xz
# 解压到安装目录
sudo tar -xJf riscv-toolchain.tar.xz -C /opt/riscv --strip-components=1
# 设置权限
sudo chown -R $USER:$USER /opt/riscv
echo "/opt/riscv/bin" >> $GITHUB_PATH
export PATH=$PATH:/opt/riscv/bin/
riscv64-unknown-elf-gcc --version # 验证编译器是否可用
提示
安装 QEMU 开发环境,请参考导学阶段的 Step0: 搭建 QEMU 开发环境。
安装 RISC-V 的交叉编译工具链:下载地址,尽量选择最新的版本,要求安装 riscv64-unknown-elf- 类型。
第二步,点击这里,自动 fork 作业仓库到 GTOC 组织下面,该仓库会为你开通代码上传权限。
第三步,需要 clone 刚刚 fork 好的仓库到本地:
git clone git@github.com:gevico/qemu-camp-2026-cpu-<你的 github 用户名>.git
# 比如 github 用户名是 zevorn,那么命令如下:
# git clone git@github.com:gevico/qemu-camp-2026-cpu-zevorn.git
第四步,添加上游远程仓库,用于同步上游的代码变更:
同步上游代码变更的常用命令:
最后一步,配置编译选项:
cd qemu
./configure --target-list=riscv64-softmmu \
--extra-cflags="-O0 -g3" \
--cross-prefix-riscv64=riscv64-unknown-elf-
执行时,如果看到以下输出,证明交叉编译工具链配置成功:
提交代码¶
所有实验的测题源码,均放在仓库根目录路径: tests/gevico/tcg/riscv64/ 。
你需要熟读每个测题源码,理解每个测题的测试意图,并实现对应的 QEMU 建模功能(需要修改 QEMU 本体源码,非测题源码),文末会给出具体实验的介绍,辅助你阅读测题源码。
每次实验完成后,需要将你的代码提交到你的 fork 仓库中。
Note
请确保你的代码符合仓库的代码规范,包括代码格式、注释等。
测评验收¶
本地运行测题的方式:
CPU 方向全部测题通过的情况下,你会看到如下输出:
BUILD riscv64-softmmu guest-tests
RUN riscv64-softmmu guest-tests
TEST 1/10 test-insn-dma on riscv64
TEST 2/10 test-insn-sort on riscv64
TEST 3/10 test-insn-crush on riscv64
TEST 4/10 test-insn-expand on riscv64
TEST 5/10 test-insn-vdot on riscv64
TEST 6/10 test-insn-vrelu on riscv64
TEST 7/10 test-insn-vscale on riscv64
TEST 8/10 test-insn-vmax on riscv64
TEST 9/10 test-insn-gemm on riscv64
TEST 10/10 test-insn-vadd on riscv64
如果你想运行某个测例,比如 test-insn-dma,可以使用如下命令:
Note
当你使用 make -C 指定了路径以后,你可以通过输入 run- 和 tab 键来查看可以运行的测题
如果你想调试某个测例,比如 test-insn-dma,可以使用如下命令启用 QEMU 的远程调试功能:
同理,你也可以通过 gdbstub- 和 tab 键来查看可以远程调试的测例。
然后需要你本地另起一个终端,使用 riscv-elf-gdb 加载被调试客户机二进制程序,进行远程调试。
Note
你需要熟读 G233 CPU 指令扩展手册 和测题的源码,来理解每个实验的测试意图,这会极大地方便你调试,提高开发效率。
每道测题 10 分,一共 10 道测题,共计 100 分,评分将显示到训练营的专业阶段排行榜。
实验介绍¶
CPU 方向的全部实验围绕 Xg233ai 自定义指令扩展展开。Xg233ai 在 RISC-V custom-3 编码空间内定义了 10 条 R-type 指令,覆盖通用数据处理与 AI 推理加速两大类别。
所有指令的编码格式、操作数约定和伪代码,详见 G233 CPU 指令扩展手册。
所有实验的测题,均在 tests/gevico/tcg/riscv64/ 目录下,以 test-insn- 开头的 .c 文件。
实验一 test-insn-dma¶
| 项目 | 内容 |
|---|---|
| 源码路径 | tests/gevico/tcg/riscv64/test-insn-dma.c |
| 指令助记符 | dma |
| 指令编码 | .insn r 0x7b, 6, 6, rd, rs1, rs2 |
| 功能描述 | FP32 矩阵转置搬运,支持 8×8 / 16×16 / 32×32 三种粒度 |
| 详细规格 | G233 CPU 指令扩展手册 §3.4 |
| 测试用例 | 测试内容 |
|---|---|
test_dma_grain_8x8 |
8×8 矩阵(粒度 0),输入按行优先填充 0-63,验证转置正确性 |
test_dma_grain_16x16 |
16×16 矩阵(粒度 1),输入 0-255,验证转置正确性 |
test_dma_grain_32x32 |
32×32 矩阵(粒度 2),输入 0-1023,验证转置正确性 |
custom_dma |
内联汇编调用指令,参数:目标地址、源地址、粒度大小 |
compare |
比较软件转置与硬件指令结果 |
实验二 test-insn-sort¶
| 项目 | 内容 |
|---|---|
| 源码路径 | tests/gevico/tcg/riscv64/test-insn-sort.c |
| 指令助记符 | sort |
| 指令编码 | .insn r 0x7b, 6, 22, rd, rs1, rs2 |
| 功能描述 | INT32 数组升序冒泡排序,支持部分排序 |
| 详细规格 | G233 CPU 指令扩展手册 §3.5 |
| 测试用例 | 测试内容 |
|---|---|
test_sort |
32 元素数组 {3, 7, 23, 9, 81, 33, ...},排序前 16 个元素 |
bubble_sort |
冒泡排序软件参考实现,提供对比基准 |
custom_sort |
内联汇编调用指令,参数:排序长度、数组地址、数组大小 |
compare |
比较软件排序与硬件指令结果 |
实验三 test-insn-crush¶
| 项目 | 内容 |
|---|---|
| 源码路径 | tests/gevico/tcg/riscv64/test-insn-crush.c |
| 指令助记符 | crush |
| 指令编码 | .insn r 0x7b, 6, 38, rd, rs1, rs2 |
| 功能描述 | 8-bit → 4-bit 压缩打包,提取低 4 位两两合并 |
| 详细规格 | G233 CPU 指令扩展手册 §3.6 |
| 测试用例 | 测试内容 |
|---|---|
pack_low4bits |
输入 {0xA, 0xB, ..., 0x4},预期输出 {0xBA, 0xDC, 0xFE, 0x21, 0x43} |
custom_crush |
内联汇编调用指令,参数:目标地址、源地址、元素数量 |
compare |
比较软件实现与硬件指令结果 |
实验四 test-insn-expand¶
| 项目 | 内容 |
|---|---|
| 源码路径 | tests/gevico/tcg/riscv64/test-insn-expand.c |
| 指令助记符 | expand |
| 指令编码 | .insn r 0x7b, 6, 54, rd, rs1, rs2 |
| 功能描述 | 4-bit → 8-bit 解压展开,每字节拆为两个 4-bit 元素 |
| 详细规格 | G233 CPU 指令扩展手册 §3.7 |
| 测试用例 | 测试内容 |
|---|---|
split_to_4bits |
输入 {0xAB, 0xBC, ...},拆分为 2 倍长度的 4-bit 数组 |
custom_expand |
内联汇编调用指令,参数:目标地址、源地址、数据数量 |
compare |
比较软件实现与硬件指令结果 |
实验五 test-insn-vdot¶
| 项目 | 内容 |
|---|---|
| 源码路径 | tests/gevico/tcg/riscv64/test-insn-vdot.c |
| 指令助记符 | vdot |
| 指令编码 | .insn r 0x7b, 6, 70, rd, rs1, rs2 |
| 功能描述 | INT32[16] 向量点积归约,INT64 累加,标量结果写入 gpr[rd] |
| 详细规格 | G233 CPU 指令扩展手册 §3.8 |
| 测试用例 | 测试内容 |
|---|---|
test_vdot_basic |
A={1..16}, B={16..1},预期结果 816 |
software_vdot |
INT64 累加器逐元素相乘求和,提供对比基准 |
custom_vdot |
内联汇编调用指令,参数:目标寄存器、向量 A 地址、向量 B 地址 |
compare |
比较软件实现与硬件指令结果 |
实验六 test-insn-vrelu¶
| 项目 | 内容 |
|---|---|
| 源码路径 | tests/gevico/tcg/riscv64/test-insn-vrelu.c |
| 指令助记符 | vrelu |
| 指令编码 | .insn r 0x7b, 6, 86, rd, rs1, rs2 |
| 功能描述 | INT32 向量 ReLU 激活 max(0, x),支持原地操作 |
| 详细规格 | G233 CPU 指令扩展手册 §3.9 |
| 测试用例 | 测试内容 |
|---|---|
test_vrelu_mixed |
输入 {-5, 3, -1, 0, 7, -100, ...},预期负值全部置零 |
software_vrelu |
逐元素判断,负值置零,提供对比基准 |
custom_vrelu |
内联汇编调用指令,参数:目标地址、源地址、元素数量 |
test_vrelu_inplace |
验证源和目标地址相同时(原地操作)的正确性 |
compare |
比较软件实现与硬件指令结果 |
实验七 test-insn-vscale¶
| 项目 | 内容 |
|---|---|
| 源码路径 | tests/gevico/tcg/riscv64/test-insn-vscale.c |
| 指令助记符 | vscale |
| 指令编码 | .insn r 0x7b, 6, 102, rd, rs1, rs2 |
| 功能描述 | INT32[16] 向量标量乘,INT64 中间精度,截断到 32 位 |
| 详细规格 | G233 CPU 指令扩展手册 §3.10 |
| 测试用例 | 测试内容 |
|---|---|
test_vscale_basic |
输入 {1..16},标量 3,预期 {3, 6, 9, ..., 48} |
test_vscale_negative |
正负混合数组 × 负数标量,验证符号处理 |
software_vscale |
INT64 中间精度逐元素相乘,提供对比基准 |
custom_vscale |
内联汇编调用指令,参数:目标地址、源地址、标量乘数(寄存器值) |
compare |
比较软件实现与硬件指令结果 |
实验八 test-insn-vmax¶
| 项目 | 内容 |
|---|---|
| 源码路径 | tests/gevico/tcg/riscv64/test-insn-vmax.c |
| 指令助记符 | vmax |
| 指令编码 | .insn r 0x7b, 6, 118, rd, rs1, rs2 |
| 功能描述 | INT32 向量最大值归约,结果符号扩展后写入 gpr[rd] |
| 详细规格 | G233 CPU 指令扩展手册 §3.11 |
| 测试用例 | 测试内容 |
|---|---|
test_vmax_positive |
输入 {5, 23, 1, 99, 42, ...},预期 99 |
test_vmax_negative |
输入 {-5, -23, -1, -99, ...},预期 -1,验证符号扩展 |
software_vmax |
遍历数组查找最大值,提供对比基准 |
custom_vmax |
内联汇编调用指令,参数:目标寄存器、数组地址、元素数量 |
compare |
比较软件实现与硬件指令结果 |
实验九 test-insn-gemm¶
| 项目 | 内容 |
|---|---|
| 源码路径 | tests/gevico/tcg/riscv64/test-insn-gemm.c |
| 指令助记符 | gemm |
| 指令编码 | .insn r 0x7b, 6, 14, rd, rs1, rs2 |
| 功能描述 | INT32 4×4 矩阵乘法 C = A × B,行优先存储,INT64 累加 |
| 详细规格 | G233 CPU 指令扩展手册 §3.12 |
| 测试用例 | 测试内容 |
|---|---|
test_gemm_basic |
A={{1..4},{5..8},...}, B={{17..20},{21..24},...},验证乘积矩阵 |
test_gemm_identity |
A × 单位矩阵 = A,验证恒等性 |
software_gemm |
三重循环标准矩阵乘法,INT64 累加器,提供对比基准 |
custom_gemm |
内联汇编调用指令,参数:目标矩阵地址、矩阵 A 地址、矩阵 B 地址 |
compare |
比较软件实现与硬件指令结果 |
实验十 test-insn-vadd¶
| 项目 | 内容 |
|---|---|
| 源码路径 | tests/gevico/tcg/riscv64/test-insn-vadd.c |
| 指令助记符 | vadd |
| 指令编码 | .insn r 0x7b, 6, 30, rd, rs1, rs2 |
| 功能描述 | INT32[16] 向量逐元素加法,溢出按补码回绕,支持原地操作 |
| 详细规格 | G233 CPU 指令扩展手册 §3.13 |
| 测试用例 | 测试内容 |
|---|---|
test_vadd_basic |
A={1..16}, B={100, 200, ..., 1600},验证逐元素之和 |
test_vadd_overflow |
INT32 最大值附近加法,验证补码回绕行为 |
software_vadd |
逐元素加法,提供对比基准 |
custom_vadd |
内联汇编调用指令,参数:目标地址、向量 A 地址、向量 B 地址 |
test_vadd_inplace |
验证目标与源地址相同时(原地操作)的正确性 |
compare |
比较软件实现与硬件指令结果 |