始终在零时间阻止执行

问题描述:

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

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** 

模拟通过$完成(1)完整的9 NS + 0

任何人都可以解释为什么第二总代码中的块在时间零之后根本不执行?

有没有一种方法可以实现始终阻止,以便它在零时间执行而不使用初始块? (类似于SV中的always_comb?)

您已经标记了这个system-verilog,所以我会给出与此相关的答案。 如果您当前的使用情况为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 

很多人没有意识到,@是一个语句修饰词,不能单独建设。它表示推迟接下来的声明,直到有事件发生。 @(A or B)表示等待,直到AB的值发生变化(不要与A|B的结果变化混淆)。 @*表示查看下面的语句,并构建一个隐式的敏感信号列表以等待更改。

在您的第一个always中,后面的语句是begin/end块,因此将reg_A添加到灵敏度列表中。在您的第二个always中,随后的声明是null声明,因此对任何更改均不敏感。

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

更好的是,使用alway_comb这是专门设计来解决这个问题。

+0

感谢戴夫的解释。 Verilog中是否有对always_comb的替代方案? – sanforyou

+0

它取决于导致块不在时间0执行的情况。一个建议可能是确保敏感性列表中的所有内容都被声明为导线。 –