我是靠谱客的博主 清脆大碗,最近开发中收集的这篇文章主要介绍阻塞/非阻塞——纸上得来终觉浅,绝知此事要躬行,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

    阻塞赋值和非阻塞赋值在可综合的代码中不需要严格的区分,但是在仿真文件中就尤为重要。阻塞赋值是指,只有当前赋值操作完成之后,后面的赋值操作才会发生;非阻塞赋值是指,当前块中的所有赋值操作完成后再计算各个变量的值,后续的赋值操作会覆盖之前的值。举个例子。

    a、b和c的值分别为a=1, b=2, c=3。

    a=b;

    a=c;

    b=a;

    以上操作后,a的值为c,b的值为3。其过程是,a=b时,a的值被修改为2后才开始执行a=c;a=c执行后,a的值已经变成3,然后才开始执行b=a;执行b=a时,a的值已经为3,所以b的值为3。如果改为非阻塞赋值:

    a<=b;

    a<=c;

    b<=a;

    上述操作后,a的值为3,b的值为1,c的值为3。其过程是,a首先被赋值为b,接着a被赋值为c。上述过程之后最后一个对a的赋值有效。因为非阻塞赋值就像他的名字,不会等到a<=b结束后才执行a<=c,而是畅通无阻的向下执行,所以只有最后一个赋值是有效的。b<=a执行时,a还是1。只有当上述操作所在的块结束后,每个变量才会被赋值。

    非阻塞赋值的行为也可以简单描述为:赋值语句块中,对同一个变量的赋值以最后一次赋值为准;当前赋值语句块结束之前,所有变量都保持原有的值;当赋值语句块结束时,所有变量被同时赋值。如a=1, b=2, c=3:

    always @ (posedge clk) begin 

        a<=b;

        a<=c;

        a<=4'hf;

        b<=a;

        c<=b;

    end

    执行完毕后,a等于4'hf,b等于1,c等于2。

    以下我仿真时使用的一个task的例子。

task tk_eset_wr(
input
[`ESET_ADDR_WID: 0]
depth,
input
logic
[`ESET_WID*`ESET_DEPTH-1: 0]
data
);
localparam FACTOR
= `ESET_WID / `REG_WID;
automatic reg
[`ESET_WID*`ESET_DEPTH-1: 0]
data_tmp=0;
mem_sel = 0;
mem_rst = 1'b1;
#(PERIOD*2) mem_rst = 1'b0;
repeat (`CH_PER_SUB) begin
data_tmp = data;
repeat (depth) begin
repeat (FACTOR) begin
@(posedge clk);
mem_wr = 1'b1;
mem_data = data_tmp[`ESET_WID*`ESET_DEPTH-1: `ESET_WID*`ESET_DEPTH-`REG_WID];
data_tmp = {data_tmp[`ESET_WID*`ESET_DEPTH-`REG_WID-1: 0], {`REG_WID{1'b0}} };
end
@(posedge clk);
mem_wr = 1'b0;
end
mem_sel++;
end
mem_wr <= 1'b0;
endtask : tk_eset_wr

    上例中,task中没有延时控制语句,是阻塞赋值保证了data_temp的向左移位。mem_data = data_tmp[`TSET_MAP_WID*16-1: `TSET_MAP_WID*16-`REG_WID];首先将data_temp的一个段赋值给mem_data,只有当该赋值结束后,data_tmp的向左移位才会发生。

 

最后

以上就是清脆大碗为你收集整理的阻塞/非阻塞——纸上得来终觉浅,绝知此事要躬行的全部内容,希望文章能够帮你解决阻塞/非阻塞——纸上得来终觉浅,绝知此事要躬行所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部