简单来说硬件描述语言有两种用途:1、仿真,2、综合。
对于wire和reg,也要从这两个角度来考虑。\\
从仿真的角度来说,HDL语言面对的是编译器(如Modelsim等),相当于软件思路。 这时: wire对应于连续赋值,如assign
reg对应于过程赋值,如always,initial\\
从综合的角度来说,HDL语言面对的是综合器(如DC等),要从电路的角度来考虑。 这时:
- wire型的变量综合出来一般是一根导线;
- 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。
总结
大体上来说,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中reg和wire的区别
组合逻辑输出变量,可以直接用assign。
如果不指定为reg类型,那么就默认为1位wire类型,故无需指定1位wire类型的变量。
专门指定出wire类型,可能是多位或为使程序易读。
wire只能被assign连续赋值,reg只能在initial和always中赋值。
比如: module lddata(clk,rst,cs,din,dout,tmpdata); input clk, rst,cs; input din; output dout,tmpdata; reg tmpdata; always@(posedge clk or negedge rst) if(!rst) tmpdata <=0; else tmpdata<= din; assign dout = tmpdata|cs; endmodule
其实他们是不同的抽象级别,wire 如同vhdl中的signal类型,是和实际的物理连接对应的,而reg属于算法描述层次用的类型,和实际电路没有直接的对应关系,也就是说它相当于c语言中的变量(int,float等),vhdl中的variable。reg不和实际的电路如寄存器对应,高层次的描述时用。而always其实算是算法级描述的语句,所以其中的变量必须声明为reg。
比如:一个简单的组合逻辑的例子,用了reg类型 module mux(a,b,c,sel); input a,b,sel; output c;reg c; always @(sel or a or b) if(sel ==1'b0) c=a; else c=b; endmodule;
这个综合出来就是一个简单的二选一选择器,组合逻辑电路。
看它描述的方式,是不是就是把电路的行为(功能)描述出来了,这种就是算法级描述。
wire表示直通,即输入有变化,输出马上无条件地反映(如与、非门的简单连接)。reg表示一定要有触发,没有输入的时候可以保持原来的值,但不直接实际的硬件电路对应(并非不能生成实际电路)。
线网型数据包括wire,wand,wor等几种类型,需要在被一个或一个以上驱动源驱动时,才能各自决定其不同线网型数据的最终值。
两者的区别是:reg寄存器型数据保持最后一次的赋值,而wire线网型数据需要持续的驱动。