System verilog 同步到时钟边缘

System verilog 同步到时钟边缘,system-verilog,System Verilog,除了使用同时触发的命名事件外,是否有任何方法可以询问模拟是否在@(posedge clk)事件中 通过以下代码,我可以确保我只在时钟的边缘做事情: module tb; bit clk; always #2 clk = ~clk; event pos_clk; always @(posedge clk) -> pos_clk; initial begin // stuff happens @(posedge clk); $dis

除了使用同时触发的命名事件外,是否有任何方法可以询问模拟是否在
@(posedge clk)
事件中

通过以下代码,我可以确保我只在时钟的边缘做事情:

module tb;

  bit clk;
  always #2 clk = ~clk;

  event pos_clk;


  always @(posedge clk)
    -> pos_clk;

  initial begin
    // stuff happens
    @(posedge clk);
    $display("[%0d] @(posedge clk)", $time());

    // control is passed asynchronously to some task
    // - since it's already at a posedge, it doesn't need to wait
    some_task();

    // other stuff happens
    #1;
    $display("[%0d] #1", $time());

    // control is passed asynchronously to some task
    // - since it's not at a posedge, it needs to catch the next one
    some_task();

    $finish();
  end

  task some_task();
    wait (pos_clk.triggered);
    $display("[%0d] wait (pos_clk.triggered)", $time());
    // do relevant stuff
  endtask
endmodule
是否有其他方法可以在没有额外命名事件的情况下执行此操作?

这就是
##0
构造所做的(请参见第14.11节循环延迟:##)。您必须定义默认时钟块,这意味着您的任务必须在
模块
接口

module tb;

  bit clk;
  always #2 clk = ~clk;

  default clocking cb @(posedge clk)
  endclocking

  initial begin
    // stuff happens
    @(cb) // when using clocking blocks, only use the clocking event
    $display("[%0d] @(posedge clk)", $time());

    // control is passed asynchronously to some task
    // - since it's already at a posedge, it doesn't need to wait
    some_task();

    // other stuff happens
    #1;
    $display("[%0d] #1", $time());

    // control is passed asynchronously to some task
    // - since it's not at a posedge, it needs to catch the next one
    some_task();

    $finish();
  end

  task some_task();
    ##0;
    $display("[%0d] wait (pos_clk.triggered)", $time());
    // do relevant stuff
  endtask
endmodule
我的建议是不要这样做,并找出一种方法来保持
某些任务的激活同步。

这就是
##0
构造所做的(请参见第14.11节循环延迟:#。您必须定义默认时钟块,这意味着您的任务必须在
模块
接口

module tb;

  bit clk;
  always #2 clk = ~clk;

  default clocking cb @(posedge clk)
  endclocking

  initial begin
    // stuff happens
    @(cb) // when using clocking blocks, only use the clocking event
    $display("[%0d] @(posedge clk)", $time());

    // control is passed asynchronously to some task
    // - since it's already at a posedge, it doesn't need to wait
    some_task();

    // other stuff happens
    #1;
    $display("[%0d] #1", $time());

    // control is passed asynchronously to some task
    // - since it's not at a posedge, it needs to catch the next one
    some_task();

    $finish();
  end

  task some_task();
    ##0;
    $display("[%0d] wait (pos_clk.triggered)", $time());
    // do relevant stuff
  endtask
endmodule

我的建议是不要这样做,并找出一种方法使
某些任务的激活保持同步。

我想在类内进行同步,因此默认的时钟将不起作用。我基本上想要的是让一个司机只在一个posedge上得到一件物品。我注意到运行在多个时钟上工作的虚拟序列时出现问题。我想唯一的选择就是这样做:等待时钟,检查物品是否有,如果没有,继续,如果有,开始开车。这有点违背了事务驱动的整个TLM理念(即使用get_next_item()),但同时,驱动程序生活在两个世界(RTL和TLM)中,必须协调这两个方面。此外,即使我同步触发
某些任务()
,我可能想写一个程序断言来检查这个前提条件(执行确实是从posedge开始的)。我仍然认为在同一个过程中混合同步和异步行为是一种不好的做法。但我认为除了最初发布的内容之外,您没有其他选择。我希望在类内执行同步,因此默认时钟将不起作用。我基本上想要的是让一个司机只在一个posedge上得到一件物品。我注意到运行在多个时钟上工作的虚拟序列时出现问题。我想唯一的选择就是这样做:等待时钟,检查物品是否有,如果没有,继续,如果有,开始开车。这有点违背了事务驱动的整个TLM理念(即使用get_next_item()),但同时,驱动程序生活在两个世界(RTL和TLM)中,必须协调这两个方面。此外,即使我同步触发
某些任务()
,我可能想写一个程序断言来检查这个前提条件(执行确实是从posedge开始的)。我仍然认为在同一个过程中混合同步和异步行为是一种不好的做法。但我认为除了你最初发布的内容之外,你没有其他选择。