Altifigence Academy

11 / 37 · 概念

編碼器與優先權:從多個請求選一個

區分獨熱編碼器的輸入假設,以及優先權編碼器的 valid 和選擇結果。

解碼器的反向操作也需要條件

解碼器解碼器啟用與二進位碼對應的輸出線。若有 enable,可在未啟用時將所有輸出設為 0。 詳細內容把位址轉為獨熱獨熱碼(one-hot)表示多個位元中恰有一個為 1。若也允許全部為 0,則另稱為 one-hot-or-zero。 詳細內容選擇線,編碼器則把有效輸入的位置轉成位址。但一般獨熱編碼器假設只有一個輸入開啟;多個輸入同時為 1 時,必須另外指定回報哪個位置。

對四位元請求 r3r2r1r0r_3r_2r_1r_0,規定編號較大的請求優先。全部輸入為 0 時,設 valid=0、index=00。不能只看 index=00 就認定沒有請求,否則會與 r0 混淆。

輸入 r3r2r1r0validindex
1---111
01--110
001-101
0001100
0000000

表中的 - 表示不論 0 或 1,結果都相同,不是允許輸入模擬的 X。各樣式由上而下定義,彼此互斥。

valid=r3+r2+r1+r0,index1=r3+r2,index0=r3+r2‾r1valid=r_3+r_2+r_1+r_0,\quad index_1=r_3+r_2,\quad index_0=r_3+\overline{r_2}r_1

1011 時 index=11;0110 時,r2 優先於 r1,因此 index=10。

每欄都是獨立的請求組合
查看波形資料
波形資料:每個字元表示一個區間;句點保持先前狀態;p 表示一個時脈週期。
訊號波形匯流排值
請求2345230000 → 0001 → 0011 → 0110 → 1011 → 1000
valid01....
index2.345.00 → 01 → 10 → 11

RTL 應明確呈現優先權

SystemVerilog
always_comb begin
  valid = |request;
  index = 2'b00;
  if      (request[3]) index = 2'd3;
  else if (request[2]) index = 2'd2;
  else if (request[1]) index = 2'd1;
end

若只有 request[0] 為 1,index 維持預設 0,valid=1。所有路徑都先給預設值,避免組合電路產生記憶行為。檢查 16 組輸入時,應確認 valid=1 時所選位元為 1,且比它更高的位元全部為 0。

選擇與公平性是不同問題

若 r3 持續為 1,r0 就一直不會被選中。這個電路只實作固定優先權。若要公平處理請求,仲裁方式就需要記住上次選擇,因而成為循序電路。

實作 · 同時觀察請求、選擇位址與 grant

同時到達的請求只選一個

r3r2r1r0=1011; valid=1; index=11; grant=1000. 編號較大的請求優先。valid=0 時,index 不代表選中的請求。

初始請求 1011 選到 r3。關掉 r3 後選到 r1,index=01、grant=0010。只要 r1 仍為 1,切換 r0 都不應改變結果。

比較按下「全部關閉」與只開啟 r0 的結果。兩者都是 index=00,但 valid 與 grant 不同。後級若只讀 index,就可能處理不存在的請求。

只有所選請求為 1 的 grant,是把 index 與 valid 再解碼的結果。

granti=valid∧(index=i)grant_i=valid\land(index=i)

需驗證三個不變量:grant 最多有一個 1;grant 為 1 的位置確實存在請求;比所選編號更大的請求全部為 0。本練習不消耗請求,也不記住前次選擇。r3 一直開啟時,較低請求持續等待,正是固定優先權的特性。

自己試試看

分別寫出請求 0101 與 0001 的 index、valid、grant。請求為 0000 時,為何不能只因 index=00 就處理 r0?

查看解說

0101 的 index=10、valid=1、grant=0100。0001 的 index=00、valid=1、grant=0001。0000 的 index=00 只是預設值;valid=0、grant=0000 表示沒有可處理的請求。

此選擇適用於本瀏覽器,隨時可從頁尾變更。