Verilog十日谈 Day 2:数字电路的筋骨:详解wire、reg与模块层次化设计
告别“变量”思维!深入硬件描述核心,搞懂“线”与“寄存器”的本质区别。
各位未来的芯片设计师,欢迎回到《Verilog十日谈》。
在Day 1,我们完成了从软件思维到硬件思维的革命性转变,并用一个简单的与门,跑通了设计->仿真的完整工业流程。现在,你已经知道你的代码不是在写程序,而是在绘制一张电路蓝图。
今天,我们要深入这张蓝图的“筋骨”所在。如果说Day 1我们搭建了骨架,那么今天就是要搞清连接骨架的“肌腱”与“神经”。
你是否曾对以下问题感到困惑?
wire和reg到底有什么区别?为什么Testbench里驱动信号用reg,而模块输出又定义成wire?- 我的代码明明语法没错,为什么仿真就是不出波形?
信号显示为红色 'X'或高阻'Z'? - 如何像搭积木一样,构建复杂的数字系统?
如果你的答案是“是”,那么今天的课程将为你拨开迷雾。理解 wire 和 reg,是写出正确、可综合Verilog代码的**第二道基石**。
一、 思维破壁:你的“变量”不是变量,是硬件连接!
请再次忘记C语言中的int, float!在Verilog中,我们描述的是**物理连接**和**数据存储**。
wire(线):*它代表的是一条**物理连接线**,用于连接器件的端口。它的值由**驱动源**决定,本身**不能存储任何值**。- 核心特质:
它需要被持续驱动。如果没有驱动,它就是高阻态 z。如果被多个源驱动,它的值由驱动强度决定(通常会导致未知x)。 - 一个比喻:
wire就像一根电线,它本身不带电,电灯泡(接收端)亮不亮,完全取决于电线另一头的开关和电池(驱动源)的状态。 reg(寄存器):它的名字具有极大的误导性!它**不一定**会生成实际的硬件寄存器。它代表的是一个**数据存储单元**,能够在某个时刻被赋值,并保持这个值直到下一次赋值。- 核心特质:
它可以在 always和initial块中被赋值。 - 一个比喻:
reg更像一个带锁的盒子,你可以往里面放东西(赋值),它会一直保存着,直到你再次打开锁改变它。
黄金法则:
assign语句的左侧必须是wire类型。always和initial块内被赋值的信号,必须定义为reg类型。模块的输入端口只能是 wire。模块的输出端口可以是 wire或reg,但取决于其驱动方式。
二、 实战一:用“结构描述法”构建一个异或门
在Day 1,我们用了行为描述 (assign y = a & b;) 。今天,我们用更底层的**结构描述**方式来构建一个异或门,这将完美展示 wire 的作用。
我们知道: y = a ^ b = (~a & b) | (a & ~b)
- 创建新项目
xor_gate.v 文件,输入以下代码:// 使用基本的与、或、非门运算符来构建一个异或门module xor_gate ( input a, input b, output y); // 定义内部连接线 wire a_not, b_not; wire and_out1, and_out2; // 使用运算符实现逻辑门功能 // 非门:产生 a 的非 assign a_not = ~a; // 非门:产生 b 的非 assign b_not = ~b; // 与门:计算 ~a & b assign and_out1 = a_not & b; // 与门:计算 a & ~b assign and_out2 = a & b_not; // 或门:将两个与门的输出合并,得到最终结果 y = (~a & b) | (a & ~b) assign y = and_out1 | and_out2;endmodule
- 点击编译,并查看RTL图。
你会看到一个清晰的门级电路结构,而那些 wire类型的信号 (a_not,b_not等),正是连接这些门的**线**!这就是wire的本质。

