2017-08-10 106 views
0

我有一段代碼表現出以下行爲。我期望看到10個並行線程,例如第一個線程:j = 0和第五個線程:j = 4,全部在模擬時間0納秒運行。此外,j = i和$ display並行運行,因此在$ display執行時,j仍然是x。爲什麼輸出始終在fork join_none中輸出j = 5?

module tb; 

integer i,j; 

initial 
for(i=0;i<5;i++) 
fork 
j = i; 
$display("Value of j is %d at time=%d \n", j, $time); 
join_none 

endmodule 

我收到以下輸出。有人可以請解釋。我在使用VCS的EDAPlayground上嘗試過。

Value of j is   5 at time=     0 

Value of j is   5 at time=     0 

Value of j is   5 at time=     0 

Value of j is   5 at time=     0 

Value of j is   5 at time=     0 

回答

1

你假設你的代碼產生了10個並行線程是正確的。但是,直到父線程阻塞或終止之後,fork/join_none纔會啓動任何這些線程。在你的情況下,在initial塊進程終止之後。到那時,在退出for循環後,i的值爲5。

另外,10個線程沒有定義的執行順序 - 它們都在比賽中。 $顯示或分配可以以任何順序進行,所以有可能j顯示x。您可能會從不同的工具獲得不同的結果

要讓您的代碼顯示0,1,...,4,您不能在j中使用靜態變量。您需要爲for循環的每次迭代使用automatic創建一個j的副本,該循環使用每個循環的當前值i進行初始化。 @埃曼已經表明了這樣做的一種方式。

1

您可能需要在變量開始執行之前向變量添加一個「自動」,自動存儲類變量映射到堆棧上。當函數被調用時,函數中聲明的所有本地(非靜態)變量都映射到堆棧中的各個位置。由於這些變量只存在於堆棧上,因此只要函數執行完成並且堆棧相應縮小,它們就不再存在。意義範圍保持活躍,直到達到所有子進程的結束。

module tb; 
     integer i,j; 
     initial 
     for(i=0;i<5;i++) 
      fork 
      automatic int j=i; 
      begin 
       $display("Value of j is %d at time=%d \n", j, $time); 
      end 
      join_none 
    endmodule 
+0

感謝您的解釋。但我的問題在於,不是如何避免這種輸出,而是爲什麼在我的代碼中看到這種行爲,爲什麼j = x不打印5次? –

+0

默認情況下,模塊或程序塊變量是靜態的,這意味着它的內存在仿真結束之前不會被解除分配。在你的情況下,因爲for循環值更新爲5首先j更新爲5,因爲我保持價值5,並從來沒有解除分配導致5,但在這種情況下自動答案中提到的只有內存在所有過程完成後都會被取消分配。 – Emman