跳到正文
Jason Xun Product Systems Builder / my_mips
RTL · COURSE LAB · 2025 Forensic review · branch risk open

把一条 MIPS 指令,拆成可观察的数据通路

一颗面向课程实验的单周期 CPU,也是一份 RTL 取证样本:9 个 Verilog 模块留下了可观察数据通路;当前分支选择逻辑同时留下一个尚未修复、尚无 assertion 覆盖的正确性风险。

An RTL forensic lab: inspect the observable datapath, surface the unresolved branch-selection defect, and keep a 520 ns historical trace separate from correctness claims.

9源码中定义的 RTL 模块
12当前启用的非 NOP ROM 槽位
1集成级观测型 testbench
520 ns留档轨迹终点 · 不是 PASS

01 / Problem

问题不是“会写几段 Verilog”,而是让一条指令完整走通。

课程给出的 ISA 语义是抽象的:lw 需要取指、读寄存器、算地址、读内存再写回;beq 还要把比较结果送回 PC 选择。真正的工程问题,是把这些依赖拆成边界清晰的模块,并让控制信号与数据在同一外部时钟周期内配合。

因此,这个项目把重点放在“端到端数据通路”上:不仅实现 ALU,还要处理寄存器堆、两类存储器、立即数扩展、控制译码、PC 计算与顶层集成。

02 / Role

原始工程实现与本次公开表达,分开记账。

JASON / 2025

RTL 与实验闭环

拆分并集成 Verilog 模块,配置片上 ROM 测试程序,搭建顶层 testbench,并在 Vivado 2018.3 中保留编译、展开、运行日志与波形文件。

AI-ASSISTED / 2026

公开案例表达

AI 协助重组案例叙事、前端样式、分享元数据与静态契约检查。本次展示重构没有修改原始 RTL、测试台或历史仿真产物。

03 / System

控制流决定“走哪条路”,数据通路负责“把值送到”。

01 / FETCH

PC + Instruction Memory

pc[7:2] 选中 64 × 32-bit ROM 中的指令。

02 / DECODE

Control + RegFile + Extend

opcode/funct 产生控制线;双端口读取操作数并扩展立即数。

03 / EXECUTE

ALU

组合逻辑执行 AND、OR、ADD、SUB、SLT、NOR,并输出 zero 标志。

04 / MEMORY

Data Memory

64 × 32-bit 数据存储器提供组合读与受时钟控制的写入。

05 / NEXT

PC Calculator + Writeback

选择顺序、分支、跳转或寄存器地址,并把 ALU、内存或返回地址写回。

关键设计选择

实现利用外部时钟的上升沿取指、下降沿更新 PC / 寄存器,并通过派生翻转信号驱动数据存储器写入,给组合数据通路留出观察窗口。这是该实验的具体时序组织,不应直接等同于已完成时序分析的标准工业单周期核。

// mips_cpu.v · 顶层选择逻辑(节选)
assign write_reg = (reg_dst == 2'b00) ? instruction[20:16] :
                   (reg_dst == 2'b01) ? instruction[15:11] :
                   5'b11111;

assign reg_write_data = (mem_to_reg == 2'b00) ? alu_result :
                        (mem_to_reg == 2'b01) ? mem_read_data :
                        (mem_to_reg == 2'b10) ? pc + 32'd4 :
                        zero_extend;

04 / Evidence

证据支持“工程曾被编译并跑出轨迹”;它不自动支持“所有语义都正确”。

AVAILABLE

编译与展开日志

留档日志逐项分析 9 个设计模块与 mips_cpu_tb,并记录 Built simulation snapshot mips_cpu_tb_behav。展开阶段同时留下 9 条 timescale 警告。

AVAILABLE

PC / 指令运行轨迹

105 行历史日志记录至 520 ns;可见 PC 从 0x00 走到 0x30 后由 j 回到 0x00,并多次重复。

OPEN

自动正确性判定

当前 testbench 使用 $monitor 与波形观察,没有 assertion、期望值对比、覆盖率或 CI 中的 RTL 仿真,因此不能把运行轨迹当成完备验证。

05 / Limitations

这是一份可追溯的课程实验,不是量产 CPU 声明。

  • 仓库没有综合报告、时序收敛、板级运行或性能 / 功耗数据。
  • 当前启用 ROM 覆盖基础算术、访存、比较、beqj 路径;被注释的扩展指令样例与译码分支不等于已验证支持。
  • pc_calculator 没有接收分支子类型,现有组合条件会让 branch 为真时的 zero / non-zero 路径都选择分支目标;这是需要自判定测试暴露并修复的正确性风险。
  • 历史 Vivado 运行来自 2018.3 环境,本次展示重构未在当前机器复跑 RTL 仿真。

如果继续迭代

  1. 把 testbench 改为自判定:按指令逐步断言 PC、寄存器与内存状态。
  2. 拆开 BEQ / BNE / BLTZ / BGEZ 的分支条件,再用最小 ROM 程序逐条回归。
  3. 补 lint、开源仿真器 CI、综合和时序报告,让“能运行”升级为可复现的验证链。
TAKEAWAY

真正值得展示的,不是“做过 CPU”,而是知道证据能证明到哪里。

这个项目留下了从模块化设计到历史仿真的完整学习轨迹,也留下了下一轮验证应该从哪里开始的明确入口。