feat(saolei): 新增纯 C 扫雷(MMIO 显示 + 中断读鼠标),扩展 CPU 外设并清理仓库

## 背景

在原有五级流水 CPU 的基础上,用一颗 RISC-V 工具链把"纯 C 写的扫雷"编译成机器码
固化进片内 ROM 运行,并为此把 MMIO 外设从"只有一个 LED 寄存器"扩展成
显示(VGA 显存)+ 七段数码管 + 鼠标事件(含中断)的完整子系统。
原 LED MMIO 的语义保持不变,原有跑马灯/中断/指令回归不受影响。

## 硬件(pipelined-cpu/srcs)

- cpu21_mmio.v:扩展成 MMIO 中枢,新增
  * 七段数码管寄存器(0x1004,8 位十六进制)
  * 鼠标寄存器组(0x1100+):STATUS/DATA/ACK/CTRL/INPUT/TIME/FRAME/EVCNT/LEVEL/MAGIC
    —— 含 16 项事件 FIFO 与 mouse_irq_o(读空自动回 0,不丢事件)
  * 显示控制器(0x1140+):CTRL(光标可见/背景色)、CURSOR(列、行)
  * 显存窗口(0x2000-0x27FF):写端口输出到板级顶层的双口 RAM,读保持组合读
  * LEVEL(0x1120):软件中断寄存器,写 1 拉起 level_irq_o(用作"关卡入口")
  * 地址译码、字节写合并、读数据 mux 全部按原风格实现
- 新增外设 RTL:cpu21_vga.v(640x480@60 按格子扫描,8x8 字模放大 2 倍)、
  cpu21_seg7.v(8 位数码管动态扫描)、cpu21_pointer.v(5 向按键→鼠标事件,1 ms 去抖
  + 事件排队)、cpu21_ps2_mouse.v(可选真鼠标,PS/2 11 位帧接收 + 3 字节包解析)
- cpu21_riscv_redirect_int_bpb.v:新增外设总线端口(显存写/读回、鼠标事件输入、
  中断输出、数码管数据、帧脉冲),例化扩展后的 cpu21_mmio
- cpu21_board_top.v:接入显存双口 RAM + VGA + 数码管 + 鼠标事件源,中断接线为
  irq_i = {SW2, LEVEL|SW1, 鼠标|SW0};ROM 宏切换(定义 SAOLEI_ROM 加载扫雷程序);
  ROM_WORDS 1024→8192
- cpu21_board_top.xdc:新增按键、SW[3]、8 位数码管、VGA、PS/2 的全部引脚约束
- tb_board_top.v:新端口显式接 0/1,避免悬空影响原跑马灯回归
- create_project.tcl:把 cpu21_saolei_rom.vh 按 Verilog Header 条件加入

## 软件(saolei/)

- sw/mmio.h:全部 MMIO 地址与格子编码(换地址只改这一个文件)
- sw/saolei.c:纯 C 扫雷 —— 背景"伪操作系统" main()(开始界面)+ 关卡 level_main()
  (在 IRQ1 里跑完整局)+ 棋盘位图/布雷(首点安全)/BFS 展开/插旗/胜负判定/逐格绘制
- sw/isr.c:**中断读鼠标的代码**。三个固定地址入口:
  * isr1_entry(.text.isr1=0x100)关卡入口:保存全部调用者保存寄存器 +
    csrrsi 打开 MIE(让鼠标中断可嵌套)→ level_main
  * isr2_entry(.text.isr2=0x200)鼠标读取:只存 ra → 纯 C 主体 isr_body
  * isr3_entry(.text.isr3=0x300)备用:直接 uret
- sw/start.c:设 sp、清 .bss、进 main(只有这一处必要内联汇编)
- sw/linker.ld:复位 0x0、三个中断入口 0x100/0x200/0x300、栈顶 0x0FFC;
  用 ASSERT 禁止 .data/.rodata(这颗核读不到 ROM 里的数据)

## 构建与工具链适配(saolei/tools)

- build.ps1:一键 C → .o → ELF → .hex + cpu21_saolei_rom.vh,任一步失败立刻停止
- check_isa.py:用"指令白名单"逐条检查反汇编,出现本核未实现的指令即报错并给修复提示
- elf2hex.py:裸二进制 → $readmemh hex + ROM 初始化头文件
- 三处针对本核的关键配置(都已写进脚本注释):
  1) -march=rv32im_zicsr(GCC 15 起 rv32im 不含 Zicsr,csrrsi 会报错)
  2) 不能禁链接器松弛:gcc 函数调用默认是 auipc+jalr,靠松弛压成 jal,
     禁掉后 35 条 auipc 会留在代码里(本核没有 auipc);
     用 -msmall-data-limit=0 防止松弛引入 gp 相对寻址
  3) 中断入口地址必须写在段声明上(.text.isr1 0x100 : ...),
     只写 ". = 0x100;" 会被 ld 忽略(实测 isr1 掉到了 0x14)
- 实测结果:text=3368B、data=0、bss=1436B,842 条指令全部通过 ISA 检查,
  入口地址 _start=0x0 / isr1_entry=0x100 / isr2_entry=0x200 / isr3_entry=0x300

## 仓库清理

- 删除被工程取代的 saolei/hw、saolei/constrs(外设已并入 srcs/rtl)
- 删除全部 Vivado 生成物:.xpr、.runs、.sim、.cache、.hw、.ip_user_files、.Xil、
  vivado.jou/log —— 需要工程时用 source create_project.tcl 一键重建(约 0.3 MB 源文件)
- .gitignore 增加 saolei/build/(构建产物可一键重建)

## 文档

- README:更新目录结构、仓库约定(不放生成物)、MMIO 地址表、文件与模块划分表、
  上板说明,新增"扫雷程序(saolei/)"章节
- saolei/README.md:重写 —— 程序结构(背景/关卡/鼠标 + 三个中断入口)、
  本核指令子集与对应写法、构建步骤与实测数据、MMIO 地址表、上板/仿真步骤、
  操作说明、验证状态与已知可改进项

## 验证状态(如实说明)

