Verilog 中定义信号为什么要区分 wire 和 reg 两种类型?

本文解析了Verilog语言中reg和wire的区别及其在电路设计中的应用。reg用于表示存储单元,可以保持状态,适用于时序逻辑;wire则用于表示直通的信号线,适用于组合逻辑。

本质上为什么要有reg和wire,因为电路需要有记忆性的单元(比如FF)以及无记忆性的单元(比如导线)。

reg a ;
reg b;
always@ (*) begin

if (<condition>)
a = tmp ;
b = a ;

end
在这段代码中a是不会综合出寄存器的,而b却会,原因在于a是中间变量,就是一条线,所以综合出来的不是寄存器,而是一条线。而在condtion不满足的情况下b要保值,所以b会综合成寄存器。绝不是综合工具对代码描述的硬件行为的一种解读。

Verilog作为一门行为描述语言,你可以把每一段程序都理解为“用语言描述一个模块”,而实际上,一个模块的组成无非就是“引脚”+“内部的各种电路”。
有个这种准备之后就好理解wire 和 reg 了。Verilog中,把没有定义类型的信号默认设置为wire,除非特殊声明一次。如:
input[7:0] a, b;
reg [7:0] a;
以上例子,由于“input”就是模块管脚的声明,他有两个管脚a,b,用作输入。而再把a定义成寄存器类型,方便功能定义中进行操作。所以此时a 为reg型 b 为 默认wire 型。
所以说,可以粗略地把wire型理解为“从管脚输入的、原始的信号序列”,他在导体上以电信号的形式流动,而把reg型理解为“用寄存器存着从管脚输入的信号”,因为之后在寄存器中存住的数字信息,才能进行诸如移位、赋值等操作。


很经典的解读:

wire表示直通,即输入有变化,输出马上无条件地反映(如与、非门的简单连接)。

reg表示一定要有触发,输出才会反映输入的状态。

reg相当于存储单元,wire相当于物理连线。reg表示一定要有触发,没有输入的时候可以保持原来的值,但不直接实际的硬件电路对应。

      两者的区别是:寄存器型数据保持最后一次的赋值,而线型数据需要持续的驱动。wire使用在连续赋值语句中,而reg使用在过程赋值语句(initial ,always)中。wire若无驱动器连接,其值为z,reg默认初始值为不定值 x 。

      在连续赋值语句中,表达式右侧的计算结果可以立即更新表达式的左侧。在理解上,相当于一个逻辑之后直接连了一条线,这个逻辑对应于表达式的右侧,而这条线就对应于wire。在过程赋值语句中,表达式右侧的计算结果在某种条件的触发下放到一个变量当中,而这个变量可以声明成reg类型的。根据触发条件的不同,过程赋值语句可以建模不同的硬件结构:如果这个条件是时钟的上升沿或下降沿,那么这个硬件模型就是一个触发器;如果这个条件是某一信号的高电平或低电平,那么这个硬件模型就是一个锁存器;如果这个条件是赋值语句右侧任意操作数的变化,那么这个硬件模型就是一个组合逻辑

      对组合逻辑输出变量,可以直接用assign。即如果不指定为reg类型,那么就默认为1位wire类型,故无需指定1位wire类型的变量。当然专门指定出wire类型,可能是多位或为使程序易读。wire只能被assign连续赋值,reg只能在initial和always中赋值。

      输入端口可以由wire/reg驱动,但输入端口只能是wire;输出端口可以是wire/reg类型,输出端口只能驱动wire;若输出端口在过程块中赋值则为reg型,若在过程块外赋值则为net型(wire/tri)。用关键词inout声明一个双向端口, inout端口不能声明为reg类型,只能是wire类型。

      默认信号是wire类型,reg类型要申明。这里所说的默认是指输出信号申明成output时为wire。如果是模块内部信号,必须申明成wire或者reg.

      对于always语句而言,赋值要申明成reg,连续赋值assign的时候要用wire。

模块调用时 信号类型确定方法总结如下:

信号可以分为端口信号内部信号。出现在端口列表中的信号是端口信号,其它的信号为内部信号。

