之後的都只有我個人能看,想看的請支援單刀大佬。
主時鐘約束
主時鐘約束,就是我們對主時鐘(Primary Clock)的時鐘週期進行約束(告訴綜合工具佈局佈線的標準),這個約束是我們用的最多的約束了,也是最重要的約束。
主時鐘必須與一個網表物件相連,該物件代表了所有時鐘邊沿的開始點,並且在時鐘樹中向下傳遞;也可以說,主時鐘的源點定義了0時刻,Vivado靠此來計算時鐘延遲和不確定性 ;vivado會忽略所有時鐘樹上從主時鐘上游的單元到主時鐘之間的延時!
主時鐘通常有兩個來源:(1)板級時鐘(主要是晶振)透過輸入埠進入FPGA;(2)FPGA的GT收發器的輸出管腳(如恢復時鐘)。
主時鐘只能透過create_clock命令來定義,且必須放在約束的開始,這是因為其它時序約束幾乎都要參考主時鐘。其基本語法如下:
create_clock -name <clock_name> -period <period> -waveform {<rise_time><fall_time>} [get_ports <port_name>]
- -name: 由設計者指定的主時鐘名稱,用於標識定義的主時鐘,若不指定,則會預設使用<port_name>作為主時鐘名稱
- -period:是定義的主時鐘週期,單位ns,取值必須大於0
- -waveform :{<rise_time><fall_time>}分別代表時鐘的上升沿和下降沿,用於指定佔空比和時鐘相位,單位為ns;若不指定,則時鐘佔空比預設為50%且第一個上升沿為0時刻
- get_ports表示定義的主時鐘的物理節點是FPGA的物理引腳;而GT收發器的引腳則使用get_pins來定義
- 下面是一個50MHZ主時鐘的例子:
-
create_clock -period 20.000 -name I_Clk -waveform {0.000 10.000} [get_ports I_Clk]
例1:引腳輸入的主時鐘約束
下圖是一個從引腳sysclk進入FPGA的主時鐘,其時鐘週期為10ns,佔空比50%且不存在相移。
根據主時鐘約束的語法,其應該被約束為:
create_clock -period 10 [get_ports sysclk]
該語句定義了名為sysclk的物理節點產生的時鐘sysclk,其時鐘週期為10ns、佔空比為50%(沒有定義時的預設佔空比)。需要注意的是,這個例項省去了主時鐘的名稱,以及省去了用 -waveform引數來描述其佔空比與相位關係。
類似的,假設有一個外部時鐘devclk透過ClkIn進入FPGA作為主時鐘,其週期為10ns,佔空比25%,相移90度。該時鐘根據語法應該被約束為:
create_clock -name devclk -period 10 -waveform {2.5 5} [get_ports ClkIn]
該語句定義了名為ClkIn的物理節點產生的時鐘devclk ,其時鐘週期為10ns、佔空比為50%,第一個上升沿在時刻2.5ns而第一個下降沿則在時刻5ns。
例2:高速收發器GT的恢復時鐘
時鐘源由高速收發器gt0提供,如下圖所示:
進入FPGA,之後經過混合時鐘管理單元MMCM生成其他時鐘,
以gt0發出的時鐘為主時鐘,其他生成時鐘都有一個共同的時鐘源,使用如下命令定義:
create_clock -name rxclk -period 3.33 [get_pins gt0/RXOUTCLK]
該語句定義了名為gt0/RXOUTCLK的物理節點產生的時鐘rxclk,其時鐘週期為3.33ns、佔空比為50%(預設情況下的佔空比)。
(使用PLL/CLOCK WIZARD 接入外界輸入的時鐘來保障穩定是一個常用的做法)
例3:差分時鐘約束
差分時鐘是指時鐘是以差分形式(P端與N端)一起進入FGPA的時鐘,
比如差分晶振等,這種情況只需要約束差分時鐘的P端即可,N端可以被vivado自動識別到。
如果同時約束了正、負兩端,反而會導致未知錯誤。
像上圖這種差分時鐘就可以這樣約束(僅約束了P端):
create_clock -name sysclk -period 3.33 [get_ports SYS_CLK_clk_p]
MIPI里約束差分時鐘的方法:
IBUFDS #(.IOSTANDARD ("LVDS_25")) ibufds_clk_inst (.I ( I_Mipi_phy_clk_p ), .IB ( I_Mipi_phy_clk_n ), .O ( Bufd_CLK )); // High Speed BUFIO clock buffer BUFIO bufio_inst (.O ( Buff_Clk ), .I ( Bufd_CLK ));