• 用一个例子来学习阻塞赋值和非阻塞赋值


    阻塞赋值与非阻塞赋值

    阻塞赋值的一般表达式为:目标变量名=驱动表达式  阻塞赋值是一种理想化的数据传输,赋值立即发生,不存在延时行为

    非阻塞赋值一般表达式为:目标变量名<=驱动表达式   非阻塞赋值比较接近真实的电路工作状态,应为他从综合的角度考虑到了延时和并行性。

    在过程启动中,非阻塞赋值使三条语句同时运行,而阻塞赋值是按顺序方式完成更新的数据的。

    新建工程,编写示例代码

    module block_nonblock(clk,rst_n,a,b,c,out );
    input clk,rst_n,a,b,c;
    
    
    output reg [1:0]out;//out=a+b+c>2,所以out应该为2位
    
    reg [1:0] d;//定义一个中间变量
    //d=a+b;
    //out=d+c
    always@(posedge clk or negedge rst_n)
    if(!rst_n)
    
    out=2'b0;
    
    else begin
    d=a+b;
    out=d+c;
    end
    
    endmodule
    
     

     从RTL 视图可以看出整个运行过程是顺序执行的。

    改变

    d=a+b;
    out=d+c;的赋值顺序,再观察RTL视图,会发现两者之间是有区别的,这说明顺序决定着输出的结果。

    将赋值语句改为非阻塞赋值。

     

    观察RTL视图,会发现两者是有明显不同。

    同样的改变

    d<=a+b;
    out<=d+c;的赋值顺序,再观察RTL视图,会发现两者之间是没有区别的,这说明顺序并没有决定输出的结果。

     

    由RTL图理论上可以看出两种赋值语句的不同,下面编写testbench进行仿真。

    `timescale 1ns/1ns
    module block_nonblock_tb;
    `define clock_period 20
    
    reg clock,rst_n,a,b,c;
    wire [1:0] out ;
    block_nonblock block_nonblock0(clock,
    rst_n,
    a,
    b,
    c,
    out    );//这里采用一一对应的调用方式
    
    initial clock=1'b0;
    always#(`clock_period/2) clock=~clock;//产生时钟信号
    initial begin
    rst_n=1'b0;
    a=0;b=0;c=0; //赋值激励信号
    #(`clock_period*200+1)
    
    rst_n=1'b1;
    a=0;b=0;c=1; 
    #(`clock_period*200)
    a=0;b=1;c=0; 
    #(`clock_period*200)
    a=0;b=1;c=1; 
    #(`clock_period*200)
    a=1;b=0;c=0; 
    #(`clock_period*200)
    a=1;b=0;c=1; 
    #(`clock_period*200)
    a=1;b=1;c=0; 
    #(`clock_period*200)
    a=1;b=1;c=1; 
    #(`clock_period*200)
    #(`clock_period*200)
    $stop;
    end
    
    endmodule

     设定文件路径后按前面的四个程序进行前仿。

    d=a+b;
    out=d+c;

    out=d+c;
    d=a+b;


    d<=a+b;
    out<=d+c;

    out<=d+c;
    d<=a+b;


    通过仿真可以看出四种情况的异同,至此阻塞赋值和非阻塞赋值就可以通过实际例子来理解了。

  • 相关阅读:
    Qt QString判断是否是数字
    Qt 判断QString中的字符串是否为纯数字
    Qt delete和deletelater的区别
    Qt QTcpSocket waitForReadyRead()等函数用法——客户端开关读写应用笔记
    Notepad++对比两个文件不同的方法
    Qt error C1071 :在注释中遇到意外的文件结束
    Qt error C2601: “...”: 本地函数定义是非法的
    Qt 错误 C1071 在注释中遇到意外的文件结束 的解决办法
    Qt 串口和线程的简单结合(通过子线程操作串口、movetothread)
    Qt 实现多线程的串口通信
  • 原文地址:https://www.cnblogs.com/noticeable/p/7200170.html
Copyright © 2020-2023  润新知