(1)阻塞赋值“=” 直到现行的赋值语句完成,才允许下一条赋值语句的执行,在串行块(begin-end)中,各赋值语句将以它们在顺序块中的排列次序依次执行。
(2)非阻塞赋值“<=” 在赋值开始时,计算赋值号右边的语句,赋值结束时,更新赋值号左边的语句,因此其他在同一时间的语句都会并行执行。
(3)非阻塞赋值操作只能对寄存器类型的变量进行赋值,因此只能使用于"initial"和"always"块中,不允许使用在连续赋值语句"assign"中。
(4)一个always语句块只对一个变量进行赋值。
(5)使用 always 块来编写组合逻辑的代码时要用阻塞赋值的方式,使用 always 块建立组合逻辑电路模型时不要忘记 always 块中的敏感列表一定要使用电平触发的方式,然后在 always 块中使用阻塞赋值语句就可以实现组合逻辑。
(6)阻塞赋值代码:
//在always语句中,使用阻塞赋值语句
module block_nonblock(clk,reset_n,in,out);
input clk;
input reset_n;
input [2:0]in;
output reg [2:0]out;
reg [2:0]mid;
always@(posedge clk or negedge reset_n)
if(!reset_n)begin
mid = 3'd0;
out = 3'd0;
end
else begin
mid = in;
out = mid;
end
endmodule
(7)综合出来的RTL视图:
(8)仿真代码:
`timescale 1ns / 1ps
module block_nonblock_tb;
reg clk;
reg reset_n;
reg [2:0]in;
wire [2:0]out;
block_nonblock block_nonblock_inst(
.clk(clk),
.reset_n(reset_n),
.in(in),
.out(out)
);
initial clk = 1'd1;
always #10 clk = ~clk;
initial begin
reset_n <= 1'd0;
in <= 3'd0;
#20
reset_n <= 1'd1;
#200;
$stop;
end
always #20 in <= {$random} % 8;
endmodule
(9)仿真波形:
mid与in之间存在一个时钟周期的延迟,而out与mid之间没有。
(10)非阻塞赋值Verilog代码:
//在always语句中,使用非阻塞赋值语句
module block_nonblock(clk,reset_n,in,out);
input clk;
input reset_n;
input [2:0]in;
output reg [2:0]out;
reg [2:0]mid;
always@(posedge clk or negedge reset_n)
if(!reset_n)begin
mid <= 3'd0;
out <= 3'd0;
end
else begin
mid <= in;
out <= mid;
end
endmodule
(11)综合出来的RTL视图:
(12)仿真代码同之前的一致,波形如下:
mid与in之间有一个时钟周期的延迟,out与mid之间也有一个时钟周期的延迟。
标签:reset,12,clk,always,阻塞,mid,out,赋值 From: https://blog.csdn.net/2301_80417284/article/details/140082417