當我們執行 testbench 時,終端只能顯示:
Sample 0: SP=5.00, FB=0.00, Error=5.00, Output=10.00
Sample 1: SP=5.00, FB=0.10, Error=4.90, Output=9.85
這種輸出的問題:
- ❌ 只能看到離散的時間點
- ❌ 無法觀察連續變化
- ❌ 難以發現瞬態問題
- ❌ 無法比較多個信號
波形查看器讓我們能夠:
- ✅ 視覺化信號的完整歷程
- ✅ 同時觀察多個信號的關係
- ✅ 測量時間和數值
- ✅ 發現隱藏的問題
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ RTL 設計 │ --> │ Testbench │ --> │ 模擬執行 │
└─────────────┘ └──────────────┘ └─────────────┘
│
▼
┌────────────────────────────┐
│ VCD 波形檔案 │
│ (Value Change Dump) │
└────────────────────────────┘
│
▼
┌────────────────────────────┐
│ GTKWave 分析 │
│ • 視覺化顯示 │
│ • 測量與分析 │
│ • 問題診斷 │
└────────────────────────────┘
# 方法一:透過 Makefile(推薦)
cd fridge_temp_controller_sky130/testbench
make wave_pid
# 方法二:直接執行
gtkwave work/pid_controller_tb.vcd┌─────────────────────────────────────────────────────────┐
│ File Edit Search Time Markers View Help │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌────────────────────────────────────┐ │
│ │ SST │ │ │ │
│ │ 信號樹狀圖 │ │ 波形顯示區 │ │
│ │ │ │ │ │
│ ├─────────────┤ │ │ │
│ │ Signals │ │ │ │
│ │ 可用信號列表 │ │ │ │
│ └─────────────┘ └────────────────────────────────────┘ │
│ [時間軸控制] [<<] [<] [>] [>>] [Zoom] [從:] [到:] │
└─────────────────────────────────────────────────────────┘
-
展開信號樹
SST 面板: └── TOP └── pid_controller_tb ├── clk ├── rst_n ├── setpoint ├── feedback └── DUT (pid_controller) ├── error ├── p_term ├── i_term ├── d_term ├── integral_acc └── output -
選擇信號
- 按住 Ctrl 多選
- 或單擊逐個選擇
-
加入波形顯示
- 點擊 "Append" 按鈕
- 或拖放到波形區
| 功能 | 快捷鍵 | 說明 |
|---|---|---|
| 放大 | + 或滾輪上 |
放大時間軸 |
| 縮小 | - 或滾輪下 |
縮小時間軸 |
| 左移 | ← |
向左移動時間軸 |
| 右移 | → |
向右移動時間軸 |
| 標記 | M |
設置時間標記 |
| 測量 | 拖曳選擇 | 測量時間間隔 |
我們的 PID 控制器包含四個測試案例,每個都有特定的觀察重點:
測試案例總覽:
┌────────────┬────────────┬────────────┬────────────┐
│ Test 1 │ Test 2 │ Test 3 │ Test 4 │
│ 階躍響應 │ 干擾抑制 │ 參數變化 │ 積分飽和 │
│ 0-5ms │ 5-8ms │ 8-12ms │ 12-16ms │
└────────────┴────────────┴────────────┴────────────┘
當系統從 0°C 要達到 5°C 時,PID 如何工作?
時間: 0-5ms
觀察信號:
- setpoint: 0 → 1280 (5°C in Q8.8)
- feedback: 逐漸上升
- error: 1280 → 0
- p_term: 立即響應
- i_term: 逐漸累積
- d_term: 初始脈衝
- output: 綜合輸出
setpoint ────┐________________________
│
│
feedback ────┘───────────────┐________
│
│
error ────┐ │
└───────────────┘________
p_term ────┐
└───────────────┐________
│
i_term ────────┐──────────┐────────
│ │
integral_acc ─────┐─────────┐─────────
│ │ (飽和點)
系統穩定在 4°C,突然受到干擾升到 6°C,如何恢復?
干擾發生時刻 (標記為 M1):
- feedback: 4°C → 6°C (突變)
- error: 0 → -2°C (變負)
- p_term: 立即變負
- i_term: 開始反向累積
- output: 快速響應降溫
- 設置標記 M1 在干擾發生時
- 設置標記 M2 在恢復到 ±5% 範圍內
- 時間差 = 恢復時間
終端輸出只顯示:
Integral accumulator: 7fffffff
但在 GTKWave 中能看到:
- 飽和過程:integral_acc 如何達到最大值
- 飽和維持:即使誤差存在,不再增加
- 解飽和過程:設定值反轉後的恢復
integral_acc 信號:
┌─────────────┐ (飽和值 0x7FFFFFFF)
│ │
─────┘ └─────────────┐
│ (解飽和)
└─────────
測量方法:
1. 找到 feedback 達到最終值 10% 的時間點 (T1)
2. 找到 feedback 達到最終值 90% 的時間點 (T2)
3. 上升時間 = T2 - T1
測量方法:
1. 確定穩態值和容許誤差帶(±5%)
2. 找到最後一次超出誤差帶的時間點
3. 這就是穩定時間
計算方法:
1. 找到 feedback 的最大值 (Vmax)
2. 確定穩態值 (Vss)
3. 過沖 % = (Vmax - Vss) / Vss × 100%
範例:觀察 PID 三個項的貢獻
1. 將 p_term, i_term, d_term 垂直對齊
2. 使用相同的數值格式(Signed Decimal)
3. 觀察各項在不同階段的貢獻比例
- 輸入信號:藍色系
- 內部信號:綠色系
- 輸出信號:紅色系
- 錯誤/警告:黃色系
對於 Q8.8 定點數:
實際值計算:
顯示值 / 256 = 實際溫度
範例:
1280 / 256 = 5.0°C
-512 / 256 = -2.0°C
建議設置:
- 右鍵信號 → Data Format → Signed Decimal
- 這樣更容易理解數值含義
-
修改
pid_controller_tb.v中的參數:// 原始參數 kp = real_to_q8_8(2.0); ki = real_to_q8_8(0.1); kd = real_to_q8_8(0.05); // 實驗 1:純 P 控制 kp = real_to_q8_8(5.0); ki = real_to_q8_8(0.0); kd = real_to_q8_8(0.0);
-
重新執行模擬:
make clean make wave_pid
-
在 GTKWave 中比較:
- 有無穩態誤差?
- 響應速度如何?
- 是否有振盪?
如果看到 output 和 feedback 持續振盪:
- 檢查 P 項:是否過大?
- 檢查 D 項:是否太小?
- 檢查採樣時間:是否合適?
- 觀察振盪週期
- 測量振幅
- 分析各項貢獻
- 調整參數
使用 GTKWave 的截圖功能:
- File → Print To File → PNG
- 標註重要時刻
- 記錄測量數據
報告模板:
測試案例:階躍響應
參數設置:Kp=2.0, Ki=0.1, Kd=0.05
測量結果:
- 上升時間:X.X ms
- 穩定時間:X.X ms
- 過沖量:X.X %
- 穩態誤差:X.X°C
結論:[性能評估]
Q1: 信號顯示全是 X(未知)?
- 檢查 testbench 是否正確初始化
- 確認 rst_n 信號是否正確釋放
Q2: 看不到預期的信號變化?
- 檢查時間範圍是否正確
- 確認信號是否被正確記錄($dumpvars)
Q3: 數值顯示很奇怪?
- 檢查數據格式設置
- 理解 Q8.8 定點數格式
# 保存當前配置
File → Write Save File → my_pid_view.gtkw
# 下次直接載入
gtkwave pid_controller_tb.vcd my_pid_view.gtkw創建腳本自動化測量:
# measure_pid.tcl
gtkwave::loadFile "pid_controller_tb.vcd"
gtkwave::addSignal "pid_controller_tb.feedback"
# ... 更多自動化命令- 載入第一個 VCD
- File → Read Save File → 載入第二個
- 使用不同顏色區分
-
組織信號顯示
- 相關信號分組
- 使用有意義的順序
- 適當的縮放比例
-
文檔記錄
- 截圖關鍵波形
- 標註重要發現
- 保存測量數據
-
迭代優化
- 小步修改參數
- 系統性記錄結果
- 建立參數-性能關係
GTKWave 不僅是查看波形的工具,更是理解和優化設計的關鍵。通過視覺化分析,我們能:
- 深入理解系統行為
- 快速定位問題
- 優化設計參數
- 驗證設計正確性
記住:一張好的波形圖勝過千行日誌輸出!