简单来说硬件描述语言有两种用途:1、仿真,2、综合。

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

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

  1. wire型的变量综合出来一般是一根导线;
  2. reg变量在always块中有两种情况:(1)、always后的敏感表中是(a or b or c)形式的,也就是不带时钟边沿的,综合出来还是组合逻辑(2)、always后的敏感表中是(posedge clk)形式的,也就是带边沿的,综合出来一般是时序逻辑,会包含触发器(Flip-Flop)

为什么在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和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线网型数据需要持续的驱动。