時鐘上升沿觸發是同步時序邏輯的基石。但許多初學者存在誤區:以為「時鐘沿到來時讀取輸入,下一個沿才輸出」。本文從 Verilog 非阻塞賦值語意、Delta 延遲、Testbench 時序、真實硬體 Setup/Hold 時間五個維度,徹底釐清「時鐘沿瞬間發生了什麼」。
module test(clk, a, b);
input clk, a;
output reg b;
always @(posedge clk) b <= a;
endmodule
Testbench:a 在 15ps 變 1,時鐘週期 10ps(上升沿 0, 10, 20...)。
波形結果:a 和 b 同時在 20ps 上升沿變為 1(而非 30ps)。
a 變 1(組合邏輯/輸入激勵)。a 當前值 1),再排程左側更新(b <= 1 放入 NBA 隊列)。b 更新在 **Nonblocking Assign Update 階段** 完成,故波形顯示 20ps 瞬間 b 變 1。a 在 20ps 時刻同時變化(同一 Delta 週期),則讀到的是舊值(取決於事件隊列順序),這就是 Setup/Hold 違例在仿真中的體現。| 場景 | 阻塞賦值 (=) | 非阻塞賦值 (<=) |
|---|---|---|
| 同一 always 塊內順序執行 | 立即生效,後續語句讀到新值 | 延後更新,本塊內後續語句讀到舊值 |
| 不同 always 塊/進程 | 不可預測(競爭) | 等價於並行,由排程器決定更新順序 |
| 時序邏輯建模 | 錯誤(產生組合回路/競爭) | 正確(對應觸發器行為) |
| 組合邏輯建模 | 正確 | 可用但非慣例 |
鐵律:時序邏輯必用非阻塞賦值,組合邏輯用阻塞賦值。
a 在時鐘沿附近變化(違反 Setup/Hold),觸發器可能進入**亞穩態**,輸出 b 產生不可預測的毛刺或延遲翻轉。initial begin
clk = 0;
forever #5 clk = ~clk; // 10ps 週期
end
initial begin
a = 0;
#15 a = 1; // 在時鐘沿中間變化,滿足 Setup/Hold
#20 a = 0;
end
#1 等微小延遲區分激勵與採樣順序時,必須理解 Delta 排程語意。時鐘沿採樣的本質:非阻塞賦值在沿到來瞬間「讀舊值、排新值」,更新完成於同一仿真時刻的 NBA 階段,而非下一個沿。
Verilog 仿真與真實硬體的對應關係:
- 仿真 Delta 延遲 ≈ 硬體觸發器 Clk-to-Q 延遲(極小)。
- 仿真競爭/不確定性 ≈ 硬體 Setup/Hold 違例導致亞穩態。
掌握非阻塞賦值排程語意、Testbench 時序編寫規範、Setup/Hold 物理意義,是寫出可綜合、可驗證、可收敛 RTL 的核心功力。