2017-10-29 257 views
1

我知道,對於2個總是具有相同觸發器的塊,它們的評估順序是完全不可預知的。在Verilog中總是在塊中觸發塊的評估順序?

然而,假設我有:

always @(a) begin : blockX 
c = 0; 
d = a + 2; 
if(c != 1) e = 2; 
end 

always @(a) begin : blockY 
e = 3; 
end 

always @(d) begin : blockZ 
c = 1; 
e = 1; 
end 

假設塊X評估第一。在blockX中更改d是否會立即跳轉到blockZ?如果不是,blockZ是否就blockY進行了評估?

我的程序員的本能認爲堆棧中的事件序列,其中評估blockX就像是一個函數調用blockZ,我立即跳到代碼中,然後完成評估blockX。但是,因爲我們稱之爲活動事件隊列,所以這是一個隊列,這表明blockZ被排隊在活動事件隊列的後面,我100%保證它會被最後評估(除非有其他的總是觸發塊)。

還有中間可能性,它既不是第一個也不是最後一個,但也是以隨機和不可預測的順序進行評估。

那麼在這個例子中,根據編譯器在運行時的感覺如何,e,所有可能的最終值是1,2或3嗎?

此外,雖然我明白,當然,這代表了糟糕的風格,我在哪裏可以找到這種behvaior規範?

+1

是否總是@(a):blockX begin'有效的語法?我認爲它必須是'始終@(a)begin:blockX'(在verilog 2001中,無論如何) – Eric

+0

正如你所說的,這是一種糟糕的風格 - 第一個塊應該在其敏感列表中包含「c」 '*' - 然後問題就變得沒有意義了。 – Eric

+0

我認爲這個問題更多的是充分理解系統行爲的精神,而不是製作實際的代碼。 就像介紹性的編程類一樣,要求學生用指向指針的(更有用的)指針跟蹤代碼並評估某些表達式的結果。這有點多用了,但這個練習足夠迂迴,清楚地表明意圖是嚴格教學的。 另外,@Eric,感謝語法catch! – Dragonsheep

回答

1

總是塊不是函數調用。看到我剛剛給了一個類似的問題recent answer。這些塊是併發進程。 LRM只保證begin/end區塊內的報表的排序。在同時執行begin/end塊之間沒有定義的順序(請參閱第4.7節「1800-2012 LRM中的非確定性」)因此,模擬器可以以任何方式自由地交織語句,只要它能夠在單個塊內完成順序即可。

所以你是正確的,e可能有最終值1,2或3取決於模擬器如何決定實現和優化你的代碼。