问题提出:关于always块中的代码是怎么被运行的?以及非阻塞语句是否能够在always块中运行?当有多个always块同时出现时其运行顺序又是怎样的?
-
对于只有一个always块的情况
always中赋值类型为阻塞赋值 | 顺序执行立刻赋值 |
always中赋值类型为非阻塞赋值 | 顺序执行后统一赋值 |
这里给出always阻塞赋值的测试代码和运行后的RTL视图,可见always中可以进行阻塞赋值,赋值的对象是reg型,千万不能是wire型。由RTL视图可见,对于一个alway块中的代码,是顺序执行的,而遇到其中的阻塞赋值右边的值(LHS)立刻被赋值到左边(RHS),这也正是阻塞的含义(即当运行到我的赋值时,阻断其他的赋值,只有当我赋值完毕再赋值其他的)。
同时,从结果中也可以看出,当运行到最后一条语句时,模块的输出是通过触发器的形式再时钟的驱动下完成的。
module test(
input wire a,
input wire b,
input wire c,
input wire clk,
output reg [1:0] out1
);
reg [1:0] tem;
always@(posedge clk)
begin
tem = a+b;
out1 = tem+c;
end
endmodule
当是非阻塞赋值的情况,把上述always中“=”全替换为“<=”,这里不贴代码。由RTL视图可见,所有的赋值操作是在顺序计算完右边的表达式后统一赋值给左边,且是在脉冲控制的前提下实现的。
-
对于多个always块的情况
显然,根据所学我们知道always块是并行执行的。显然我们知道下述两种写法等价,因为非阻塞赋值都是块结束统一赋值。然而阻塞赋值以下形式还等价吗?答案是否定的。
原因在于:两个always块并行执行,而每个块中是顺序执行的,由于阻塞赋值的“赋值即时性”,在左边的代码中tem = a+b先执行先赋值,再执行下一条语句;而再右边代码中,两个语句分别在两个块中,因此并行执行,故等同于非阻塞赋值其结果便是上述非阻塞RTL视图。不信你试试看。。。