Verilog HDL学习笔记(二)| 第2章 层次建模的概念
2.1 设计方法学Design Methodologies一、为什么需要设计方法学在正式开始写Verilog代码之前必须先理解一个问题如何组织一个大型的数字电路设计想象一下如果要设计一个包含几十万个逻辑门的CPU不可能一个人从头到尾把所有细节都想清楚。这就需要一套系统化的设计方法来管理复杂度。数字电路设计中有两种基本的设计方法在实际工程中这两种方法混合使用。二、自顶向下设计方法Top-Down核心思想从系统最顶层的功能需求出发逐层分解为更小的子模块直到最底层的实现细节。流程图┌─────────────────────────────────────────────────────────────────┐ │ 第1步定义顶层功能模块 │ │ 例如四位计数器 → 实现计数功能 │ └───────────────────────────┬─────────────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 第2步分析需要哪些子模块 │ │ 四位计数器需要4个T触发器 │ └───────────────────────────┬─────────────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 第3步继续分解子模块 │ │ T触发器 → D触发器 非门 │ └───────────────────────────┬─────────────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 第4步直到无法继续分解 │ │ D触发器 → 逻辑门非门 → 门级原语 │ └─────────────────────────────────────────────────────────────────┘优点设计思路清晰层次分明便于团队分工不同工程师负责不同层次的模块便于早期进行系统级仿真和架构评估顶层模块的接口定义明确后各子模块可以并行开发缺点对设计者的顶层规划能力要求较高如果顶层划分不合理后续修改代价较大三、自底向上设计方法Bottom-Up核心思想从最底层的基础元件开始设计然后用这些元件搭建更高层次的功能模块最终组合成完整的系统。流程图┌─────────────────────────────────────────────────────────────────┐ │ 第1步设计最底层元件 │ │ 例如设计D触发器、逻辑门 │ └───────────────────────────┬─────────────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 第2步用底层元件搭建中层模块 │ │ 用D触发器 非门 → 搭建T触发器 │ └───────────────────────────┬─────────────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 第3步用中层模块搭建顶层模块 │ │ 用4个T触发器 → 搭建四位计数器 │ └─────────────────────────────────────────────────────────────────┘四、混合设计方法实际工程中的做法真实项目中这两种方法是结合使用的自顶向下架构师 ↓ ┌─────────────────────┐ │ 系统顶层划分 │ │ 定义模块接口 │ └──────────┬──────────┘ ↓ ┌────┴────┐ ↓ ↓ ┌─────────┐ ┌─────────┐ │ 模块A │ │ 模块B │ ← 自顶向下继续分解 │ 高层│ │ 高层│ └────┬────┘ └────┬────┘ ↓ ↓ ┌─────────┐ ┌─────────┐ │ 底层库 │←─────────┤ ← 自底向上提供基础元件 │已验证│ │ └─────────┘ └─────────┘ ↑ 自底向上电路设计师架构师从顶层向下分解功能模块电路设计师从底层向上优化基本元件两者在中间层次会合。2.2 四位脉动进位计数器4-bit Ripple Carry Counter一、什么是脉动进位计数器脉动进位计数器Ripple Carry Counter是一种最简单的计数器结构由多个T触发器级联而成。工作原理每个T触发器在时钟下降沿或上升沿翻转一次前一级T触发器的输出作为后一级T触发器的时钟信号因为时钟信号像水波一样逐级脉动传递所以称为脉动进位计数器结构框图二、T触发器T Flip-Flop功能每来一个时钟脉冲输出状态翻转一次0→1→0→1→...T触发器可以用D触发器 非门实现工作过程q输出0 → 非门输出1d 1时钟下降沿到来D触发器锁存d的值 → q变为1q变为1 → 非门输出0d 0下一个时钟下降沿到来q变为0如此循环每个时钟周期翻转一次三、D触发器D Flip-Flop with Asynchronous ResetD触发器的功能很简单在时钟有效边沿到来时将输入d的值传输到输出q。带异步复位的D触发器增加了复位功能当reset 1时立即将q清零不等待时钟当reset 0时正常工作2.3 模块Module一、什么是模块模块Module是Verilog中最基本的设计单元。每一个模块都对应一个具有特定功能的硬件电路。可以把模块理解为C语言中的函数有输入参数input、返回值output、内部局部变量reg/wire电路中的芯片有输入引脚、输出引脚、内部逻辑电路二、模块的语法结构module 模块名 ( 端口列表 ); // 1. 端口声明input / output / inout // 2. 数据类型声明wire / reg / parameter // 3. 功能描述assign / always / 模块实例调用 endmodule各部分说明三、模块的四种抽象层次Verilog允许在模块的内部实现中使用不同的抽象层次重点理解同一个模块对外接口端口保持不变内部可以更换不同的实现层次。这是Verilog设计的核心优势之一。// 同一个四选一多路选择器可以用三种方式实现 // 方式1门级实现用逻辑门 // 方式2数据流实现用assign和操作符 // 方式3行为级实现用always和case // 三种实现方式的端口完全相同可以互相替换2.4 模块实例Module Instantiation一、模块与实例的区别这是初学者最容易混淆的概念之一必须彻底理解关键理解一个模块可以被实例化多次每个实例都是独立的拥有自己的存储单元和信号连接每个实例必须有唯一的名字二、实例化的语法模块名 实例名 ( 端口连接 );示例// 定义一个T触发器模块模板 module T_FF(q, clk, reset); // ... endmodule // 在顶层模块中实例化4个T触发器 module ripple_carry_counter(q, clk, reset); output [3:0] q; input clk, reset; // 方式1按顺序连接端口 T_FF tff0(q[0], clk, reset); T_FF tff1(q[1], q[0], reset); T_FF tff2(q[2], q[1], reset); T_FF tff3(q[3], q[2], reset); // 方式2按名字连接端口推荐可读性更好 // T_FF tff0 (.q(q[0]), .clk(clk), .reset(reset)); endmodule端口的两种连接方式对比三、模块实例化的规则实例名必须唯一同一个模块的多个实例必须有不同名字模块不能嵌套定义不能在module ... endmodule内部再定义另一个模块实例化时可以省略实例名仅限门级原语and (out, a, b);合法2.5 逻辑仿真的构成一、仿真两个组成部分一个完整的Verilog仿真由两个独立的部分组成┌─────────────────────────────────────────────────────────────────────┐ │ 完整的Verilog仿真 │ │ │ │ ┌─────────────────────────┐ ┌──────────────────────────────┐ │ │ │ 激励块Testbench │ │ 设计块Design │ │ │ │ │ │ │ │ │ │ • 产生输入信号 │───→│ • 实现核心功能 │ │ │ │ • 监视输出信号 │←───│ • 是真正被测试的电路 │ │ │ │ • 检查功能正确性 │ │ │ │ │ └─────────────────────────┘ └──────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘设计块Design Block实现具体功能的Verilog模块是被测试的对象DUTDesign Under Test通常有输入端口和输出端口激励块Testbench / Stimulus Block为设计块提供输入信号监视和检查设计块的输出通常没有端口顶层模块二、两种激励模式模式一激励块直接调用设计块┌─────────────────────────────────────────────────────────────────┐ │ 激励块顶层模块 │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ ① 产生激励信号clk、reset、data等 │ │ │ │ ↓ │ │ │ │ ② 实例化设计块将激励信号连接到设计块输入端 │ │ │ │ ↓ │ │ │ │ ③ 监视设计块的输出 │ │ │ │ ↓ │ │ │ │ ④ 检查输出是否符合预期 │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘模式二顶层模块分别调用激励块和设计块┌─────────────────────────────────────────────────────────────────┐ │ 顶层模块无端口 │ │ │ │ ┌───────────────┐ ┌─────────────────────────────────────┐ │ │ │ 激励块 │ │ 设计块 │ │ │ │ (Stimulus) │───→│ (Design) │ │ │ │ │←───│ │ │ │ │ 产生/监视信号 │ │ 实现核心功能 │ │ │ └───────────────┘ └─────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘两种模式的对比2.6 四位脉动进位计数器——完整代码与逐行讲解一、设计块的完整实现1顶层模块ripple_carry_counter// // 模块名ripple_carry_counter // 功能四位脉动进位计数器 // 输入clk时钟信号reset复位信号高电平有效 // 输出q[3:0]4位计数值 // module ripple_carry_counter(q, clk, reset); // ---- 端口声明 ---- output [3:0] q; // [3:0]表示4位向量q[3]是最高位q[0]是最低位 input clk, reset; // clk和reset是1位标量输入 // ---- 实例化4个T触发器 ---- // 脉动进位结构前一级的输出作为后一级的时钟输入 T_FF tff0(q[0], clk, reset); // 实例0直接使用系统时钟clk T_FF tff1(q[1], q[0], reset); // 实例1时钟来自q[0] T_FF tff2(q[2], q[1], reset); // 实例2时钟来自q[1] T_FF tff3(q[3], q[2], reset); // 实例3时钟来自q[2] endmodule逐行深度讲解2中层模块T_FF// // 模块名T_FF // 功能T触发器Toggle Flip-Flop // 原理每个时钟周期翻转一次输出取反 // 实现方式D触发器 非门反馈连接 // module T_FF(q, clk, reset); // ---- 端口声明 ---- output q; input clk, reset; // ---- 内部连线声明 ---- wire d; // d是内部节点连接D触发器的输入端 // ---- 实例化D触发器 ---- D_FF dff0(q, d, clk, reset); // 注意端口顺序输出, 输入, 输入, 输入 // ---- 实例化非门 ---- not n1(d, q); // d ~q将输出q取反后反馈到输入端d endmodule逐行深度讲解T触发器工作原理初始状态假设q 0非门输出d ~0 1时钟下降沿到来时D触发器将d1锁存到q现在q 1非门输出d ~1 0下一个时钟下降沿q变为0如此往复每个时钟周期q翻转一次3底层模块D_FF// // 模块名D_FF // 功能带异步复位的D触发器 // 触发方式时钟下降沿negedge触发 // 复位方式异步复位reset上升沿立刻生效 // module D_FF(q, d, clk, reset); // ---- 端口声明 ---- output q; input d, clk, reset; // ---- 数据类型声明 ---- reg q; // q需要保持状态必须声明为reg类型 // ---- 行为描述 ---- // 敏感列表reset的上升沿 或 clk的下降沿 // 当这两个事件中的任何一个发生时执行always块内的语句 always (posedge reset or negedge clk) begin if (reset) // 如果reset 1 q 1b0; // 异步清零立即生效不等待时钟 else // 如果reset 0 q d; // 在clk下降沿将d的值锁存到q end endmodule逐行深度讲解关于阻塞赋值 vs 非阻塞赋值初学者记住在always (posedge clk)这样的时序逻辑块中一律使用非阻塞赋值。这是Verilog最重要的规则之一。二、激励块Testbench的完整实现// // 模块名stimulus // 功能测试四位脉动进位计数器 // 注意此模块没有端口是仿真顶层模块 // module stimulus; // ---- 声明激励信号 ---- reg clk; // 时钟信号由测试模块产生所以是reg reg reset; // 复位信号由测试模块产生所以是reg wire [3:0] q; // 计数输出来自设计模块只能观测所以是wire // ---- 实例化被测试的设计模块 ---- ripple_carry_counter r1(q, clk, reset); // 端口连接顺序q, clk, reset与模块定义顺序一致 // ---- 产生时钟信号 ---- initial begin clk 1b0; // 时钟初始化为0 forever #5 clk ~clk; // 每5个时间单位翻转一次 end // 这样产生的时钟周期为10个时间单位占空比50% // ---- 产生复位信号 ---- initial begin reset 1b1; // 初始时刻复位有效 #15 reset 1b0; // 15个时间单位后释放复位 #180 reset 1b1; // 180个时间单位后再次复位 #10 reset 1b0; // 10个时间单位后释放复位 #20 $finish; // 20个时间单位后结束仿真 end // ---- 监视输出信号 ---- initial $monitor($time, Output q %d, q); // $time当前仿真时间 // %d以十进制格式显示q的值 // 每当q发生变化时自动打印一行 endmodule逐行深度讲解initial块执行时间线仿真时刻 0 clk 0, reset 1 仿真时刻 5 clk 1第一次翻转 仿真时刻 10 clk 0第二次翻转 ... 仿真时刻 15 reset 0释放复位 ... 仿真时刻 195 reset 1再次复位 ... 仿真时刻 205 reset 0释放复位 ... 仿真时刻 225 $finish结束仿真三、完整的仿真输出结果分析0 Output q 0 ← 初始状态 20 Output q 1 ← 第1个计数 30 Output q 2 ← 第2个计数 40 Output q 3 50 Output q 4 60 Output q 5 70 Output q 6 80 Output q 7 90 Output q 8 100 Output q 9 110 Output q 10 120 Output q 11 130 Output q 12 140 Output q 13 150 Output q 14 160 Output q 15 170 Output q 0 ← 计满16后归零4位计数器模16 180 Output q 1 190 Output q 2 195 Output q 0 ← 复位信号触发计数器清零 210 Output q 1 220 Output q 2数据分析具体代码已在Quartus复现完成

