Menu Close

Verilog 顺序语句

在Verilog中不仅有并发语句、并发过程,也有顺序语句。顺序语句是由always,initial,function,task等关键字引导的块结构组成。在块结构(block)中可以由一条或多条语句组成,多条语句组成的块由begin…end结构隔离。

顺序语句的特点:

  1. 顺序性

就是由always,initial,function,task等引导的过程块内部语句是顺序执行,是从上到下或按书写顺序执行的,因此语句书写的顺序会影响代码的执行结果。

例1:

reg [3:0] a, b, c, d;

always@(*)
begin
    a = 2;
    b = 3;
    c = a + b;
    c = 4;
    d = a + b - c;
end

 

运行结果 d=1;

如果调换顺序,如例2,

例2:

reg [3:0] a, b, c, d;

always@(*)
begin
    a = 2;
    b = 3;
    c = a + b;     // c=5
    d = a + b - c; // d=0
    c = 4;         // c=4
end

 

运行结果 d=0;

2.在顺序语句中可以对reg型变量多次赋值。

reg型变量只能在顺序语句中被赋值,而且可以多次赋值,如上面的例1,例2.

但在同一个module内reg型变量依然不能在多个顺序过程内赋值,因为这些顺序过程之间是并发的。

例3:

reg [3:0] a, b, c, d, e;

always@(*)
begin
    a = 2;
    b = 3;
    c = a + b;     //c=5
    d = a + b - c; //d=0
    c = 4;         //c=4
end

always@(*)
begin
    d = a + c - b;
    e = a * b;
end

 

这两个独立always块,在同一module内出现赋值冲突,因为变量d在两个always块中赋值。由于这两个独立的always块是两个并发过程,因此不允许在两个并发过程中对同一个变量赋值。像上面的例子在综合时会有错误提示,在仿真时变量d在赋值冲突时会有’X’值生成,并且会引起 ‘X ’ 在整个系统中传递。

3. 在顺序语句中不能对wire型变量赋值。

由于wire 型变量语句,以及wire型的输出接口只接受并发赋值,即每个wire型变量的赋值都是并发过程(连续检测的),而对于always块结构而言也是一个并发过程,并发过程是不允许嵌套的。就像不能在一个assign语句嵌套另一个assign 或always语句一样。因此在always块中只能对寄存器赋值。并发赋值语句可以等效成一个always过程。

例:并发赋值(assign)与always的等效性

(1)     wire    [3:0]     c;

assign c = a + b;

(2)   reg      [3:0]     c;

always@(*)
c = a + b;

4. 顺序语句赋值

顺序过程中的赋值语句有两种,分别为阻塞赋值语句与非阻塞赋值语句,这两种赋值语句是Verilog在顺序赋值语句中的建模,既有区别又有联系。下面对这两种赋值做简单的描述,跟多的细节请关注后续课程中更专业的文章或视频。

(1)阻塞赋值语句  “=”

    •   阻塞赋值语句在顺序执行时,被赋值变量值立即更新。
    •  对同一变量后面赋值语句覆盖前面的赋值,但覆盖前已被使用的表达式的值不受影响
    • 阻塞赋值语句不会引起always重入,或者可以说重入不会影响运行结果。

 

(2)非阻塞赋值语句 “<=”

    •  非阻塞赋值语句”<=”在顺序执行的过程中赋值不能立即实现,而是当该过程中所有语句完成后一起评估执行结果。
    • 本次得到的赋值不能被其它表达式直接使用,本次过程执行只能使用进入该过程之前的变量值。
    • 对同一变量的赋值,后面的赋值覆盖前面的赋值。
    • 非阻塞赋值语句会引起always重入,重入会影响运行结果的改变。

例4:

reg [3:0] a, b, c, d, e;
//假设在进入always过程之前, a,b,c的值分别为7,8,9,分析本例的运行结果。
always@(*)
begin
    a <= 2;
    b <= 3;
    c <= a + b;     //c=?
    d <= a + b - c; //d=?
    c <= 4;         //c=?
end

执行结果如下:
a = 2,
b = 3,
c = 4,
d = 6;

5. always过程可以使用边沿激励,从而实现时序电路设计 详细内容参见时序电路设计部分。 可见,阻塞与非阻塞赋值语句差别还是很大的,注意在学习与使用过程中不断体会。

 

对应视频:

Posted in FPGA, FPGA 教材教案, IC, Verilog, Verilog

发表回复

相关链接