Verilog 阻塞赋值与非阻塞赋值(二)

时间:2021-03-15 11:35:38   收藏:0   阅读:0

问题一

在这个程序下:

//d=a+b
//out=d+c

always @(posedge Clk or negedge Rst_n) begin
    if(!Rst_n)
        out = 2‘b0;
    else begin
        d <= a + b;
        out <= d + c;
    end

end

技术图片

问题分析:分析出现了out暂时为0的情况

技术图片

分析出现了out暂时为0的情况(2):

技术图片

技术图片

技术图片

技术图片


`timescale 1ns/1ns
`define tp 1 
module block_nonblock(Clk,Rst_n,a,b,c,out);

    input Clk;
    input Rst_n;
    input a,b,c;
    
    output reg [1:0]out;    
//因为out 是在always@ 中进行赋值的,所以要将out定义为reg类型

//  out = a + b + c; //把该算式分解为两步
//  d = a + b;
//  out = d + c;
    reg [1:0]d;

always @(posedge Clk or negedge Rst_n) begin
    if(!Rst_n)
        out <=#`tp 2‘b0;		//加入模拟电路延迟
    else begin
        d <=#`tp a + b;
        out <=#`tp d + c;
    end

end

endmodule

技术图片

现在可以明确的看到,当时钟上升沿检测到b=1,a=0的时候,就会对d进行赋值操作,但这样一个赋值操作并不是马上就发生的,而是之后了这么久(#`tp),才对d进行的赋值,d=1;并在下一个上升延时才对out进行赋值;

在实际的电路中就是这种情况。

程序:

module block_nonblock(Clk,Rst_n,a,b,c,out);

    input Clk;
    input Rst_n;
    input a,b,c;
    
    output reg [1:0]out;    
//因为out 是在always@ 中进行赋值的,所以要将out定义为reg类型

//  out = a + b + c; //把该算式分解为两步
//  d = a + b;
//  out = d + c;
    reg [1:0]d;

always @(posedge Clk or negedge Rst_n) begin
    if(!Rst_n)
        out <= 2‘b0;
    else begin
        d <= a + b;
        out <= d + c;
    end

end

endmodule

时序的仿真波形如下:

技术图片

在这个过程中,out 的这个 00 的状态是我们不希望看到的;为什么这里out的值 会相比于a+b=d 的值会有一拍的的延迟呢?原因就是中间加的 这一个 d = a+b ,从而使生成的电路中多出一个寄存器(如下图),所以在always@ 语句块中推荐使用非阻塞赋值。

技术图片

always @(posedge Clk or negedge Rst_n) begin
    if(!Rst_n)
        out <= 2‘b0;
     else begin
    //     d <= a + b;
    //     out <= d + c;
    out <= a + b + c;   //a+b+c是一段组合逻辑
    end

end
endmodule

生成电路如下:

技术图片

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!