📅  最后修改于: 2021-01-11 14:47:41             🧑  作者: Mango
Verilog支持Always块内具有不同行为的阻塞和非阻塞分配语句。
阻塞分配类似于大多数流行编程语言中的软件分配语句。非阻塞分配是描述许多硬件系统(尤其是用于综合)的更自然的分配声明。
阻塞分配只能在少数情况下使用,例如对组合逻辑建模,定义函数或实现测试平台算法。要求所有符合IEEE P1364.1的综合工具都必须以显式样式代码支持阻塞和非阻塞分配,但要限制每个变量和每个块只能使用一种或另一种分配。
块分配语句是使用(=)运算符分配的,并在过程块中一个接一个地执行。但是,这不会阻止在并行块中运行的语句的执行。
module Block;
reg [7:0] a, b, c, d, e;
initial begin
a = 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
b = 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c = 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
d = 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
e = 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
有两个初始块可以并行执行。语句在每个块中顺序执行,并且两个块均在时间0ns处完成。
更具体地说,首先分配变量,然后分配display语句,然后分配所有其他语句。
这在输出中可见,其中在第一条显示语句中变量b和c为8'hxx。这是因为在调用第一个$ display时尚未执行变量b和c的赋值。
ncsim> run
[0] a=0xda b=0xx c=0xx
[0] a=0xda b=0xf1 c=0xx
[0] a=0xda b=0xf1 c=0x30
[0] d=0xaa e=0xx
[0] d=0xaa e=0x55
ncsim: *W,RNQUIE: Simulation is complete.
在下面的示例中,我们将在同一组语句中添加一些延迟,以查看其反应和行为方式。
module Block;
reg [7:0] a, b, c, d, e;
initial begin
a = 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
#10 b = 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c = 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
#5 d = 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
#5 e = 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
执行后,将提供以下数据。
ncsim> run
[0] a=0xda b=0xx c=0xx
[5] d=0xaa e=0xx
[10] a=0xda b=0xf1 c=0xx
[10] a=0xda b=0xf1 c=0x30
[10] d=0xaa e=0x55
ncsim: *W,RNQUIE: Simulation is complete.
非阻塞分配语句允许在不阻塞以下语句执行的情况下进行调度,并由(<=)符号指定。
相同的符号在表达式中用作关系运算符符,在非阻塞分配中用作赋值运算符。
采取与上述相同的示例,将所有(=)符号替换为非阻塞赋值运算符(<=),我们将获得输出的差异。
module Block;
reg [7:0] a, b, c, d, e;
initial begin
a <= 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
b <= 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c <= 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
d <= 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
e <= 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
现在,所有$ display语句都打印'h'x 。此行为的原因是非阻塞分配语句的执行。
捕获特定时间步长的每个非阻塞语句的RHS,并将其移至下一个语句。
仅在时间步结束时才将捕获的RHS值分配给LHS变量。
ncsim> run
[0] a=0xx b=0xx c=0xx
[0] a=0xx b=0xx c=0xx
[0] a=0xx b=0xx c=0xx
[0] d=0xx e=0xx
[0] d=0xx e=0xx
ncsim: *W,RNQUIE: Simulation is complete.