# verilog语言教程 **Repository Path**: bingbingyihao/verilog-language-tutorial ## Basic Information - **Project Name**: verilog语言教程 - **Description**: verilog语言教程 - **Primary Language**: Verilog - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-06-09 - **Last Updated**: 2026-06-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Verilog 语言教程 本项目是一套从零开始学习 Verilog 硬件描述语言的完整教程,最终目标是设计并实现一个**自定义指令集的单周期 CPU**。教程包含四个层次的课程文档,以及基于 Vivado 的完整工程实现。 --- ## 项目结构 ``` ├── README.md # 项目说明 ├── course/ # 教程文档 │ ├── 01_Verilog基础教程.md # Verilog 语法基础 │ ├── 02_Verilog中级教程.md # 组合/时序逻辑、状态机、存储器 │ ├── 03_Verilog进阶教程.md # Testbench编写、仿真技巧 │ └── 04_Verilog高级教程.md # 单周期CPU设计实战 └── vivado/ # Vivado 工程 ├── src/ # 源代码 │ ├── single_cycle_cpu.v # CPU 顶层模块 │ ├── alu.v # ALU 算术逻辑单元 │ ├── control_unit.v # 控制单元 │ ├── reg_file.v # 寄存器文件(16个32位寄存器) │ ├── instruction_decoder.v # 指令译码器 │ ├── pc_reg.v # PC 寄存器 │ ├── pc_update.v # PC 更新逻辑 │ ├── instruction_memory.v # 指令存储器(ROM) │ └── data_memory.v # 数据存储器(RAM) └── sim/ # 仿真文件 ├── tb_cpu.v # CPU 测试平台 └── program.hex # 测试程序机器码 ``` --- ## CPU 架构 ### 基本参数 | 参数 | 值 | |------|------| | 指令字长 | 32 位定长 | | 数据字长 | 32 位 | | 通用寄存器 | 16 个(x0-x15) | | 指令存储器 | 256 字(1KB) | | 数据存储器 | 256 字(1KB) | | 执行模式 | 单周期(每条指令一个时钟周期完成) | ### 寄存器定义 | 编号 | 名称 | 用途 | |------|------|------| | x0 | zero | 零寄存器(恒为 0,不可写) | | x1 | ra | 返回地址寄存器 | | x2 | sp | 栈指针寄存器 | | x3 | gp | 全局指针寄存器 | | x4-x15 | t0-t11 | 通用临时寄存器(推荐编程使用) | ### 指令格式 **R-type(寄存器-寄存器型)**:用于算术逻辑运算 ``` 31 24 23 16 15 8 7 0 ┌────────────┬────────────┬────────────┬────────────┐ │ opcode │ reg1 │ reg2 │ reg3 │ │ (8位) │ (8位) │ (8位) │ (8位) │ └────────────┴────────────┴────────────┴────────────┘ ``` **B-type(寄存器-立即数型)**:用于立即数、访存、分支跳转 ``` 31 24 23 20 19 16 15 0 ┌────────────┬────────────┬────────────┬──────────────────────────────────┐ │ opcode │ reg1 │ reg2 │ immediate (16位) │ │ (8位) │ (4位) │ (4位) │ │ └────────────┴────────────┴────────────┴──────────────────────────────────┘ ``` ### 支持的指令 #### 算术逻辑指令(R-type) | 指令 | 操作码 | 功能 | |------|--------|------| | `add` | `8'h01` | 加法 | | `sub` | `8'h02` | 减法 | | `and` | `8'h03` | 按位与 | | `or` | `8'h04` | 按位或 | | `xor` | `8'h05` | 按位异或 | | `slt` | `8'h06` | 有符号小于比较 | | `sll` | `8'h07` | 逻辑左移 | | `srl` | `8'h08` | 逻辑右移 | | `sra` | `8'h09` | 算术右移 | | `mul` | `8'h0A` | 乘法 | | `div` | `8'h0B` | 有符号除法 | #### 立即数指令(B-type) | 指令 | 操作码 | 功能 | |------|--------|------| | `li` | `8'h10` | 加载立即数 | | `addi` | `8'h11` | 立即数加法 | | `andi` | `8'h12` | 立即数与 | | `ori` | `8'h13` | 立即数或 | | `xori` | `8'h14` | 立即数异或 | #### 访存指令(B-type) | 指令 | 操作码 | 功能 | |------|--------|------| | `lw` | `8'h20` | 加载字(从内存读取) | | `sw` | `8'h21` | 存储字(写入内存) | #### 分支跳转指令(B-type) | 指令 | 操作码 | 功能 | |------|--------|------| | `jmp` | `8'h30` | 无条件跳转 | | `beq` | `8'h31` | 相等则跳转 | | `bne` | `8'h32` | 不等则跳转 | | `blt` | `8'h33` | 小于则跳转 | | `bge` | `8'h34` | 大于等于则跳转 | | `jal` | `8'h35` | 跳转并链接(保存返回地址) | | `ret` | `8'h36` | 寄存器间接返回(PC = [ra]) | #### 控制指令 | 指令 | 操作码 | 功能 | |------|--------|------| | `nop` | `8'h00` | 空操作 | | `halt` | `8'hFF` | 停机 | --- ## 数据通路 ``` PC → 指令存储器 → 指令译码 → 寄存器文件 → 控制单元 → ALU → 数据存储器 → 写回 → PC 更新逻辑 → PC 寄存器 ``` ### 五大执行阶段 | 阶段 | 全称 | 功能 | |------|------|------| | **IF** | Instruction Fetch | 从指令存储器取指令 | | **ID** | Instruction Decode | 解析指令,读取寄存器 | | **EX** | Execute | ALU 执行计算 | | **MEM** | Memory Access | 访问数据存储器 | | **WB** | Write Back | 结果写回寄存器 | --- ## 快速开始 ### 环境要求 - Xilinx Vivado 2020.1 或更高版本 ### 运行仿真 1. 打开 Vivado,新建工程或打开 `vivado/vivado.xpr` 2. 确保所有源文件已添加到工程中 3. 设置仿真顶层模块为 `tb_cpu` 4. 点击 **Run Simulation** → **Run Behavioral Simulation** 5. 仿真运行后,波形窗口会自动显示所有 debug 信号 ### 测试程序 内置测试程序(`vivado/sim/program.hex`)计算 `1+2+...+10=55`: ```assembly li t0, 0 # t0 = 0 (累加器) li t1, 1 # t1 = 1 (计数器) li t2, 11 # t2 = 11 (循环结束值) li t3, 1 # t3 = 1 (步长) loop: add t0, t0, t1 # t0 = t0 + t1 addi t1, t1, 1 # t1 = t1 + 1 blt t1, t2, loop # if t1 < 11, jump to loop sw t0, 0(x0) # mem[0] = t0 = 55 halt # 停机 ``` ### Debug 信号说明 顶层模块已内置 Debug 输出端口,仿真时可直接在波形窗口观察以下信号: | 信号 | 说明 | |------|------| | `debug_pc` | 当前程序计数器值 | | `debug_instruction` | 当前执行的指令 | | `debug_opcode` | 当前指令操作码 | | `debug_alu_result` | ALU 运算结果 | | `debug_zero_flag` | ALU 零标志 | | `debug_negative_flag` | ALU 负数标志 | | `debug_reg_t0 ~ debug_reg_t3` | t0-t3 寄存器值 | | `debug_reg_write` | 寄存器写使能 | | `debug_mem_read` / `debug_mem_write` | 存储器读写使能 | | `debug_branch` / `debug_jump` | 分支/跳转使能 | | `debug_halt` | 停机信号 | --- ## 学习路径 1. 阅读 [01_Verilog基础教程](course/01_Verilog基础教程.md) 了解基本语法 2. 阅读 [02_Verilog中级教程](course/02_Verilog中级教程.md) 掌握组合/时序逻辑设计 3. 阅读 [03_Verilog进阶教程](course/03_Verilog进阶教程.md) 学习 Testbench 编写 4. 阅读 [04_Verilog高级教程](course/04_Verilog高级教程.md) 理解 CPU 设计全流程 5. 在 Vivado 中打开工程,运行仿真验证 6. 修改 `program.hex` 编写自己的测试程序 --- ## 许可证 Apache 2.0 License