同步到时钟的posedge

时间:2016-08-07 06:40:58

标签: 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);
    $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

如果没有额外的命名事件,还有其他方法吗?

1 个答案:

答案 0 :(得分:2)

这是##0构造的作用(参见 14.11循环延迟:1800-2012 LRM的## 部分)。您必须定义默认时钟块,这意味着您的任务必须在moduleinterface

内定义
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

我的建议是不要做任何事情并找出一种方法来保持some_task的同步激活。