引言
??本文主要介紹了亞穩態的分析與處理。
一、亞穩態的相關概念
??亞穩態(Metastability)是指 D 觸發器無法在某個規定的時間段內(決斷時間)達到一個可確認的狀態(0 或 1),進而處于一個振蕩的不確定狀態。
??亞穩態的具體表現是當一個 D 觸發器進入亞穩態時,既無法預測該單元的輸出電平(不確定是 0 還是 1),也無法預測何時輸出才能夠穩定下來(通常情況下,一個時鐘、或者兩個時鐘的時間之內可以返回穩態)。在這個達到穩定之前的時間內,D 觸發器輸出一些中間級電平,或者可能處于振蕩狀態,或者可能會沿著信號通道上的各個 D 觸發器級聯式傳播下去,最終導致系統的崩潰。
??亞穩態的產生原因是 D 觸發器的建立時間和保持時間在時鐘上升沿左右定義了一個時間窗口(亞穩態窗口)(較新的邏輯器件會有較小的亞穩態窗口),在這段時間內,輸入信號和時鐘都應該保持不變。如果 D 觸發器的輸入數據在這個時間窗口內發生變化(數據更新),那么就違反了建立時間和保持時間的要求,從而產生了時序違規(Timing Violation)。此時 D 觸發器內部的一個節點(一個內部節點或者要輸出到外部節點)可能會在一個電壓范圍內浮動(徘徊在一個中間電平狀態),無法確定最終是穩定在邏輯 0 或者是邏輯 1 的狀態,而在這段時間里,數據輸出端 Q 為毛刺、振蕩狀態,而不是等于數據輸入端 D 的值。
??亞穩態的隨機輸出表現為 D 觸發器輸出端 Q 在時鐘上升沿之后,比較長的一段時間處于不確定的狀態,在這段時間里 Q 端在 0 和 1 之間處于振蕩狀態,而不是等于數據輸入端 D 的值,這段時間稱為決斷時間。經過決斷時間之后 Q 端將穩定為 0 或 1 ,但是具體是 0 或 1 卻是隨機的,與輸入沒有必然關聯。亞穩態無法根除,但是可以減小亞穩態發生的概率。
二、亞穩態的解決方法
- 降低系統時鐘頻率;
- 提高時鐘信號邊沿變化速度(這個取決于晶振、器件、工藝等等);
- 用反應更快的 DFF;
- 引入同步機制,防止亞穩態的傳播;
- 相位控制技術,PLL 控制分頻與相位。
三、亞穩態的解決案例
??對于以上的第 4 點,有多級 D 觸發器級聯處理方式(節拍),可對異步信號進行同步處理。可以看出,前面基于時鐘域 Clk_a 的信號發送過來,在基于時鐘域 Clk_b 的時鐘下進行采樣,可能會出現采樣時鐘上升沿剛好出現在數據變化的那一刻,于是,就會產生亞穩態。
??當第一個寄存器發生亞穩態后,經過 Tmet 的振蕩穩定后,第二級、或者第三級寄存器就能采集到一個穩定的值,避免了亞穩態跟隨著電路一直傳遞下去,從而最終導致的系統的崩潰。
打兩拍電路圖
打兩拍時序圖
打兩拍時序圖
四、亞穩態的 Verilog 代碼(打兩拍、慢到快)
reg [1:0] signal_r; // 兩級緩沖器、兩級寄存器,打完兩拍之后,才可以進行組合邏輯的操作
always @(posedge clkb or negedge rst_n)begin
if(!rst_n)
signal_r <= 2'b00;
else begin
signal_r <= {signal_r[0], signal_in};//signal_in 是基于 clka 的
end
end
assign signal_out = signal_r[1];
五、亞穩態的 Verilog 代碼(打兩拍、快到慢)
module Sync_Pulse( // clka 下生成展寬信號,展寬信號同步到 clkb,再同步回 clka
input clka,
input clkb,
input rst_n,
input pulse_ina, // clka下的脈沖;
output pulse_outb,// 上升沿檢測;
output signal_outb// clkb下的脈沖;
);
reg signal_a;
reg [2:0] signal_b_r;
reg [1:0] signal_a_r;
//-------------------------------------------------------
// 在 clka 下,生成展寬信號 signal_a
always @(posedge clka or negedge rst_n)begin
if(!rst_n)
signal_a <= 1'b0;
else if(pulse_ina) // 檢測到輸入信號 pulse_ina 被拉高,則拉高 signal_a
signal_a <= 1'b1;
else if(signal_a_r[1]) // 檢測到反饋信號 signal_a_r[1] 被拉高,則拉低 signal_a
signal_a <= 1'b0;
else
signal_a <= signal_a;
end
//-------------------------------------------------------
// 在 clkb 下打三拍,前兩個用于同步 signal_a,后一個用于生成脈沖信號、// 輸出信號
always @(posedge clkb or negedge rst_n)begin
if(!rst_n)
signal_b_r <= 3'b000;
else
signal_b_r <= {signal_b_r[1:0], signal_a};
end
assign pulse_outb = ~signal_b_r[2] & signal_b_r[1];// 判斷上升沿;
assign signal_outb = signal_b_r[2];
// 不需要用到跳變沿的來自同一時鐘域的輸入,沒有必要對信號進行寄存;
// 需要用到跳變沿的來自同一時鐘域的輸入,寄存一次即可;
// 需要用到跳變沿的來自不同時鐘域的輸入,需要用到 3 個觸發器,前兩個用// 于同步,第 3 個觸發器的輸出和第 2 個的輸出經過邏輯門來判斷跳變沿。
//-------------------------------------------------------
// 在 clka 下打兩拍,采集 signal_b_r[2],生成 signal_a_r[1] 用于反饋拉// 低 signal_a
always @(posedge clka or negedge rst_n)begin
if(!rst_n)begin
signal_a_r <= 2'b00;
end
else begin
signal_a_r <= {signal_a_r[0], signal_b_r[2]};
end
end
endmodule
-
寄存器
+關注
關注
31文章
5430瀏覽量
123964 -
時鐘
+關注
關注
11文章
1891瀏覽量
133024 -
觸發器
+關注
關注
14文章
2034瀏覽量
62012 -
亞穩態
+關注
關注
0文章
47瀏覽量
13506
發布評論請先 登錄
評論