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

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

日志

Verilog 自触发always块浅析

已有 4236 次阅读| 2010-9-21 10:23

下边是夏宇文教材的一段文字

 

一般而言,Verilogalways块不能触发自己,见下面的例子:

 [3]  使用阻塞赋值的非自触发振荡器

 module osc1 (clk);

      output clk;

      reg    clk;

 

        initial #10 clk = 0;

        always @(clk) #10 clk = ~clk;

 

 endmodule

 

上例描述的时钟振荡器使用了阻塞赋值。阻塞赋值时,计算RHS表达式并更新LHS的值,此时不允许其他语句的干扰。阻塞赋值必须在@(clk)边沿触发到来时刻之前完成。当触发事件到来时,阻塞赋值已经完成了,因此没有来自always块内部的触发事件来触发@(clk),是一个非自触发振荡器。

 

而例4中的振荡器使用的是非阻塞赋值,它是一个自触发振荡器。

[4] 采用非阻塞赋值的自触发振荡器  

module osc2 (clk);

      output clk;

      reg    clk;

 

      initial #10 clk = 0;

      always @(clk) #10 clk <= ~clk;

 

endmodule

@(clk)的第一次触发之后,非阻塞赋值的RHS表达式便计算出来,把值赋给LHS的事件被安排在更新事件队列中。在非阻塞赋值更新事件队列被激活之前,又遇到了@(clk)触发语句,并且always块再次对clk的值变化产生反应。当非阻塞LHS的值在同一时刻被更新时, @(clk)再一次触发。该例是自触发式,在编写仿真测试模块时不推荐使用这种写法的时钟信号源。

 

上边这段文字对于初学者来说很不容易明白,很容易进入死胡同,我也一样,想破脑袋最终才略微明白123。下边咱们就分析一下这123,也不知道对不对,希望高手指点一下。

 如果直接拿上边代码仿真会分别得到波形(modelsim

阻塞赋值

非阻塞赋值

仿真虽然不一样,但用Quartus2综合的结果确是一样的,都是振荡器。

综合结果如图:

    为什么会有这样的结果呢?网上的答案基本就两个,一个是上边那个,另个一个是一篇外文翻译,但是基本一样,看了好久也没看懂。突然有一个时刻,有点明白了,就跟大家探讨一下。

   为弄懂这段代码,本人感觉有必要搞清楚层积事件队列,层积事件列是层次模型:层积事件列的执行顺序是按优先级排列的。本人感觉这篇文章讲的不错:http://www.21eic.com/eda/method5322.html,理解它有助于我们理解阻塞和非阻塞赋值的功能。

   最初我不明白的是虽然阻塞和非阻塞赋值在这里调度事件和执行的不一样,但跟always触发块的时间关系又是什么呢?我记得在网上哪个博客上看到这样一句话:阻塞赋值执行完,always块才结束;非阻塞赋值在always块执行完后才执行(估右值在其前,刷新左值在其后)。个人感觉这句话对于此代码仿真的理解非常有帮助。

  下边是我用我的理解来画的事件执行图

阻塞赋值:

在阻塞赋值流程中,个人感觉主要是在always块结束,才能让always块再次对敏感信号敏感。

非阻塞赋值:                                                        

同理,非阻塞赋值的刷新RHS是在上次always块结束后才被执行的,所以可以再次引起always块敏感事件。

下边为说明这点我们改变一下非阻塞赋值例子:

     代码

module oscl(clk);

  output clk;

  reg clk;

  reg a, b, c;

  initial # 10 clk = 0;

  initial # 5   b = 0;

  initial # 13   b = 1;

  initial # 23   b = 0;

  always@(clk) begin

       #10 clk <= ~clk;

       #1  a <= b;

  end 

endmodule

它在ModelSim中的仿真图形是

它的事件分析跟上边非阻塞赋值基本是一样。

     在理解中,要注意这些分析,基于电路设计本身的少,大部分是从仿真器的内部处理角度看的。由于电路是并行的,但仿真器大部分是顺序执行来处理并行事件,所以采用层积事件的特性,这一特性跟仿真器本身的设计有关,由于仿真器的存在是介于我们设计电路本意和综合出实际电路的之间,这样有时候设计本意、仿真、综合这三者之间就会存在差异,如上边,仿真不同,但得到的综合结果是一样。

仿真事件的分析最好是看一下Verilog协议第五讲,没有多少文字,但讲的很好!如下摘录一段:

5.4 The Verilog simulation reference model

In all the examples that follow, T refers to the current simulation time, and all events are held in the event queue, ordered by simulation time.

while (there are events) {

if (no active events) {

if (there are inactive events) {

activate all inactive events;

} else if (there are non blocking assign update events) {

activate all non blocking assign update events;

} else if (there are monitor events) {

activate all monitor events;

} else {

advance T to the next event time;

activate all inactive events for time T;

}

}

E = any active event;

if (E is an update event) {

update the modified object;

add evaluation events for sensitive processes to event queue;

} else { /* shall be an evaluation event */

evaluate the process;

add update events to the event queue;

}

}


点赞

发表评论 评论 (3 个评论)

回复 冰语晨星 2016-9-1 20:05
:loveliness: :loveliness: 大神,您好,您的仿真图在30ns 时CLK并没有跳变,是不是不对呢???
回复 冰语晨星 2016-9-1 20:44
:loveliness: :loveliness: 大神,您好,您的仿真图在30ns 时CLK并没有跳变,是不是不对呢???

facelist

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

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

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 1

    粉丝
  • 0

    好友
  • 0

    获赞
  • 7

    评论
  • 387

    访问数
关闭

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

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

GMT+8, 2024-5-7 04:35 , Processed in 0.015325 second(s), 7 queries , Gzip On, Redis On.

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