阻塞赋值和非阻塞赋值的区别

1.1简单叙述阻塞赋值和非阻塞赋值的区别:

  • (1)阻塞赋值(=)必须是阻塞赋值完成后,才进行下一条语句的执行;赋值一旦完成,等号左边的变量值立即变化。在同一个块中,非阻塞赋值表达式的书写顺序不影响赋值的结果。硬件没有对应的电路。(要点为串行,立即生效)

  • (2)非阻塞赋值(<=)在赋值开始时计算表达式右边的值,在本次仿真周期结束时才更新被赋值变量,即赋值不是立即生效的;非阻塞赋值允许块中其他语句同时执行。在同一个块中,非阻塞赋值表达式的书写顺序不影响赋值的结果。硬件有对应的电路。(要点:并行,不是立即生效,同时执行)

夏宇闻老师《Verilog数字系统设计教程》的读书笔记

阻塞赋值对应的电路结构往往与触发沿没有关系,只与输入的电平变化有关系;非阻塞赋值对应的电路结构往往与触发沿有关系,只有在触发沿时才有可能发生赋值的情况。

阻塞赋值操作符是“=”,非阻塞赋值操作符是“<=”。

阻塞的概念是指在同一个always块中,其后面的赋值语句从概念上是前一句赋值语句结束后再开始赋值的。

非阻塞赋值的概念是指在赋值操作开始时刻计算RHS表达式,赋值操作结束时刻更新LHS。关键来了,always块里的其他语句是同时进行计算RHS表达式和更新LHS的。

非阻塞赋值操作只能对寄存器类型变量进行赋值,因此只能用在“initial”块和“always”块等过程块中,非阻塞赋值不能用于连续赋值(assign语句)。

个人理解:阻塞赋值是指过程块中的语句是串行执行的(即一条语句执行完成才能执行下一条语句);非阻塞赋值是指过程块中的语句是并行执行的,即所有的语句都可以在赋值操作开始时刻同时计算RHS,在赋值操作结束时刻同时更新LHS。

8个要点:

(1) 时序电路建模时,用非阻塞赋值(<=)。

(2) 锁存器电路建模时,用非阻塞赋值(<=)。

(3) 用always块建立组合逻辑时,用阻塞赋值(=)。

(4) 在同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值。

(5) 在同一个always块中不要既用非阻塞赋值又用阻塞赋值。

(6) 不要在一个以上的always块中为同一个变量赋值。

(7) 用$strobe系统任务来显示用非阻塞赋值的变量值。

(8) 在赋值时不要使用#0延迟。

举例:移位寄存器

(1)阻塞赋值按照下面的写法生成的并非移位寄存器

module pipe(
input d,
input clk,
output q3
);
reg q1,q2,q3;
always@(posedge clk)
    begin
            q1=d;
            q2=q1;
           q3=q2;
    end
endmodule

综合效果如下图所示

阻塞赋值和非阻塞赋值的区别_第1张图片

用阻塞赋值实现移位寄存器的代码:

module pipe(
input d,
input clk,
output q3
);
reg q1,q2,q3;
always@(posedge clk)
begin
q3=q2;
q2=q1;
q1=d;
end
endmodule
阻塞赋值和非阻塞赋值的区别_第2张图片

综合出来的结果是不同的。

(2)将上面两个换成非阻塞赋值后,综合出来的结果都是移位寄存器且结果相同。

第一种情况的代码及对应电路

module pipe(
input d,
input clk,
output q3
);
reg q1,q2,q3;
always@(posedge clk)
    begin
            q1<=d;
            q2<=q1;
           q3<=q2;
    end
endmodule
阻塞赋值和非阻塞赋值的区别_第3张图片

第二种情况的代码和对应的电路

module pipe(
input d,
input clk,
output q3
);
reg q1,q2,q3;
always@(posedge clk)
    begin
        q3<=q2;
        q2<=q1;
        q1<=d;
    end
endmodule
阻塞赋值和非阻塞赋值的区别_第4张图片

参考出处传送门

你可能感兴趣的:(笔记,verilog,fpga开发)