始终在零时刻阻止执行

时间:2017-08-31 21:38:44

标签: verilog system-verilog

我想在零时刻执行始终阻止。 对于例如下面的代码不会在零时执行。

always @* begin
//functional code
end

我在最后移动了敏感度列表,以便代码将在零时刻执行,

always begin
//funcitonal code
@*;
end

此代码在零时刻执行,但在零时间之后根本不执行,即使块内使用的输入发生了变化。例如,请参阅下面的代码及其输出:

module AlwaysTimeZeroTest_v();

reg reg_A;

initial begin
  $display ("I'm in Initial begin block       \tTime=%f, reg_A=%b\n",$stime,reg_A);
  #1
  reg_A=1'bZ;

  #1
  reg_A=1'b1;

  #1
  reg_A=1'b0;

  #1
  reg_A=1'bZ;

  #5 $finish;
end

always @* begin
    $display ("I'm in Non-time Zero always block\tTime=%f, reg_A=%b\n",$stime,reg_A);
end

always begin
   $display ("I'm in time Zero always block     \tTime=%f, reg_A=%b\n",$stime,reg_A);
    @*;
end

endmodule

输出:

**I'm in Initial begin block              Time=0.000000, reg_A=x

I'm in time Zero always block           Time=0.000000, reg_A=x

I'm in Non-time Zero always block       Time=1.000000, reg_A=z

I'm in Non-time Zero always block       Time=2.000000, reg_A=1

I'm in Non-time Zero always block       Time=3.000000, reg_A=0

I'm in Non-time Zero always block       Time=4.000000, reg_A=z**

在时间9 NS + 0

时通过$ finish(1)完成模拟

任何人都可以解释为什么在时间零之后,代码中的第二个始终阻塞根本不执行吗?

有没有办法可以实现总是阻塞,以便它在零时执行而不使用初始块? (类似于SV中的always_comb?)

2 个答案:

答案 0 :(得分:5)

许多人没有意识到@是一个语句修饰符,而不是自己构造。它说要延迟发生事件之前的声明。 @(A or B)表示等到AB的值发生变化(不要与A|B的结果发生变化混淆)。 @*表示查看后面的语句,并构建一个隐含的信号敏感列表以等待更改。

在您的第一个always中,后面的语句是begin/end块,因此reg_A会被添加到敏感列表中。在您的第二个always中,后面的语句是 null 语句,因此对任何更改都没有敏感性。

确保always @*在零时执行的唯一方法是对块中的变量进行一些引用,该变量在时间0处有变化。然后对该变量使用非阻塞赋值以避免任何变量时间0比赛条件。

更好的是,使用专为解决此问题而设计的alway_comb

答案 1 :(得分:0)

你标记了这个系统 - verilog所以我会给出答案。 如果您当前的使用率是always @*并且您没有从多个always块驱动输出,请使用always_comb。每LRM,always_comb将在0时执行。

module AlwaysTimeZeroTest_v();

reg reg_A;

initial begin
  $display ("I'm in Initial begin block       \tTime=%f, reg_A=%b\n",$stime,reg_A);
  #1
  reg_A=1'bZ;
  #1
  reg_A=1'b1;
  #1
  reg_A=1'b0;
  #1
  reg_A=1'bZ;
  #5 $finish;
end

always_comb begin
    $display ("I'm in Non-time Zero always block\tTime=%f, reg_A=%b\n",$stime,reg_A);
end

always_comb begin
   $display ("I'm in time Zero always block     \tTime=%f, reg_A=%b\n",$stime,reg_A);
    // @*;
end

endmodule