軟體把組態寫兩次。Shadow 比較器看到相符,便提交更新。若兩次都是同一錯值,協定仍會成功。本課分開檢查更新一致性,以及是否有權選這個值。
第一筆只暫存
器材櫃的管理規則要改兩次確認。現在使用代碼9,老師第一次寫6,只放進待確認欄,柜子仍照9工作;第二次也寫6才算接受更新,之後使用值變6。它們對應active、staged、pending與csr_commit。第二筆7不符就維持9。這個故事檢查一次組態更新,沒有把兩次寫入當兩次獨立政策審核。
控制/狀態暫存器稱為 CSR,供軟體讀寫組態或狀態。Shadow 更新先暫存值,不改硬體正在使用的 committed value。第二次相符才完成。本課四位元 RW 範例從限制值 FAIL=9 開始。
Edge 1 寫 6,該緣後 staged 保存 6,pending 變 true,使用中的 CSR 仍為 9。Edge 2 再寫 6,與 staged 相符。更新 commit 在該緣發生,使用值之後才改。CSR commit 指組態更新被接受,不是指令退休。
第二次若寫 7,配對失敗,使用值維持 9,並記錄更新錯誤。這只辨認寫入協定不一致。成功更新後若保存值出錯,仍需要另外的檢查與測試。
OpenTitan 文件說明成對 shadow 寫入、更新與保存錯誤,以及 reset 問題。本課簡化協定省略反相保存、讀取重置 phase 與特定 bus 語意,不能說成 prim_subreg_shadow 複刻。Register generator 文件
把兩次寫入拆成取樣前後
第1拍老師寫6前,使用值9、沒有待確認;鐘響後待確認6、pending=1。第2拍先看第二筆是否等於6,成立才紀錄commit,之後改使用值。這對應原表的緣前/緣後。兩次6很一致,但若學校只准9,仍是越權更新;相同的字跡沒有提供改規則的權力。
CSR 是 Control and Status Register(控制與狀態暫存器)。Active 是已生效的值,staged 是尚待確認的值,pending 表示已收到第一筆。先假設未鎖定、沒有 reset、pair 政策、兩筆都寫 6(0110),active 初始為 9(1001)。
| edge | 緣前 active/pending/staged | 動作與緣後結果 |
|---|---|---|
| 1 | 9 / 0 / 9 | 第一筆 6 只暫存:active=9、pending=1、staged=6;commit=0 |
| 2 | 9 / 1 / 6 | 第二筆 6 相符:commit=1;緣後 active=6、pending=0 |
| 3 | 6 / 0 / 6 | 沒有新寫入,保持 active=6 |
若第二筆改成 7,edge 2 的相符比較為 0,active 保持 9,並記錄 update error。兩筆都寫 6 的情況沒有資料不一致;但如果可信政策只允許 9,它仍是越權更新。Pair checker 不能代替寫入授權。
寫入相符仍可能沒有授權
校規只准代碼9,老師連續寫兩次6,配對員會說一致,獨立政策簿卻說不準。Policy-bound另外查准許值。柜子鎖定後兩筆都不能接收;若一次把lockSeen壓低覆蓋兩筆窗口,則是另一個lock故障情境。『同一錯值寫兩次』與『一次鎖定強制』不是同一種預算,不能把配對一致當成全套存取權限。
本情境預期組態是 9。兩次寫 6 彼此相符,卻不符合獨立政策 reference。只查配對的硬體會接受,monitor 因而記越權。重複資料沒有提供第二次政策判斷。
Policy-bound 要求每次接受寫入,符合另有可信依據的預期值。實驗從可信 harness 取得它。產品可以改查權限、生命週期與欄位允許值。政策來源與最終 write enable 都須保護。
Lock 另有工作:組態凍結後,兩個 phase 都不得再接受寫入。Locked 控制會拒絕兩筆。另一組 lock 故障,以一次暫時強制,讓 lockSeen 在兩筆窗口都清零。資料配對正確,仍能改到鎖定暫存器。
重置值,也要重置協定狀態
兩次確認之間換班清場,校規作廢舊待確認單。如果只把柜子使用值設回9,卻留下pending與staged,下一班的一筆9會被接成舊單的第二筆。這對應partial-reset;資料沒錯,世代錯了。Coherent-reset連待確認狀態一起清,新班那筆9只算第一筆。換班比喻用於協議世代,不表示本課已模擬真實reset偏斜或所有軟體中斷。
分離 reset 可能只重置使用中的 CSR,卻保留 staged 與 pending。本課刻意錯誤的 reset 目標在 edge 1 後,只恢復 value=9。Edge 2 仍保留第二筆 phase。設 first=second=expected=9,資料正確,DUT 卻把 reset 前的第一筆接上 reset 後的第二筆。獨立判準已取消舊階段,因此這次提交越權。
本情境明列 reset 目標及保留欄位,不是單位元翻轉,也沒有宣稱 OpenTitan 有此行為。Reset 清除獨立 referencePending。一致 reset 也清除 DUT pending:edge 2 的 pending=false,不提交;該筆之後暫存為新的第一筆。Edge 3 的 pending=true、value=9;9 仍是重置值,不是完成更新的結果。產品須一起定義 value、phase、lock 與錯誤歷史的 reset。
交錯寫入是另一個協定問題。若中斷程式插入一筆,第二筆可能屬於別的操作。軟體原子存取或明確交易協定能避免混用,但它們不會自動擋住受擾 lock 或共同錯值。
值沒錯,更新世代仍可能錯
故意把兩筆與expected都設9:第一筆9在舊班留下待確認,清場只恢復active,第二筆9便錯誤commit。獨立登記簿已經取消舊班第一筆,所以referencePending=0。同樣最後都顯示9,仍有一次不該接受的更新;查更新簿要看commit與世代,不能只看柜子最後用了哪個值。
在 partial-reset 反例,first=second=expected=9,故障不是把資料改成錯值。Edge 1 先暫存 9;之後 reset 只把 active 回到 9,卻留下 pending=1、staged=9。可信協定則取消 reset 前的第一筆,referencePending=0。Edge 2 的第二筆 9 因殘留 pending 被 DUT 當成確認,commit=1;reference 沒有完整的新世代配對,因此判定越權。
改用 coherent-reset,同一個 reset 也清掉 pending。Edge 2 的 9 便是新世代第一筆,只暫存而不 commit。這解釋為何比對「最後值等於 expected」會漏掉協定錯誤。先在實驗台把三個值設為 9,再切換兩種 reset,看 edge 2 的 pending、referencePending、commit;不要只看 active。
只計一次更新,並查看保留值
先寫6、7看配對錯誤,再只改第二筆為6看相符卻違規,最後用9、9分別試鎖定與兩種reset。每組都重新開始柜子流程,能把數據、鎖與世代的原因分開。256組配對是十六個四位元值的全表,不代表現實有256次攻擊;Policy-bound也不能修好殘留的pending。
選 first=6、second=7、expected=9 與 pair。看 edge 3:value 仍為 9,bad 為 true。只改 second=6,edge 2 會有一次 commit,bad 為 false,reference 卻為 false。先匯出相符錯值,再試 policy-bound。
已執行枚舉遍歷 256 組四位元寫入配對,十六組相符。其中十五種相符值不等於 expected=9,pair 政策因此越權。Policy-bound 拒絕這些組合。合法相符配對只提交一次;不一致不改使用值。
先把兩筆與 expected 都設為 9,再做 lock 實驗。設 locked=true、target=none:不提交。只改 target=lock:正確資料仍繞過可信鎖定政策。接著清除 locked,比較 none、partial-reset 與 coherent-reset:分別正常提交一次、跨 reset 越權提交,以及只暫存新第一筆而不提交。Policy-bound 無法修復保留的 phase。
待驗證 RTL/SVA
柜子規則代碼沒變,也可能有一次被接受的確認,所以RTL把csr_commit寫成事件,而不只比較新舊active。像老師簽完第二筆9後,登記員仍應查有無本班完整配對與權限。對應reference_pair_authorized與reference_locked。這段程式沒有完整bus或reset優先權,不能把紙上雙簽直接當成已驗證CSR實現。
讀懂本課的性質:更新事件與寫入政策
稽核員在第二筆被接受的同一拍,核對獨立的鎖定與配對紀錄。若直接抄柜子pending,跨班舊單也會被說成合法;reference須自行取消舊世代。Cover則拿合法9、9展示一次可達更新。這只保留正向路徑,沒有保證並行簽字或讀回會怎樣,也沒有證明reset本身安全。
SVA 是 SystemVerilog Assertions;assertion 是檢查規則,不是放行電路。以下每個上升緣,reset 未生效時,若 accepted_commit(第九課用 csr_commit)為 1,|-> 要求右側判準在同一緣成立。沒有接受時,這條蘊涵不會報授權失敗;還需要正常工作的正向控制。disable iff (!rst_n) 排除 reset 有效期間;不能據此保證 reset 安全。
Cover 找一條符合條件的路徑,不證明所有交易正確。Reference 是 testbench(測試平台)獨立保存的期望值,harness 是提供輸入、注入預算與判準的測試外框,DUT 是被測設計。本課的兩態模型只計 0、1,不模擬 X 或拍內延遲;「兩態」不指 FSM 只有兩個狀態。語法與接線對照可回查第一課第 5 節。片段尚未編譯,不能把列出性質當成已證明。
// An accepted update counts even if wdata equals the old active value.
assign csr_commit = write && !locked_q && policy_ok_i && pending_q
&& (wdata == staged_q);
// Illustrative write rule; a complete RTL module must define priorities.
if (write && !locked_q && policy_ok_i) begin
if (!pending_q) begin staged_q <= wdata; pending_q <= 1; end
else begin
if (wdata == staged_q) committed_q <= wdata;
else update_error_q <= 1;
pending_q <= 0;
end
end
assert property (@(posedge clk) disable iff (!rst_n)
csr_commit |-> !reference_locked && reference_pair_authorized);
cover property (@(posedge clk) disable iff (!rst_n)
reference_pair_authorized && csr_commit);
片段尚未編譯,沒有完整 reset、bus 回應、byte enable 與存取型態。產品須測 lock 極性、讀回、保存檢查、phase 完整性與 reset skew。下一課會量出錯誤訊號何時真正阻止接受。
故障實驗台
把value讀成當前柜規,staged與pending讀成待確認單,referencePending讀成獨立本班登記。重設後換target,逐拍看edge2是否commit,再看edge3留下什么。實驗臺紀錄的是有限協議模型;沒有把書面簽字變成完整匯流排測試,也不含反相保存或byte enable。
已執行有限、兩態教學模型。RTL 模擬、合成、形式證明與晶片驗證均尚未執行。Reference 欄位是可信測試平台的觀察,不是晶片多出來的防禦。
檢查你的推理
做題時先問第一筆能否改柜規,再問同樣寫9為何仍可能跨班違規,最後問鎖定時第一筆是否也該拒絕。它們分別對應staging、epoch與lock,不能只用『兩筆一樣』回答。若兩筆間加入讀取,是否取消待確認要另外訂規則,故事沒有默默給出答案。
1. 第一筆何時改使用中的 CSR?
不會;相符第二筆才提交。
2. Expected=9 時,多少相符值是錯的?
十六種中有十五種。
3. 只在第二筆查 lock,協定就完整嗎?
不完整,第一筆鎖定時能否暫存也須定義。
4. Partial-reset 留下什麼?
Staged 資料與 pending phase。
5. 更新不一致與保存不一致是同一目標嗎?
不是;階段與觀察不同。
MY ACADEMY · LESSON FILM
教學影片
影片依序說明本課的資料路徑。看完一段,可以回到下面的互動練習,改變輸入或故障條件。動畫呈現教學模型;它沒有替代 RTL 模擬。
旁白使用合成聲音。互動教學與動畫均有模型邊界;請以本課的來源與驗證範圍解讀結果。
本課故障互動實驗
此實驗執行有限、兩態教學模型。RTL/SVA 為待驗證範例,未執行 RTL 模擬、合成、形式證明、時序收斂或晶片驗證。枚舉數量不是實體攻擊機率。
Wrap-up|把這一課帶回設計審查
把這張兩次確認單與柜子active一起交接,並保留清場在哪里發生。下面收尾繼續區分一致性、權力與世代;只有最後值相同的截圖不夠,也沒有把其他CSR類型順便納入。
- 威脅模型與成立條件
兩筆在edge1、2,鎖被壓低與只清active各另跑。共同錯值是輸入情境,不可都稱一次保存bit翻轉。
四位元 RW CSR,edge 1/2 寫兩筆,edge 2 接受更新。共同錯值、lock 強制與只重置 committed 的案例分開。
- 失效原因
兩次6一致卻違背只准9,跨班9也可缺本班完整配對。相等沒有證明權力或正確世代。
相等無法建立政策授權。脆弱 lock 或保留 phase,可能接受原本禁止的更新。
- 防護方法
柜子不接受錯配,仍保留舊9;清場還應取消待確認單。數據、鎖與phase都需自己的完整性,雙簽不能包辦。
保護政策、lock、暫存與提交協定,以及一致 reset。不一致時保留原使用值。
- 驗證方式與待做檢查
十六乘十六種配對、合法9/9與跨班舊單分別留紀錄。當前測試是協議枚舉,沒有跑完整CSR bus。
Node 已跑 256 組配對、lock/reset 反例與合法配對一次提交。尚未跑完整 CSR RTL 或 bus 測試。
- 防護界線與未驗證項目
紙上雙簽沒有定義讀回會不會取消待確認,也沒有byte mask或並發簽字。必須另外訂這些協議,不能借故事猜硬體行為。
簡化協定排除反相保存、byte mask、讀取語意、並行寫入與實體 reset 行為。
換個情境再想一次
兩筆之間讀柜規,若校規定讀取取消pending,下一筆就只是新第一筆。若保留則另推結果;原課模型沒有這個讀操作。
在兩筆間加入讀取。定義是否取消 pending,再預測下一筆寫入。
以上整理對照本課的教學案例、參考資料與實驗範圍;未列為已完成的驗證,都是後續工作。