相关新闻

单片机计算机毕设之基于 STM32 或 51 单片机的恒温饮水及水质水位监测设备设计 基于 STM32 或 51 单片机的定时饮水提示与温度闭环控制系统设计(025305)

单片机计算机毕设之基于 STM32 或 51 单片机的恒温饮水及水质水位监测设备设计 基于 STM32 或 51 单片机的定时饮水提示与温度闭环控制系统设计(025305)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/9/6 18:23:29 阅读更多 →
生产型ERP选哪个好?2026主流服务商优劣盘点

生产型ERP选哪个好?2026主流服务商优劣盘点

生产型ERP没有绝对的“最好”,只有适配自身行业、规模、预算的最优选项本土深耕制造领域的宝泓软件E9 ERP,凭借精益数字化融合能力,是大中小本土生产企业的首选之一海外头部厂商性能稳定但综合成本高、定制难度大,仅适配超大型外资…

2026/9/21 18:04:37 阅读更多 →
单片机计算机毕设之基于 STM32 或 51 单片机的 WiFi 水族设备移动端监控平台设计 基于 STM32 或 51 单片机的鱼缸补光加热自动养护系统开发(025205)

单片机计算机毕设之基于 STM32 或 51 单片机的 WiFi 水族设备移动端监控平台设计 基于 STM32 或 51 单片机的鱼缸补光加热自动养护系统开发(025205)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/9/12 3:10:29 阅读更多 →