对于端口信号,输入端口只能是net类型。输出端口可以是net类型,也可以是register类型。若输出端口在过程块中赋值则为register类型;若在过程块外赋值(包括实例化语句),则为net类型。

内部信号类型与输出端口相同,可以是netregister类型。判断方法也与输出端口相同。若在过程块中赋值,则为register类型;若在过程块外赋值,则为net类型。

若信号既需要在过程块中赋值,又需要在过程块外赋值。这种情况是有可能出现的,如决断信号。这时需要一个中间信号转换

下面所列是常出的错误及相应的错误信息(error message)

用过程语句给一个net类型的或忘记声明类型的信号赋值。

           信息:illegal …… assignment.

将实例的输出连接到声明为register类型的信号上。

           信息:<name> has illegal output port specification.

将模块的输入信号声明为register类型。

           信息:incompatible declaration, <signal name> ……



### Verilog 中测试平台 `reg` `wire` 的区别及正确使用方法 #### 一、基本概念 在 Verilog HDL 中,`reg` `wire` 是两种不同的数据类型,它们的主要用途行为存在显著差异。 - **Wire 类型** Wire 表示一种物理连线,在硬件中类似于一根导线。它的值由与其相连的连续赋值语句或模块实例化决定[^1]。如果未被驱动,则默认为高阻态(z)。Wire 型号的数据通常用于描述组合逻辑电路中的信号传递过程[^2]。 - **Reg 类型** Reg 并不直接代表寄存器硬件实体;而是指代能够存储数值的状态变量。只有当该状态发生变化时才重新计算并保存新值——这通常是通过 always 块实现的。因此,在仿真过程中,reg 可以保留上次赋予它的值直至再次修改为止[^3]。 #### 二、测试平台中的应用 在构建测试平台 (Testbench) 时: - 对于激励源部分,比如设置输入信号模式或者控制序列发生器等功能单元内部需要用到可变状态量的地方,应该选用 reg 数据类型来声明这些局部变量; - 而对于待测设备(Device Under Test, DUT)接口端口之间相互交换的信息流则应采用 wire 定义形式以便更贴近真实情况下的互连关系模拟[^4]。 具体来说: - 输入到 DUT 的信号一般定义reg ,因为我们需要主动去改变它们作为刺激给定。 - 来自 DUT 输出的结果读取往往利用 wire 进行接收处理分析比较操作等。 #### 三、代码示例 下面给出一段简单的例子展示如何在一个典型的同步计数器验证环境中合理运用这两种不同类型: ```verilog // 计数器模块 module counter ( input clk, input reset, output reg [3:0] count ); always @(posedge clk or posedge reset) begin if(reset) count <= 4'b0; else count <= count + 1; end endmodule // 测试平台 module test_counter(); reg clk; // 钟控信号,需手动切换 reg reset; // 复位信号,同样需要人为干预调整高低电平转换时刻点 wire [3:0] out_count; counter dut(.clk(clk), .reset(reset), .count(out_count)); initial begin $dumpfile("test.vcd"); $dumpvars(0,test_counter); clk = 0; // 初始化钟控脉冲低电平开始周期循环迭代运行下去... forever #5 clk = ~clk; // 创建周期性的时钟波形图样供后续采样检测用 end initial begin reset = 1; // 初始状态下拉复位按钮激活生效一段时间后再释放恢复正常工作流程继续前进探索未知领域吧少年们加油哦! #10; reset = 0; repeat(16)@(posedge clk); // 等待十六次上升沿触发事件完成整个范围内的遍历考察一遍看看有没有什么异常现象出现呢? $finish(); // 结束当前进程退出系统返回主函数调用处等待进一步指示命令下达执行新的任务咯嘿嘿嘿~ end endmodule ``` 上述代码片段展示了如何创建一个基础的计数器及其对应的测试环境配置方案。其中特别注意区分哪些地方用了 reg (如 clock reset 控制开关),以及那些位置采用了 wire 接收来自子组件 outputs[] 数组成员项的内容进行下一步动作规划安排部署实施落地开花结果啦! ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值