wjw576657631的个人空间 https://blog.eetop.cn/743817 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

容易弄混的阻塞赋值与非阻塞赋值的几个问题

已有 1851 次阅读| 2011-11-7 17:22 |个人分类:个人心得

程序语句如下:

always @(posedge RST or posedge CLK)
if(RST)
    begin
    addra <=0;
    flag  <=0;
    end
else
    begin
    addra <= addra +1'b1;
    if(addra==1)
        flag<=1;
  end

意思就是说addra在RST为0时开始从0增长,长到1时flag非阻塞赋值为1.仿真结果如下:

过程解析:addra从0变到1的时钟上长沿时刻,检测addra的值,addra的值为0,因为是非阻塞赋值,左式还没来得及更新。等到addra从1变到2的clk上升沿时刻,检测addra的值,此时addra的值为1,并非2,同样也是因为左式没有更新,此时才符合flag赋1的条件,也就是在这个时间步,flag非阻塞赋值为1,该时间步刚刚结束flag立即更新为1.图中第三行为flag,第四行为addra的值变化。

若将addra的值由非阻塞赋值改为阻塞赋值,那么addra 值是立即更新的,即在addra由0变为1的时钟沿时刻即能检测出addra的值是1的,于是flag立即变为1.当然对于flag而言,阻塞赋值与非阻塞赋值是一样的,但会对以flag为判断标志的其它信号造成影响。仿真结果如下图:

其实以上说法有失准确,addra阻塞赋值时,addra由0变为1的时钟沿时刻能检测出addra的值是1实属巧合,因为“检测”这一动作也是在时钟沿时刻进行的,属于非阻塞赋值左式更新之前的活跃事件,而活跃事件(阻塞赋值,非阻塞赋值右式计算,连续赋值等)的进行是随机的,本次实验时,“检测”恰好在addra的阻塞赋值之后。通过实验,或将assign flag1= addra(连续赋值),flag在flag1由1变到2的时钟沿时刻才变为1的,这恰恰说明了“检测”发生在该连续赋值语句的前面,检测时还末经过连续赋值,下一次检测时才检测出来。

这里也加深一下对连续赋值的认识:一个线网型变量一旦被连续赋值语句赋值之后,赋值语句右端赋值表达式的值将持续对被赋值变量产生连续驱动。只要右端表达式任一个操作数的值发生变化,就会立即触发对被赋值变量的更新操作。这种更新不像过程赋值那样只发生在时钟沿时刻,它除了发生在时钟沿时刻,还发生在其它任一时刻。

 

 


点赞

发表评论 评论 (4 个评论)

回复 mafan88 2011-12-27 15:54
楼主写的很好, 但是不喜欢从赋值的角度来看问题。 因为addr也是用clk产生的,那么从实际的电路考虑,addr的值相对于clk的边沿是延后一点的,那么这个时候再用clk上升沿的时刻去比较addr,这个时候比较的是前边的值。 clk ------|-------|-------|---------| addr 1| 2| 3| 4| 如上图实际上是如此的关系
回复 wjw576657631 2012-1-1 22:41
有道理,多谢兄台提醒啊
回复 shiyinjita 2012-1-13 08:19
如果是仿真的话,可以加入 parameter delay= 1 ; #delay 后赋值, 这样在功能验证的时候,就会有好处。 当然时序验证这个是忽略掉的

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 1

    粉丝
  • 0

    好友
  • 1

    获赞
  • 33

    评论
  • 1523

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-5-18 05:30 , Processed in 0.019101 second(s), 16 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部