幾乎稍微復雜的數字設計都離不開時鐘。 時鐘也是所有時序邏輯建立的基礎。 前面介紹建立時間和保持時間時也涉及過時鐘偏移的概念。 下面將總結下時鐘的相關知識,以便更好的進行數字設計。
時鐘源
根據時鐘源在數字設計模塊的位置,可以將時鐘源分為外部時鐘源和內部時鐘源。
外部時鐘源:
RC/LC 振蕩電路:利用正反饋或負反饋電路產生周期性變化時鐘信號。 此類時鐘源電路簡單,頻率變化范圍大,但工作頻率較低,穩定度不高。
無源/有源晶體振蕩器:利用石英晶體的壓電效應(壓力和電信號可以相互轉換)產生諧振信號。 此類時鐘頻率精度高,穩定性很好,噪聲低,溫漂小。 有源晶振中,往往還加入了壓控或溫度補償,時鐘的相位和頻率都有較好的特性。 但電路實現相對復雜,頻帶較窄,頻率基本不能調節。
調試特定電路時,往往也會使用一些搭建的特定電路(例如施密特觸發器)或信號發生器設備產生的時鐘源。
內部時鐘源:
鎖相環(PLL, Phase Locked Loop): 利用外部輸入的參考信號控制環路內部振蕩信號的頻率和相位,實現輸出信號頻率對輸入信號頻率的自動跟蹤,通過反饋通路可以將信號倍頻到一個較高的固定頻率。
一般晶振由于工藝與成本原因,做不到很高的頻率,利用 PLL 路就可以實現穩定且高頻的時PLL 集成到設計模塊的內部,可以保證數字電路具有較好的延遲和穩定特性。
時鐘分頻:有些模塊工作頻率會低于系統時鐘頻率,此時就需要對系統時鐘進行一定的分頻得到頻率較低的時鐘。
通過在 always 語句塊中計數并輸出時鐘信號,是分頻器常用的方法。
時鐘切換:系統或某些模塊的工作頻率有時候會在特定狀況下改變,例如低功耗模式下需要降頻,例如要提高計算能力時需要提高工作時鐘的頻率。 此時系統往往會有多個時鐘源,以備有需求時進行時鐘切換。
時鐘切換邏輯如果不進行優化,在時鐘切換的過度時,大概率會出現尖峰脈沖干擾,會對電路產生不利影響。
數字系統往往會采用外部晶振輸入、內部 PLL 進行倍頻的方案。 再根據設計需求進行時鐘分頻或時鐘切換。
時鐘特性
仿真時,所有同步的時鐘都是理想的:時鐘的翻轉是在瞬間完成的,模塊之間的時鐘沿都是對齊的,沒有延遲的,沒有抖動。 實際電路中,時鐘在傳輸、翻轉時都會有延遲。 完美的數字設計,也應該考慮這些不完美的時鐘特性,否則也會造成時序不滿足的狀況。
下面對時鐘的特性進行簡單說明。
時鐘偏移(skew)
由于線網的延遲,時鐘信號在到達觸發器端口時,不能保證不同觸發器端口的時鐘沿是對齊的,即不同觸發器端口的時鐘相位存在差異。 這種差異稱為時鐘偏移。 示意圖如下:
一般時鐘偏移與時鐘頻率沒有直接的關系,與走線長度、負載電容、負載數量等有關。
時鐘抖動(jitter)
相對于理想時鐘沿,實際時鐘中存在的不隨時間積累的、時而超前、時而滯后的偏移稱為時鐘抖動。 可以用抖動頻率和抖動幅度對時鐘抖動進行定量描述。 數字設計中,時鐘抖動都是用時間來描述,示意圖如下。
時鐘抖動可分為隨機抖動和固定抖動。
隨機抖動的來源為熱噪聲、半導體工藝等。
固定抖動的來源為開關電源、電磁干擾或其他不合理的布局布線等。
在綜合工具 Design Compiler 中,時鐘的偏移和抖動統一用不確定度 uncertainty 來統一表示。
轉換時間(transition)
時鐘從上升沿跳變到下降沿,或者從下降沿跳變到上升沿時,并不是“直上直下”不需要時間完成電平跳變,而是“斜坡式”需要一個過渡時間完成電平跳變。 這個過渡時間稱之為時鐘的轉換時間,示意圖如下。
轉換時間大小與單元庫工藝、電容負載等有關。
時鐘延時(lantency)
時鐘從時鐘源(例如晶振、PLL 或分頻器輸出端)觸發到達寄存器端口的延遲時間,稱為時鐘延時。 時鐘延時包含時鐘源延遲(source latency)和時鐘網絡延遲(network latency),如下圖所示。
時鐘源延時,是時鐘信號從實際時鐘原點到設計模塊時鐘定義點的傳輸時間。 上圖所示為 3ns。
時鐘網絡延時,是從設計模塊時鐘定義點到模塊內觸發器時鐘端的傳輸時間,傳輸路徑上可能經過緩沖器(buffer)。 上圖所示為 1ns。
由圖可知,時鐘源延時(source latency)是設計模塊內所有觸發器共有的延時,所以不會影響時鐘偏移(skew)。
時鐘樹
數字設計時各個模塊應當使用同步時鐘電路,同步電路中被相同時鐘信號驅動的觸發器共同組成一個時鐘域。 理想電路中,時鐘信號會同時到達同時鐘域所有觸發器的時鐘端。 但是實際中因為各種延遲的存在,這種無延遲的時鐘特性是很難實現的。 而且時鐘信號的驅動能力有限,難以獨立的為一個包含較多的觸發器的時鐘域提供有效扇出。 為解決時鐘延遲與驅動的問題,就需要采用時鐘樹系統對時鐘信號進行管理,來確保時序的良好和大量的扇出。
時鐘樹,是個由許多緩沖單元 (buffer cell) 平衡搭建的網狀結構。 一般由一個時鐘源點,經一級一級的緩沖單元搭建而成。 增加 clock buffer(圖中橙色三角模塊) 的實際時鐘樹結構如下所示。
藍色的上升沿符號表示時鐘的轉換時間(transition),紅色的實線則表示時鐘延時 (latency),包含 network delay 和 source latency,綠色的虛線表示時鐘不確定度(uncertainty),包括時鐘偏移(skew)和時鐘抖動(jitter)。
時鐘樹并不是來減少時鐘信號到達各個觸發器的時間,而是減少到達各個觸發器之間的時間差異。 一般是后端設計人員通過插入 clock buffer 完成時鐘樹的設計。 前端設計人員,往往需要保證時鐘方案與數字邏輯的功能正確性。
其他時鐘分類:
同步、異步時鐘
當時鐘同源且滿足整數倍關系是,一般可以認為時鐘是同步的。 數字設計中同步時鐘的定義比較寬泛。 同時鐘域下的邏輯不需要進行同步處理。
下面從同步電路的角度來理解同步時鐘的概念。
同步電路是由時序和組合邏輯電路構成的電路。 同步電路的特點是各觸發器的時鐘端全部連接在一起,并接在系統時鐘端。 只有當時鐘脈沖到來時,電路的狀態才能改變。 改變后的狀態將一直保持到下一個時鐘脈沖的到來。 這期間無論外部輸入 x 有無變化,狀態表中的每個狀態都是穩定的。
門控時鐘
門控時鐘的基本原理:使能信號有效的時候,打開時鐘。 使能信號無效的時候,關閉時鐘。
由于門控時鐘可以將工作時鐘在適合的時間關閉,所以門控時鐘在低功耗設計中有著廣泛應用。 門控時鐘最簡單是實現邏輯是將使能信號直接與時鐘信號做“與”操作,但這樣是不安全的,容易出現毛刺現象。 詳細門控時鐘介紹請參考《6.4 RTL 級低功耗設計(下)》。
雙邊沿時鐘
某些模塊可以在時鐘的上升沿和下降沿都進行數據傳輸,達到速率增倍的效果。
DDR (Double Data Rate) SDRAM 是典型的采用雙邊沿傳輸數據的例子。
典型 DDR 數據傳輸示意圖如下。
下面對時鐘雙邊沿傳輸數據的行為進行一個簡單的仿真。
基本設計思路是,利用時鐘雙邊沿對數據進行讀取,然后通過與時鐘相反的片選信號對數據進行選擇輸出,完成數據在時鐘雙邊沿的傳輸。
Verilog 代碼描述如下 。
module double_rate(
input rstn ,
input clk,
input csn,
input [7:0] din,
input din_en,
output [7:0] dout,
output dout_en);
//capture at posedge
reg [7:0] datap_r ;
reg datap_en_r ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
datap_r <= 'b0 ;
datap_en_r <= 1'b0 ;
end
else if (din_en) begin
datap_r <= din ;
datap_en_r <= 1'b1 ;
end
else begin
datap_en_r <= 1'b0 ;
end
end
//capture at negedge
reg [7:0] datan_r ;
reg datan_en_r ;
always @(negedge clk or negedge rstn) begin
if (!rstn) begin
datan_r <= 'b0 ;
datan_en_r <= 1'b0 ;
end
else if (din_en) begin
datan_r <= din ;
datan_en_r <= 1'b1 ;
end
else begin
datan_en_r <= 1'b0 ;
end
end
assign dout = !csn ? datap_r : datan_r ;
assign dout_en = datan_en_r | datap_en_r ;
endmodule
testbench 描述如下,其中雙邊沿數據傳輸模塊的時鐘頻率為 100MHz,但輸入的數據速率為 200MHz。
`timescale 1ns/1ps
module test ;
reg clk_100mhz, clk_200mhz ;
reg rstn ;
reg csn ;
reg [7:0] din ;
reg din_en ;
wire [7:0] dout ;
wire dout_en ;
always #(2.5) clk_200mhz = ~clk_200mhz ;
always @(posedge clk_200mhz)
clk_100mhz = ~clk_100mhz ;
initial begin
clk_100mhz = 0 ;
clk_200mhz = 0 ;
rstn = 0 ;
din = 0 ;
din_en = 0 ;
csn = 0 ;
//start work
#11 rstn = 1 ;
@(negedge clk_100mhz) ;
din_en = 1 ;
#0.2 ;
csn = 1 ; //csn=1 時輸出下降沿采集的數據
//generate csn
forever begin
@(posedge clk_100mhz) ;
#0.2 ; //增加些許延遲確保數據采集正確
csn = 0 ; //csn=0 時輸出上升沿采集的數據
@(negedge clk_100mhz) ;
#0.2 ;
csn = 1 ; //csn=1 時輸出下降沿采集的數據
end
end
always @(negedge clk_200mhz) begin
din <= {$random()} % 8'hFF ; //產生傳輸的隨機數據
end
double_rate u_double_rate(
.rstn (rstn),
.clk (clk_100mhz),
.csn (csn),
.din (din),
.din_en (din_en),
.dout (dout),
.dout_en (dout_en));
initial begin
forever begin
#100;
if ($time >= 10000) $finish ;
end
end
endmodule
前幾個數據的仿真結果如下。
由圖可知,數據傳輸正常,且速率為時鐘頻率的 2 倍。
本次只是對時鐘雙邊沿傳輸數據進行簡單的仿真,并不是仿真 DDR 的工作原理。 DDR 雙倍速率傳輸數據的工作原理遠比此次仿真復雜的多。
但是一般情況下,不建議使用雙邊沿時鐘邏輯,主要有以下幾點原因。
always 塊中,不能同時使用上升沿和下降沿作為敏感列表,也不能在 2 個always 塊中為同一個變量賦值,例如下列描述就是錯誤的。 雖然 RTL 編譯可能不會報錯,但也不能綜合成實際電路。 這就導致了信號間通信的難度。
always @(posedge clk or negedge clk) begin
數據傳輸速率是數據時鐘頻率的兩倍,如果使用時鐘上升沿和下降沿邏輯進行 RTL 建模,則還需要翻轉速率和時鐘一致的片選信號; 如果不使用片選信號,模塊內應該引入數據時鐘頻率 2 倍的同源時鐘信號,才可以正常對數據進行選擇。
當使用的雙邊沿時鐘邏輯之后,需要對上升沿和下降沿都進行合理的約束。 時鐘約束就會變得復雜,布局布線要求更加嚴格,調試難度增加。
使用時鐘雙邊沿進行設計,要求時鐘的質量很高,設計時鐘樹時也需要考慮眾多因素。
-
反饋電路
+關注
關注
11文章
146瀏覽量
37167 -
振蕩器
+關注
關注
28文章
3814瀏覽量
138912 -
振蕩電路
+關注
關注
17文章
501瀏覽量
98724 -
時鐘
+關注
關注
10文章
1721瀏覽量
131377 -
時鐘源
+關注
關注
0文章
93瀏覽量
15938
發布評論請先 登錄
相關推薦
評論