62 / 63 · 概念
暫存器介面與副作用的發生時點
指定地址、位元組寫入與回應暫停,讓每個請求恰好導致一次狀態變更。
單元可免費閱讀,註冊課程即可儲存學習進度。
定義「寫入暫存器」的行為
先備知識:位址解碼器解碼器啟用與二進位碼對應的輸出線。若有 enable,可在未啟用時將所有輸出設為 0。 詳細內容、ready/valid交握(handshake)規定傳送端的 valid 與接收端的 ready 在同一邊緣皆為 1 時,才確定完成傳輸。等待期間如何保持資料也是契約的一部分。 詳細內容、enable 與狀態更新優先權。
把設定暫存器暫存器儲存多個位元的狀態。本課程中的同步暫存器會在時脈邊緣儲存指定的輸入。 詳細內容接到外部控制器,不能只確認地址正確。還須定義請求接受時點、回應等待時的保持條件,以及寫唯讀地址的處理。此處用同時脈的簡單單請求、單回應介面。
下列為位元組地址,採 32 位元對齊。每個請求恰好產生一個成功或錯誤回應。
| 地址 | 名稱 | 行為 |
|---|---|---|
| 0x0 | CONFIG | 可讀寫,套用 byte strobe |
| 0x4 | STATUS | 唯讀,回傳接受時的值 |
| 0x8 | COMMAND | 讀為 0,寫 byte 0 的 bit 0 產生 start pulse |
| 其他 | 未定義 | 錯誤回應,不改狀態 |
回應槽空或即將清空的邊緣才接受
module register_interface (
input logic clk, rst,
input logic req_valid, req_write,
output logic req_ready,
input logic [3:0] req_addr,
input logic [31:0] req_wdata,
input logic [3:0] req_wstrb,
output logic rsp_valid,
input logic rsp_ready,
output logic [31:0] rsp_rdata,
output logic rsp_error,
input logic [31:0] status_value,
output logic [31:0] config_value,
output logic start_pulse
);
assign req_ready = !rsp_valid || rsp_ready;
always_ff @(posedge clk) begin
if (rst) begin
rsp_valid <= 1'b0;
config_value <= 32'd0;
start_pulse <= 1'b0;
end else begin
start_pulse <= 1'b0;
if (req_ready) begin
rsp_valid <= req_valid;
if (req_valid) begin
rsp_rdata <= 32'd0;
rsp_error <= 1'b0;
case (req_addr)
4'h0: begin
if (req_write) begin
for (int i=0; i<4; i++)
if (req_wstrb[i])
config_value[8*i +: 8]
<= req_wdata[8*i +: 8];
end else rsp_rdata <= config_value;
end
4'h4: begin
if (req_write) rsp_error <= 1'b1;
else rsp_rdata <= status_value;
end
4'h8: begin
if (req_write)
start_pulse <= req_wstrb[0] && req_wdata[0];
end
default: rsp_error <= 1'b1;
endcase
end
end
end
end
endmodule回應受阻時 req_ready=0,因此 config 寫入與 command pulse 不會再執行。已接受請求的副作用可能已發生,只有回應在等待。若因回應延遲就無條件重送,可能重複執行命令。
計算 byte strobe 的意義
CONFIG=32'h11223344 時寫入 req_wdata=32'hAABBCCDD、req_wstrb=4'b0101,只改 byte 0、byte 2,結果為 32'h11BB33DD。地址對齊、位元位置與記憶體位元組順序應分別確認。wstrb=0000 的寫入成功回應,但不改值。
從 MSBMSB是位權最高的位元。索引編號會隨向量的宣告方向而異,因此不能一律假設它的編號最大。 詳細內容 起為 byte3,2,1,0。Strobe=0101 選 byte2、byte0,因此只寫新 BB、DD。Strobe 是位元組單位 write enable,不是單一位元選擇。
- 原有 CONFIG: 11 | 22 | 33 | 44
- 寫入資料: AA | BB | CC | DD
- strobe 0101: 保持 · 替換 · 保持 · 替換
- 新的 CONFIG: 11 | BB | 33 | DD
狀態是哪個時點的值
STATUS 的讀取回應會儲存請求接受時的 status_value。之後回應暫停,即使實際 status 改變,rsp_rdata 仍保持。rsp_valid=1、rsp_ready=0 時若直接把組合 status 接到回應,內容會改變,違反協定。
連續邊緣 req_valid、req_ready 都為 1,表示兩個不同請求。請求被接受後,傳送端須降 valid 或更新成下一請求,不能一直保留同一請求卻期待只處理一次。
驗證的三個面向
- 位址與權限:檢查有效、未對齊、未定義地址與 STATUS 寫入的錯誤及副作用。
- 資料選擇:窮舉四個 strobe 位元,確認未啟用 byte 保留。
- 流量控制:阻擋回應多週期時,回應與狀態保持;同時消費回應、接受下個請求時,交易數也須一致。
自己試試看
接受 req_wstrb[0]=1、req_wdata[0]=1 的 COMMAND 寫入後,rsp_ready=0 維持三週期。Start_pulse 應重複三週期嗎?STATUS 寫入可以改 config_value 嗎?
查看解說
Start_pulse 只在請求接受後一週期為 1,之後為 0。回應暫停不是重複執行命令的條件。STATUS 寫入應回錯誤,不改 config_value 等其他狀態。回應完成前的重試政策,也需由收發雙方約定。