# CPU-Verilog **Repository Path**: orange_cat_studio/cpu-verilog ## Basic Information - **Project Name**: CPU-Verilog - **Description**: 这是oc cpu 的 Verilog版本实现,具体描述见README.md和./docs目录下的文档 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-14 - **Last Updated**: 2026-06-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OC CPU - Verilog Implementation 基于 ORANAGE VM 架构的 32 位处理器 Verilog 实现,支持 5 级流水线、可变长度指令、数据转发和冒险检测。 ## 架构特性 | 特性 | 说明 | |------|------| | 架构位数 | 32-bit | | 通用寄存器 | 9 个 (R0-R8) | | 特殊寄存器 | CR0-CR4, FLAGR, IP, SI, DI, SP | | 指令长度 | 可变 (1/4/6 字节) | | 指令存储 | 大端序 (Big-Endian) | | 数据存储 | 小端序 (Little-Endian) | | 流水线级数 | 5 级 (IF/ID/EX/MEM/WB) | | 取指模式 | 原始取指 / 指令队列 (宏切换) | | 冒险处理 | 数据转发 + Load-Use/CMP 冒险 stall | ## 项目结构 ``` cpu-verilog/ ├── rtl/ # RTL 源文件 │ ├── oc_cpu_top.sv # 顶层模块 │ ├── oc_cpu_defs_pkg.sv # 公共定义包 │ ├── control_unit.sv # 控制单元 (协调 alu/branch/mem 子模块) │ ├── hazard_detection.sv # 冒险检测与数据转发 │ ├── original_fetch.sv # 原始取指模块 │ ├── instruction_queue.sv# 指令队列取指模块 │ ├── mem_interface.sv # 内存接口单元 │ ├── alu_ctrl.sv # ALU 控制子模块 │ ├── branch_ctrl.sv # 分支控制子模块 │ ├── mem_ctrl.sv # 内存控制子模块 │ ├── wb_ctrl.sv # 写回控制子模块 │ ├── pipeline/ # 流水线阶段模块 │ │ ├── if_stage.sv # IF 阶段 │ │ ├── id_stage.sv # ID 阶段 │ │ ├── ex_stage.sv # EX 阶段 │ │ ├── mem_stage.sv # MEM 阶段 │ │ ├── wb_stage.sv # WB 阶段 │ │ └── pipeline_registers.sv # 流水线寄存器 │ └── comp/ # 组件模块 │ ├── alu.sv # ALU │ ├── decoder.sv # 指令解码器 │ ├── reg_file.sv # 寄存器文件 │ ├── pc_reg.sv # PC 寄存器 │ ├── flag_reg.sv # 标志寄存器 │ ├── mem_controller.sv # 内存控制器 │ └── peripheral_if.sv # 外设接口 ├── tb/ # 测试平台 │ ├── oc_cpu_tb.sv # 主测试平台 │ ├── oc_cpu_tb_cpi.sv # CPI 测试平台 │ ├── tb_alu.sv # ALU 单元测试 │ ├── tb_alu_flag_update.sv # ALU 标志更新测试 │ ├── tb_reg_write.sv # 寄存器写入测试 │ ├── tb_alu_to_reg.sv # ALU 到寄存器测试 │ ├── tb_pipeline_registers.sv # 流水线寄存器测试 │ ├── tb_halt.sv # HALT 指令测试 │ ├── tb_branch_ctrl.sv # 分支控制测试 │ ├── tb_pc_reg.sv # PC 寄存器测试 │ ├── tb_hazard_detection.sv # 冒险检测测试 │ ├── tb_instruction_queue.sv # 指令队列测试 │ ├── tb_control_unit.sv # 控制单元测试 │ ├── gen_test.py # 测试程序生成脚本 │ ├── test_alu.bin # ALU 测试程序 │ ├── test_load.bin # Load 测试程序 │ └── test_cpi.bin # CPI 测试程序 ├── docs/ │ └── architecture.md # 架构文档 ├── build/ # 编译输出目录 ├── sim/ # 仿真输出目录 ├── Makefile # 构建和测试命令 └── README.md # 本文件 ``` ## 指令集 ### 操作码 (5-bit) | 操作码 | 指令类型 | 功能码 | 说明 | |--------|----------|--------|------| | 0x00 | NOP | - | 空操作 | | 0x01 | MOVE | LOAD/STORE | 内存加载/存储 | | 0x02 | ART | ADD/SUB/MUL/DIV/UP/DOWN | 算术运算 | | 0x03 | LOGIC | AND/OR/XOR/NOR | 逻辑运算 | | 0x04 | JMP | JMP | 无条件跳转 | | 0x05 | JCON | JA/JB/JE/JNE | 条件跳转 | | 0x06 | CMP | - | 比较 (更新标志位) | | 0x07 | LOOP | - | 循环 | | 0x08 | CTRL | HALT/CALL/RET | 控制指令 | | 0x09 | PORT | INP/OUTP | I/O 端口访问 | | 0x0A | SHIFT | SHL/SHR/RCL/RCR | 移位运算 | | 0x0B | STACK | PUSH/POP | 栈操作 | ### 指令格式 ``` 1 字节: [opcode(5)][funcode(3)] 4 字节: [opcode(5)][funcode(3)] [ext(8)] [reg1(8)] [reg2(8)] 6 字节: [opcode(5)][funcode(3)] [ext(8)] [reg1(8)] [reg2(8)] [imm/mem(16)] ``` - `ext=0x00`: 寄存器-寄存器操作 (4 字节) - `ext=0x01`: 立即数操作 (6 字节) - `ext=0x02`: 内存地址操作 (6 字节) ## 流水线架构 ``` IF ──→ ID ──→ EX ──→ MEM ──→ WB 取指 译码 执行 访存 写回 ``` ### 冒险处理 | 冒险类型 | 检测条件 | 处理方式 | |----------|----------|----------| | RAW (EX/MEM) | EX/MEM 有写回,ID 读同一寄存器 | 转发 EX/MEM 数据 | | RAW (MEM/WB) | MEM/WB 有写回,ID 读同一寄存器 | 转发 MEM/WB 数据 | | Load-Use | EX 阶段 load,ID 阶段依赖 | stall 1 周期 | | CMP→JCON | EX 阶段 CMP,ID 阶段 JCON/JMP | stall 1 周期 | ## 快速开始 ### 环境要求 - Icarus Verilog (iverilog) >= 10.0 - Verilator (可选,用于 lint 检查) - Python 3 (用于生成测试程序) ### 编译与仿真 ```bash # 编译并运行主仿真 make run # 使用自定义程序 make run PROG=/path/to/program.bin # 运行单元测试 make test-alu # ALU 测试 make test-alu-flag # ALU 标志更新测试 make test-reg # 寄存器写入测试 make test-alu-reg # ALU 到寄存器测试 make test-pipe # 流水线寄存器测试 make test-halt # HALT 指令测试 make test-branch # 分支控制测试 make test-pc # PC 寄存器测试 make test-hazard # 冒险检测测试 make test-ctrl # 控制单元测试 make test-queue # 指令队列测试 # CPI 测试 (统计每指令周期数) make test-cpi make test-cpi PROG=/path/to/program.bin # 清理 make clean make clean-all # 清理所有生成文件 ``` ### 查看仿真波形 ```bash gtkwave sim/oc_cpu_tb.vcd ``` ## 当前状态 | 指标 | 状态 | |------|------| | 仿真结果 | CPU Halted = 1,Final PC = 0x45 | | 指令执行 | 所有指令正确执行 | | 标志位更新 | 正确 | | 数据转发 | 正常 (EX/MEM 和 MEM/WB 转发) | | 冒险检测 | Load-Use 和 CMP 冒险检测正常 | | 流水线 flush | 正常 (跳转时 flush) | ## 已知问题 1. **仿真竞争条件**: ALU 的 `result` 是 `reg` 类型在 `always @(*)` 中赋值,`zf_out` 是 `wire` 连续赋值,仿真中可能存在竞争条件。 2. **TB 内存写入时序**: 测试平台使用 `force` 语句写入 ROM,`force` 在 vvp 中只执行一次。 3. **ex_stage.sv 未使用**: `ex_stage.sv` 模块存在但未被实例化,EX 阶段逻辑分散在 `oc_cpu_top.sv` 和 `pipeline_registers.sv` 中。 ## 详细文档 参见 [docs/architecture.md](docs/architecture.md) 获取完整的架构说明、模块端口定义和变更日志。