最新新闻

花类识别数据集实战:从解压到YOLOv8训练全流程

花类识别数据集实战:从解压到YOLOv8训练全流程

简介:面向计算机视觉入门与图像分类实践的花卉识别数据集,内含洋甘菊、郁金香、玫瑰、向日葵、蒲公英五个常见类别的花朵照片,每类约800张,可用于植物识别模型训练、迁移学习或数据增强实验。压缩包约449.82MB,文件总数…

2026/9/23 4:46:17 阅读更多 →
空窗期怎么回答?从“跑外卖”案例看数据化表达如何逆转面试

空窗期怎么回答?从“跑外卖”案例看数据化表达如何逆转面试

我记得第一次刷到这段对话的时候,先是被那个反转逗笑了,然后忍不住把这句话重新读了三遍。面试官问一个被裁三个月的人:“空窗期在干嘛?”对方答:“跑外卖。”面试官愣住。紧接着对方补了一句:“送了1278单…

2026/9/23 4:46:17 阅读更多 →
3本销售管理书籍拆解面试必问底层逻辑

3本销售管理书籍拆解面试必问底层逻辑

3本销售管理书籍拆解面试必问底层逻辑 官方文档堆砌术语让人头秃,抓不住重点导致面试频频卡壳。别慌,销售管理书籍里的核心模型才是破局关键。这篇把 面试必问 的底层原理拆碎揉烂,用代码思维带你秒懂。 一句话原理:销售漏斗是状态机…

