Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Verilog:始终@*块未被触发_Verilog_System Verilog - Fatal编程技术网

Verilog:始终@*块未被触发

Verilog:始终@*块未被触发,verilog,system-verilog,Verilog,System Verilog,在下面显示的测试台代码中,我观察到时钟信号clk没有按预期切换。 时钟在时间5从低变高,但此后不会切换 module tb(); reg clk; initial begin clk = 'b0; #100 $finish; end always@* #5 clk = ~clk; endmodule 但是,如果我从始终@*语句中删除@*,时钟将按预期每5ns切换一次。我的问题是为什么进程块在第一次更改后不总是被触发 注意:我已经在NCSIM和VCS中测试了代

在下面显示的测试台代码中,我观察到时钟信号
clk
没有按预期切换。 时钟在时间5从低变高,但此后不会切换

module tb();
  reg clk;
  initial begin
     clk = 'b0;
     #100 $finish;
  end
  always@* #5 clk = ~clk;
endmodule
但是,如果我从
始终@*
语句中删除
@*
,时钟将按预期每5ns切换一次。我的问题是为什么进程块
在第一次更改后不总是被触发


注意:我已经在NCSIM和VCS中测试了代码,我不认为这是模拟器的问题。

时钟生成器通常通过以下两种方式之一实现:

  • 如您已尝试过的,始终在没有敏感度列表的情况下使用

    always #5 clk = ~clk;
    
  • 无灵敏度列表的
    始终
    块将永远循环,如果没有延迟,将导致模拟挂起。尽管后者使它成为时钟发生器的完美之选

  • 初始
    块中使用永久循环:

    initial begin
        forever
            #5 clk = ~clk;
    end
    

  • 上述代码的工作方式与前面的
    始终

    相同。接受的答案是错误的-
    始终
    最初是由
    初始
    块中的0赋值触发的,因此您有一个完全有效的问题,这就是为什么
    always
    块在第一次运行后不会自动触发(显然它确实运行了,因为
    clk
    设置为1)

    运行下面的代码-如果您将阻塞分配更改为非阻塞分配,或者如果您使用内部分配延迟而不是延迟控制(
    clk=#5~clk
    ),您将看到它按预期工作。所以,这是一个日程安排问题。您可能直觉地认为您的流程只会触发一次,因为最终的阻塞分配和流程评估实际上发生在同一个增量中,因此阻塞分配可能会丢失。然而,我在LRM中看不到具体的理由。延迟控制将变成一个未来的非活动事件,调度程序最终执行它,创建一个更新事件,更新
    clk
    (这种情况只发生一次)。然后,这应该为流程创建一个评估事件,因为它对
    clk
    敏感,但它没有这样做。日程安排部分(非常)杂乱无章,并没有真正涵盖这一点。如果你问他们,导师可能会告诉你他们对正在发生的事情的看法。VHDL通过使所有信号分配无阻塞来避免此问题

       module tb();
          reg clk1, clk2, clk3;
          initial begin
             $monitor($time,, "clk1 = %b; clk2 = %b, clk3 = %b", clk1, clk2, clk3);
             clk1 = 1'b0;
             clk2 = 1'b0;
             clk3 = 1'b0;
             #100 $finish;
          end
    
          always @* 
             #5 clk1 = ~clk1;
    
          always @*
             #5 clk2 <= ~clk2;
    
          always @(clk3) 
             clk3 <= #5 ~clk3;
       endmodule
    
    moduletb();
    注册号clk1、clk2、clk3;
    初始开始
    $monitor($time,,“clk1=%b;clk2=%b,clk3=%b”,clk1,clk2,clk3);
    clk1=1'b0;
    clk2=1'b0;
    clk3=1'b0;
    #100美元完成;
    结束
    始终@*
    #5 clk1=~clk1;
    总是@*
    
    #5 clk2问题始终是@(*)对写入其中的信号不敏感。所以在您的例子中,always块的隐式敏感度没有“clk”。相反,它对任何信号都不敏感

    有一件事:永远不要使用非阻塞分配来生成时钟。它是许多竞争问题的根源。如果我在灵敏度列表中明确添加clk信号,它是否有效?