[英]About verilog flip flop delay
我想用兩個單位觸發器來緩沖一個“完成”的單位信號。 在我的設計中,完成的信號將僅上升一個時鍾周期。 所以我寫了下面的代碼。
//first level buffer done signal for one cycle to get ciphertext_reg ready
always @(posedge clk or posedge rst) begin
if(rst)
done_buf_1 = 1'b0;
else
done_buf_1 = done;
end
//second level buffer
always @(posedge clk or posedge rst) begin
if(rst)
done_buf_2 = 1'b0;
else
done_buf_2 = done_buf_1;
end
在功能仿真中,我發現done_buf_1在完成后上升一個周期,但done_buf_2與done_buf_1同時上升。
這有什么解釋?
謝謝!
您已經有了解決方案的答案(“使用非阻塞分配”),但是這里嘗試了為什么需要這樣做。
您的兩個always
語句都具有相同的事件,因此它們可以按任何順序運行。 似乎正在發生的事情是第一個先運行。 當行...
done_buf_1 = done;
...被點擊,它將阻塞直到分配完成(這是一個“阻塞”分配)。 因此,done_buf_1立即采用新值。 這與非阻塞版本不同...
done_buf_1 <= done;
...表示“在時間片結束時將done_buf_1的值賦予完成(我現在將對其進行評估)”。
現在我們繼續,並分配done_buf_2。
done_buf_2 = done_buf_1;
現在,如果用阻塞分配更新了done_buf_1
,則它已經具有done
的當前值,並且您將看到兩個信號同時上升。 如果它是非阻塞分配,那么done_buf_1
仍具有以前的done
值,因為直到時間片結束之前它都不會更新,結果是done_buf_2
有2個周期的延遲。
但是,還有另一個問題。 還記得我說過,因為事件相同,所以always語句可以按任意順序運行嗎? 好吧,如果第二個代碼先執行,那么代碼似乎可以按預期工作( db2 = db1; db1 = done;
沒問題)。 因此,值得一提的是,使用這樣的阻塞分配會產生不穩定的結果,尤其是在工具之間。 這可能會導致一些細微的錯誤。
您正在使用阻塞分配=
對同步邏輯進行建模。 您需要使用非阻塞分配<=
。
正如其他人所說:不要為此使用阻塞分配( =
)。
關鍵是“這”是不同進程之間進行通信的工作。 阻止分配所固有的競賽條件使這種情況無法預測。 VHDL非常認真地對待這一點,以至於將這些類型的分配分開,這樣您就不會使用錯誤的分配(只要您遠離共享變量)。
Jan Decaluwe撰寫了一些有關該主題的有趣著作:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.