具有延迟的非阻塞语句

时间:2019-09-01 07:37:14

标签: verilog

always@(a)
begin
#1 t<=a;
#1 c<=t;
end

我正在使用下面给出的测试平台来分析上述Verilog代码

   a=0;
#5 a=1;
#5 a=0;
#5 a=1;
#5;

这是我的分析: 从上面的测试台上,我可以看出“ a”是一个总长度为20ns的时钟信号,OFF和ON时间均为5ns。在第0 ns时,“ a”从X更改为0。因此始终触发块。块中的第一个语句具有1ns的内部延迟,它等待1ns。 1ns编译器知道它是非阻塞语句后,就不会进行赋值评估。因此,“ a”值将被存储为临时值,并并行执行第二条语句。由于第二条语句也存在内部延迟,因此它等待1ns 。然后进行评估。由于两个评估均已完成,因此现在将进行分配。

    time   a   t   c
    0ns    0   x   x
    1ns    0   x   x
    2ns    0   x   x
    3ns    0   0   x
    4ns    0   0   x

此分析正确吗?

2 个答案:

答案 0 :(得分:0)

不,不是这样,非阻塞分配的工作方式与您描述的不同。

您正确的是,非阻塞语句的实际赋值是“延迟”执行的。但是什么时候“以后”呢?

当不再有未完成的阻塞事件时,将处理

“非阻塞”事件。但是在处理延迟之前。因此,一旦模拟器发现必须处理您的#1,它就会首先处理所有非阻塞分配,然后才开始处理延迟。
这意味着甚至在#1延迟t开始之前,它就已经收到了a的值。

Verilog标准中有一整章,描述了各种“动作”应以什么顺序执行。

答案 1 :(得分:0)

always块重新编写为单独的行并有意识地移动begin/end块的位置可能会有所帮助。这不会对行为产生影响,因为所有操作都是按顺序执行的。

always // instantiate a procedural block
      begin
      @a  // blocking event delay waits for a change on -a-
      #1  // blocking time delay waits for 1 time unit
      t <= a; // non-blocking assignment 
              // uses the current value of -a- one time unit after it changed
              // and schedules an assignment to t
      #1 // blocking time delay waits for 1 time unit
         // since there is no more active things to do -a- gets updated
      c <= a; // uses the updated value of t and schedules an assignment to c
      end // now 2 time units after -a- was first changed
          // goes back to the top of the block and waits for another change 
          // on -a-.

请注意,执行块时在 a 上进行的任何更改都将丢失。这是一个不错的presentation on non-blocking assignments

相关问题