Altifigence Academy

17 / 37 · 實作

實作:驗證計數器的重設、回捲與不變量

逐上升緣將狀態與參考模型比較,分開初值、重設與位元寬度的影響。

實驗對象與觀察條件

初值設為 3,在第一個上升緣上升緣是時脈由 0 變成 1 的瞬間。它與表示整段 CLK=1 期間的高準位不同。 詳細內容重設重設將狀態回復至規格指定的初始值。必須一併定義它是同步或非同步,以及是否優先於其他控制訊號。 詳細內容,之後依序 0、1、2、3、0。即使重設訊號已啟用,邊緣前的值仍不變。

開始之前

請準備 Digital Design Studio Desktop 專案與有效執行權限。各範例存於獨立資料夾的 rtl/top.sv。

SystemVerilog 原始碼

SystemVerilog
module top (
    input logic clk,
    input logic rst,
    output logic [1:0] count
);
    // Active-high synchronous reset: sampled only at the rising clock edge.
    always_ff @(posedge clk)
        if (rst) count <= 2'b00;
        else count <= count + 2'b01;
endmodule

執行方式

在 New analysis 選擇 Two-state single-clock v1,Clock port 為 clk,週期 1000ps。依下列設定完成 Preflight,再執行 Run RTL simulation 並比較結果。

設定值
暫存器初值,從 LSB 起[true,true]
Reset portrst · Active high · 1 cycle
Maximum cycles / time5 / 5000ps

輸入激勵

json
[
  {
    "inputs": {}
  },
  {
    "inputs": {}
  },
  {
    "inputs": {}
  },
  {
    "inputs": {}
  },
  {
    "inputs": {}
  }
]

每欄是一次上升緣上升緣是時脈由 0 變成 1 的瞬間。它與表示整段 CLK=1 期間的高準位不同。 詳細內容的觀察紀錄。輸入為邊緣前值,名稱含「後」的狀態為更新後值。欄位對齊表示取樣順序,並未繪出實體傳播延遲傳播延遲是輸入改變後,輸出穩定至正確值所需的時間。邏輯式是否等價與時間特性是兩個不同問題。 詳細內容。
E0~E4 分別是 500、1500、2500、3500、4500ps 的上升緣。不只最終值,也要比較全部中間 count 欄。

實作中的五個上升緣
查看波形資料
波形資料:每個字元表示一個區間;句點保持先前狀態;p 表示一個時脈週期。
訊號波形匯流排值
邊緣23452E0 → E1 → E2 → E3 → E4
reset10...
count 前2345211 → 00 → 01 → 10 → 11
count 後2345200 → 01 → 10 → 11 → 00

結果比較

5 cycles · count=00。確認 500、1500、2500、3500、4500ps 依序為 00 → 01 → 10 → 11 → 00。

本練習使用 0/1 單一時脈 RTL,不含 #delay、initial、X/Z 測試平台。學習完成標示是學習紀錄,不代表實際模擬結果。

逐邊緣計算預期狀態

暫存器暫存器儲存多個位元的狀態。本課程中的同步暫存器會在時脈邊緣儲存指定的輸入。 詳細內容初值為 3,但第一個上升緣重設優先。不要把初始化與重設視為相同。

上升緣rst邊緣前 count邊緣後 count
500ps11100
1500ps00001
2500ps00110
3500ps01011
4500ps01100

沒有重設的區段,每個邊緣都應滿足下列關係。

ck+1=(ck+1) mod 4c_{k+1}=(c_k+1)\bmod 4

只確認最後 00,即使中間經過錯誤值也可能通過。請分別檢查整個狀態序列與重設優先權。

每次只改一項實驗條件

  • 將初值改成 00,第一個重設後的序列仍相同,可藉此確認重設不依賴初值。
  • 將 Reset cycles 改成 2,前兩個上升緣的 count 都應為 00,開始遞增的時點延後一個邊緣。
  • 擴展為 3 位元時,回捲週期為八次遞增。除了宣告,也要檢查常數寬度、初始暫存器陣列與執行長度。

推廣到 modulo-10 設計

4 位元儲存空間表示 0~15,因此單純遞增不會在 9 之後變成 0,必須另外定義下一狀態函數。

ck+1={0rk=10rk=0 ∧ ek=1 ∧ ck≥9ck+1rk=0 ∧ ek=1 ∧ ck<9ckrk=0 ∧ ek=0c_{k+1}=\begin{cases}0 & r_k=1\\0 & r_k=0\ \land\ e_k=1\ \land\ c_k\ge 9\\c_k+1 & r_k=0\ \land\ e_k=1\ \land\ c_k<9\\c_k & r_k=0\ \land\ e_k=0\end{cases}

此定義會在未使用狀態 10~15 收到 enable 時回到 0。也可採用其他復原策略,但規格與驗證模型必須使用相同策略。

自己試試看

原本的 2 位元計數器在第一個上升緣重設後,再執行 11 次不受 enable 控制的遞增,count 是多少?請不列出中間狀態直接計算。

查看解說

重設後狀態為 0,11 mod 4=311\bmod4=3,所以是 11。「總共 11 個邊緣」與「重設後遞增 11 次」不同;前者若第一個邊緣用於重設,實際只遞增 10 次。

Lesson files

counter-top.sv ↓counter-inputs.json ↓

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