5 / 24 · 概念
在時脈邊緣解讀暫存器傳輸
區分舊狀態與下一個狀態,並追蹤致能訊號如何保留儲存值。
單元可免費閱讀,註冊課程即可儲存學習進度。
所有暫存器都讀取舊狀態
首先找出必須跨週期保留的資訊。累加器、已擷取的運算元、迴圈計數與輸出 valid 都是狀態。當前累加器與運算元的總和則是組合值。對變數賦值本身並不足以說明儲存行為;必須訂定擷取其值的事件。
此累加器只在 en 成立的上升緣將 x 加入。en 為低時,它會保持原值。九位元中間結果讓加法的寬度明確;選取其最低八個位元則定義模 256 行為。always_ff 中的非阻塞賦值,會使用當前邊緣讀取的數值安排下一個狀態。涉及多個暫存器時,若將這個區塊解讀為立即執行的軟體賦值,便會得到錯誤解讀。
logic [7:0] acc;
logic [8:0] next_sum;
assign next_sum = {1'b0, acc} + {1'b0, x};
always_ff @(posedge clk) begin
if (rst) acc <= 8'd0;
else if (en) acc <= next_sum[7:0];
end重設為同步重設,優先於致能。en 為低時省略循序賦值,代表暫存器保持原值。組合路徑省略賦值,則可能推導出非預期的鎖存器。組合式下一狀態邏輯應先提供預設值,再依特定條件覆寫。
| 邊緣 | rst | en | x | 舊 acc | 新 acc |
|---|---|---|---|---|---|
| 0 | 1 | 1 | 9 | 未知 | 0 |
| 1 | 0 | 1 | 7 | 0 | 7 |
| 2 | 0 | 0 | 100 | 7 | 7 |
| 3 | 0 | 1 | 250 | 7 | 1 |
在邊緣 2,可見輸入 100 並未被接受。在邊緣 3,7+250=257 縮窄為 1。後續將 en 改為 valid AND ready 時,區分輸入的呈現與接受仍然至關重要。
對 a<=x; b<=a; 而言,舊 a=5 且 x=9 會產生新 a=9、b=5。若 b 應接收 9,便將其輸入連接至 x。先填完舊狀態欄,再一起計算所有下一狀態值;如此便能找出資料與控制之間相差一個週期的問題。
自己試試看
初始 a=4、b=0。輸入 x 依序為 8 與 12,每個邊緣都執行 a<=x; b<=a。第二個邊緣後,a 與 b 各是多少?
查看解說
第一個邊緣後,a=8、b=4。第二個邊緣後,a=12、b=8。每次更新 b 都使用舊 a,因此 x=12 不會在同一個邊緣穿過兩個暫存器。
✓ 已學習