目錄
(1)什麼情況下,時鐘應該「上樹」?
(2)如何選擇時鐘樹?
(3)時鐘訊號如何「上樹」?
(4)被「拉下樹」的時鐘訊號
上篇博文:時鐘域問題簡介,介紹了時鐘域的相關知識,形象的說就是時鐘訊號的「勢力」範圍,它通過時鐘樹的形式實現。
時鐘樹不僅可以做到高扇出,還可以做到讓時鐘訊號到達各個觸發器的時刻盡可能一致,也即保證時鐘訊號到達時鐘域內不同觸發器的時間差最小。
這篇博文進一步說時鐘樹的問題,我們知道了時鐘樹的這麼強大的功能,好處這麼多,那麼怎麼使用時鐘樹,我什麼時候使用到了時鐘樹呢?
如果乙個時鐘訊號是為fpga內部的一些邏輯資源提供「脈搏」的,那麼強烈建議該時鐘「上樹」;
如果時鐘訊號的時鐘域實在太小,例如僅控制若干個觸發器,那麼也許不利用時鐘樹,fpga設計也可能通過時序分析,但是仍然建議使用時鐘樹;
如果時鐘訊號的時鐘域只包括乙個觸發器,那麼也就不存在所謂的時間差了,此時就完全不需要時鐘樹;
如果乙個時鐘訊號僅僅是為fpga外部的硬體電路提供時鐘激勵的,那麼外部無論有多少個儲存單元需要使用該時鐘,都沒必要使用時鐘樹,因為fpga內部的時鐘樹無法延伸到fpga晶元外部。
上篇博文提到了時鐘樹的型別,分為全域性時鐘樹、區域性時鐘樹和io時鐘樹。那麼具體來說,如果需要使用時鐘樹,該為時鐘選擇哪一類時鐘樹呢?
也許自覺會這麼告訴自己,時鐘域大的,選擇全域性時鐘樹;時鐘域小的,選擇區域時鐘樹;時鐘域特別小,選擇io時鐘樹。
事實告訴你,自覺是完全錯誤的。
io時鐘樹分布在fpga的介面資源中,由於它們離io管腳最近,所以可以協助fpga完成一些較高速率的序列資料接收,再經過簡單地串並轉換之後,以比較低的速率將並行資料丟進fpga晶元的內部,供其他資源使用。一般來說,每個io bank內部會有若干個io時鐘樹的資源,因此io時鐘樹雖然覆蓋範圍小,但並不是為小規模的時鐘域量身定做的,因此fpga內部的資源也無法使用該時鐘樹。
再看全域性時鐘樹,由於全域性時鐘樹可以覆蓋到整個fpga晶元,因此全域性時鐘樹的個數也十分有限,因此使用一定要謹慎,不可濫用。但是如果你硬著頭皮省下來一堆全域性時鐘樹,結果卻閒置在一邊,不派上用場,那簡直就是浪費時間,白花心思。因此,全域性時鐘樹這樣的資源,不可濫用,也不可不用,要充分利用。
因此,在全域性時鐘樹不緊缺的情況下,無論時鐘域的大小,統一建議使用全域性時鐘樹,因此這樣也能給編譯器提供最大的布局佈線自由度,從而讓時序約束更容易實現。
最後來看區域時鐘樹。老實說,區域時鐘樹覆蓋範圍也是相當的大,最大可能能到fpga晶元的幾分之一,因此如果時鐘域不是特別大,到底使用全域性時鐘樹還是區域時鐘樹,其實沒有乙個確定的結論。不過如果不是全域性時鐘樹資源不夠用,一般不建議使用區域時鐘樹。當然了,使用區域時鐘樹可以讓時鐘域中資源的分布在物理上更緊湊一些,並且有些功能是必須使用區域時鐘樹和io時鐘樹配合來完成的,因此請注意相關功能的說明。
最後總結下,io時鐘樹用於io介面的串並轉換,不可用於fpga內部時鐘域。
全域性時鐘樹,可以覆蓋到整個fpga晶元,在全域性時鐘樹不緊缺的情況下,盡量使用全域性時鐘樹,可以給編譯器提供最大的布局佈線自由度,讓時序約束更容易實現。
區域性時鐘樹,特定情況下可能又用途,但全域性時鐘樹不緊缺的情況下,建議使用全域性時鐘樹。
1)使用全域性時鐘樹資源
方法一,通過正確的物理連線。
如果時鐘訊號是由fpga晶元外部產生的,那麼我們可以不通過程式設計就可以實現時鐘樹資源的分配。
因為在fpga晶元的外圍管腳中,有一些專門為全域性時鐘設計的管腳,這點我們可以通過相應的fpga晶元的資料手冊來確認,如果在製作電路板時,直接將外部時鐘訊號通過這些管腳接入fpga內部,那麼它將自動佔據全域性時鐘樹資源。當然了,這些管腳也可以接入普通的資料訊號,編譯器會對該管腳引入的訊號在fpga設計內部扮演的角色進行分析,如果發現其並沒有作為時鐘訊號來使用,那麼將不會為其分配時鐘樹資源。
方法二,通過恰當的**描述。
如果很不巧,外部的時鐘訊號(外部時鐘)沒有通過專用的全域性時鐘管腳連線到fpga內部,又或者某乙個時鐘訊號是fpga內部產生(再生時鐘)的,例如fpga內部pll的輸出,那麼此時就需要通過編寫程式來完成時鐘的「上樹」工作了。有些時候,即使不使用**顯示指定,編譯器也會根據**的分析結果,來為時鐘訊號分配全域性時鐘資源。不過這種靠「天」吃飯的思想不可取,fpga工程師一定要讓fpga晶元盡可能的處於自己,而不是編譯器的掌控之下,因此強烈建議通過自己的**來指明時鐘樹的使用。
那麼具體要怎麼通過hdl**來實現時鐘樹資源的分配呢?答案就是使用原語。
由於原語是跟fpga晶元的生產廠商息息相關的,因此同乙個功能的原語在不同的編譯器中的名稱很可能大相徑庭,例如用於全域性時鐘樹分配的最主要的原語,xilinx公司叫它bufg,而altera公司卻稱其為global。
這裡,以xilinx公司的fpga產品為例,來介紹**的描述方法,其他公司的fpga產品方法類似,只不過需要替換原語的名稱罷了。
如果fpga內部有乙個名為innerclk的時鐘訊號,我們想為它分配乙個全域性時鐘樹,verilog hdl描述為:
wire globalclk;
bufg ontree(.o(globalclk), .i(innerclk));
按照上述hdl**描述以後,我們就可以在後續的邏輯功能中放心使用上樹後的innerclk——globalclk了。
實際上,直接從外部全域性時鐘管腳引入的時鐘訊號,相當於在hdl**中使用了ibufg + bufg原語。
除此之外,如果希望多個時鐘訊號分享乙個時鐘樹,也可以使用bugmux這個原語,相當於mux +bufg,例如,希望當前fpga設計中的某一部分邏輯其時鐘是可以在40hz和60hz之間切換的。
2)使用區域時鐘樹、io時鐘樹資源
與全域性時鐘管腳類似,fgpa晶元的外圍管腳中也有專門為區域時鐘和io時鐘設計的專有管腳,但是,光將時鐘訊號連線到這些管腳上,還並不一定能完成相應時鐘樹的使用,還必須要在**中顯式地進行描述才行。
以xilinx公司為例,使用原語bufio,將會為這些專用管腳上的訊號分配io時鐘樹資源,使用bufr,將會為這些專用管腳上的訊號分配區域時鐘樹資源。由於區域時鐘常配合io時鐘完成串並轉換,因此,bufr還具有神奇的分頻功能。最後,由於這兩個時鐘樹的覆蓋範圍並不是整個fpga晶元,所以在進行hdl**編寫時,也請注意資源的使用。
已經上樹的時鐘訊號,若不小心,也可能被拉下樹,因此,在hdl**編寫的時候,一定要避免這種情況。
是什麼導致時鐘訊號脫離了時鐘樹了呢?
通過前面的介紹,我們知道時鐘樹是由若干級緩衝器再加上一些近似等長的連線組成的,這也就是說,時鐘樹僅能對時鐘訊號起到乙個基本的傳遞作用,除此以外,別無它用。
因此,凡是相對時鐘樹上的時鐘訊號進行任何邏輯操作,來生成乙個新的訊號,那麼新的訊號已經不再位於時鐘樹上了(注意,原來的時鐘訊號仍在時鐘樹上)。如果希望新的訊號仍然作為時鐘來驅動一些邏輯,那麼必須重新呼叫相應原語來讓新的時鐘訊號獲得空閒的時鐘樹資源,所以,之前介紹的fpga內部生成的再生時鐘,門控時鐘,行波時鐘,如果需要使用,一定要先使用原語為它們分配好時鐘樹資源。
下面舉例說明,原始時鐘訊號被拉下樹以及在此上樹的過程:
// gclkontreea is on the clock tree
assign midclk0 = ~gclkontreea; // midclk0 is not on the clock tree
assign midclk1 = en & gclkontreea; // midclk1 is not on the clock tree
bufg reontree0(.o(gclkontreeb),.i(midclk0)); //gclkontreeb is on the clock tree
bufg reontree1(.o(gclkontreec),.i(midclk1)); //gclkontreec is on the clock tree
FPGA 時鐘簡介
在時序邏輯中,正是時鐘訊號將各個儲存單元中的資料一級一級地推動下去,如果時鐘訊號突然停止,那麼整個時序邏輯也將陷入癱瘓,因此,時鐘就好像時序邏輯的心跳一樣,那麼重要卻又平常的存在著。幾乎所有的fpga設計都是時序邏輯,就意味著幾乎所有的fpga設計都離不開時鐘,時鐘之於時序邏輯,好比空氣之於眾生。因...
關於FPGA的時鐘分頻問題
關於fpga的時鐘分頻問題 在fpga裡面,關於時鐘分頻,可以通過鎖相環來實現,但是,鎖相環的分頻系統受到一定的限制 根據所用的fpga晶元不同,所受到的限制也不一樣 不能隨心所欲的按照自己的想法來分頻。所以,我們可以自己寫乙個分頻的程式,當然,能夠達到分頻的效果,只是精度並沒有像pll的那麼高,但...
FPGA 時鐘分頻
時鐘訊號的處理是fpga的特色之一,因此分頻器也是fpga設計中使用頻率非常高的基本設計之一。一般在fpga中都有整合的鎖相環可以實現各種時鐘的分頻和倍頻設計,但是通過語言設計進行時鐘分頻是最基本的訓練,在對時鐘要求不高的設計時也能節省鎖相環資源。在本實驗中我們將實現任意整數的分頻器,分頻的時鐘保持...