systemverilog中@和wait的區別


在SystemVerilog中,用來觸發事件時,使用->;用來等待事件使用@或者wait。那么@和wait有什么區別呢?

在Verilog中當一個線程在一個事件上發生阻塞的同時,正好另一個線程觸發了這個事件,則競爭就出現了。如果觸發線程先於阻塞線程,則觸發無效(觸發是一個零寬度的脈沖);
例如:verilog中使用@等待某個event產生競爭

`timescale 1ns/10fs
module event_test();
  event a;    	//使用關鍵字event來聲明一個事件a
  initial begin
    #50ns;
    ->a;
  end
  initial begin
    #50ns;
    @a; 		//第一個進程在50ns后觸發了事件a,第二個進程在50ns的時候等待a,有可能等的到,有可能等不到,產生競爭
  end
endmodule

一、解決方法:
Systemverilog 引入了triggered()函數,用於檢測某個事件是否已被觸發過,包括正在觸發。線程可以等待這個結果,而不用在@操作符上阻塞。

1.2、使用wait(event_a.triggered)等待event
module event_test();
  event a;    //使用關鍵字event來聲明一個事件a
  initial begin
    #50;
    ->a;
    $display("Event a is being triggered!");
  end
  
  initial begin
    #20;
    wait(a.triggered); 			**//使用wait來等待事件a,這種方式是一定可以等到a的**
    $display("#20 a.triggered!");
  end
  
  initial begin
    #50;
    wait(a.triggered); 			**//使用wait來等待事件a,這種方式是一定可以等到a的,這是和使用@來等待的區別**
    $display("#50 a.triggered!");
  end
  
  initial begin
    #60;
    wait(a.triggered); 			**//使用wait來等待事件a,a會被trigger一次,並且並且發生在wait之前,永遠等不到**
    $display("#60 a.triggered!");  //不會被打印
  end
endmodule

從上面可以看出,使用wait(event.triggered)要優於使用@event的方法,但wait(event.triggered)的方法在任何時候都會優於@event嗎?
看下面這個例子:

forever begin
  wait(handshake.triggered); //注意不要寫成wait(handshake.triggered()),會有編譯錯誤,因為triggered不是一個function
  $display("get nexr event ...");
  process_in_zero_time();
end

如果是在循環中使用wait(event.triggered),並且在下次等待之前沒有延時,那么該事件一旦被觸發就會反復執行,對上面的例子,如果某一時刻觸發了handshake事件,則該Thread就會一直display(導致仿真Hang死),這種結果不是我們想要的,解法有兩種:
1、wait(handshake.triggered)之后增加讓時間推進的操作,如@(clk)。

forever begin
  wait(handshake.triggered);
  $display("get nexr event ...");
  process_in_zero_time();
  @clk;
end

2、將wait(handshake.triggered)換成@handshake,可以避免零延時循環。

forever begin
  @handshake;
  $display("get nexr event ...");
  process_in_zero_time();
end


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM