verilog HDL中wire和reg的区别

更新时间:2023-12-14 18:44:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

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类型。

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

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

下面所列是常出的错误及相应的错误信息(error message) ?用过程语句给一个net类型的或忘记声明类型的信号赋值。 信息:illegal …… assignment. ?将实例的输出连接到声明为register类型的信号上。

信息: has illegal output port specification. ?将模块的输入信号声明为register类型。

信息:incompatible declaration, ……

****************************************************************************** wire与reg的区别?什么时候用wire?什么时候用reg? 简单来说硬件描述语言有两种用途:1、仿真,2、综合。 对于wire和reg,也要从这两个角度来考虑。

从仿真的角度来说,HDL语言面对的是编译器(如Modelsim等),相当于软件思路。 这时:

wire对应于连续赋值,如assign reg对应于过程赋值,如always,initial

从综合的角度来说,HDL语言面对的是综合器(如DC等),要从电路的角度来考虑。 这时:

1、wire型的变量综合出来一般是一根导线; 2、reg变量在always块中有两种情况:

(1)、always后的敏感表中是(a or b or c)形式的,也就是不带时钟边沿的,综合出来还是组合逻辑

(2)、always后的敏感表中是(posedge clk)形式的,也就是带边沿的,综合出来一般是时序逻辑,会包含触发器(Flip-Flop)

在设计中,输入信号一般来说你是不知道上一级是寄存器输出还是组合逻辑输出,那么对

于本级来说就是一根导线,也就是wire型。而输出信号则由你自己来决定是寄存器输出还是组合逻辑输出,wire型、reg型都可以。但一般的,整个设计的外部输出(即最顶层模块的输出),要求是寄存器输出,较稳定、扇出能力也较好。 为什么在verilog中要定义wire? 有几种情况变量需要定义成wire。 第一。assign 语句 例如: reg a,b; wire and_result; ...

assign and_result =a&&b;

你可以试试把wire定义成reg。综合器会报错。 第二。元件例化时候的输出必须用wire 例如: wire dout; ram u_ram ( ... .out(dout) ... );

wire按照国外的教材上面的定义:

wire为无逻辑连线。只做连线,wire本身是不带逻辑性的,所以输入什么输出就是什么。所以你尝试着用always语句对wire变量赋值。综合器就会报错。 那么你可能会问。assign c =a&&b不是就是对wire的赋值吗?

其实并非如此。综合器综合时将a&&b综合成ab经过一个与门。而c只是连接到与门输出的线。

正真综合出与门的是&&。而不是c。 Abstract

Verilog初學者最常見的問題:『什麼時候該用wire?什麼時候又該用reg?』 Introduction

大體上來說,wire和reg都類似於C/C++的變數,但若此變數要放在begin...end內,該變數就須使用reg,在begin...end之外,則使用wire。 另外使用wire時,須搭配assign;reg則不必。 input,ouput,inout預設值都是wire。

若wire和reg用錯地方,compiler都會提醒,所以不必太擔心。

一個很重要的觀念,在Verilog中使用reg,並不表示合成後就是暫存器(register)。若在組合電路中使用reg,合成後仍只是net,唯有在循序電路中使用reg,合成後才會以flip-flop形式表示成register。

****************************************************************************** 【转载】Verilog HDL 初级入门知识简单讲解(wire 和 reg 类型的区别, always 和 assign 的区别,“阻塞”赋值 和 “非阻塞赋值”的区别 )

很多刚学Verilog HDL (硬件描述语言)的朋友肯定会对阻塞赋值和非阻塞赋值比较疑惑,那我们就一起来抛开这层迷雾吧。

首先我们要理解两种变量类型 Net Type(连线型)和 Register Type (寄存器型)。(有些参考书上有分为3种类型,这个无关紧要) verilog数据类型.PNG

Net Type(连线型),从名字上理解就是“导线”呗,导线的这头和导线的另一头始终是直接连通的,这头是什么值,那头就是什么值,所以输出随着输入随时变化的。连线型中 wire 最常见。

Register Type(寄存器型),寄存器就不像普通导线了,它可以把值给存住,你只要给它赋一次值,它都会存住那个值,直到你给它赋一个新的值它才会改变。寄存器型中 reg 最常见。

最常用到的是 wire 和 reg 这两种类型,其他的对我们初学者来说一般很少用到,可以暂时跳过,以后慢慢学下去自然会理解。

注意:wire型变量如果没有赋予初始值,默认初始值为高阻态“Z”。

reg 型变量如果没有赋予初始值,默认初始值为不定态“X”。

在理解这两种基本的数据类型之后,我们来看看verilog语言中的赋值语句。verilog语言中的赋值语句有两种,一种是持续赋值语句(assign语句),另一种是过程赋值语句(always语句)。

持续赋值语句(assign语句)主要用于对wire型变量的赋值,因为wire(线型)的值不能存住,需要一直给值,所以需要用持续赋值。

例如:assign c = a + b; 只要a和b有任意变化,都可以立即反映到c上,也就是说c的值是根据a,b的值随时变化的。

过程赋值语句(always语句)主要用于reg 型变量的赋值 ,因为always语句被执行是需要满足触发条件的,所以always过程块里面的内容不是每时每刻都被执行,因此需要将被赋值的对象定义成寄存器类型,以便这个值能被保持住。

过程赋值又分为 阻塞赋值 “=” 和 非阻塞赋值 “<=” 两种。这里的非阻塞赋值符号 “<=” 与 “小于等于” 符号相同,他们在不同的语境下表示不同含义,要注意区分,例如在“if-else”等判断语句中,一般都表示为“小于等于”。 接下来对这两种赋值作具体讲解...

① 阻塞赋值 “=“ 。 阻塞赋值和我们平时理解的赋值差不多,不用太多解释,就是按照语句的顺序,一句句往下顺序执行。一个赋值语句执行完,然后执行下一个赋值语句。 ② 非阻塞赋值 “<=” 。非阻塞赋值就比较特别了,在同一个always过程块中,非阻塞赋值语句都是同时并发执行的,并且在过程块结束时才执行赋值操作。也就是说,在同一个always过程块中,非阻塞赋值语句被执行没有先后顺序,在过程快结束时,大家一起被赋值。

给大家举一个具体的例子:

module test (clk, a1, a2, b1, b2, c1, c2); // test为module名称,括号内的是端口列表,包含所有输入输出的变量名称

input clk, a1, a2; // 定义输入变量,这里没有定义位宽,默认为1位宽度 output b1, b2, c1, c2; // 定义输出变量,这里没有定义位宽,默认为1位宽度 reg b1 = 0 , b2 = 0, c1 = 0 , c2 = 0; // 注意!因为这些变量将会在always过程块中被赋值,所以必须定义成 reg 型

// 注意!这里省略了对输入信号clk, a1, a2 的类型定义,它们默认为1位的wire 型(因为输入信号是随时要变化,所以必须用wire型)

本文来源:https://www.bwwdw.com/article/g615.html

Top