Files
risc-v-cpu/testbench/programs/isa_test.asm
T
Anccend 192e28795a 实现 MMIO,LED 显示从 ecall 改为内存映射存储
cpu21_mmio.v(新增)
- 在 MEM 级做地址译码,把外设寄存器映射进数据地址空间;目前实现 LED 数据
  寄存器(地址由顶层 parameter LED_ADDR 指定,默认 0x0000_1000,位于 4 KB
  数据 RAM 之外,不会与 RAM 冲突);
- 地址译码按“字”对齐:同一 32 位寄存器内任意字节偏移都算命中,具体修改
  哪几个字节由 wstrb 决定,因此 sw 写全字、sb 只写单字节(与 RAM 字节写
  语义一致);
- 读命中时由顶层用 rdata_o 取代 data_rdata_i,从而支持把 LED 值读回;
- led_valid_o 在写入后拉高一拍,作为“本周期有 LED 写入”的指示。

cpu21_riscv_redirect_int_bpb.v
- 顶层参数新增 LED_ADDR;例化 cpu21_mmio 并新增访存读数据选择
  mem_rdata = mmio_rdata_hit ? mmio_rdata : data_rdata_i(MEM/WB 捕获用它);
- 删除 ecall 驱动的 LED 逻辑(原 ex_led_event 与 led_data_q/led_valid_q 寄存器
  移入 MMIO 模块),LED 输出端口改由 cpu21_mmio 驱动;
- ecall 保留停机语义:a7==34 的历史“显示”调用保留为无操作,其余(如 a7=10)
  仍置 halted_o。

测试资产
- tools/rv_asm.py:print 伪指令改为“lui t6,LED_ADDR>>12 + sw a0,0(t6)”(写 MMIO
  LED 寄存器,仍需两个字);新增 sb 支持;文末说明同步更新;
- testbench/programs/mmio_test.asm + mmio_test.expected(新增):覆盖全字写、
  读回、字节写三种情况;
- isa_test.asm / lui_test.asm 迁移到 MMIO 输出方式;
- 两个 testbench 的 RAM 模型处注明 MMIO 区域不属于 RAM。

验证(xsim,按提交后的正式路径生成 hex)
- mmio_test:4 项输出全部匹配(12345678 / 12345678 / ffffffff / ffff7fff,
  最后一项为 sb 覆盖 led[15:8] 后读回);
- isa_test:24 项输出与 isa_test.expected 逐项一致;lui_test:4 项输出正确;
- 中断测试程序回归:IRQ1@cyc85、IRQ2@cyc266、IRQ3@cyc447 与改动前一致,
  FINAL 统计完全一致(stalls=11 bubbles=297 cond_taken=648 pred_ok=663
  pred_fail=102,6003 周期);
- benchmark 长仿真回归:FINAL 统计与改动前完全一致(stalls=3195 bubbles=6955
  cond_taken=8857 pred_ok=9455 pred_fail=1050,60000 周期),且 LED 输出次数为 0,
  确认 ecall 已不再驱动 LED;
- cpu21_mmio.v 已加入 Vivado 工程 sources_1。
2026-09-13 16:30:57 +08:00

111 lines
3.5 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 指令扩展验证程序:每条被测指令的结果都通过 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