wire与reg的运用区别
0赞简单来说硬件描述语言有两种用途: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型都可以。但一般的,整个设计的外部输出(即最顶层模块的输出),要求是寄存器输出,较稳定、扇出能力也较好。
总结1:
1、行为上:
wire或是reg并不会导致电路行为的改变,而是组合逻辑还是时许逻辑改变了电路的行为。加上reg或是wire并没有影响电路,电路并不会因为加上了一个reg而改变,而是有clk的always中的reg才会影响电路。
2、语法上:(端口和例化)
源是reg和wire,目的地是wire。
3、语法上:(做右值)
wire和reg在任何情况下都可以做右值,也即在左值允许的情况下可以相互赋值。
4、语法上:(做左值)
wire仅用于assign,reg仅用于initial和always。
5、语法上:(初始化)
wire在声明的时候(可以用reg、wire初始化,不可以用常数)初始化。
reg在声明的时候(可以用reg、wire、常数)初始化。
列表如下:
项目 |
wire |
reg |
端口和例化 |
可以做源、目的地 |
只能作源 |
做右值 |
可以 |
|
做左值 |
assign |
initial和always |
声明时初始化 |
可以用reg、wire、常数,但是最好不要初始化wire,否则在综合的时候可能会报错:multi-driver。 |
只能用常数 |
但是,初始化时不能再一行声明多个变量.即:不允许 wire w1=1’b0,w2;但是可以wire w1=1’b0;wire w2; |
总结2:
assign |
initial和always |
|
赋值符 |
用且仅用= |
=和<=都可以,但是一般情况下,组合用=,时序用<= |
左值 |
左值用且仅用wire |
左值用且仅用reg |
描述电路类型 |
组合 |
initial:组合 always:组合或时序 |
(有@(posedge clk)的才是时序,否则都是组合) |
||
注意:
1、一般情况下,要将一个模块的所有输入设为wire,将输出设为wire和reg都行。
但是,当输出用assign赋值或者作为其子模块的输出时,必须为wire。
2、模块端口的output和input信号,在模块内部都是可读的。可作为右值,可以
为什么在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。