【原創】systemverilog 線程中的fork使用


systemverilog 內容龐雜,需要不停的花時間,不停的思考與練習。保持謙虛不急不躁的心態,穩步學習。路漫漫其修遠兮,吾將上下而求索。

實際硬件中,時序邏輯通過時鍾沿激活,組合邏輯的輸出則隨着輸入的變化而變化。在測試平台的環境里,大多數語句塊被模擬成事務處理器,並運行在各自的線程里。
Systemverilog 每個線程總是會跟相鄰的線程通信。這里涉及到測試平台組成問題。環境類需要知道發生器什么時候完成任務,以便及時終止測試平台中還在運行的線程。這個過程需要用線程間通信IPC來完成。
常見的線程通信有:event,wait,Systemverilog mailbox,Systemverilog semaphone。
注意:在systemverilog中 線程thread,進程process是一個東西

一:線程的使用
systemverilog在verilog基礎上擴展兩種線程:

fork
...
join

fork
...
join_none

fork
...
join_any

測試平台通過已有的結構來實現線程間的通信,同步以及對線程 的控制。
下面列舉systemverilog for verification的代碼進一步說明用法加深理解
fork_join:

VCS運行結果:

記得我第一次做這個example時,人是暈的,下面來重新理一理:
begin....end是順序執行,從上至下執行,如果帶延時肯定按照延時來
fork...join是並行執行,只有當fork塊的代碼全部執行完畢,才會往下走。
fork...begin...end...join 帶延時這個問題,即便join后面的內容發生時間再前,同樣也不會執行。

-----------------------------------------分割線----------------------------------------------

fork...join_none:產生線程
fork...join_none在調度其塊內語句時,父線程繼續執行。代碼與fork...join一致

注意:fork...join_none后面那一條語句執行早於塊內任何一條語句。

-----------------------------------------分割線----------------------------------------------

fork...join_any:實現線程同步
fork...join_any 第一個語句完成后,父線程才繼續執行,其他停頓的線程也繼續。代碼與fork...join一致

fork...join_any的代碼中display("after join_any")完成於並發塊內第一個語句之后。

-----------------------------------------分割線----------------------------------------------

二:動態線程:使用fork_join_none 可以開啟一個線程,比如隨機事務發生器的代碼。使用fork...join_none可以使代碼不發生阻塞
綠皮書183示例代碼:

class Gen_drive
  task run(int n);
  Packet  p;
  fork
      repeat(n)begin
      p = new();
      assert(p.randomzie());
      transmit(p);
      end
  join_none;
  endtask
  task trnansmit(input Packet p);
  ...
  endtask
endclass
Gen_drive gen;
initial beign
    gen = new();
    gen.run(10);
    ...
end

以上代碼並不是在new()函數中啟動的,構造函數只用來對數值進行初始化,並不啟動任何線程,把構造函數同真正進行事務處理的代碼分開,允許在開始執行事務處理代碼之前修改任何變量,這樣,就可以引入錯誤檢測,修改缺省值或變更代碼的行為。

任務run通過fork..join_none塊啟動了一個線程,用於具體事務處理,該線程不是在父類中啟動,而是run之后產生的。

在動態線程中,任務被調用,就可以產生一個線程總線以獲取匹配的事務地址。在並發線程中務必使用自動變量來保存數值。

錯誤示例:

program mo_auto;
  initial begin
      for(int j = 0;j < 3;j ++)
          fork
              $write(j);
          join_none
      #0 $display("\n");
  end
endprogram


免責聲明!

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



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