10 / 37 · 概念
組合 RTL 與完整指定
用條件運算子與 always_comb 表達同一函數,找出會產生鎖存器的遺漏。
單元可免費閱讀,註冊課程即可儲存學習進度。
組合電路由目前輸入決定輸出
最直接的 MUX多工器是依選擇訊號,將多個輸入之一連至輸出的組合電路。必須明確定義選擇位元與輸入編號的對應關係。 詳細內容 寫法是 assign y = sel ? b : a;。要一起計算多個輸出時,可使用 always_comb。
always_comb begin
y = a;
if (sel) y = b;
end先給預設值,就定義了 sel=0 的路徑。反之,若只留 if (sel) y = b;,sel=0 時必須保持先前 y,就不再是純組合函數。不能忽略工具警告,或只相信 always_comb 關鍵字。
預設 y=a、只在 sel=1 時選 b 的程式,與下方電路具有相同的 0/1 組合功能。sel=0 時輸出也一定有定義。
y = sel ? b : a
不要只把程序語法當成軟體執行順序
組合區塊通常用 blocking 指定 = 計算暫存結果。同一區塊後面的式子若讀取前面已指定的結果,這項相依性會形成組合路徑。請區分它與循序暫存器暫存器儲存多個位元的狀態。本課程中的同步暫存器會在時脈邊緣儲存指定的輸入。 詳細內容更新使用的 nonblocking非阻塞賦值(nonblocking)在循序 RTL 中以 <= 表示。它先求右側運算式的值,再排程更新,讓同一邊緣的暫存器都能依據先前狀態計算。 詳細內容 指定 <=。
always_comb begin
next_y = sel ? b : a;
inverted_y = ~next_y;
end同一輸出不能由多個區塊驅動,也是基本規則。模組拆分越多,就越應透過介面追蹤「這個訊號唯一的驅動者是誰」。
先對齊不同寬度的兩筆資料
若要在 8 位元與 12 位元間選擇,請明確指定 y 寬度與符號擴展。應在設計階段決定輸入範圍,不要靠波形偶然確認隱含擴展是否符合意圖。0/1 模型之外,sel=X 時條件運算子的意義可能不同於單純 if,因此不能把本課程的二態結果概括到完整四態行為。
自己試試看
always_comb 中只有 if(en) y=d;。若要改成沒有 enable 時輸出 0 的組合電路,應如何寫?
查看解說
在區塊開頭先指定 y=0,en 有效時再以 d 覆寫;或使用相當於 assign y = en ? d : 0 且寬度明確的表示式。en=0 時保持舊值,是暫存器或鎖存器的另一項規格,不等同輸出 0。