FPGA基础02-阻塞与非阻塞

  在always内部赋值语句中,常常用到阻塞赋值和非阻塞赋值,下面讲一下二者的区别及适用情况。

1. 阻塞赋值

  阻塞赋值类似C语言的顺序执行,即上一条语句执行完以后,立即执行下一条,并且上一条语句相应的变量也会进行更新,可以理解为串行执行。

1.1 测试代码

module  block
//========================< 端口 >==========================================
(
        //input
        input                       clk            ,
        input                          rst_n        ,
        //output
        output  reg        [ 1:0]   out1        ,
        output  reg           [ 1:0]    out2                
        
);

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        out1 = 2'd1;
        out2 = 2'd2;
    end
    else begin
        out1 = 2'd0;
        out2 = out1;
    end
end


endmodule

1.2 仿真波形

分析:由上图可以看出,再复位后的第一个时钟上升沿后,out1和out2均立即变为0,即顺序赋值,out1为0后,立即执行 out2 = out1,当这条语句执行完以后,out2的值也立即变化。

2.非阻塞赋值

  非阻塞赋值是由时钟节拍决定,在时钟上升到来时,执行赋值语句右边,然后将begin-end之间的所有赋值语句同时赋值到赋值语句的左边,注意:是begin—end之间的所有语句, 一起执行,且一个时钟只执行一次,属于并行执行语句。

2.1 测试代码

module  block
//========================< 端口 >==========================================
(
        //input
        input                       clk            ,
        input                          rst_n        ,
        //output
        output  reg        [ 1:0]   out1        ,
        output  reg           [ 1:0]    out2                
        
);

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        out1 <= 2'd1;
        out2 <= 2'd2;
    end
    else begin
        out1 <= 2'd0;
        out2 <= out1;
    end
end


endmodule

2.2 仿真波形

分析:因为阻塞赋值是先计算右边表达式的值,再赋值到左边变量。所以在第一个时钟上升沿之后,首先计算右边表达式的值,ou1为0,out2为上一时刻的out1数值(复位时out1为1,out2为2),然后再同时更新,表现为ou1为0,out2为1。

3.区别&使用情况

(1)区别

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

-非阻塞:非阻塞语句的执行过程是:首先计算语句块内部所有右边表达式(RHS)的值,然后完成对左边寄存器变量的赋值操作。

(2)使用情况

-在描述组合逻辑电路的时候,使用阻塞赋值;比如assign赋值语句和不带时钟的always赋值语句。

-在描述时序逻辑的时候,使用非阻塞赋值,综合成时序逻辑的电路结构,比如带时钟的always语句。

posted @ 2021-04-16 11:24  Sonny_2020  阅读(844)  评论(0)    收藏  举报