diff --git a/.gitignore b/.gitignore index f1a1650..ff21045 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ +# Vivado 工程生成物不入库;源文件都在 pipelined-cpu/ 下(srcs/、tools/、programs/) pipelined-cpu/* -# 例外:一键重建工程的分享脚本要入库(其余工程生成物不入库) +!pipelined-cpu/srcs/ +!pipelined-cpu/tools/ +!pipelined-cpu/programs/ !pipelined-cpu/create_project.tcl # 本地临时目录(仿真脚本、日志、中间文件) @@ -10,4 +13,4 @@ _vivado/ *.vcd *.pb *.hex.lst -.Xil/ +.Xil/ \ No newline at end of file diff --git a/cpu21_riscv_redirect_int_bpb说明.md b/cpu21_riscv_redirect_int_bpb说明.md index 5dccf26..df8ad6a 100644 --- a/cpu21_riscv_redirect_int_bpb说明.md +++ b/cpu21_riscv_redirect_int_bpb说明.md @@ -1,6 +1,6 @@ # `cpu21-riscv-4.circ` 的 Verilog 实现 -处理器顶层文件:`rtl/cpu21_riscv_redirect_int_bpb.v` +处理器顶层文件:`pipelined-cpu/srcs/rtl/cpu21_riscv_redirect_int_bpb.v` 该设计对应原电路中的“重定向流水线+中断+分支预测”部分,顶层模块为 `cpu21_riscv_redirect_int_bpb`。为便于单独仿真与调试,各功能单元已拆分为 @@ -10,26 +10,25 @@ ```text risc-v/ -├─ rtl/ 处理器 RTL(13 个文件,cpu21_riscv_redirect_int_bpb.v 为顶层) -├─ board/ 上板(Nexys4DDR):板级顶层、引脚约束、片内 ROM 初始化 -│ ├─ cpu21_board_top.v 板级顶层(时钟分频 + 片内 ROM/RAM + 引脚) -│ ├─ cpu21_board_top.xdc 引脚约束与分频时钟约束 -│ ├─ cpu21_board_rom.vh 片内 ROM 内容(由 tools/hex2vh.py 生成,上板用) -│ └─ cpu21_board_rom_fast.vh 短延时的 ROM 内容(仅仿真,-d BOARD_ROM_FAST 选择) -├─ testbench/ 仿真 -│ ├─ tb_cpu21_riscv_redirect_int_bpb.v 中断/分支预测测试平台 -│ ├─ tb_no_intr.v 无中断测试平台(指令集测试用) -│ ├─ tb_board_top.v 板级顶层仿真 -│ ├─ rom/ 仿真实际加载的 ROM 镜像(.hex) -│ └─ programs/ 汇编源程序、期望值、课程原始资产(RARS) -├─ tools/ rv_asm.py(迷你汇编器)、hex2vh.py(hex → ROM 初始化) -├─ pipelined-cpu/ Vivado 工程(本地目录,不入库) -└─ cpu21_riscv_redirect_int_bpb说明.md 本文档 +├─ pipelined-cpu/ Vivado 工程目录(也是源文件所在地) +│ ├─ create_project.tcl 一键重建工程的 Tcl 脚本 +│ ├─ srcs/rtl/*.v 处理器 RTL(13 个文件,cpu21_riscv_redirect_int_bpb.v 为顶层) +│ ├─ srcs/board/*.v|*.vh 板级顶层(时钟分频 + 片内 ROM/RAM + 引脚)、片内 ROM 初始化 +│ ├─ srcs/constrs/*.xdc 引脚与分频时钟约束(+ Nexys4DDR 母版) +│ ├─ srcs/tb/*.v 三个测试平台 +│ ├─ srcs/rom/*.hex 测试平台加载的 ROM 镜像 +│ ├─ tools/ rv_asm.py(迷你汇编器)、hex2vh.py(hex → ROM 初始化)、run_regress.ps1(一键回归) +│ ├─ programs/ 汇编源程序、期望值、课程原始资产(RARS) +│ └─ pipelined-cpu.xpr(+*.runs/…) 本机工程与生成物(不入库,可删) +├─ cpu21_riscv_redirect_int_bpb说明.md 本文档 +└─ _tmp/、_vivado/ 本地临时目录(不入库) ``` -约定:`rtl/` 只放可综合的处理器源码;板级/仿真相关的东西都在 `board/`、 -`testbench/` 下;`testbench/rom/` 里的镜像是测试平台默认加载的那个版本 -(已按 MMIO 写 LED 修改),`testbench/programs/` 保留课程原始程序与 RARS 输出。 +约定:git 只跟踪 `pipelined-cpu/` 下的源文件(`srcs/`、`tools/`、`programs/`、 +`create_project.tcl`),Vivado 生成物(`*.xpr`、`*.runs`、`*.sim`、`*.cache`…)由 +`.gitignore` 排除。`srcs/rtl/` 只放可综合的处理器源码;板级顶层与约束在 `srcs/board/`、 +`srcs/constrs/`;测试平台与 ROM 镜像在 `srcs/tb/`、`srcs/rom/`(镜像是按 MMIO 写 LED +修改过的版本,课程原始程序与 RARS 输出保留在 `programs/`)。 ## 已转换的功能 @@ -47,7 +46,7 @@ risc-v/ - `sltiu`:I 型 `funct3=011`,立即数符号扩展后按无符号与 rs1 比较。 - M 扩展乘法(`funct7=0000001`):`mul`(乘积低 32 位)、`mulh`(有符号×有符号高 32 位)、`mulhsu`(有符号×无符号高 32 位)、`mulhu`(无符号×无符号高 32 位)。 - M 扩展除法:课程真值表里的 `divu`(`funct3=101`,无符号商)与 `remu`(`funct3=111`,无符号余数)。 - 以上六条乘法/除法指令都由 **多周期单元** `rtl/cpu21_riscv_muldiv.v` 完成(见“时序和使用说明”第 7 条), + 以上六条乘法/除法指令都由 **多周期单元** `pipelined-cpu/srcs/rtl/cpu21_riscv_muldiv.v` 完成(见“时序和使用说明”第 7 条), 而不是组合逻辑。 ## 指令编码 @@ -73,7 +72,7 @@ risc-v/ ## MMIO 与外设 -外设寄存器映射在数据存储器地址空间,由 `rtl/cpu21_mmio.v` 在 MEM 级译码, +外设寄存器映射在数据存储器地址空间,由 `pipelined-cpu/srcs/rtl/cpu21_mmio.v` 在 MEM 级译码, 顶层参数 `LED_ADDR`(默认 `0x0000_1000`)指定 LED 数据寄存器的地址。 该地址位于 4 KB 数据 RAM(`0x0000`–`0x0FFC`)之外,因此不会与 RAM 冲突。 @@ -85,7 +84,7 @@ risc-v/ 具体修改哪几个字节由 `data_wstrb_o` 决定。`data_addr_o` 在命中 MMIO 时不会 访问外部 RAM;读数据由 `cpu21_mmio` 的输出在顶层与 `data_rdata_i` 做选择。 -典型用法(LED 写 `0x12345678`,可用 `tools/rv_asm.py` 汇编): +典型用法(LED 写 `0x12345678`,可用 `pipelined-cpu/tools/rv_asm.py` 汇编): ```asm lui t0, 0x1 # t0 = LED_ADDR = 0x00001000 @@ -95,9 +94,9 @@ risc-v/ lw a0, 0(t0) # MMIO 读回 ``` -`testbench/programs/mmio_test.asm`(期望值见 `mmio_test.expected`)覆盖了 +`pipelined-cpu/programs/mmio_test.asm`(期望值见 `mmio_test.expected`)覆盖了 全字写、读回、字节写三种情况。加入新外设(拨码开关、UART 等)时只需在 -`rtl/cpu21_mmio.v` 里扩展地址译码,处理器流水线无需改动。 +`pipelined-cpu/srcs/rtl/cpu21_mmio.v` 里扩展地址译码,处理器流水线无需改动。 ## 顶层端口约定 @@ -124,29 +123,29 @@ risc-v/ ## 文件与模块划分 -| 文件 | 模块 | 职责 | -| --------------------------------------------- | --------------------------------- | ---------------------------------------------------------------- | -| `rtl/cpu21_riscv_redirect_int_bpb.v` | `cpu21_riscv_redirect_int_bpb` | 顶层:五级流水寄存器、子模块例化、PC/IF-ID/ID-EX 控制、对外输出 | -| `rtl/cpu21_riscv_alu.v` | `cpu21_riscv_alu` | 组合 ALU(加减/移位/逻辑/比较,不做乘除) | -| `rtl/cpu21_riscv_muldiv.v` | `cpu21_riscv_muldiv` | 多周期乘除法单元:32 拍移位迭代,mul/mulh/mulhsu/mulhu/divu/remu | -| `rtl/cpu21_bpb_8.v` | `cpu21_bpb_8` | 8 项全相联分支目标缓冲(2 位饱和计数器 + 近似 LRU) | -| `rtl/cpu21_riscv_decoder.v` | `cpu21_riscv_decoder` | ID 级组合译码器(操作码`IR[6:2]`) | -| `rtl/cpu21_riscv_regfile.v` | `cpu21_riscv_regfile` | 寄存器堆,`x0` 恒为 0,同周期 WB 写优先旁路 | -| `rtl/cpu21_riscv_forward_unit.v` | `cpu21_riscv_forward_unit` | EX 级前递网络(EX/MEM 优先于 MEM/WB) | -| `rtl/cpu21_riscv_store_unit.v` | `cpu21_riscv_store_unit` | EX 级存储数据对齐:`sw`/`sb` 的写数据与字节写掩码 | -| `rtl/cpu21_riscv_branch_unit.v` | `cpu21_riscv_branch_unit` | EX 级控制流裁决:分支方向/目标、JAL/JALR 重定向 | -| `rtl/cpu21_riscv_hazard_unit.v` | `cpu21_riscv_hazard_unit` | load-use 冒险、停顿(stall)与冲刷(flush)判定 | -| `rtl/cpu21_riscv_irq_ctrl.v` | `cpu21_riscv_irq_ctrl` | 中断采样与优先级、`ustatus`/`uepc` CSR、嵌套返回栈 | -| `rtl/cpu21_riscv_perf_counters.v` | `cpu21_riscv_perf_counters` | 周期/停顿/气泡/分支/预测成功率等统计计数器 | -| `rtl/cpu21_mmio.v` | `cpu21_mmio` | MMIO 外设:LED 数据寄存器(可写、可读回,支持字节写) | -| `board/cpu21_board_top.v` | `cpu21_board_top` | 板级顶层:时钟分频、复位同步、片内 ROM/RAM、引脚外设连接 | -| `board/cpu21_board_top.xdc` | — | Nexys4DDR 引脚约束 + 分频时钟(`create_generated_clock`) | -| `board/cpu21_board_rom.vh` | — | 片内 ROM 内容(生成文件,`rom[i] = 32'h…;`) | -| `testbench/tb_board_top.v` | `tb_board_top` | 板级顶层的 RTL 仿真(观察 LED 跑马灯与写入指示) | -| `testbench/tb_no_intr.v` | `tb_no_intr` | 无中断测试平台(指令集/MMIO 测试,默认加载 benchmark 镜像) | -| `testbench/tb_cpu21_riscv_redirect_int_bpb.v` | `tb_cpu21_riscv_redirect_int_bpb` | 中断与分支预测测试平台(默认加载中断测试镜像) | -| `tools/rv_asm.py` | — | 迷你汇编器:`.asm` → 机器码 hex(`.lst` 带反汇编清单) | -| `tools/hex2vh.py` | — | hex →`board/cpu21_board_rom.vh`(`rom[i] = 32'h…;` 初始化语句) | +| 文件 | 模块 | 职责 | +| --------------------------------------------------------- | --------------------------------- | ---------------------------------------------------------------------------------- | +| `pipelined-cpu/srcs/rtl/cpu21_riscv_redirect_int_bpb.v` | `cpu21_riscv_redirect_int_bpb` | 顶层:五级流水寄存器、子模块例化、PC/IF-ID/ID-EX 控制、对外输出 | +| `pipelined-cpu/srcs/rtl/cpu21_riscv_alu.v` | `cpu21_riscv_alu` | 组合 ALU(加减/移位/逻辑/比较,不做乘除) | +| `pipelined-cpu/srcs/rtl/cpu21_riscv_muldiv.v` | `cpu21_riscv_muldiv` | 多周期乘除法单元:32 拍移位迭代,mul/mulh/mulhsu/mulhu/divu/remu | +| `pipelined-cpu/srcs/rtl/cpu21_bpb_8.v` | `cpu21_bpb_8` | 8 项全相联分支目标缓冲(2 位饱和计数器 + 近似 LRU) | +| `pipelined-cpu/srcs/rtl/cpu21_riscv_decoder.v` | `cpu21_riscv_decoder` | ID 级组合译码器(操作码`IR[6:2]`) | +| `pipelined-cpu/srcs/rtl/cpu21_riscv_regfile.v` | `cpu21_riscv_regfile` | 寄存器堆,`x0` 恒为 0,同周期 WB 写优先旁路 | +| `pipelined-cpu/srcs/rtl/cpu21_riscv_forward_unit.v` | `cpu21_riscv_forward_unit` | EX 级前递网络(EX/MEM 优先于 MEM/WB) | +| `pipelined-cpu/srcs/rtl/cpu21_riscv_store_unit.v` | `cpu21_riscv_store_unit` | EX 级存储数据对齐:`sw`/`sb` 的写数据与字节写掩码 | +| `pipelined-cpu/srcs/rtl/cpu21_riscv_branch_unit.v` | `cpu21_riscv_branch_unit` | EX 级控制流裁决:分支方向/目标、JAL/JALR 重定向 | +| `pipelined-cpu/srcs/rtl/cpu21_riscv_hazard_unit.v` | `cpu21_riscv_hazard_unit` | load-use 冒险、停顿(stall)与冲刷(flush)判定 | +| `pipelined-cpu/srcs/rtl/cpu21_riscv_irq_ctrl.v` | `cpu21_riscv_irq_ctrl` | 中断采样与优先级、`ustatus`/`uepc` CSR、嵌套返回栈 | +| `pipelined-cpu/srcs/rtl/cpu21_riscv_perf_counters.v` | `cpu21_riscv_perf_counters` | 周期/停顿/气泡/分支/预测成功率等统计计数器 | +| `pipelined-cpu/srcs/rtl/cpu21_mmio.v` | `cpu21_mmio` | MMIO 外设:LED 数据寄存器(可写、可读回,支持字节写) | +| `pipelined-cpu/srcs/board/cpu21_board_top.v` | `cpu21_board_top` | 板级顶层:时钟分频、复位同步、片内 ROM/RAM、引脚外设连接 | +| `pipelined-cpu/srcs/constrs/cpu21_board_top.xdc` | — | Nexys4DDR 引脚约束 + 分频时钟(`create_generated_clock`) | +| `pipelined-cpu/srcs/board/cpu21_board_rom.vh` | — | 片内 ROM 内容(生成文件,`rom[i] = 32'h…;`) | +| `pipelined-cpu/srcs/tb/tb_board_top.v` | `tb_board_top` | 板级顶层的 RTL 仿真(观察 LED 跑马灯与写入指示) | +| `pipelined-cpu/srcs/tb/tb_no_intr.v` | `tb_no_intr` | 无中断测试平台(指令集/MMIO 测试,默认加载 benchmark 镜像) | +| `pipelined-cpu/srcs/tb/tb_cpu21_riscv_redirect_int_bpb.v` | `tb_cpu21_riscv_redirect_int_bpb` | 中断与分支预测测试平台(默认加载中断测试镜像) | +| `pipelined-cpu/tools/rv_asm.py` | — | 迷你汇编器:`.asm` → 机器码 hex(`.lst` 带反汇编清单) | +| `pipelined-cpu/tools/hex2vh.py` | — | hex →`pipelined-cpu/srcs/board/cpu21_board_rom.vh`(`rom[i] = 32'h…;` 初始化语句) | 拆分只调整了模块边界与文件组织,端口、时序与行为完全等价:使用同一 ROM 程序 在 xsim 下对拆分前后逐周期对比,波形输出与最终统计(周期、停顿、气泡、分支 @@ -175,7 +174,7 @@ BPB/中断观测值)。如果直接把它设为实现顶层,这些端口会 乘除法原本是 ALU 里的组合运算(`a*b`、`a%b`),实测关键路径约 94 ns(325 级逻辑、 286 个 CARRY4),在 100 MHz 下必然不收敛,所以之前只能把时钟 16 分频到 6.25 MHz。 -现在乘除法改成了 `rtl/cpu21_riscv_muldiv.v` 里的 **32 拍迭代多周期单元**,关键路径上 +现在乘除法改成了 `pipelined-cpu/srcs/rtl/cpu21_riscv_muldiv.v` 里的 **32 拍迭代多周期单元**,关键路径上 不再有组合乘/除,也不需要再分频了;但把所有加法器/比较器都换成迭代后,在 100 MHz 下仍有约 1.1 ns 的违例——那是 **EX 级“分支判决 / 中断保存 → BPB 更新”这条与乘除法 无关的组合路径**(逻辑只占约 3 ns,剩下 7~8 ns 全是布线)。 @@ -215,12 +214,13 @@ create_generated_clock -name cpu_clk -source [get_ports { clk100 }] \ ### 演示程序的生成与仿真 ```powershell -# 1) 汇编 + 生成 ROM 初始化文件(在仓库根目录执行) -python tools/rv_asm.py testbench/programs/board_demo.asm _tmp/board_demo.hex -python tools/hex2vh.py _tmp/board_demo.hex board/cpu21_board_rom.vh 1024 +# 在工程目录 pipelined-cpu/ 下执行: +# 1) 汇编 + 生成 ROM 初始化文件 +python tools/rv_asm.py programs/board_demo.asm _tmp/board_demo.hex +python tools/hex2vh.py _tmp/board_demo.hex srcs/board/cpu21_board_rom.vh 1024 # 2) 上板顶层的 RTL 仿真(默认程序延时约 20 ms,只需确认第一次写入 LED=0001) -xvlog rtl/*.v board/cpu21_board_top.v testbench/tb_board_top.v +xvlog srcs/rtl/*.v srcs/board/cpu21_board_top.v srcs/tb/tb_board_top.v xelab -top tb_board_top -snapshot board_sim xsim board_sim -tclbatch run_quit.tcl ``` @@ -229,20 +229,24 @@ xsim board_sim -tclbatch run_quit.tcl 每步之间用软件循环延时约 20 ms(50 MHz 下)。仓库里同时提供了两份 ROM 初始化 文件,由 `BOARD_ROM_FAST` 宏选择(综合流程不会定义该宏): -| 文件 | 用途 | 每步耗时 | -| ------------------------------- | ------------------------------ | -------- | -| `board/cpu21_board_rom.vh` | 综合/上板(默认) | 约 20 ms | -| `board/cpu21_board_rom_fast.vh` | 仅仿真:一次跑完整个跑马灯序列 | 2.6 µs | +| 文件 | 用途 | 每步耗时 | +| -------------------------------------------------- | ------------------------------ | -------- | +| `pipelined-cpu/srcs/board/cpu21_board_rom.vh` | 综合/上板(默认) | 约 20 ms | +| `pipelined-cpu/srcs/board/cpu21_board_rom_fast.vh` | 仅仿真:一次跑完整个跑马灯序列 | 2.6 µs | ```powershell -# 快速版仿真:编译时加上 -d BOARD_ROM_FAST(注意 xvlog/elaborate 都要带) -xvlog -d BOARD_ROM_FAST rtl/*.v board/cpu21_board_top.v testbench/tb_board_top.v +# 快速版仿真:编译时加上 -d BOARD_ROM_FAST(xvlog 与 xelab 都要带) +xvlog -d BOARD_ROM_FAST srcs/rtl/*.v srcs/board/cpu21_board_top.v srcs/tb/tb_board_top.v xelab -top tb_board_top -snapshot board_sim_fast -d BOARD_ROM_FAST ``` -两份文件都由同样的两步生成,只有延时循环的初值不同(把 `board_demo.asm` 里的 -`lui t2, 0x7a` 换成 `addi t2, zero, 64` 再照上面两步走一遍,输出到 -`board/cpu21_board_rom_fast.vh`)。 +两份 ROM 初始化文件由 `programs/board_demo.asm`(默认,≈ 20 ms/步)与 +`programs/board_demo_fast.asm`(快速版,≈ 2.6 µs/步,只差延时循环的初值)生成: + +```powershell +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 +``` ### Vivado 工程设置与实现结果 @@ -250,13 +254,12 @@ Vivado 工程 `pipelined-cpu/pipelined-cpu.xpr` 被 `.gitignore` 排除,需要 1. `sources_1` 顶层设为 `cpu21_board_top`(纯 RTL 仿真时也可切回 `cpu21_riscv_redirect_int_bpb`); -2. 加入 `board/cpu21_board_top.v`、`board/cpu21_board_top.xdc`, - `board/cpu21_board_rom.vh` 的文件类型设成 `Verilog Header`(不能当普通源码, +2. 加入 `pipelined-cpu/srcs/board/cpu21_board_top.v`、`pipelined-cpu/srcs/constrs/cpu21_board_top.xdc`, + `pipelined-cpu/srcs/board/cpu21_board_rom.vh` 的文件类型设成 `Verilog Header`(不能当普通源码, 否则会被当成顶层候选); 3. 三个 testbench 放在**仿真 fileset**(`sim_1` 顶层 `tb_cpu21_riscv_redirect_int_bpb`、 `sim_2` 顶层 `tb_no_intr`),不参与综合,因此不会再出现“testbench 被当成顶层” - 导致的 `[Place 30-494] The design is empty`。仓库里的 `testbench/` 与工程里的 - `srcs/tb/` 是同一批文件。 + 导致的 `[Place 30-494] The design is empty`。 `xc7a100tcsg324-1` 上的实现结果(乘除法改为多周期单元、`CLK_DIV=2` = 50 MHz): @@ -274,6 +277,34 @@ CPU 时钟 6.25 MHz → 50 MHz(快 8 倍),并且乘除法不再位于关 `.bit`。复位后跑马灯立即从 `0001` 开始逐位左移(演示程序不执行 `ecall`,所以不用 按 `go`;`go` 只对执行了 `ecall` 停机、等待继续运行的程序有意义),LED16_B 每次写入时点亮。 +## 回归测试 + +工程里带了一个 xsim 回归脚本,在 `pipelined-cpu/` 目录下运行: + +```powershell +powershell -ExecutionPolicy Bypass -File tools\run_regress.ps1 +``` + +它会按顺序做四件事: + +1. 编译 `srcs/rtl/` 下的处理器源码; +2. 跑 4 个指令测试(`muldiv_test`、`isa_test`、`lui_test`、`mmio_test`),把测试平台 + 打印的 LED 序列与 `programs/*.expected` 逐值比对; +3. 跑两个流水基线(`tb_no_intr`、`tb_cpu21_riscv_redirect_int_bpb`),打印 FINAL 统计行; +4. 跑板级顶层(`-d BOARD_ROM_FAST`),检查跑马灯 LED 序列。 + +最后汇总 PASS/FAIL,并以失败数作为退出码。编译与仿真的中间文件都写在 +`%TEMP%\cpu21_regress` 下,不会污染工程目录;需要 `xvlog`/`xelab`/`xsim` 在 PATH 上。 + +期望结果(2026-09,多周期乘除法 + `CLK_DIV=2`): + +| 测试 | 期望 | +| ---- | ---- | +| muldiv_test / isa_test / lui_test / mmio_test | 13 / 24 / 4 / 5 个 LED 值全部匹配 | +| tb_no_intr(benchmark,5560 周期) | `stalls=1528 bubbles=1830 cond_taken=639 uncond=71 pred_ok=687 pred_fail=80` | +| tb_cpu21_riscv_redirect_int_bpb(中断,6003 周期) | `stalls=963 bubbles=1205 cond_taken=547 uncond=28 pred_ok=557 pred_fail=87` | +| 板级(快速 ROM) | 跑马灯 `0001 → … → 8000` 循环,每步约 2.6 µs | + ## 工程分享(Tcl 一键重建) `pipelined-cpu/` 已整理成“自包含 + 可直接分享”的工程目录,设计文件都在里面, @@ -282,7 +313,7 @@ CPU 时钟 6.25 MHz → 50 MHz(快 8 倍),并且乘除法不再位于关 ```text pipelined-cpu/ ├─ create_project.tcl 一键重建脚本(用 [info script] 定位自身目录) -├─ srcs/rtl/*.v 处理器 RTL(12 个文件) +├─ srcs/rtl/*.v 处理器 RTL(13 个文件) ├─ srcs/board/*.v|*.vh 板级顶层、片内 ROM 初始化(含 __FAST 仿真版本) ├─ srcs/constrs/*.xdc 引脚约束 + 板级母版 ├─ srcs/tb/*.v 三个测试平台 @@ -311,19 +342,11 @@ source create_project.tcl 就停下(看起来像卡死)。 分享前建议删掉生成目录:`*.xpr`、`*.runs`、`*.sim`、`*.cache`、`*.hw`、`*.gen`、 -`*.ip_user_files`、`.Xil`。实测只带 `create_project.tcl` + `srcs/` + `tools/` + +`*.ip_user_files`、`.Xil`。实测只带 `create_project.tcl` + `srcs/` + `pipelined-cpu/tools/` + `programs/` + 说明文档约 **0.3 MB**,在任意路径重建工程并综合成功。 -> 仓库根目录的 `rtl/`、`board/`、`testbench/` 是源文件,`pipelined-cpu/srcs/` 里的是 -> 分享用副本。在仓库里改了 RTL/测试平台后,同步一下即可: -> -> ```powershell -> Copy-Item rtl\*.v pipelined-cpu\srcs\rtl\ -Force -> Copy-Item board\cpu21_board_top.v,board\cpu21_board_rom*.vh pipelined-cpu\srcs\board\ -Force -> Copy-Item board\cpu21_board_top.xdc pipelined-cpu\srcs\constrs\ -Force -> Copy-Item testbench\tb_*.v pipelined-cpu\srcs\tb\ -Force -> Copy-Item testbench\rom\*.hex pipelined-cpu\srcs\rom\ -Force -> ``` +> 源文件只有一份,就在 `pipelined-cpu/srcs/`(`tools/`、`programs/` 同理), +> 直接在工程目录里改即可,没有需要同步的副本。 也可以用 Vivado 自动生成: diff --git a/testbench/programs/board_demo.asm b/pipelined-cpu/programs/board_demo.asm similarity index 100% rename from testbench/programs/board_demo.asm rename to pipelined-cpu/programs/board_demo.asm diff --git a/pipelined-cpu/programs/board_demo_fast.asm b/pipelined-cpu/programs/board_demo_fast.asm new file mode 100644 index 0000000..4884117 --- /dev/null +++ b/pipelined-cpu/programs/board_demo_fast.asm @@ -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 diff --git a/testbench/programs/isa_test.asm b/pipelined-cpu/programs/isa_test.asm similarity index 100% rename from testbench/programs/isa_test.asm rename to pipelined-cpu/programs/isa_test.asm diff --git a/testbench/programs/isa_test.expected b/pipelined-cpu/programs/isa_test.expected similarity index 100% rename from testbench/programs/isa_test.expected rename to pipelined-cpu/programs/isa_test.expected diff --git a/testbench/programs/lui_test.asm b/pipelined-cpu/programs/lui_test.asm similarity index 100% rename from testbench/programs/lui_test.asm rename to pipelined-cpu/programs/lui_test.asm diff --git a/testbench/programs/lui_test.expected b/pipelined-cpu/programs/lui_test.expected similarity index 100% rename from testbench/programs/lui_test.expected rename to pipelined-cpu/programs/lui_test.expected diff --git a/testbench/programs/mmio_test.asm b/pipelined-cpu/programs/mmio_test.asm similarity index 100% rename from testbench/programs/mmio_test.asm rename to pipelined-cpu/programs/mmio_test.asm diff --git a/testbench/programs/mmio_test.expected b/pipelined-cpu/programs/mmio_test.expected similarity index 100% rename from testbench/programs/mmio_test.expected rename to pipelined-cpu/programs/mmio_test.expected diff --git a/testbench/programs/muldiv_test.asm b/pipelined-cpu/programs/muldiv_test.asm similarity index 100% rename from testbench/programs/muldiv_test.asm rename to pipelined-cpu/programs/muldiv_test.asm diff --git a/testbench/programs/muldiv_test.expected b/pipelined-cpu/programs/muldiv_test.expected similarity index 100% rename from testbench/programs/muldiv_test.expected rename to pipelined-cpu/programs/muldiv_test.expected diff --git a/testbench/programs/rars_f0c874c.jar b/pipelined-cpu/programs/rars_f0c874c.jar similarity index 100% rename from testbench/programs/rars_f0c874c.jar rename to pipelined-cpu/programs/rars_f0c874c.jar diff --git a/testbench/programs/risc-v-benchmark_ccab.asm b/pipelined-cpu/programs/risc-v-benchmark_ccab.asm similarity index 100% rename from testbench/programs/risc-v-benchmark_ccab.asm rename to pipelined-cpu/programs/risc-v-benchmark_ccab.asm diff --git a/testbench/programs/risc-v-benchmark_ccab.hex b/pipelined-cpu/programs/risc-v-benchmark_ccab.hex similarity index 100% rename from testbench/programs/risc-v-benchmark_ccab.hex rename to pipelined-cpu/programs/risc-v-benchmark_ccab.hex diff --git a/testbench/programs/risc-v-分支预测测试.hex b/pipelined-cpu/programs/risc-v-分支预测测试.hex similarity index 100% rename from testbench/programs/risc-v-分支预测测试.hex rename to pipelined-cpu/programs/risc-v-分支预测测试.hex diff --git a/testbench/programs/risc-v多级中断测试(EPC内存堆栈保护) - ccab.asm b/pipelined-cpu/programs/risc-v多级中断测试(EPC内存堆栈保护) - ccab.asm similarity index 100% rename from testbench/programs/risc-v多级中断测试(EPC内存堆栈保护) - ccab.asm rename to pipelined-cpu/programs/risc-v多级中断测试(EPC内存堆栈保护) - ccab.asm diff --git a/testbench/programs/risc-v多级中断测试(EPC内存堆栈保护) - ccab.hex b/pipelined-cpu/programs/risc-v多级中断测试(EPC内存堆栈保护) - ccab.hex similarity index 100% rename from testbench/programs/risc-v多级中断测试(EPC内存堆栈保护) - ccab.hex rename to pipelined-cpu/programs/risc-v多级中断测试(EPC内存堆栈保护) - ccab.hex diff --git a/testbench/programs/真值表.txt b/pipelined-cpu/programs/真值表.txt similarity index 100% rename from testbench/programs/真值表.txt rename to pipelined-cpu/programs/真值表.txt diff --git a/board/cpu21_board_rom.vh b/pipelined-cpu/srcs/board/cpu21_board_rom.vh similarity index 100% rename from board/cpu21_board_rom.vh rename to pipelined-cpu/srcs/board/cpu21_board_rom.vh diff --git a/board/cpu21_board_rom_fast.vh b/pipelined-cpu/srcs/board/cpu21_board_rom_fast.vh similarity index 100% rename from board/cpu21_board_rom_fast.vh rename to pipelined-cpu/srcs/board/cpu21_board_rom_fast.vh diff --git a/board/cpu21_board_top.v b/pipelined-cpu/srcs/board/cpu21_board_top.v similarity index 100% rename from board/cpu21_board_top.v rename to pipelined-cpu/srcs/board/cpu21_board_top.v diff --git a/pipelined-cpu/srcs/constrs/Nexys4DDR_Master.xdc b/pipelined-cpu/srcs/constrs/Nexys4DDR_Master.xdc new file mode 100644 index 0000000..ecf1c90 --- /dev/null +++ b/pipelined-cpu/srcs/constrs/Nexys4DDR_Master.xdc @@ -0,0 +1,265 @@ +## This file is a general .xdc for the Nexys4 DDR Rev. C +## To use it in a project: +## - uncomment the lines corresponding to used pins +## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project + +## Clock signal +#set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { CLK100MHZ }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz +#create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {CLK100MHZ}]; + + +##Switches + +#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { SW[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0] +#set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { SW[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1] +#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { SW[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2] +#set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { SW[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3] +#set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { SW[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4] +#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { SW[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5] +#set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { SW[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6] +#set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { SW[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7] +#set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { SW[8] }]; #IO_L24N_T3_34 Sch=sw[8] +#set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { SW[9] }]; #IO_25_34 Sch=sw[9] +#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { SW[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10] +#set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { SW[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11] +#set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { SW[12] }]; #IO_L24P_T3_35 Sch=sw[12] +#set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { SW[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13] +#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { SW[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14] +#set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { SW[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15] + + +## LEDs + +#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { LED[0] }]; #IO_L18P_T2_A24_15 Sch=led[0] +#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { LED[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1] +#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { LED[2] }]; #IO_L17N_T2_A25_15 Sch=led[2] +#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { LED[3] }]; #IO_L8P_T1_D11_14 Sch=led[3] +#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { LED[4] }]; #IO_L7P_T1_D09_14 Sch=led[4] +#set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { LED[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5] +#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { LED[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6] +#set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { LED[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7] +#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { LED[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8] +#set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { LED[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9] +#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { LED[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10] +#set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { LED[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11] +#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { LED[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12] +#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { LED[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13] +#set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { LED[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14] +#set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { LED[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15] + +#set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { LED16_B }]; #IO_L5P_T0_D06_14 Sch=led16_b +#set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { LED16_G }]; #IO_L10P_T1_D14_14 Sch=led16_g +#set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { LED16_R }]; #IO_L11P_T1_SRCC_14 Sch=led16_r +#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { LED17_B }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b +#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { LED17_G }]; #IO_0_14 Sch=led17_g +#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { LED17_R }]; #IO_L11N_T1_SRCC_14 Sch=led17_r + + +##7 segment display + +#set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { CA }]; #IO_L24N_T3_A00_D16_14 Sch=ca +#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { CB }]; #IO_25_14 Sch=cb +#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { CC }]; #IO_25_15 Sch=cc +#set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { CD }]; #IO_L17P_T2_A26_15 Sch=cd +#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { CE }]; #IO_L13P_T2_MRCC_14 Sch=ce +#set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { CF }]; #IO_L19P_T3_A10_D26_14 Sch=cf +#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { CG }]; #IO_L4P_T0_D04_14 Sch=cg + +#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { DP }]; #IO_L19N_T3_A21_VREF_15 Sch=dp + +#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { AN[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0] +#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { AN[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1] +#set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { AN[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2] +#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { AN[3] }]; #IO_L19P_T3_A22_15 Sch=an[3] +#set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { AN[4] }]; #IO_L8N_T1_D12_14 Sch=an[4] +#set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { AN[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5] +#set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { AN[6] }]; #IO_L23P_T3_35 Sch=an[6] +#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { AN[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7] + + +##Buttons + +#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { CPU_RESETN }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn + +#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { BTNC }]; #IO_L9P_T1_DQS_14 Sch=btnc +#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { BTNU }]; #IO_L4N_T0_D05_14 Sch=btnu +#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { BTNL }]; #IO_L12P_T1_MRCC_14 Sch=btnl +#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { BTNR }]; #IO_L10N_T1_D15_14 Sch=btnr +#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { BTND }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd + + +##Pmod Headers + + +##Pmod Header JA + +#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { JA[1] }]; #IO_L20N_T3_A19_15 Sch=ja[1] +#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { JA[2] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2] +#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { JA[3] }]; #IO_L21P_T3_DQS_15 Sch=ja[3] +#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { JA[4] }]; #IO_L18N_T2_A23_15 Sch=ja[4] +#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { JA[7] }]; #IO_L16N_T2_A27_15 Sch=ja[7] +#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { JA[8] }]; #IO_L16P_T2_A28_15 Sch=ja[8] +#set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { JA[9] }]; #IO_L22N_T3_A16_15 Sch=ja[9] +#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { JA[10] }]; #IO_L22P_T3_A17_15 Sch=ja[10] + + +##Pmod Header JB + +#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { JB[1] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1] +#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { JB[2] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2] +#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { JB[3] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3] +#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { JB[4] }]; #IO_L15P_T2_DQS_15 Sch=jb[4] +#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { JB[7] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7] +#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { JB[8] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8] +#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { JB[9] }]; #IO_0_15 Sch=jb[9] +#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { JB[10] }]; #IO_L13P_T2_MRCC_15 Sch=jb[10] + + +##Pmod Header JC + +#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { JC[1] }]; #IO_L23N_T3_35 Sch=jc[1] +#set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { JC[2] }]; #IO_L19N_T3_VREF_35 Sch=jc[2] +#set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { JC[3] }]; #IO_L22N_T3_35 Sch=jc[3] +#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { JC[4] }]; #IO_L19P_T3_35 Sch=jc[4] +#set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { JC[7] }]; #IO_L6P_T0_35 Sch=jc[7] +#set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { JC[8] }]; #IO_L22P_T3_35 Sch=jc[8] +#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { JC[9] }]; #IO_L21P_T3_DQS_35 Sch=jc[9] +#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { JC[10] }]; #IO_L5P_T0_AD13P_35 Sch=jc[10] + + +##Pmod Header JD + +#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { JD[1] }]; #IO_L21N_T3_DQS_35 Sch=jd[1] +#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { JD[2] }]; #IO_L17P_T2_35 Sch=jd[2] +#set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { JD[3] }]; #IO_L17N_T2_35 Sch=jd[3] +#set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { JD[4] }]; #IO_L20N_T3_35 Sch=jd[4] +#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { JD[7] }]; #IO_L15P_T2_DQS_35 Sch=jd[7] +#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { JD[8] }]; #IO_L20P_T3_35 Sch=jd[8] +#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { JD[9] }]; #IO_L15N_T2_DQS_35 Sch=jd[9] +#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { JD[10] }]; #IO_L13N_T2_MRCC_35 Sch=jd[10] + + +##Pmod Header JXADC + +#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVDS } [get_ports { XA_N[1] }]; #IO_L9N_T1_DQS_AD3N_15 Sch=xa_n[1] +#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVDS } [get_ports { XA_P[1] }]; #IO_L9P_T1_DQS_AD3P_15 Sch=xa_p[1] +#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVDS } [get_ports { XA_N[2] }]; #IO_L8N_T1_AD10N_15 Sch=xa_n[2] +#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVDS } [get_ports { XA_P[2] }]; #IO_L8P_T1_AD10P_15 Sch=xa_p[2] +#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVDS } [get_ports { XA_N[3] }]; #IO_L7N_T1_AD2N_15 Sch=xa_n[3] +#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVDS } [get_ports { XA_P[3] }]; #IO_L7P_T1_AD2P_15 Sch=xa_p[3] +#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVDS } [get_ports { XA_N[4] }]; #IO_L10N_T1_AD11N_15 Sch=xa_n[4] +#set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVDS } [get_ports { XA_P[4] }]; #IO_L10P_T1_AD11P_15 Sch=xa_p[4] + + +##VGA Connector + +#set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0] +#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1] +#set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2] +#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3] + +#set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0] +#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1] +#set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2] +#set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3] + +#set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0] +#set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[1] }]; #IO_L4N_T0_35 Sch=vga_b[1] +#set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2] +#set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[3] }]; #IO_L4P_T0_35 Sch=vga_b[3] + +#set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { VGA_HS }]; #IO_L4P_T0_15 Sch=vga_hs +#set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { VGA_VS }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs + + +##Micro SD Connector + +#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { SD_RESET }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset +#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { SD_CD }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd +#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { SD_SCK }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck +#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { SD_CMD }]; #IO_L16N_T2_35 Sch=sd_cmd +#set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0] +#set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1] +#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2] +#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3] + + +##Accelerometer + +#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { ACL_MISO }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso +#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { ACL_MOSI }]; #IO_L5N_T0_AD9N_15 Sch=acl_mosi +#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { ACL_SCLK }]; #IO_L14P_T2_SRCC_15 Sch=acl_sclk +#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { ACL_CSN }]; #IO_L12P_T1_MRCC_15 Sch=acl_csn +#set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { ACL_INT[1] }]; #IO_L2P_T0_AD8P_15 Sch=acl_int[1] +#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { ACL_INT[2] }]; #IO_L20P_T3_A20_15 Sch=acl_int[2] + + +##Temperature Sensor + +#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { TMP_SCL }]; #IO_L1N_T0_AD0N_15 Sch=tmp_scl +#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { TMP_SDA }]; #IO_L12N_T1_MRCC_15 Sch=tmp_sda +#set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { TMP_INT }]; #IO_L6N_T0_VREF_15 Sch=tmp_int +#set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { TMP_CT }]; #IO_L2N_T0_AD8N_15 Sch=tmp_ct + +##Omnidirectional Microphone + +#set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { M_CLK }]; #IO_25_35 Sch=m_clk +#set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { M_DATA }]; #IO_L24N_T3_35 Sch=m_data +#set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { M_LRSEL }]; #IO_0_35 Sch=m_lrsel + + +##PWM Audio Amplifier + +#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { AUD_PWM }]; #IO_L4N_T0_15 Sch=aud_pwm +#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { AUD_SD }]; #IO_L6P_T0_15 Sch=aud_sd + + +##USB-RS232 Interface + +#set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { UART_TXD_IN }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in +#set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { UART_RXD_OUT }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out +#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { UART_CTS }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts +#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { UART_RTS }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts + +##USB HID (PS/2) + +#set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { PS2_CLK }]; #IO_L13P_T2_MRCC_35 Sch=ps2_clk +#set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { PS2_DATA }]; #IO_L10N_T1_AD15N_35 Sch=ps2_data + + +##SMSC Ethernet PHY + +#set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { ETH_MDC }]; #IO_L11P_T1_SRCC_16 Sch=eth_mdc +#set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { ETH_MDIO }]; #IO_L14N_T2_SRCC_16 Sch=eth_mdio +#set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { ETH_RSTN }]; #IO_L10P_T1_AD15P_35 Sch=eth_rstn +#set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { ETH_CRSDV }]; #IO_L6N_T0_VREF_16 Sch=eth_crsdv +#set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXERR }]; #IO_L13N_T2_MRCC_16 Sch=eth_rxerr +#set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXD[0] }]; #IO_L13P_T2_MRCC_16 Sch=eth_rxd[0] +#set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXD[1] }]; #IO_L19N_T3_VREF_16 Sch=eth_rxd[1] +#set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXEN }]; #IO_L11N_T1_SRCC_16 Sch=eth_txen +#set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXD[0] }]; #IO_L14P_T2_SRCC_16 Sch=eth_txd[0] +#set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXD[1] }]; #IO_L12N_T1_MRCC_16 Sch=eth_txd[1] +#set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { ETH_REFCLK }]; #IO_L11P_T1_SRCC_35 Sch=eth_refclk +#set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { ETH_INTN }]; #IO_L12P_T1_MRCC_16 Sch=eth_intn + + +##Quad SPI Flash + +#set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0] +#set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1] +#set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2] +#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3] +#set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { QSPI_CSN }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn + + + + + + + + + + + + + diff --git a/board/cpu21_board_top.xdc b/pipelined-cpu/srcs/constrs/cpu21_board_top.xdc similarity index 100% rename from board/cpu21_board_top.xdc rename to pipelined-cpu/srcs/constrs/cpu21_board_top.xdc diff --git a/testbench/rom/board_demo.hex b/pipelined-cpu/srcs/rom/board_demo.hex similarity index 100% rename from testbench/rom/board_demo.hex rename to pipelined-cpu/srcs/rom/board_demo.hex diff --git a/testbench/rom/cpu21_riscv_redirect_int_bpb_rom.hex b/pipelined-cpu/srcs/rom/cpu21_riscv_redirect_int_bpb_rom.hex similarity index 100% rename from testbench/rom/cpu21_riscv_redirect_int_bpb_rom.hex rename to pipelined-cpu/srcs/rom/cpu21_riscv_redirect_int_bpb_rom.hex diff --git a/testbench/rom/isa_test.hex b/pipelined-cpu/srcs/rom/isa_test.hex similarity index 100% rename from testbench/rom/isa_test.hex rename to pipelined-cpu/srcs/rom/isa_test.hex diff --git a/testbench/rom/lui_test.hex b/pipelined-cpu/srcs/rom/lui_test.hex similarity index 100% rename from testbench/rom/lui_test.hex rename to pipelined-cpu/srcs/rom/lui_test.hex diff --git a/testbench/rom/mmio_test.hex b/pipelined-cpu/srcs/rom/mmio_test.hex similarity index 100% rename from testbench/rom/mmio_test.hex rename to pipelined-cpu/srcs/rom/mmio_test.hex diff --git a/testbench/rom/muldiv_test.hex b/pipelined-cpu/srcs/rom/muldiv_test.hex similarity index 100% rename from testbench/rom/muldiv_test.hex rename to pipelined-cpu/srcs/rom/muldiv_test.hex diff --git a/testbench/rom/risc-v-benchmark_ccab.hex b/pipelined-cpu/srcs/rom/risc-v-benchmark_ccab.hex similarity index 100% rename from testbench/rom/risc-v-benchmark_ccab.hex rename to pipelined-cpu/srcs/rom/risc-v-benchmark_ccab.hex diff --git a/testbench/rom/risc-v-branch-predict.hex b/pipelined-cpu/srcs/rom/risc-v-branch-predict.hex similarity index 100% rename from testbench/rom/risc-v-branch-predict.hex rename to pipelined-cpu/srcs/rom/risc-v-branch-predict.hex diff --git a/rtl/cpu21_bpb_8.v b/pipelined-cpu/srcs/rtl/cpu21_bpb_8.v similarity index 100% rename from rtl/cpu21_bpb_8.v rename to pipelined-cpu/srcs/rtl/cpu21_bpb_8.v diff --git a/rtl/cpu21_mmio.v b/pipelined-cpu/srcs/rtl/cpu21_mmio.v similarity index 100% rename from rtl/cpu21_mmio.v rename to pipelined-cpu/srcs/rtl/cpu21_mmio.v diff --git a/rtl/cpu21_riscv_alu.v b/pipelined-cpu/srcs/rtl/cpu21_riscv_alu.v similarity index 100% rename from rtl/cpu21_riscv_alu.v rename to pipelined-cpu/srcs/rtl/cpu21_riscv_alu.v diff --git a/rtl/cpu21_riscv_branch_unit.v b/pipelined-cpu/srcs/rtl/cpu21_riscv_branch_unit.v similarity index 100% rename from rtl/cpu21_riscv_branch_unit.v rename to pipelined-cpu/srcs/rtl/cpu21_riscv_branch_unit.v diff --git a/rtl/cpu21_riscv_decoder.v b/pipelined-cpu/srcs/rtl/cpu21_riscv_decoder.v similarity index 100% rename from rtl/cpu21_riscv_decoder.v rename to pipelined-cpu/srcs/rtl/cpu21_riscv_decoder.v diff --git a/rtl/cpu21_riscv_forward_unit.v b/pipelined-cpu/srcs/rtl/cpu21_riscv_forward_unit.v similarity index 100% rename from rtl/cpu21_riscv_forward_unit.v rename to pipelined-cpu/srcs/rtl/cpu21_riscv_forward_unit.v diff --git a/rtl/cpu21_riscv_hazard_unit.v b/pipelined-cpu/srcs/rtl/cpu21_riscv_hazard_unit.v similarity index 100% rename from rtl/cpu21_riscv_hazard_unit.v rename to pipelined-cpu/srcs/rtl/cpu21_riscv_hazard_unit.v diff --git a/rtl/cpu21_riscv_irq_ctrl.v b/pipelined-cpu/srcs/rtl/cpu21_riscv_irq_ctrl.v similarity index 100% rename from rtl/cpu21_riscv_irq_ctrl.v rename to pipelined-cpu/srcs/rtl/cpu21_riscv_irq_ctrl.v diff --git a/rtl/cpu21_riscv_muldiv.v b/pipelined-cpu/srcs/rtl/cpu21_riscv_muldiv.v similarity index 100% rename from rtl/cpu21_riscv_muldiv.v rename to pipelined-cpu/srcs/rtl/cpu21_riscv_muldiv.v diff --git a/rtl/cpu21_riscv_perf_counters.v b/pipelined-cpu/srcs/rtl/cpu21_riscv_perf_counters.v similarity index 100% rename from rtl/cpu21_riscv_perf_counters.v rename to pipelined-cpu/srcs/rtl/cpu21_riscv_perf_counters.v diff --git a/rtl/cpu21_riscv_redirect_int_bpb.v b/pipelined-cpu/srcs/rtl/cpu21_riscv_redirect_int_bpb.v similarity index 100% rename from rtl/cpu21_riscv_redirect_int_bpb.v rename to pipelined-cpu/srcs/rtl/cpu21_riscv_redirect_int_bpb.v diff --git a/rtl/cpu21_riscv_regfile.v b/pipelined-cpu/srcs/rtl/cpu21_riscv_regfile.v similarity index 100% rename from rtl/cpu21_riscv_regfile.v rename to pipelined-cpu/srcs/rtl/cpu21_riscv_regfile.v diff --git a/rtl/cpu21_riscv_store_unit.v b/pipelined-cpu/srcs/rtl/cpu21_riscv_store_unit.v similarity index 100% rename from rtl/cpu21_riscv_store_unit.v rename to pipelined-cpu/srcs/rtl/cpu21_riscv_store_unit.v diff --git a/testbench/tb_board_top.v b/pipelined-cpu/srcs/tb/tb_board_top.v similarity index 100% rename from testbench/tb_board_top.v rename to pipelined-cpu/srcs/tb/tb_board_top.v diff --git a/testbench/tb_cpu21_riscv_redirect_int_bpb.v b/pipelined-cpu/srcs/tb/tb_cpu21_riscv_redirect_int_bpb.v similarity index 100% rename from testbench/tb_cpu21_riscv_redirect_int_bpb.v rename to pipelined-cpu/srcs/tb/tb_cpu21_riscv_redirect_int_bpb.v diff --git a/testbench/tb_no_intr.v b/pipelined-cpu/srcs/tb/tb_no_intr.v similarity index 100% rename from testbench/tb_no_intr.v rename to pipelined-cpu/srcs/tb/tb_no_intr.v diff --git a/tools/hex2vh.py b/pipelined-cpu/tools/hex2vh.py similarity index 94% rename from tools/hex2vh.py rename to pipelined-cpu/tools/hex2vh.py index af4c263..32df10c 100644 --- a/tools/hex2vh.py +++ b/pipelined-cpu/tools/hex2vh.py @@ -8,7 +8,7 @@ rom[0] = 32'h00001037; rom[1] = 32'h00100093; -配套 RTL 用法(见 board/cpu21_board_top.v,两者同目录,所以 include 能直接解析): +配套 RTL 用法(见 srcs/board/cpu21_board_top.v,两者同目录,所以 include 能直接解析): initial begin for (i = 0; i < ROM_WORDS; i = i + 1) rom[i] = 32'h0000_0013; // NOP 填充 diff --git a/pipelined-cpu/tools/run_regress.ps1 b/pipelined-cpu/tools/run_regress.ps1 new file mode 100644 index 0000000..e6b3c52 --- /dev/null +++ b/pipelined-cpu/tools/run_regress.ps1 @@ -0,0 +1,109 @@ +# ============================================================================ +# cpu21-riscv 回归脚本(Vivado xsim) +# +# 在工程目录 pipelined-cpu/ 下运行: +# powershell -ExecutionPolicy Bypass -File tools\run_regress.ps1 +# +# 做四件事: +# 1) 逐个跑指令测试:muldiv_test / isa_test / lui_test / mmio_test, +# 把测试平台打印的 LED 序列与 programs/<名字>.expected 逐值比对; +# 2) 跑两个流水基线(默认 ROM):tb_no_intr、tb_cpu21_riscv_redirect_int_bpb, +# 只打印 FINAL 统计行,便于和已知基线核对; +# 3) 跑板级顶层(-d BOARD_ROM_FAST),检查跑马灯 LED 序列; +# 4) 最后汇总 PASS/FAIL 并按失败数设置退出码。 +# +# 编译与仿真都放在 $env:TEMP\cpu21_regress 下,不会往工程目录写中间文件。 +# 需要 xvlog / xelab / xsim 在 PATH 上(Vivado 安装目录的 bin)。 +# ============================================================================ +$ErrorActionPreference = 'Stop' + +$proj = Split-Path -Parent $PSScriptRoot # tools/ 的上一级就是工程目录 +$projF = ($proj -replace '\\', '/') # Verilog 字符串里要用正斜杠 +$sim = Join-Path $env:TEMP 'cpu21_regress' +$enc = New-Object System.Text.UTF8Encoding($false) + +foreach ($tool in 'xvlog', 'xelab', 'xsim') { + if (-not (Get-Command $tool -ErrorAction SilentlyContinue)) { + Write-Output "ERROR: 找不到 $tool,请把 Vivado 的 bin 目录加到 PATH" + exit 1 + } +} + +New-Item -ItemType Directory -Force $sim | Out-Null +Set-Content -Path "$sim\run.tcl" -Value @('run all', 'quit') -Encoding ascii + +$RTL = @(Get-ChildItem "$proj\srcs\rtl\*.v" | ForEach-Object FullName) +$fail = 0 + +# TB 里的 ROM_FILE 参数默认是文件名,这里替换成绝对路径(PowerShell 传参有坑, +# 直接改副本最稳) +function Sim-Top { + param($Top, $TbFile, $DefaultRom, $RealRom, $Snap) + $txt = [System.IO.File]::ReadAllText($TbFile, $enc) + $new = $txt.Replace('"' + $DefaultRom + '"', '"' + $projF + '/srcs/rom/' + $RealRom + '"') + [System.IO.File]::WriteAllText("$sim\$Snap.v", $new, $enc) + Remove-Item -Recurse -Force "$sim\xsim.dir" -ErrorAction SilentlyContinue + & xvlog @RTL "$sim\$Snap.v" 2>&1 | Out-File -Encoding ascii "$sim\xvlog_$Snap.txt" + & xelab -top $Top -snapshot $Snap 2>&1 | Out-File -Encoding ascii "$sim\xelab_$Snap.txt" + & xsim $Snap -tclbatch run.tcl 2>&1 | Out-File -Encoding ascii "$sim\run_$Snap.txt" + $err = Select-String -Path "$sim\xvlog_$Snap.txt", "$sim\xelab_$Snap.txt" -Pattern 'ERROR' | + Select-Object -First 1 -ExpandProperty Line + if ($err) { Write-Output "!! $Snap : $err"; $script:fail++ } +} + +Push-Location $sim +try { + Write-Output '===== 1) 指令测试(tb_no_intr,与 programs/*.expected 比对)=====' + foreach ($t in 'muldiv_test', 'isa_test', 'lui_test', 'mmio_test') { + Sim-Top -Top tb_no_intr -TbFile "$proj\srcs\tb\tb_no_intr.v" ` + -DefaultRom 'risc-v-benchmark_ccab.hex' -RealRom "$t.hex" -Snap "sim_$t" + $log = "$sim\run_sim_$t.txt" + $obs = @(Select-String -Path $log -Pattern 'LEDv=1 LED=([0-9a-fA-F]{8})' -AllMatches | + ForEach-Object { $_.Matches[0].Groups[1].Value.ToLower() }) + $exp = @(Get-Content "$proj\programs\$t.expected" | + ForEach-Object { $_.Trim().ToLower() } | Where-Object { $_ -ne '' }) + if (($obs -join ',') -eq ($exp -join ',')) { + Write-Output (" {0,-13} PASS ({1} 个 LED 值)" -f $t, $obs.Count) + } else { + Write-Output (" {0,-13} FAIL 期望 {1} / 观测 {2}" -f $t, $exp.Count, $obs.Count) + Write-Output (" 期望: " + ($exp -join ' ')) + Write-Output (" 观测: " + ($obs -join ' ')) + $fail++ + } + Write-Output (' ' + (Select-String -Path $log -Pattern 'FINAL:' | + Select-Object -First 1 -ExpandProperty Line)) + } + + Write-Output '===== 2) 流水基线(默认 ROM)=====' + Sim-Top -Top tb_no_intr -TbFile "$proj\srcs\tb\tb_no_intr.v" ` + -DefaultRom 'risc-v-benchmark_ccab.hex' -RealRom 'risc-v-benchmark_ccab.hex' -Snap 'base_no_intr' + Write-Output (' tb_no_intr : ' + (Select-String -Path "$sim\run_base_no_intr.txt" -Pattern 'FINAL:' | + Select-Object -First 1 -ExpandProperty Line)) + Sim-Top -Top tb_cpu21_riscv_redirect_int_bpb -TbFile "$proj\srcs\tb\tb_cpu21_riscv_redirect_int_bpb.v" ` + -DefaultRom 'cpu21_riscv_redirect_int_bpb_rom.hex' -RealRom 'cpu21_riscv_redirect_int_bpb_rom.hex' ` + -Snap 'base_intr' + Write-Output (' tb_intr : ' + (Select-String -Path "$sim\run_base_intr.txt" -Pattern 'FINAL:' | + Select-Object -First 1 -ExpandProperty Line)) + + Write-Output '===== 3) 板级顶层(-d BOARD_ROM_FAST,跑马灯)=====' + Remove-Item -Recurse -Force "$sim\xsim.dir" -ErrorAction SilentlyContinue + & xvlog -d BOARD_ROM_FAST @RTL "$proj\srcs\board\cpu21_board_top.v" "$proj\srcs\tb\tb_board_top.v" 2>&1 | + Out-File -Encoding ascii "$sim\xvlog_board.txt" + & xelab -top tb_board_top -snapshot board -d BOARD_ROM_FAST 2>&1 | Out-File -Encoding ascii "$sim\xelab_board.txt" + & xsim board -tclbatch run.tcl 2>&1 | Out-File -Encoding ascii "$sim\run_board.txt" + $seq = @(Select-String -Path "$sim\run_board.txt" -Pattern 'LED=([0-9a-f]{4})' -AllMatches | + ForEach-Object { $_.Matches[0].Groups[1].Value }) + Write-Output (' 前 18 个 LED: ' + (($seq[0..17]) -join ' ')) + Write-Output (" 变化次数: " + $seq.Count) + if (($seq[0..17] -join ' ') -ne '0000 0001 0002 0004 0008 0010 0020 0040 0080 0100 0200 0400 0800 1000 2000 4000 8000 0001') { + Write-Output ' FAIL:跑马灯序列与预期不符'; $fail++ + } else { + Write-Output ' PASS' + } +} finally { + Pop-Location +} + +Write-Output '' +if ($fail -eq 0) { Write-Output '全部通过 (所有回归 PASS)' } else { Write-Output "有 $fail 项失败" } +exit $fail diff --git a/tools/rv_asm.py b/pipelined-cpu/tools/rv_asm.py similarity index 98% rename from tools/rv_asm.py rename to pipelined-cpu/tools/rv_asm.py index 80ea464..9f93380 100644 --- a/tools/rv_asm.py +++ b/pipelined-cpu/tools/rv_asm.py @@ -9,7 +9,7 @@ lw/sw/sb、beq/bne/blt/bge/bltu/bgeu、lui、jal/jalr、ecall、标签、# 注释 伪指令:print(= lui t6,LED_ADDR>>12 + sw a0,0(t6),向 MMIO 的 LED 寄存器写入 a0)、 halt(= addi a7,zero,10 + ecall),各占两个字。 -示例:python tools/rv_asm.py testbench/programs/isa_test.asm out.hex +示例:python tools/rv_asm.py programs/isa_test.asm srcs/rom/isa_test.hex """ import re