三、 实战二:Testbench进阶与 reg 的深入理解
现在,为我们的异或门搭建测试平台。我们将通过这个Testbench,彻底理解 reg 在测试中的用法。
新建 tb_xor_gate.v 文件,输入以下代码:
`timescale 1ns/1nsmodule tb_xor_gate(); // 1. 定义激励信号 // 注意:它们要驱动DUT的输入,所以在always/initial块中赋值,必须定义为 reg! reg a, b; // 注意:它们要连接DUT的输出,所以定义为 wire wire y; // 2. 实例化被测设计 xor_gate u_xor_gate ( .a (a), .b (b), .y (y) ); // 3. 产生激励 initial begin // 初始化 a = 1'b0; b = 1'b0; #20; // 生成所有4种输入组合,观察输出 a = 1'b0; b = 1'b1; #20; a = 1'b1; b = 1'b0; #20; a = 1'b1; b = 1'b1; #20; // 额外加一个case,确保波形完整 a = 1'b0; b = 1'b0; #20; $stop; endendmodule
关键解释:
为什么 a和b是reg?因为在这个Testbench模块内部,是initial块在给a和b赋值。它们是被Testbench**驱动**的,需要一个“数据存储”的抽象来描述它们值的变化。为什么 y是wire?因为它仅仅是将被测模块u_xor_gate的输出端口连接到了这里,它是一条**连接线**。
四、 联合仿真:在波形中验证逻辑
按照Day 1的流程,设置好仿真,启动ModelSim。 运行仿真,查看波形。

请仔细观察:
当 a和b相同时,y为0。当 a和b不同时,y为1。同时,你还可以在波形图中看到内部连接线 and_out1和and_out2的变化,这能帮助你更深层次地理解电路的运作流程。**这就是仿真的强大之处——让你能窥探芯片内部的任何一根“线”!
五、 模块的层次化设计:工程师的必备技能
现在,我们已经有两个“芯片”了:and_gate(Day1设计) 和 xor_gate。如何将它们组合成一个更复杂的系统?答案就是:模块实例化。
让我们设计一个 logic_unit,它包含一个与门和一个异或门。
新建 logic_unit.v文件:
module logic_unit ( input [1:0] sel, // 2位选择信号 input x, input y, output out); wire and_out, xor_out; // 内部连接线 // 实例化我们已经设计好的与门模块 and_gate u_and ( .a (x), .b (y), .y (and_out) // 输出连接到内部线 and_out ); // 实例化我们刚刚设计的异或门模块 xor_gate u_xor ( .a (x), .b (y), .y (xor_out) // 输出连接到内部线 xor_out ); // 根据选择信号 sel,选择输出哪一个结果 // 这是一个2选1选择器,我们用条件运算符实现 assign out = (sel == 2'b00) ? and_out : (sel == 2'b01) ? xor_out : 1'b0; // 默认输出0endmodule

为 logic_unit编写Testbench并进行仿真。这将是一个绝佳的练习,让你真正体验如何像搭积木一样构建数字系统。
【今日源码下载】本文的完整源码(xor_gate.v, tb_xor_gate.v, logic_unit.v)已准备好。点击文末原文链接下载
【明日预告】
今天,我们彻底剖析了Verilog的“筋骨”——wire和reg,并迈入了模块化设计的大门。你已经具备了构建复杂系统的基本能力。
但是,组合逻辑的世界里暗藏玄机!一个巨大的陷阱正等着90%的初学者。
**Day 3:组合逻辑的双刃剑:assign与always@(*)与Latch陷阱**
我们将:
深入讲解描述组合逻辑的另一种强大方式: always@(*)块。揭示一个由 if或case语句不完整而引发的**锁存器**大坑!总结出安全编写组合逻辑的“军规”。
互动话题: 在今天的实验中,你成功看到内部信号的波形了吗?对于wire和reg,你是否还有疑问?或者你最想在Day 3中解决关于组合逻辑的什么问题?欢迎在评论区留言讨论!
《Verilog十日谈》系列精华目录(更新):
- Day 1: 从软件思维到硬件思维:我的第一行Verilog代码与ModelSim仿真
- Day 2: 数字电路的筋骨:详解wire、reg与模块层次化设计 (当前)
Day 3: 组合逻辑的双刃剑:assign与always@(*)与Latch陷阱 Day 4: 时序逻辑的基石:时钟、复位与非阻塞赋值(<=) Day 5: 价值千金的法则:阻塞(=)与非阻塞(<=)的终极对决 Day 6: 实战:用有限状态机实现一个序列检测器 Day 7: Testbench进阶:自动化验证、任务与系统函数 Day 8: 高效设计之道:PLL、RAM等IP核的调用与仿真 Day 9: 番外篇:常见问题答疑与调试技巧精讲 Day 10: 总结与展望:你的FPGA学习路线图
从思维到工具,从语法到项目,我们已经为你铺平了道路。点击关注,用十天,我们深入Verilog的“筋骨”所在,不见不散!
源码下载
2、支付问题请联系微信公众号客服。
3、优质Verilog/VHDL代码资源,所见即所得。
Verilog/VHDL资源下载 » Verilog十日谈 Day 2:数字电路的筋骨:详解wire、reg与模块层次化设计