SystemVerilog Event

event是一个静态对象句柄,用于在两个或多个同时活动的进程之间进行同步。 一个进程将触发事件,另一个进程将等待事件。

【1】可以赋值或与其他事件变量进行比较
【2】可以赋值为空
【3】当赋值给另一个事件时,两个变量都指向同一个同步对象
【4】可以传递给队列,函数和任务

 event  over;                     //将创建一个新事件(event)over
 event  over_again = over;        //over_again成为over的别名
 event  empty = null;             // 没有同步对象的事件变量

如何触发并等待事件?

【1】可以使用->或->>运算符触发命名事件
【2】进程可以使用@运算符或.triggered等待事件

Example

module tb;
 
  //创建一个事件变量,进程可用于触发和等待
  event event_a;
 
  // 线程1:使用“->”运算符触发事件
  initial begin
    #20 ->event_a;
    $display ("[%0t] Thread1: triggered event_a", $time);
  end
 
  // 线程2:使用“ @”运算符等待事件
  initial begin
    $display ("[%0t] Thread2: waiting for trigger ", $time);
    @(event_a);
    $display ("[%0t] Thread2: received event_a trigger ", $time);
  end
 
  // 线程3:使用“ .triggered”等待事件
  initial begin
    $display ("[%0t] Thread3: waiting for trigger ", $time);
    wait(event_a.triggered);
    $display ("[%0t] Thread3: received event_a trigger", $time);
  end
endmodule  
 
Simulation Log
ncsim> run
[0] Thread2: waiting for trigger 
[0] Thread3: waiting for trigger 
[20] Thread1: triggered event_a
[20] Thread2: received event_a trigger 
[20] Thread3: received event_a trigger
ncsim: *W,RNQUIE: Simulation is complete.

@和.triggered有什么区别?

事件的触发状态会在整个时间步中持续存在,直到仿真继续进行。 因此,如果等待事件和事件触发同时发生,则将存在竞争条件,并且触发的属性有助于避免这种情况。
无论等待和触发的顺序如何,等待触发状态的进程始终会解锁。

module tb;
 
  // 创建一个事件变量,进程可用于触发和等待
  event event_a;
 
  // 线程1:使用“->”运算符在20ns时触发事件
  initial begin
    #20 ->event_a;
    $display ("[%0t] Thread1: triggered event_a", $time);
  end
 
  // 线程2:在20ns开始使用“ @”运算符等待事件
  initial begin
    $display ("[%0t] Thread2: waiting for trigger ", $time);
    #20 @(event_a);
    $display ("[%0t] Thread2: received event_a trigger ", $time);
  end
 
  // 线程3:在20ns开始使用“ .triggered”等待事件
  initial begin
    $display ("[%0t] Thread3: waiting for trigger ", $time);
    #20 wait(event_a.triggered);
    $display ("[%0t] Thread3: received event_a trigger", $time);
  end
endmodule

wait_order

等待事件以给定的顺序触发,如果任何事件执行不正确,则发出错误。

module tb;
  //声明三个可以分别触发的事件
  event a, b, c;
 
  // 此块逐个触发每个事件
  initial begin
    #10 -> a;
    #10 -> b;
    #10 -> c;
  end
 
  // 该块等待,直到以给定顺序触发每个事件
  initial begin
 
    wait_order (a,b,c) 
      $display ("Events were executed in the correct order");
    else 
        $display ("Events were NOT executed in the correct order !");  
  end
endmodule
 
Simulation Log
Compiler version J-2014.12-SP1-1; Runtime version J-2014.12-SP1-1;
Events were executed in the correct order
           V C S   S i m u l a t i o n   R e p o r t 

Merging Events合并活动

当一个事件变量赋值给另一个事件变量时,所有等待第一个事件触发的进程都将等待,直到触发第二个变量。

module tb;
 
  // 创建事件变量
  event event_a, event_b;
 
  initial begin
    fork
      // 线程1:等待event_a被触发
      begin
        wait(event_a.triggered);
        $display ("[%0t] Thread1: Wait for event_a is over", $time);
      end
      // 线程2:等待event_b被触发   
      begin
        wait(event_b.triggered);
        $display ("[%0t] Thread2: Wait for event_b is over", $time);
      end
 
      // 线程3:在20ns时触发event_a
      #20 ->event_a;
 
      // 线程4:在30ns时触发event_b
      #30 ->event_b;
 
      // 线程5:在10ns时将event_b分配给event_a
      begin
        // Comment code below and try again to see Thread2 finish later
        #10 event_b = event_a;
      end
    join
  end
endmodule
 
Simulation Log
ncsim> run
[20] Thread1: Wait for event_a is over
[20] Thread2: Wait for event_b is over
ncsim: *W,RNQUIE: Simulation is complete.

参考文献:
【1】https://www.chipverify.com/systemverilog/systemverilog-event

发布了91 篇原创文章 · 获赞 7 · 访问量 5219

猜你喜欢

转载自blog.csdn.net/qq_43042339/article/details/104466025