- 已实测:C 工具链链路(编译/链接/ISA 检查/hex 生成/入口地址逐条核对)
- 未验证:所有 RTL 未经综合与仿真(本机无 Vivado),C 程序也未在仿真器/硬件上运行过;
  建议先跑 tools/run_regress.ps1 确认原回归仍全 PASS,再用 SAOLEI_ROM 宏做行为仿真
This commit is contained in:
2026-09-16 20:11:00 +08:00
commit f50639e90f
66 changed files with 19733 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
# 上板演示程序(Nexys4DDR):通过 MMIO 写 LED 数据寄存器,做 16 位跑马灯。
# LED_ADDR = 0x0000_1000(与 cpu21_board_top.v / cpu21_mmio.v 的默认参数一致)。
# 用 tools/hex2vh.py 把它转成 cpu21_board_rom.vh,供综合时初始化片内 ROM。
lui t0, 0x1 # t0 = LED_ADDR = 0x00001000
addi t1, zero, 1 # 跑马灯初值:bit0
main_loop:
sw t1, 0(t0) # MMIO 写 LED -> 板载 LED[15:0]
slli t1, t1, 1 # 左移一位
lui t4, 0x8 # t4 = 0x00008000
bltu t4, t1, restart # 移出 16 位后重新开始
jal zero, delay
restart:
addi t1, zero, 1
delay: # 软件延时,让人眼能看到跑马灯(50 MHz 下约 20 ms)
lui t2, 0x7a # 延时计数 0x0007A000 ≈ 5e5 次循环
addi t3, zero, 1
delay_loop:
sub t2, t2, t3
bne t2, zero, delay_loop
jal zero, main_loop
@@ -0,0 +1,25 @@
# 上板演示程序的**快速版**(仅仿真用):与 board_demo.asm 只差延时循环的初值——
# 从 `lui t2, 0x7a`(≈ 20 ms/步)改成 `addi t2, zero, 64`(≈ 2.6 µs/步 @50 MHz),
# 这样一次仿真(tb_board_top,300 µs 窗口)就能看完整个跑马灯序列。
# 重新生成:python tools/rv_asm.py programs/board_demo_fast.asm _tmp/board_demo_fast.hex
# python tools/hex2vh.py _tmp/board_demo_fast.hex srcs/board/cpu21_board_rom_fast.vh 1024
# 综合时用 -d BOARD_ROM_FAST 才会选到它(见 srcs/board/cpu21_board_top.v)。
lui t0, 0x1 # t0 = LED_ADDR = 0x00001000
addi t1, zero, 1 # 跑马灯初值:bit0
main_loop:
sw t1, 0(t0) # MMIO 写 LED -> 板载 LED[15:0]
slli t1, t1, 1 # 左移一位
lui t4, 0x8 # t4 = 0x00008000
bltu t4, t1, restart # 移出 16 位后重新开始
jal zero, delay
restart:
addi t1, zero, 1
delay: # 短延时(仿真用,人眼看不见)
addi t2, zero, 64 # 延时计数 64 次循环
addi t3, zero, 1
delay_loop:
sub t2, t2, t3
bne t2, zero, delay_loop
jal zero, main_loop
+110
View File
@@ -0,0 +1,110 @@
# 指令扩展验证程序:每条被测指令的结果都通过 MMIO 写 LED 输出,最后用 halt 停机。
# 期望输出顺序见每行注释(共 24 次输出),同时保存在同目录 isa_test.expected(每行一项 LED 值)。
#
# 用法(在仓库根目录执行):
# python tools/rv_asm.py testbench/programs/isa_test.asm <仿真工作目录>/risc-v-benchmark_ccab.hex
# 再用 testbench/tb_no_intr.v 仿真;hex 命名为 risc-v-benchmark_ccab.hex 时会被测试
# 平台优先从仿真工作目录载入(参见 tb_no_intr.v 的 ROM 探测顺序)。
# print / halt 是 tools/rv_asm.py 提供的双字伪指令(print 会占用 t6):
# print = lui t6,0x1000>>12 + sw a0,0(t6)(写 MMIO 的 LED 寄存器);
# halt = addi a7,zero,10 + ecall(ecall 停机)。
# ---- sltiu:立即数符号扩展后做无符号比较 ----
addi t0, zero, 1
addi t1, zero, -1 # t1 = 0xffffffff
sltiu a0, t0, -1 # 1 <u 0xffffffff -> 00000001
print
sltiu a0, t1, 1 # 0xffffffff <u 1 -> 00000000
print
# ---- xor / sll / srl / sra(原有指令回归)----
addi t0, zero, 0xff
addi t1, zero, -1
xor a0, t0, t1 # 0xff ^ 0xffffffff -> ffffff00
print
addi t0, zero, 1
addi t1, zero, 31
sll a0, t0, t1 # 1 << 31 -> 80000000
print
addi t0, zero, -1
addi t1, zero, 28
srl a0, t0, t1 # 逻辑右移 -> 0000000f
print
sra a0, t0, t1 # 算术右移 -> ffffffff
print
# ---- mul:无符号乘积低 32 位 ----
addi t0, zero, 1234
addi t1, zero, 567
mul a0, t0, t1 # 1234*567 = 0x000aad1e
print
# ---- mulh / mulhu / mulhsu:64 位乘积的高 32 位 ----
addi t0, zero, -1 # 有符号 -1 / 无符号 0xffffffff
addi t1, zero, -1
mulh a0, t0, t1 # (-1)*(-1)=1 -> 00000000
print
mulhu a0, t0, t1 # 0xffffffff^2 -> fffffffe
print
addi t0, zero, -1
addi t1, zero, 2
mulhsu a0, t0, t1 # (-1)*2=-2 -> ffffffff
print
# ---- bltu:0 <u 0xffffffff 成立(按有符号比较则不成立)----
addi t0, zero, -1
bltu zero, t0, bltu_ok
addi a0, zero, 0x101 # 不应执行
print
bltu_ok:
addi a0, zero, 0x601 # 00000601
print
# ---- bge:有符号 >= ,(-1) >= 0 不成立,应走 fall-through ----
addi t0, zero, -1
bge t0, zero, bge_bad
addi a0, zero, 0x602 # 00000602
print
jal zero, bge_done
bge_bad:
addi a0, zero, 0x102 # 不应执行
print
bge_done:
# ---- bgeu:无符号 >= ,0xffffffff >=u 0 成立 ----
addi t0, zero, -1
bgeu t0, zero, bgeu_ok
addi a0, zero, 0x103 # 不应执行
print
bgeu_ok:
addi a0, zero, 0x603 # 00000603
print
# ---- bge 循环:从 -3 递增到 0(共 4 次输出)----
addi s1, zero, -3
bge_loop:
add a0, zero, s1
print # fffffffd / fffffffe / ffffffff / 00000000
addi s1, s1, 1
bge zero, s1, bge_loop
# ---- bgeu 循环:3 -> 1(共 3 次输出)----
addi t0, zero, 3
bgeu_loop:
add a0, zero, t0
print # 00000003 / 00000002 / 00000001
addi t0, t0, -1
addi t2, zero, 1
bgeu t0, t2, bgeu_loop
# ---- bltu 循环:4 -> 1(共 4 次输出)----
addi s1, zero, 4
bltu_loop:
add a0, zero, s1
print # 00000004 / 00000003 / 00000002 / 00000001
addi s1, s1, -1
bltu zero, s1, bltu_loop
halt
+24
View File
@@ -0,0 +1,24 @@
00000001
00000000
ffffff00
80000000
0000000f
ffffffff
000aad1e
00000000
fffffffe
ffffffff
00000601
00000602
00000603
fffffffd
fffffffe
ffffffff
00000000
00000003
00000002
00000001
00000004
00000003
00000002
00000001
+21
View File
@@ -0,0 +1,21 @@
# LUI 指令测试:依次把 lui 的结果写到 MMIO 的 LED 寄存器,最后停机。
# 期望输出:12345000 / fffff000 / 80000000 / 12345678,随后停机(halted=1)。
# 用法:python tools/rv_asm.py testbench/programs/lui_test.asm <仿真工作目录>/risc-v-benchmark_ccab.hex
lui t0, 0x12345 # t0 = 0x12345000
add a0, zero, t0
print # MMIO 写 LED -> 12345000
lui t0, 0xfffff # t0 = 0xfffff000
add a0, zero, t0
print # -> fffff000
lui t0, 0x80000 # t0 = 0x80000000
add a0, zero, t0
print # -> 80000000
lui t0, 0x12345 # 常见用法 lui+addi:0x12345678
addi t0, t0, 0x678
add a0, zero, t0
print # -> 12345678
halt # 停机
+4
View File
@@ -0,0 +1,4 @@
12345000
fffff000
80000000
12345678
+25
View File
@@ -0,0 +1,25 @@
# MMIO 验证程序:写 LED 寄存器(0x0000_1000)-> 读回 -> 字节写 -> 再读回。
# 期望 LED 输出顺序(共 5 次,见同目录 mmio_test.expected):
# ① 12345678 sw 0x12345678
# ② 12345678 lw 读回后 print(print = lui t6 + sw a0,0(t6),本身就是一次 MMIO 写)
# ③ ffffffff sw 0xffffffff
# ④ ffff7fff sb 0x7f 覆盖 led[15:8]
# ⑤ ffff7fff 读回后 print
# 用法:python tools/rv_asm.py testbench/programs/mmio_test.asm <仿真工作目录>/risc-v-benchmark_ccab.hex
lui t0, 0x1 # t0 = LED_ADDR = 0x00001000
lui t1, 0x12345
addi t1, t1, 0x678 # t1 = 0x12345678
sw t1, 0(t0) # ① MMIO 写 LED
lw a0, 0(t0) # MMIO 读回
print # ② 应为 12345678
addi t2, zero, -1 # t2 = 0xffffffff
sw t2, 0(t0) # ③ 应为 ffffffff
addi t3, zero, 0x7f
sb t3, 1(t0) # 字节写:led[15:8] = 0x7f
lw a0, 0(t0) # 读回
print # ④ 应为 ffff7fff
halt
@@ -0,0 +1,5 @@
12345678
12345678
ffffffff
ffff7fff
ffff7fff
+95
View File
@@ -0,0 +1,95 @@
# 乘除法(多周期单元)测试:每个结果都写给 MMIO 的 LED 寄存器,供测试平台比对。
# 期望输出顺序见同目录 muldiv_test.expected(共 13 个值)。
#
# ① mul 7 * 6 = 42 -> 0000002a
# ② mul -5 * 4 = -20 -> ffffffec
# ③ mulh 0x40000000 * 4 高 32 位 -> 00000001
# ④ mulhu 0xffffffff * 2 高 32 位 -> 00000001
# ⑤ mulhsu -1 * 0xffffffff 高 32 位 -> ffffffff
# ⑥ divu 100 / 7 = 14 -> 0000000e
# ⑦ remu 100 % 7 = 2 -> 00000002
# ⑧ divu 0xffffffff / 2 = 2147483647 -> 7fffffff
# ⑨ divu 12345 / 0 除零约定 -> ffffffff
# ⑩ remu 12345 % 0 除零约定 -> 00003039
# ⑪ remu 0xffffffff % 16 = 15 -> 0000000f
# ⑫ mul 0x12345678 * 16 低 32 位 -> 23456780
# ⑬ mulh 0x12345678 * 0x1000 高 32 位 -> 00000123
#
# 用法:python tools/rv_asm.py testbench/programs/muldiv_test.asm testbench/rom/muldiv_test.hex
# ① mul:有符号乘法的低 32 位
addi t1, zero, 7
addi t2, zero, 6
mul a0, t1, t2
print
# ② mul:负乘数(低 32 位)
addi t1, zero, -5
addi t2, zero, 4
mul a0, t1, t2
print
# ③ mulh:正数相乘,高 32 位不为 0
lui t1, 0x40000
addi t2, zero, 4
mulh a0, t1, t2
print
# ④ mulhu:无符号高位(0xffffffff * 2 = 0x1_fffffffe)
addi t1, zero, -1
addi t2, zero, 2
mulhu a0, t1, t2
print
# ⑤ mulhsu:有符号 x 无符号(-1 * 4294967295 = 0xffffffff_00000001)
addi t1, zero, -1
addi t2, zero, -1
mulhsu a0, t1, t2
print
# ⑥ divu:普通除法
addi t1, zero, 100
addi t2, zero, 7
divu a0, t1, t2
print
# ⑦ remu:普通取余
remu a0, t1, t2
print
# ⑧ divu:无符号大数
addi t1, zero, -1
addi t2, zero, 2
divu a0, t1, t2
print
# ⑨ divu:除零(商为全 1)
lui t1, 0x3
addi t1, t1, 0x39 # t1 = 12345
addi t2, zero, 0
divu a0, t1, t2
print
# ⑩ remu:除零(余数为被除数)
remu a0, t1, t2
print
# ⑪ remu:0xffffffff % 16
addi t1, zero, -1
addi t2, zero, 16
remu a0, t1, t2
print
# ⑫ mul:0x12345678 * 16 的低 32 位
lui t1, 0x12345
addi t1, t1, 0x678
addi t2, zero, 16
mul a0, t1, t2
print
# ⑬ mulh:0x12345678 * 0x1000 的高 32 位
lui t2, 0x1
mulh a0, t1, t2
print
halt
@@ -0,0 +1,13 @@
0000002a
ffffffec
00000001
00000001
ffffffff
0000000e
00000002
7fffffff
ffffffff
00003039
0000000f
23456780
00000123
Binary file not shown.
@@ -0,0 +1,428 @@
#############################################################
#测试jal,jalr指令,
#############################################################
.text
addi s1,zero, 1 #测试jal,jalrr指令
j jmp_next1 #jal x0,8
addi s1,zero, 1
addi s2,zero, 2
addi s3,zero, 3
jmp_next1:
j jmp_next2
addi s1,zero, 1
addi s2,zero, 2
addi s3,zero, 3
jmp_next2:
j jmp_next3
addi s1,zero, 1
addi s2,zero, 2
addi s3,zero, 3
jmp_next3:
j jmp_next4
addi s1,zero, 1
addi s2,zero, 2
addi s3,zero, 3
jmp_next4:jal jmp_count
#移位测试 需要支持超addi,sll,add,ecall,srl,sll,sra,beq,j,ecall revise date:2015/12/16 tiger
.text
addi s0,zero,1 #简单移位,循环测试,0号区域显示的是初始值1左移1位重复15次的值,1号区域是累加值
addi s1,zero,1
slli s1, s1, 31 #逻辑左移31位 s1=0x80000000
###################################################################
# 逻辑左移测试
# 显示区域依次显示0x80000000 0x20000000 0x08000000 0x02000000 0x00800000 0x00200000 0x00080000 0x00020000 0x00008000 0x00002000 0x00000800 0x00000200 0x00000080 0x00000020 0x00000008 0x00000002 0x00000000
###################################################################
LogicalRightShift: #逻辑右移测试,将最高位1逐位向右右移直至结果为零
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srli s1, s1, 2
beq s1, zero, shift_next1
j LogicalRightShift
shift_next1:
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
###################################################################
# 逻辑右移测试
# 显示区域依次显示0x00000004 0x00000010 0x00000040 0x00000100 0x00000400 0x00001000 0x00004000 0x00010000 0x00040000 0x00100000 0x00400000 0x01000000 0x04000000 0x10000000 0x40000000 0x00000000
###################################################################
addi s1,zero, 1
LogicalLeftShift: #逻辑左移测试,将最低位1逐位向左移直至结果为零
slli s1, s1, 2
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
beq s1, zero, ArithRightShift
j LogicalLeftShift
###################################################################
# 算术右移测试
# 显示区域依次显示0x80000000 0xf0000000 0xff000000 0xfff00000 0xffff0000 0xfffff000 0xffffff00 0xfffffff0 0xffffffff
###################################################################
ArithRightShift: #算术右移测试,#算术移位测试,80000000算术右移,依次显示为F0000000,FF000000,FFF00000,FFFF0000直至FFFFFFFF
addi s1,zero,1
slli s1, s1, 31 #逻辑左移31位 s1=0x80000000
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 3 #s1=0X80000000-->0XF0000000
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4 #0XF0000000-->0XFF000000
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4 #0XFF000000-->0XFFF00000
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
srai s1, s1, 4
add a0,zero,s1 #display s1
addi a7,zero,34 # display hex
ecall # we are out of here.
#############################################################
#走马灯测试,测试addi,andi,sll,srl,sra,or,ori,nor,ecall LED按走马灯方式来回显示数据
#############################################################
.text
addi s0,zero,1
slli s3, s0, 31 # s3=0x80000000
srai s3, s3, 31 # s3=0xFFFFFFFF
add s0,zero,zero # s0=0
addi s2,zero,12
addi s6,zero,3 #走马灯计数
zmd_loop:
addi s0, s0, 1 #计算下一个走马灯的数据
andi s0, s0, 15
#######################################
addi t0,zero,8
addi t1,zero,1
left:
slli s3, s3, 4 #走马灯左移
or s3, s3, s0
add a0,zero,s3 # display s3
addi a7,zero,34 # system call for LED display
ecall # display
sub t0,t0,t1
bne t0,zero,left
#######################################
addi s0, s0, 1 #计算下一个走马灯的数据
addi t6,zero,15
and s0, s0, t6
slli s0, s0, 28
addi t0,zero,8
addi t1,zero,1
zmd_right:
srli s3, s3, 4 #走马灯右移
or s3, s3, s0
add a0,zero,s3 # display s3
addi a7,zero,34 # system call for LED display
ecall # display
sub t0,t0,t1
bne t0,zero,zmd_right
srli s0, s0, 28
#######################################
sub s6,s6,t1
beq s6,zero, exit
j zmd_loop
exit:
add t0,zero,zero
xori t0,t0,-1 #test r xori
slli t0,t0,8
ori t0,t0,255
add a0,zero,t0 # display t0
addi a7,zero,34 # system call for LED display
ecall # display
#################################################################################
#本程序实现0-15号字单元的降序排序,此程序可在rars 仿真器中运行
#运行时请将rars Setting中的Memory Configuration设置为Compact,data at address 0
#################################################################################
.text
sort_init:
addi s0,zero,-1
addi s1,zero,0
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
sw s0,0(s1)
addi s0,s0,1
addi s1,s1,4
addi s0,s0,1
add s0,zero,zero
addi s1,zero,60 #排序区间
sort_loop:
lw s3,0(s0)
lw s4,0(s1)
slt t0,s3,s4
beq t0,zero,sort_next #降序排序
sw s3, 0(s1)
sw s4, 0(s0)
sort_next:
addi s1, s1, -4
bne s0, s1, sort_loop
add a0,zero,s0 #display s0
addi a7,zero,34 # display hex
ecall # we are out of here. DISP: disp r0, 0
addi s0,s0,4
addi s1,zero,60
bne s0, s1, sort_loop
addi a7,zero,10 # benchmark 测试完成,ecall 停止 # 停止后点击继续运行,将进入下方 CCAB 附加指令测试区
#############################################
# insert your ccmb benchmark program here!!!
#############################################
#===== [1] 运算类C:DIVU 无符号除法(divu/mflo)=====
#依次输出0x11110000 0x08888000 0x04444000 0x02222000 0x01111000 0x00888800 0x00444400 0x00222200 0x00111100 0x00088880 0x00044440 0x00022220 0x00011110 0x00008888 0x00004444 0x00002222 0x00001111 0x00000888 0x00000444 0x00000222 0x00000111 0x00000088 0x00000044 0x00000022 0x00000011 0x00000008 0x00000004 0x00000002 0x00000001
addi t0,zero,2 # /2
addi s1,zero, 0x11
slli s1,s1,8
addi s1,s1,0x11
slli s1,s1,16
add a0,zero,s1
addi a7,zero,34
ecall
addi t3,zero,28 #循环次数
divu_branch:
divu s1,s1,t0 #测试指令
add a0,zero,s1
addi a7,zero,34
ecall #输出当前值
addi t3,t3, -1
bne t3,zero,divu_branch #循环
addi a7,zero,10 # 暂停或退出
#===== [2] 运算类C:REMU 无符号取余 =====
#输出 0x87540110
addi s1,x0,0x88
slli s1,s1,8
addi s1,s1,0x48
addi s2,x0,0x87
slli s2,s2,8
addi s2,s2,0x54
remu s2,s2,s1
slli s2,s2,16
ori s2,s2,0x110
add a0,zero,s2
addi a7,zero,34 # system call for print
ecall
addi a7,zero,10 # system call for exit
#===== [3] 存储类A:SB 存字节 =====
#依次输出 0x00000000 0x00000001 0x00000002 0x00000003 0x00000004 0x00000005 0x00000006 0x00000007 0x00000008 0x00000009 0x0000000a 0x0000000b 0x0000000c 0x0000000d 0x0000000e 0x0000000f 0x00000010 0x00000011 0x00000012 0x00000013 0x00000014 0x00000015 0x00000016 0x00000017 0x00000018 0x00000019 0x0000001a 0x0000001b 0x0000001c 0x0000001d 0x0000001e 0x0000001f 0x03020100 0x07060504 0x0b0a0908 0x0f0e0d0c 0x13121110 0x17161514 0x1b1a1918 0x1f1e1d1c
addi t1,zero,0 #init_addr
addi t3,zero,32 #counter
#sb写入 01,02,03,04
addi s1,zero, 0x00 #
addi s2,zero, 0x01 #
sb_store:
sb s1,(t1)
add a0,zero,s1
addi a7,zero,34 # system call for print
ecall # print
add s1,s1,s2 #data +1
addi t1,t1,1 # addr ++
addi t3,t3,-1 #counter
bne t3,zero,sb_store
addi t3,zero,8
addi t1,zero,0 # addr
sb_branch:
lw s1,(t1) #读出数据
add a0,zero,s1
addi a7,zero,34 # system call for print
ecall # print
addi t1,t1,4
addi t3,t3, -1
bne t3,zero,sb_branch
addi a7,zero,10 # system call for exit
#===== [4] 跳转类B:BLT 小于则跳转(从负数向零累加)=====
#依次输出0xfffffff1 0xfffffff2 0xfffffff3 0xfffffff4 0xfffffff5 0xfffffff6 0xfffffff7 0xfffffff8 0xfffffff9 0xfffffffa 0xfffffffb 0xfffffffc 0xfffffffd 0xfffffffe 0xffffffff
addi s1,zero,-15 #初始值
blt_branch:
add a0,zero,s1
addi a7,zero,34
ecall #输出当前值
addi s1,s1,1
blt s1,zero,blt_branch #测试指令
ccab_end:
addi a7,zero,10
#处理器实现中请用停机指令实现ecall
jmp_count: addi s0,zero, 0
addi s0,s0, 1
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 2
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 3
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 4
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 5
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 6
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 7
add a0,zero,s0
addi a7,zero,34 # display hex
ecall # we are out of here.
addi s0,s0, 8
add a0,zero,s0
addi a7,zero,34 # display hex
addi a7,zero,34 # display hex
ecall # we are out of here.
ret #persudo instruction jalr x0,x1,0
@@ -0,0 +1,281 @@
00100493
0100006f
00100493
00200913
00300993
0100006f
00100493
00200913
00300993
0100006f
00100493
00200913
00300993
0100006f
00100493
00200913
00300993
394000ef
00100413
00100493
01f49493
00900533
02200893
00000073
0024d493
00048463
fedff06f
00900533
02200893
00000073
00100493
00249493
00900533
02200893
00000073
00048463
fedff06f
00100493
01f49493
00900533
02200893
00000073
4034d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
4044d493
00900533
02200893
00000073
00100413
01f41993
41f9d993
00000433
00c00913
00300b13
00140413
00f47413
00800293
00100313
00499993
0089e9b3
01300533
02200893
00000073
406282b3
fe0294e3
00140413
00f00f93
01f47433
01c41413
00800293
00100313
0049d993
0089e9b3
01300533
02200893
00000073
406282b3
fe0294e3
01c45413
406b0b33
000b0463
f95ff06f
000002b3
fff2c293
00829293
0ff2e293
00500533
02200893
00000073
fff00413
00000493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
0084a023
00140413
00448493
00140413
00000433
03c00493
00042983
0004aa03
0149a2b3
00028663
0134a023
01442023
ffc48493
fe9412e3
00800533
02200893
00000073
00440413
03c00493
fc9416e3
00a00893
00000073
00200293
01100493
00849493
01148493
01049493
00900533
02200893
00000073
01c00e13
0254d4b3
00900533
02200893
00000073
fffe0e13
fe0e16e3
00a00893
00000073
08800493
00849493
04848493
08700913
00891913
05490913
02997933
01091913
11096913
01200533
02200893
00000073
00a00893
00000073
00000313
02000e13
00000493
00100913
00930023
00900533
02200893
00000073
012484b3
00130313
fffe0e13
fe0e12e3
00800e13
00000313
00032483
00900533
02200893
00000073
00430313
fffe0e13
fe0e14e3
00a00893
00000073
ff100493
00900533
02200893
00000073
00148493
fe04c8e3
00a00893
00000073
00000413
00140413
00800533
02200893
00000073
00240413
00800533
02200893
00000073
00340413
00800533
02200893
00000073
00440413
00800533
02200893
00000073
00540413
00800533
02200893
00000073
00640413
00800533
02200893
00000073
00740413
00800533
02200893
00000073
00840413
00800533
02200893
02200893
00000073
00008067
@@ -0,0 +1,67 @@
00500493
0140006f
00100493
00200913
00300993
00400a13
0140006f
00100493
00200913
00300993
00400a13
0140006f
00100493
00200913
00300993
00400a13
0140006f
00100493
00200913
00300993
00400a13
0140006f
00100493
00200913
00300993
00400a13
0140006f
00100493
00200913
00300993
00400a13
0140006f
00100493
00200913
00300993
00400a13
0140006f
00100493
00200913
00300993
00400a13
fff48493
f80492e3
00100413
0ff00913
00100493
00300993
01240c63
00840a63
00100493
00200913
00300993
00400a13
00949a63
01249863
00100493
00200913
00300993
00c000ef
00a00893
00000073
00000413
00140413
00800533
02200893
00000073
00008067
@@ -0,0 +1,421 @@
.text
addi sp, zero, 2000 #内存堆栈初始化
#############################################################
#走马灯测?,测试addi,andi,slli,srli,srai,or,ori,nor,ecall LED按走马灯方式来回显示数据
#############################################################
.text
START:
addi s0,zero,1
slli s3, s0, 31 # s3=0x80000000
srai s3, s3, 31 # s3=0xFFFFFFFF
add s0,zero,zero # s0=0
addi s2,zero,12
addi s6,zero,8 #走马灯计数
zmd_loop:
addi s0, s0, 1 #计算下一个走马灯的数
andi s0, s0, 15
#######################################
addi t0,zero,8
addi t1,zero,1
left:
slli s3, s3, 4 #走马灯左移
or s3, s3, s0
add a0,zero,s3 # display s3
addi a7,zero,34 # system call for LED display
ecall # display
sub t0,t0,t1
bne t0,zero,left
#######################################
addi s0, s0, 1 #计算下一个走马灯的数
addi t6,zero,15
and s0, s0, t6
slli s0, s0, 28
addi t0,zero,8
addi t1,zero,1
zmd_right:
srli s3, s3, 4 #走马灯右移
or s3, s3, s0
add a0,zero,s3 # display s3
addi a7,zero,34 # system call for LED display
ecall # display
sub t0,t0,t1
bne t0,zero,zmd_right
srli s0, s0, 28
#######################################
sub s6,s6,t1
beq s6,zero, exit
j zmd_loop
exit:
add t0,zero,zero
xori t0,t0,-1 #test nor ori
slli t0,t0,16
ori t0,t0,-1
add a0,zero,t0 # display t0
addi a7,zero,34 # system call for LED display
ecall # display
j START # loop forever
#InteruptProgram1:
#############################################################################################
# exceptoin 1
# 使用?s6? s5?s4?s3?s0?a0?a7
#############################################################################################
################# 保护现场
InteruptProgram1:
sw t0, 0(sp) #保护t0现场
addi sp, sp, 4
sw t3, 0(sp) #保护t3现场
addi sp, sp, 4
sw s1, 0(sp) #保护s1现场
addi sp, sp, 4
sw a7, 0(sp)
addi sp, sp, 4
sw a0, 0(sp)
addi sp, sp, 4
sw s0, 0(sp)
addi sp, sp, 4
sw s3, 0(sp)
addi sp, sp, 4
sw s4, 0(sp)
addi sp, sp, 4
sw s5, 0(sp)
addi sp, sp, 4
sw s6, 0(sp)
addi sp, sp, 4
csrrsi s6,0x41,0 #s6=uepc
sw s6, 0(sp) #uepc压栈保护
addi sp, sp, 4
################# 开中断
csrrsi zero,0x4,1 #ustatus.MIE=1
################# DIVU测试
addi t0,zero,2 # /2
addi s1,zero, 0x11
slli s1,s1,8
addi s1,s1,0x11
slli s1,s1,16
add a0,zero,s1
addi a7,zero,34
ecall
addi t3,zero,28 #ѭ������
divu_branch:
divu s1,s1,t0 #����ָ��
add a0,zero,s1
addi a7,zero,34
ecall #�����ǰֵ
addi t3,t3, -1
bne t3,zero,divu_branch #ѭ��
addi a7,zero,10
################# 中断服务
addi s6,zero,1 #中断?1,2,3 不同中断号显示值不一样
addi s4,zero,3 #循环次数初始值
addi s5,zero,1 #计数器累加值
IntLoop1:
add s0,zero,s6
IntLeftShift1:
slli s0, s0, 4
or s3,s0,s4
add a0,zero,s3 #display s0
addi a7,zero,34 # display hex
ecall
bne s0, zero, IntLeftShift1
sub s4,s4,s5 #循环次数递减
bne s4, zero, IntLoop1
################# 关中断
csrrci zero,0x4,1 #ustatus.MIE=0
################# 恢复现场
addi sp, sp, -4
lw s6, 0(sp)
csrrw zero,0x41,s6 #uepc=s6
addi sp, sp, -4
lw s6, 0(sp)
addi sp, sp, -4
lw s5, 0(sp)
addi sp, sp, -4
lw s4, 0(sp)
addi sp, sp, -4
lw s3, 0(sp)
addi sp, sp, -4
lw s0, 0(sp)
addi sp, sp, -4
lw a0, 0(sp)
addi sp, sp, -4
lw a7, 0(sp)
addi sp, sp, -4
lw s1, 0(sp) #恢复s1现场
addi sp, sp, -4
lw t3, 0(sp) #恢复t3现场
addi sp, sp, -4
lw t0, 0(sp) #恢复t0现场
################ 中断返回
uret #同步开中断,uepc-->pc
#InteruptProgram2:
#############################################################################################
# exceptoin 2
# 使用?s6? s5?s4?s3?s0?a0?a7
#############################################################################################
################# 保护现场
InteruptProgram2:
sw t1, 0(sp) #保护t1现场
addi sp, sp, 4
sw t3, 0(sp) #保护t3现场
addi sp, sp, 4
sw s1, 0(sp) #保护s1现场
addi sp, sp, 4
sw s2, 0(sp) #保护s2现场
addi sp, sp, 4
sw a7, 0(sp)
addi sp, sp, 4
sw a0, 0(sp)
addi sp, sp, 4
sw s0, 0(sp)
addi sp, sp, 4
sw s3, 0(sp)
addi sp, sp, 4
sw s4, 0(sp)
addi sp, sp, 4
sw s5, 0(sp)
addi sp, sp, 4
sw s6, 0(sp)
addi sp, sp, 4
csrrsi s6,0x41,0 #s6=uepc
sw s6, 0(sp) #uepc压栈保护
addi sp, sp, 4
################# 开中断
csrrsi zero,0x4,1 #ustatus.MIE=1
################# BLT测试
addi s1,zero,-15 #初始值
blt_branch:
add a0,zero,s1
addi a7,zero,34
ecall #输出当前值
addi s1,s1,1
blt s1,zero,blt_branch #当前指令
addi a7,zero,10
################# 中断服务
addi s6,zero,2 #中断?1,2,3 不同中断号显示值不一样
addi s4,zero,3 #循环次数初始值
addi s5,zero,1 #计数器累加值
IntLoop2:
add s0,zero,s6
IntLeftShift2:
slli s0, s0, 4
or s3,s0,s4
add a0,zero,s3 #display s0
addi a7,zero,34 # display hex
ecall
bne s0, zero, IntLeftShift2
sub s4,s4,s5 #循环次数递减
bne s4, zero, IntLoop2
################# 关中断
csrrci zero,0x4,1 #ustatus.MIE=0
################# 恢复现场
addi sp, sp, -4
lw s6, 0(sp)
csrrw zero,0x41,s6 #uepc=s6
addi sp, sp, -4
lw s6, 0(sp)
addi sp, sp, -4
lw s5, 0(sp)
addi sp, sp, -4
lw s4, 0(sp)
addi sp, sp, -4
lw s3, 0(sp)
addi sp, sp, -4
lw s0, 0(sp) #恢复s0现场
addi sp, sp, -4
lw a0, 0(sp)
addi sp, sp, -4
lw a7, 0(sp)
addi sp, sp, -4
lw s2, 0(sp) #恢复s2现场
addi sp, sp, -4
lw s1, 0(sp) #恢复s1现场
addi sp, sp, -4
lw t3, 0(sp) #恢复t3现场
addi sp, sp, -4
lw t1, 0(sp) #恢复t1现场
################ 中断返回
uret #同步开中断,uepc-->pc
#InteruptProgram3:
#############################################################################################
# exceptoin 3
# 使用?s6? s5?s4?s3?s0?a0?a7
#############################################################################################
################# 保护现场
InteruptProgram3:
sw s1, 0(sp) #保护s1现场
addi sp, sp, 4
sw a7, 0(sp)
addi sp, sp, 4
sw a0, 0(sp)
addi sp, sp, 4
sw s0, 0(sp)
addi sp, sp, 4
sw s3, 0(sp)
addi sp, sp, 4
sw s4, 0(sp)
addi sp, sp, 4
sw s5, 0(sp)
addi sp, sp, 4
sw s6, 0(sp)
addi sp, sp, 4
csrrsi s6,0x41,0 #s6=uepc
sw s6, 0(sp) #uepc压栈保护
addi sp, sp, 4
################# 开中断
csrrsi zero,0x4,1 #ustatus.MIE=1
################# SB测试
addi t1,zero,0 #init_addr
addi t3,zero,32 #counter
#sb写入 01,02,03,04
addi s1,zero, 0x00 #
addi s2,zero, 0x01 #
sb_store:
sb s1,(t1)
add a0,zero,s1
addi a7,zero,34 # system call for print
ecall # print
add s1,s1,s2 #data +1
addi t1,t1,1 # addr ++
addi t3,t3,-1 #counter
bne t3,zero,sb_store
addi t3,zero,8
addi t1,zero,0 # addr
sb_branch:
lw s1,(t1) #读出数据
add a0,zero,s1
addi a7,zero,34 # system call for print
ecall # print
addi t1,t1,4
addi t3,t3, -1
bne t3,zero,sb_branch
addi a7,zero,10 # system call for exit
################# 中断服务
addi s6,zero,3 #中断?1,2,3 不同中断号显示值不一样
addi s4,zero,3 #循环次数初始值
addi s5,zero,1 #计数器累加值
IntLoop3:
add s0,zero,s6
IntLeftShift3:
slli s0, s0, 4
or s3,s0,s4
add a0,zero,s3 #display s0
addi a7,zero,34 # display hex
ecall
bne s0, zero, IntLeftShift3
sub s4,s4,s5 #循环次数递减
bne s4, zero, IntLoop3
################# 关中断
csrrci zero,0x4,1 #ustatus.MIE=0
################# 恢复现场
addi sp, sp, -4
lw s6, 0(sp)
csrrw zero,0x41,s6 #uepc=s6
addi sp, sp, -4
lw s6, 0(sp)
addi sp, sp, -4
lw s5, 0(sp)
addi sp, sp, -4
lw s4, 0(sp)
addi sp, sp, -4
lw s3, 0(sp)
addi sp, sp, -4
lw s0, 0(sp)
addi sp, sp, -4
lw a0, 0(sp)
addi sp, sp, -4
lw a7, 0(sp)
addi sp, sp, -4
lw s1, 0(sp) #恢复s1现场
################ 中断返回
uret #同步开中断,uepc-->pc
@@ -0,0 +1,270 @@
7d000113
00100413
01f41993
41f9d993
00000433
00c00913
00800b13
00140413
00f47413
00800293
00100313
00499993
0089e9b3
01300533
02200893
00000073
406282b3
fe0294e3
00140413
00f00f93
01f47433
01c41413
00800293
00100313
0049d993
0089e9b3
01300533
02200893
00000073
406282b3
fe0294e3
01c45413
406b0b33
000b0463
f95ff06f
000002b3
fff2c293
01029293
fff2e293
00500533
02200893
00000073
f5dff06f
00512023
00410113
01c12023
00410113
00912023
00410113
01112023
00410113
00a12023
00410113
00812023
00410113
01312023
00410113
01412023
00410113
01512023
00410113
01612023
00410113
04106b73
01612023
00410113
0040e073
00200293
01100493
00849493
01148493
01049493
00900533
02200893
00000073
01c00e13
0254d4b3
00900533
02200893
00000073
fffe0e13
fe0e16e3
00a00893
00000073
00100b13
00300a13
00100a93
01600433
00441413
014469b3
01300533
02200893
00000073
fe0416e3
415a0a33
fe0a10e3
0040f073
ffc10113
00012b03
041b1073
ffc10113
00012b03
ffc10113
00012a83
ffc10113
00012a03
ffc10113
00012983
ffc10113
00012403
ffc10113
00012503
ffc10113
00012883
ffc10113
00012483
ffc10113
00012e03
ffc10113
00012283
00200073
00612023
00410113
01c12023
00410113
00912023
00410113
01212023
00410113
01112023
00410113
00a12023
00410113
00812023
00410113
01312023
00410113
01412023
00410113
01512023
00410113
01612023
00410113
04106b73
01612023
00410113
0040e073
ff100493
00900533
02200893
00000073
00148493
fe04c8e3
00a00893
00000073
00200b13
00300a13
00100a93
01600433
00441413
014469b3
01300533
02200893
00000073
fe0416e3
415a0a33
fe0a10e3
0040f073
ffc10113
00012b03
041b1073
ffc10113
00012b03
ffc10113
00012a83
ffc10113
00012a03
ffc10113
00012983
ffc10113
00012903
ffc10113
00012483
ffc10113
00012e03
ffc10113
00012303
ffc10113
00012403
ffc10113
00012503
ffc10113
00012883
00200073
00912023
00410113
01112023
00410113
00a12023
00410113
00812023
00410113
01312023
00410113
01412023
00410113
01512023
00410113
01612023
00410113
04106b73
01612023
00410113
0040e073
00000313
02000e13
00000493
00100913
00930023
00900533
02200893
00000073
012484b3
00130313
fffe0e13
fe0e12e3
00800e13
00000313
00032483
00900533
02200893
00000073
00430313
fffe0e13
fe0e14e3
00a00893
00000073
00300b13
00300a13
00100a93
01600433
00441413
014469b3
01300533
02200893
00000073
fe0416e3
415a0a33
fe0a10e3
0040f073
ffc10113
00012b03
041b1073
ffc10113
00012b03
ffc10113
00012a83
ffc10113
00012a03
ffc10113
00012483
ffc10113
00012983
ffc10113
00012403
ffc10113
00012503
ffc10113
00012883
00200073
+33
View File
@@ -0,0 +1,33 @@
# 指令 "Funct7
(十进制)" "Funct3
(十进制)" "OpCode
(十六进制)" ALU_OP MemtoReg MemWrite ALU_Src RegWrite ecall S_Type BEQ BNE Jal jalr REMU sel BLT r1u r2u CSR CSRW CSRRCI
1 add 0 0 C 5 1 1 1
2 sub 32 0 C 6 1 1 1
3 and 0 7 C 7 1 1 1
4 or 0 6 C 8 1 1 1
5 slt 0 2 C 11 1 1 1
6 sltu 0 3 C 12 1 1 1
7 addi 0 4 5 1 1 1
8 andi 7 4 7 1 1 1
9 ori 6 4 8 1 1 1
10 xori 4 4 9 1 1 1
11 slti 2 4 11 1 1 1
12 slli 0 1 4 0 1 1 1
13 srli 0 5 4 2 1 1 1
14 srai 32 5 4 1 1 1 1
15 lw 2 0 5 1 1 1 1
16 sw 2 8 5 1 1 1 1 1
17 ecall 0 0 1C 1 1 1
18 beq 0 18 6 1 1 1
19 bne 1 18 6 1 1 1
20 jal 1B 1 1
21 jalr 0 19 6 1 1 1 1
22 CSRRSI 6 1C 8 1 1 1
23 CSRRCI 7 1C 7 1 1 1 1
24 URET 2 0 1C 1
25 DIVU 1 5 C 4 1 1 1
26 REMU 1 7 C 4 1 1 1 1
27 SB 0 8 5 1 1 1 1 1 1
28 BLT 4 18 11 1 1 1
29 CSRRW 1 1C 1 1 1