2026/9/23 4:46:17 阅读更多 →
广东税务app源码解析:搞定版本升级后API全变的坑

广东税务app源码解析:搞定版本升级后API全变的坑

广东税务app源码解析:搞定版本升级后API全变的坑 上周帮水利站的老张修数据对接接口,他差点砸了电脑。升级完新版广东税务app后,原本跑得好好的个税申报脚本直接报404,所有字段全对不上。这就是典型的版本升级后 API…

2026/9/23 4:46:17 阅读更多 →
FastAPI异步方法中调用同步方法,事件循环阻塞的坑与解决方案

FastAPI异步方法中调用同步方法,事件循环阻塞的坑与解决方案

FastAPI异步方法中调用同步方法,你们是不是也这么踩过坑前几天调一个FastAPI接口,在异步方法里直接调用了一个第三方SDK的同步方法,单测全绿,一发到测试环境压测就发现请求延迟越堆越高。最后定位到问题:async def里面…

2026/9/23 4:46:13 阅读更多 →
老挑毛U盘启动工具全指南:从PE到Win7/Linux安装避坑

老挑毛U盘启动工具全指南:从PE到Win7/Linux安装避坑

帮人修老电脑这件事做多了,就会总结出一个规律:凡是还在坚持用win7的机器,十有八九是配置不高、年代久远、跑不动新系统的老伙计;凡是问到linux的人,多半是想把一台吃灰机器变成学习机。这两种需求碰在一起&#xff0c…

2026/9/23 4:45:12 阅读更多 →

日新闻

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A…

2026/9/23 0:00:23 阅读更多 →
2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我 刚把开发环境的显示器从1080P换到2K,跑老项目直接报错,版本升级后 API…

2026/9/23 0:01:25 阅读更多 →
3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点 官方文档翻了三遍还是云里雾里?别急,美眉图在实战项目中常被用来做数据可视化,但它的原理比你想的简单。今天咱们直接上手,用一个完整的小项目把美眉图跑通,不再死磕那些冗长的理论说明。…

2026/9/23 0:01:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/22 4:32:41 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/22 4:38:57 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/22 8:51:04 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/22 2:43:42 阅读更多 →