怎么通過域名做網(wǎng)站年度關鍵詞有哪些
基本時序參數(shù)
圖1.1??D觸發(fā)器結構
圖1.2 ?D觸發(fā)器時序
時鐘clk采樣數(shù)據(jù)D時,Tsu表示數(shù)據(jù)前邊沿距離時鐘上升沿的時間,MicTsu表示時鐘clk能夠穩(wěn)定采樣數(shù)據(jù)D的所要求時間,Th表示數(shù)據(jù)后邊沿距離時鐘上升沿的時間,MicTh表示時鐘clk采樣到數(shù)據(jù)D后,數(shù)據(jù)D仍然需要保持時間。時鐘clk采樣到數(shù)據(jù)D后輸出,MicTco表示時鐘clk上升沿距離數(shù)據(jù)Q輸出達到穩(wěn)定的時間。
寄存器的時序分析是最基本的時序分析,對于實際邏輯電路約束中還需要考慮其它參考因素,包含延時、抖動等等。由于實際電路時序約束并直接針對寄存器本身,因為寄存器本身時序MicTsu/MicTh/MicTco是相對固定的,但是端口與寄存器之間的路徑或寄存器之間的路徑,因為距離不同存在不同的延遲,該部分延時導致端口上實際的采樣信號與到達寄存器后的時序特性存在差異,這樣我們就需要對端口處的時序特性進行約束,以保證端口上的信號到達寄存器后,能夠滿足寄存器的采樣要求。信號從端口到寄存器的結構圖如下:
圖1.3 ?基本接口電路時序分析及時序參數(shù)
如上圖所示,第一級寄存器處,由于存在data delay1和clk delay1,那么對于端口上的數(shù)據(jù)和時鐘的時序要求相對于與寄存器處的時序要求有所區(qū)別,保證端口約束后,經(jīng)過一段延遲到達寄存器時能夠滿足寄存器的時序要求。
幾個術語:
??源時鐘?(source clock) 也稱為發(fā)送時鐘?(launch clock)。
??目標時鐘?(destination clock) 也稱為捕獲時鐘?(capture clock)。
- 發(fā)送沿?(launch edge) 表示發(fā)送數(shù)據(jù)的源時鐘的處于活動狀態(tài)的時鐘沿。
??捕獲沿?(capture edge) 表示捕獲數(shù)據(jù)的目標時鐘的處于活動狀態(tài)的時鐘沿。
??建立要求?(setup requirement) 表示定義最嚴格的建立約束的發(fā)送沿與捕獲沿之間的關系。
??建立關系?(setup relationship) 表示經(jīng)時序分析工具驗證的建立時間檢查。
??保持要求?(hold requirement) 表示定義最嚴格的保持約束的發(fā)送沿與捕獲沿之間的關系。
??保持關系?(hold relationship) 表示經(jīng)時序分析工具驗證的保持時間檢查。
端口建立時間Tsu
對于端口Tsu有:Tsu?= data delay1 – clk delay1 + MicTsu
端口建立時間時序:
圖1.4??端口建立時間
上圖clk_delay以及data_delay對應圖1.3中的clk_delay1和data_delay1 input,可見時鐘延遲越小,數(shù)據(jù)延遲越大,對建立時間要求越大,即建立時間決定了數(shù)據(jù)到達的最大延遲,也決定了時鐘最高頻率。因此在進行set input delay約束時,-max(對setup分析)使用使用最小時鐘延遲和最大數(shù)據(jù)延遲(后面會具體講怎么約束)。
建立時間計算示例如下圖,圖上有兩個建立時間setup(1)和setup(2):
Setup(1) = 1*Tclk1 – 0*Tclk0 = 4ns
Setup(2) = 2*Tclk1 – 1*Tclk0 = 2ns,setup(2)最小2ns,詳細計算如下:
源時鐘發(fā)數(shù)沿時間:0ns + 1*Tclk0 = 6ns;
目的時鐘采數(shù)沿時間:0ns + 2*Tclk1 = 8ns;
建立時間=采數(shù)沿時間 – 發(fā)數(shù)沿時間 =?8?– 6?=?2ns,這里有兩個假設,時鐘是理想的,兩個時鐘初始相位對齊的。
圖1.5??建立時間示例
端口保持時間Th
對于端口Th有:Th?= clk delay1 – data delay1 + MicTh
圖1.6 ?端口保持時間
上圖clk_delay以及data_delay對應圖1.3中的clk delay1和data?delay1 input,可見時鐘延遲越大,數(shù)據(jù)延遲越小,對保持時間要求越大,即保持時間決定了數(shù)據(jù)最早到達的時間。因此在進行set input delay約束時,-min(對hold分析)使用使用最大時鐘延遲和最小數(shù)據(jù)延遲(后面會具體講怎么約束)。
保持時間計算實例如下圖,從圖上可以看出,對于每個建立時間有兩個保持時間要求:第一,requirement(a):前一個采數(shù)沿減去當前發(fā)數(shù)沿;第二,requirement(b):當前采數(shù)沿減去后一個發(fā)數(shù)沿。
對于setup(1):
H1a?= (1-1)*Tclk1 – 0*Tclk0 = 0ns
H1b =?1*Tclk1 – (0+1)Tclk0 = -2ns
對于setup(2):
H2a =?(2-1)*Tclk1 – 1*Tclk0 = -2ns
H2b =?2*Tclk1 – (1+1)*Tclk0 = -4ns
圖1.7??保持時間示例
端口輸出時間Tco
對于端口Tco有:Tco = clk delay2 + data delay3 + MicTco
圖1.8 ?端口輸出時間
上圖clk delay及data delay對于圖1.3中的clk delay2和data delay3 output.
時鐘偏差(skew)
時鐘偏差表示同一時鐘到達不同寄存器的時鐘端的時鐘延遲差,如圖1.3所示,對于skew有:skew = clk delay1 – clk delay2或者skew = clk delay2?– clk delay1,可見skew可以是正值,也可以是負值。
時序分析
從路徑上看,時序分析可以分4類:
(1)輸入端口到內部時序元件路徑:由外部器件出發(fā)輸出數(shù)據(jù),經(jīng)過一段延遲(Input Delay)后進入芯片,再經(jīng)過器件內部邏輯到達時序元件后,被目的時鐘采樣。
(2)內部時序元件到內部時序元件路徑:數(shù)據(jù)在芯片內部的時序元件被源時鐘觸發(fā),經(jīng)過內部邏輯時序元件后被目的時鐘采樣。
(3)內部時序元件到輸出端口路徑:數(shù)據(jù)在芯片內部的時序元件被源時鐘觸發(fā),經(jīng)過器件內部邏輯到達芯片輸出端口,經(jīng)過一段延遲后(Output Delay)被外部器件采樣。
(4)輸入端口到輸出端口路徑:數(shù)據(jù)從輸入端口到輸出端口沒有被寄存過的路徑。
其中內部時序元件到內部時序元件路徑工具分析的基礎,其它3類殊途同歸,下面以第2類講下建立時間和保持時間分析。另外可以把每個時鐘沿的鄰域劃分出一個數(shù)據(jù)保持穩(wěn)定窗口,在數(shù)據(jù)保持穩(wěn)定窗口是不允許數(shù)據(jù)跳變的,這就是時序分析的基礎。
建立時間Tsu時序分析
時鐘建立檢查確保在當前發(fā)送沿(Current launch edge),源寄存器發(fā)送的數(shù)據(jù),能夠在當前捕獲沿(Current capture edge)被目標寄存器正確捕獲。時序分析工具使用最長路徑確定目標寄存器的數(shù)據(jù)到達時間,使用最短路徑確定目標寄存器的時鐘到達時間,分析時鐘到達時間與數(shù)據(jù)到達時間之差是否大于或等于寄存器固有建立時間(Micro Tsu),即Clock Arrival Time – Data Arrival Time >= Micro Tsu .
圖1.9 ?建立關系分析
Data Required?Time?(setup) =?捕獲沿時間?(capture edge time) ?+ 最小目標時鐘路徑延遲?(destination clock path min delay)- 時鐘不確定性?(clock uncertainty)- 建立時間?(Micro Tsu);
Data Arrival Time?(setup) =?發(fā)送沿時間?(launch edge time)?+ 最長源時鐘路徑延遲?(source clock path max delay) + MicroTco + 最長數(shù)據(jù)路徑延遲?(datapath max delay);
建立時間裕量?(Clock Setup Slack) =?數(shù)據(jù)必需時間?(Data Required Time) - 數(shù)據(jù)到達時間?(Data Arrival Time)
如上述公式所示,當數(shù)據(jù)到達時間早于必需時間時,建立裕量為正值。恢復檢查類似于建立檢查,但它適用于異步管腳(如預置或清除)。恢復關系方式與建立相同,裕量公式也相同(只是使用恢復時間取代建立時間)。
保持時間Th時序分析
時鐘保持檢查是確保在當前發(fā)送沿(Current launch edge),源寄存器發(fā)出的數(shù)據(jù),在目標寄存器不會被前一個捕獲沿(Previous capture edge)采到;并且下一個發(fā)送沿(Next launch edge),源寄存器發(fā)出的數(shù)據(jù),在目標寄存器不會被當前捕獲沿(Current capture edge)采到(如圖1.7中, setup(1)對應的H1a和H1b或setup(2)對應的H2a和H2b)。時序分析工具使用最短路徑確定目標寄存器的數(shù)據(jù)到達時間,使用最長路徑確定目標寄存器的時鐘到達時間,分析時鐘到達時間與數(shù)據(jù)到達時間之差是否大于或等于寄存器的固有保持時間(Micro?Th),即Data Arrival Time??-?Clock Arrival Time >= Micro Th。需要注意保持時間分析是數(shù)據(jù)到達時間減去時鐘到達時間,而建立時間分析是時鐘到達時間減去數(shù)據(jù)到達時間。
?
圖1.9 ?保持關系分析
當路徑要求已知后,即可引入路徑延遲、時鐘不確定性和保持時間以計算裕量。典型裕量公式為:
Data Required Time (hold)= 捕獲沿時間?(capture edge time) + 最長目標時鐘路徑延遲?(longest destination clock path delay)?+ 時鐘不確定性?(clock uncertainty)??+ 保持時間(hold time);
Data Arrival Time (hold)= 發(fā)送沿時間?(launch edge time) + 最短源時鐘路徑延遲?(shortest source clock path delay) + 最短數(shù)據(jù)路徑延遲?(shortest data path delay);
保持時間裕量?(Clock Hold?Slack?)= 數(shù)據(jù)到達時間?(Data Arrival Time) - 數(shù)據(jù)必需時間?(DataRequired Time)
?
如上述公式所示,當新數(shù)據(jù)到達時間晚于必需時間時,保持裕量為正值。移除檢查類似于保持檢查,但它適用于異步管腳(如預置或清除)。關系建立方式與保持相同,裕量公式也相同(只是使用移除時間取代保持時間)。
在芯片pre-CTS (前時鐘樹綜合)的過程中, setup建立時間的不確定性:包含系統(tǒng)時鐘的影響(即時間抖動jitter)和時鐘偏移(即skew)帶來的影響。hold保持時間的不確定性只會由時鐘偏移(skew)決定。(如果前后寄存器是同一個時鐘,那么保持時間分析的捕獲沿和啟動沿是同一個沿,jitter是一致的,只用考慮skew;建立時間分析的捕獲沿和啟動沿是前、后兩個沿,jitter是不一樣的,skew和jitter都要考慮)。
在芯片post-CTS (后時鐘樹綜合)的過程中,時鐘樹已經(jīng)被綜合,時鐘樹的偏移已經(jīng)明確。setup建立時間的不確定性包含系統(tǒng)時鐘的影響(即時間抖動jitter)帶來的影響。hold保持時間不受系統(tǒng)時鐘影響。
時序約束
我們先看下邏輯開發(fā)流程,如圖。時鐘方案決定了整個工程的時鐘網(wǎng)絡,是后端實現(xiàn)的關鍵部分。代碼約束是針對當前設計的實現(xiàn)進行限制的約束要求,比如異步處理的打拍寄存器,我們期望這些寄存器必須使用寄存器實現(xiàn),不能插入組合邏輯,走線足夠近,而不能用移位寄存器實現(xiàn)。在vivado工具時,可以代碼中在寄存器前添加(*ASYNC_REG = “true” *)約束,例如:
(*ASYNC_REG = “true” *)reg bist_en_dly;
(*ASYNC_REG = “true” *)reg bist_en_2dly;
當然不同的工具其代碼約束語法不同,類似約束還有最大扇出約束、寄存器保留約束等。
物理約束和時序約束是指導工具實現(xiàn)后端的關鍵輸入,包含管腳約束,位置約束,時鐘約束,內部時序要求等,后面會重點講時序約束。
綜合,布局布線是最后的后端實現(xiàn),器件和工具版本,設置等的配合都可能較大的差異,所以需要提前了解相應的器件和優(yōu)選的工具版本及選型設置。
FPGA開發(fā)流程
時序約束的關系
時序約束有3大部分:時鐘約束、IO接口input/output delay約束、例外約束,三者分工如下,后面以約束命令為例詳細講解。
在約束時,一定先需要了解網(wǎng)表中的一些專用術語,如下表:
舉例如下:
時鐘約束
create_clock
基準時鐘是指用于為設計定義時序參考的時鐘,而時序引擎可利用基準時鐘衍生出時序路徑要求以及與其他時鐘的相位關系。主時鐘插入延遲的計算范圍是從時鐘源點(用于定義時鐘的驅動管腳/端口)到時序單元(作為時鐘扇出目標)的時鐘管腳。因此,重要的是在對應于設計邊界的對象上定義基準時鐘,以便準確計算其延遲并間接計算其偏差。用create_clock 定義的基準時鐘的起點即時序的“零起點” ,在這之前的上游路徑延時都被工具自動忽略。管腳輸入時鐘,聲明了時鐘周期,對應上下沿相位關系。時鐘的定義也遵從Tcl 的一般優(yōu)先級,即:在同一個點上,由用戶定義的時鐘會覆蓋工具自動推導的時鐘,且后定義的時鐘會覆蓋先定義的時鐘。若要二者并存,必須使用-add 選項。
Command: create_clock
Options :
[-name <clock_name>]
-period <time>
[-waveform {<rise_time> <fall_time>}]
[<targets>]
[-add]
create_clock –period 20.0 –name clk_50 [get_ports clk_in]
create_clock –period 10.0 –waveform {2.0 8.0} [get_ports sysclk]
create_clock -name txclk -period 6.667 [get_pins gt0/TXOUTCLK]
建議:對于面向?7 系列器件的設計,xilinx還建議定義 GT 輸入時鐘,因為 Vivado 工具會計算 GT 輸出管腳上期望的時鐘,并將這些時鐘與用戶創(chuàng)建的時鐘進行比較。如果時鐘不同或者到?GT 的輸入時鐘丟失,工具會發(fā)出方法論檢查警告。但值得注意的是,如果時鐘輸入管腳是差分時鐘,那么在P端約束即可。如果在P/N輸入上都創(chuàng)建主時鐘,將導致過約束,產(chǎn)生不符合實際的CDC路徑。
create_clock -name sysclk -period 3.33 [get_ports SYS_CLK_clk_p]
重要提示!在基準時鐘傳遞扇出中不應定義另外?1 個基準時鐘,因為這種情況不但不符合任何硬件現(xiàn)實,還會妨礙完整的時鐘插入延遲計算,從而阻礙正確的時序分析。如果發(fā)生這種情況,必須重新修改并修正約束。下圖顯示的示例中,時鐘?clk1 是在時鐘 clk0 的傳遞扇出中定義的。時鐘 clk1 會從 BUFG1 輸出開始覆蓋此輸出處所定義的?clk0。因此,由于 clk0 與 clk1 之間skew,導致 REGA 與 REGB 之間的時序分析并不準確(不建議在另一個時鐘的扇出中使用?create_clock)。
creat_generated_clock
生成時鐘?(generated clock) 是從先有的主時鐘 (master clock) 衍生的,它通常用于描述對主時鐘執(zhí)行的波形變換。由于生成時鐘定義取決于主時鐘特性,因此必須首先定義主時鐘。為顯式定義生成時鐘,必須使用create_generated_clock 命令。create_generated_clock能夠定義設計中內部生成的時鐘的屬性和約束,可以為修改時鐘信號任何節(jié)點的屬性,重新定義生成的時鐘,包括修改相位,頻率,偏移或占空比,同時能夠保留主時鐘的屬性,如uncertainty等。生成的時鐘最常應用于PLL的輸出,寄存器時鐘分頻器,時鐘多路復用器。
自動衍生時鐘:大部分生成時鐘都是由?Vivado 時序引擎自動衍生的,該引擎可識別時鐘修改塊 (CMB) 及其對主時鐘執(zhí)行的變換。
在?xilinx?7 系列器件中,CMB 包括:
??MMCM*/PLL*
??BUFR
??PHASER*
在?xilinx UltraScale 系列器件中,CMB 包括:
??MMCM*/PLL*
??BUFG_GT/BUFGCE_DIV
??GT*_COMMON/GT*_CHANNEL/IBUFDS_GTE3
??BITSLICE_CONTROL/RX*_BITSLICE
??ISERDESE3
對于時鐘樹上的任何其他組合單元而言,時序時鐘可通過這些單元進行傳輸,且無需在輸出端重新定義,除非此類單元已進行波形變換。
Command: create_generated_clock
Options
[-name <clock_name>]
-source <master_pin>
[-master_clock <clock_name>]
[-divide_by <factor>]
[-multiply_by <factor>]
[-duty_cycle <percent>]
[-invert]
[-phase <degrees>]
[-edges <edge_list>]
[-edge_shift <shift_list>]
[<targets>]
[-add]
create_generated_clock –name clk_div \
–source [get_pins inst|clk] -divide_by 2 [get_pins inst|regout]
create_clock –period 10 [get_ports clk_in]
create_generated_clock –name pulse_clk_out -source clk_in \
–edges {1 4 5}?[get_pins pulse_logic|out]
edges編號為1...<n>,在列表中,第一個數(shù)字對應于生成時鐘的第一個上升沿,第二個數(shù)字是第一個下降沿,第三個數(shù)字是第二個上升沿。因此,產(chǎn)生了占空比為75%的源周期的一半的時鐘。
create_clock –period 10 [get_ports clk_in]
create_generated_clock –name pulse_clk_out -source clk_in \
–edges {1 4 5} -edge_shift {2.5 2.5 0}?[get_pins pulse_logic|out]
與上一個示例相同,不同之處在于-edge_shift移動每個邊緣指示的時間量。
set_clock_uncertainty
clock uncertainty包括Clock jitter、skew?、Phase error和自定義的uncertainty。對于FPGA,抖動特性是可預測的;它們可以由Vivado IDE?時序引擎自動計算,也可以單獨指定。對于由MMCM或PLL驅動的衍生時鐘,輸入抖動被計算的離散抖動代替。對于生成的時鐘由組合或時序單元創(chuàng)建的情況,生成的時鐘抖動與其主時鐘抖動相同。
如果需要在某個時鐘的時序路徑上或?2 個時鐘之間的時序路徑上添加額外裕度,必須使用set_clock_uncertainty 命令。這也是對部分設計進行過約束而不必修改實際時鐘沿和總體時鐘關系的最佳且最安全的途徑。定義的時鐘不確定性是在綜合工具計算所得抖動的基礎上附加的,并且可為建立時間和保持時間分析單獨指定此不確定性。
Command: set_clock_uncertainty
?Use to model jitter, guard band, or skew
??Allows generation of clocks that are non-ideal
?Options
??[-setup | -hold]
??[-fall_from <fall_from_clock>]
??[-fall_to <fall_to_clock>]
??[-from <from_clock>]
??[-rise_from <rise_from_clock>]
??[-rise_to <rise_to_clock>]
??[-to <to_clock>]
??<value>
例如,設計時鐘?clk0 的所有時鐘間路徑上的裕度需收緊,幅度為 500 ps,以使設計更穩(wěn)健,承受建立時間和保持時間噪聲的能力更強(可以使用250 ps的setup uncertainty和250 ps的hold?uncertainty):
set_clock_uncertainty -from clk0 -to clk0?-setup?0.2500
set_clock_uncertainty -from clk0 -to clk0?-hold?0.2500
Setup uncertainty會減少setup分析的data require time,Hold uncertainty 會增加?hold分析的data required time。
注釋:收緊設計上的保持時間裕度可能導致專用站點內部路徑和級聯(lián)路徑上出現(xiàn)保持時間違例,并且布線器無法通過繞行站點內部信號線來解決此類違例。
如果在?2 個時鐘之間指定額外的不確定性,那么必須應用雙向約束(假定數(shù)據(jù)流為雙向)。以下示例演示了如何在clk0 和 clk1 之間僅針對建立時間將不確定性增加 250 ps:
set_clock_uncertainty -from clk0 -to clk1 0.250 -setup
set_clock_uncertainty -from clk1 -to clk0 0.250 -setup
IO約束
用于IO約束的命令包括set_input_delay/set_output_delay和set_max_delay/set_min_delay。其中,只有那些從芯片管腳進入,一直到芯片管腳輸出,中間都不經(jīng)過任何時序元件的純組合邏輯路徑,可以使用set_max_delay/set_min_delay來約束,其余I/O時序路徑都必須由set_input_delay/set_output_delay來約束。
set_max_delay –from [get_ports in1] –to [get_ports out*] 5.0
set_max_delay –from [get_ports in2] –to [get_ports out*] 7.5
set_max_delay –from [get_ports in3] –to [get_ports out*] 9.0
set_min_delay –from [get_ports in1] –to [get_ports out*] 1.0
set_min_delay –from [get_ports in2] –to [get_ports out*] 2.0
set_min_delay –from [get_ports in3] –to [get_ports out*] 3.0
如果對FPGA的I/O不加任何約束,vivado會缺省認為時序要求為無窮大,不僅綜合和時序不會考慮I/O時序,而且時序分析時也不會報這些未約束的路徑。
Input Delay
Input Delay用來表示芯片輸入接口的數(shù)據(jù)和其參考時鐘之間的相位關系。因為工具本身不知道芯片輸入接口的時序(上游器件輸出),所以需要我們通過input delay告訴工具,在芯片IO入口,數(shù)據(jù)與時鐘的相對相位關系。Input Delay和Output Delay都需要考慮系統(tǒng)同步和源同步兩種方式。
系統(tǒng)同步接口
對系統(tǒng)同步接口做input約束相對容易,只需要考慮上游器件的Tco和數(shù)據(jù)在板級的時延即可。下圖是一個SDR上升沿采樣系統(tǒng)同步接口的input約束示例。
約束FPGA中REG2的Tsu時延“-max”:
Input delay max = Tclk1(max) + Tco(max)+Tdata_Pcb(max)-Tclk2(min)
?= Tdata_Pcb(max) – (Tclk2(min) – Tclk1(max)) + Tco(max)
= Tdata_Pcb(max) – Tclk_skew(min)+ Tco(max)
約束FPGA中REG2的Th時延“-min”:
Input delay min = Tclk1(min) + Tco(min)+Tdata_Pcb(min)-Tclk2(max)
= Tdata_Pcb(min) – (Tclk2(max) – Tclk1(min)) + Tco(min)
= Tdata_Pcb(min) – Tclk_skew(max) + Tco(min)
一條完整的時序路徑,從源觸發(fā)器的Clk端開始,經(jīng)過Tco和路徑傳輸延時,再到目的觸發(fā)器的D端結束。放在系統(tǒng)同步的接口時序上,傳輸延時則變成板級傳輸延時(要考慮skew),所以上述-max后的數(shù)值是Tco的最大值加上板級延時的最大值而來,而-min后的數(shù)值是兩個最小值相加而來。
上面結果出現(xiàn)負值并不代表延時真的為負數(shù),而是跟數(shù)據(jù)相對于時鐘沿的方向有關。請一定要牢記set_input_delay中的“-max/min”的定義,即時鐘采樣沿到達之后最大與最小的數(shù)據(jù)有效窗口,如下圖所示。
源同步接口
為了改進系統(tǒng)同步接口中的時鐘頻率受限的弊端,一種針對高速I/O的同步時序接口應運而生,在發(fā)送端將數(shù)據(jù)和時鐘同步傳輸,在接收端用時鐘沿脈沖來對數(shù)據(jù)進行鎖存,重新使數(shù)據(jù)與時鐘同步,這種電路就是源同步接口電路(?Source Synchronous Interface )。
源同步接口最大的優(yōu)點就是大大提升了總線的速度,在理論上信號的傳送可以不受傳輸延遲的影響,所以源同步接口也經(jīng)常應用DDR 方式,在相同時鐘頻率下提供雙倍于SDR 接口的數(shù)據(jù)帶寬。源同步接口的約束設置相對復雜,一則是因為有SDR 、DDR 、中心對齊( Center Aligned )和邊沿對齊(?Edge Aligned )等多種方式,二者可以根據(jù)客觀已知條件,選用與系統(tǒng)同步接口類似的系統(tǒng)級視角的方式,或是用源同步視角的方式來設置約束。
如上圖所示,對源同步接口進行Input 約束可以根據(jù)不同的已知條件,選用不同的約束方式。一般而言,對于芯片輸入接口,數(shù)據(jù)有效窗口是已知條件,所以方法2 更常見。但不論以何種方式來設置Input 約束,作用是一樣,時序報告的結果也應該是一致的。
Datain相對于clkin的input delay(源同步理想情況下Tdata_PCB和Tclk_skew是一致的):
Input?delay max = Tdata_PCB(max) – Tclk_skew(min) + Tco(max)
??????????????= Tco(max)
Input?delay min = Tdata_PCB(min) – Tclk_skew(max) + Tco(min)
??????????????= Tco(min)
SDR接口的約束設置
針對上圖所示的對齊源同步SDR接口時序,分別按照兩種方式來約束,需要已知條件和計算方式雖然不同,卻可以得到完全一樣的結果。
?
DDR 接口的約束設置
DDR 源同步接口的約束稍許復雜,需要將上升沿和下降沿分別考慮和約束,以下以源同步接口為例,分別就輸入接口數(shù)據(jù)為中心對齊或邊沿對齊的方式來舉例。
方法一:Setup/Hold Based Method
圖 x DDR源同步中心對齊輸入接口
已知條件如下:
時鐘信號src_sync_ddr_clk 的頻率: 100 MHz
數(shù)據(jù)總線:?src_sync_ddr_din[3:0]
上升沿之前的數(shù)據(jù)有效窗口( dv_bre ) : 0.4 ns
上升沿之后的數(shù)據(jù)有效窗口( dv_are ) : 0.6 ns
下降沿之前的數(shù)據(jù)有效窗口( dv_bfe ) : 0.7 ns
下降沿之后的數(shù)據(jù)有效窗口( dv_afe ) : 0.2 ns
可以這樣計算輸入接口約束:?DDR 方式下數(shù)據(jù)實際的采樣周期是時鐘周期的一半;上升沿采樣的數(shù)據(jù)(?Rise Data )的-max 應該是采樣周期減去這個數(shù)據(jù)的發(fā)送沿(下降沿)之前的數(shù)據(jù)有效窗口值dv_bfe ,而對應的-min 就應該是上升沿之后的數(shù)據(jù)有效窗口值dv_are ;同理,下降沿采樣的數(shù)據(jù)( Fall Data )的-max應該是采樣周期減去這個數(shù)據(jù)的發(fā)送沿(上升沿)之前的數(shù)據(jù)有效窗口值dv_bre ,而對應的-min 就應該是下降沿之后的數(shù)據(jù)有效窗口值dv_afe 。
所以最終寫入XDC 的Input 約束應該如下所示:
set period 10.0;
create_clock -period $period -name clk [get_ports src_sync_ddr_clk];
set_input_delay -clock clk -max [expr $period/2 – 0.7] [get_ports src_sync_ddr_din[*]] ;
set_input_delay -clock clk -min 0.6 [get_ports src_sync_ddr_din[*]] ;
set_input_delay -clock clk –max [expr $period/2 – 0.4] \
[get_ports src_sync_ddr_din[*]] -clock_fall -add_delay ;
set_input_delay -clock clk -min 0.2 [get_ports src_sync_ddr_din[*]] -clock_fall -add_delay;
方法二:Skew Based Method
邊緣對齊是指時鐘和數(shù)據(jù)到達后級時序單元時,時鐘沿與數(shù)據(jù)變化沿重合,如圖所示(如IMX222視頻傳感器的的DDR)。
由于是隨路時鐘的關系,時鐘和數(shù)據(jù)極有可能同時達到FPGA的輸入端口,這樣很明顯不能滿足目的端寄存器的時序要求,通常的做法是通過邏輯或鎖相環(huán)對時鐘和數(shù)據(jù)的關系進行相位調整,這樣就能正確采集數(shù)據(jù)了,之后在以調整后的相位進行時序約束即可。
圖x?DDR 源同步邊沿對齊輸入接口
已知條件如下:
時鐘信號src_sync_ddr_clk 的頻率: 100 MHz
數(shù)據(jù)總線:?src_sync_ddr_din[3:0]
上升沿之前的數(shù)據(jù)skew (skew_bre ) : 0.6 ns
上升沿之后的數(shù)據(jù)skew (skew_are ) : 0.4 ns
下降沿之前的數(shù)據(jù)skew (skew_bfe ) : 0.3 ns
下降沿之后的數(shù)據(jù)skew (skew_afe ) : 0.7 ns
可以這樣計算輸入接口約束:因為已知條件是數(shù)據(jù)相對于時鐘上升沿和下降沿的skew ,所以可以分別獨立計算;上升沿的-max 是上升沿之后的數(shù)據(jù)skew (skew_are ) ,對應的-min 就應該是負的上升沿之前的數(shù)據(jù)skew (skew_bre ) ;下降沿的-max 是下降沿之后的數(shù)據(jù)skew (skew_afe ) ,對應的-min 就應該是負的下降沿之前的數(shù)據(jù)skew (skew_bfe ) 。
所以最終寫入XDC 的Input 約束應該如下所示:
create_clock -period 10.0 -name clk [get_ports src_sync_ddr_clk];
set_input_delay -clock clk -max 0.4 [get_ports src_sync_ddr_din[*]] ;
set_input_delay -clock clk -min -0.6 [get_ports src_sync_ddr_din[*]] ;
set_input_delay -clock clk -max 0.7 [get_ports src_sync_ddr_din[*]] -clock_fall -add_delay ;
set_input_delay -clock clk -min -0.3 [get_ports src_sync_ddr_din[*]] -clock_fall -add_delay;
出現(xiàn)負值并不代表延時真的為負,而是跟數(shù)據(jù)相對于時鐘沿的方向有關。請一定牢記set_input_delay 中-max/-min 的定義,即時鐘采樣沿到達之后最大與最小的數(shù)據(jù)有效窗口,切記切記!!( set_output_delay 中-max/-min 的定義與之正好相反,詳見后續(xù)章節(jié)舉例說明)。
Output Delay
Output Delay的定義:用來表示芯片輸出接口的數(shù)據(jù)與參考時鐘之間的相位關系。因為工具不知道芯片輸出接口的時序(下游器件輸入),所以需要我們通過output delay告訴工具,在芯片IO出口,數(shù)據(jù)與時鐘需要滿足的的相對相位關系。Output 的接口時序同樣也可以分為系統(tǒng)同步與源同步。在設置約束時,總體思路與Input 類似,只是換成要考慮下游器件的時序模型。
系統(tǒng)同步接口
與Input 的系統(tǒng)同步接口一樣, FPGA 做Output 接口的系統(tǒng)同步設計,芯片間只傳遞數(shù)據(jù)信號,時鐘信號的同步完全依靠板級設計來對齊。所以設置約束時候要考慮的僅僅是下游器件的Tsu/Th 和數(shù)據(jù)在板級的延時。下圖是一個SDR上升沿采樣系統(tǒng)同步接口的output約束示例。
約束下級芯片(ASSP)REG2的Tsu使用”-max”:
Output delay max = Tdata_Pcb(max) +?Tsu + Tclk1(max) – Tclk2(min)
=Board Delay(max) + Tsu – Board clock skew(min)
Output delay min = Tdata_Pcb(min) - Th- Tclk1(min) + Tclk2(max)
?=Board Delay(min) -?Th – Board clock skew(max)
上圖是一個SDR 上升沿采樣系統(tǒng)同步接口的Output 約束示例。其中,?-max 后的數(shù)值是板級延時的最大值與下游器件的Tsu 相加而得出,-min 后的數(shù)值則是板級延時的最小值減去下游器件的Th 而來。
源同步接口
與源同步接口的Input 約束設置類似, 芯片做源同步接口的Output 也有兩種方法可以設置約束。方法一我們稱作Setup/Hold Based Method ,與上述系統(tǒng)同步接口的設置思路基本一致,僅需要了解下游器件用來鎖存數(shù)據(jù)的觸發(fā)器的Tsu 與Th 值與系統(tǒng)板級的延時便可以設置。方法二稱作Skew Based Method ,此時需要了解芯片送出的數(shù)據(jù)相對于時鐘沿的關系,根據(jù)Skew 的大小和時鐘頻率來計算如何設置Output約束。
具體約束時可以根據(jù)不同的已知條件,選用不同的約束方式。一般而言,?芯片作為輸出接口時,數(shù)據(jù)相對時鐘的Skew 關系是已知條件(或者說,把同步數(shù)據(jù)相對于時鐘沿的Skew 限定在一定范圍內是設計源同步接口的目標),所以方法二更常見。
SDR接口的約束設置
Setup/Hold Based Method 的計算公式如下,可以看出其跟系統(tǒng)同步輸出接口的設置方法完全一樣。如果換成DDR 方式,則可參考上一篇I/O 約束方法中關于Input 源同步DDR 接口的約束,用兩個可選項-clock_fall 與-add_delay 來添加針對時鐘下降沿的約束值。
方法一Setup/Hold Based Method(以下游寄存器位參照,反推到FPGA輸出管腳時序)
如果板級延時的最小值(在源同步接口中,因為時鐘與信號同步傳遞,所以板級延時常??梢砸曌鳛?)小于接收端寄存器的Th,這樣計算出的結果就會在-min 后出現(xiàn)負數(shù)值,很多時候會讓人誤以為設置錯誤。其實這里的負數(shù)并不表示負的延遲,而代表最小的延遲情況下,數(shù)據(jù)是在時鐘采樣沿之后才有效。同樣的,?-max后的正數(shù),表示最大的延遲情況下,數(shù)據(jù)是在時鐘采樣沿之前就有效了。
這便是接口約束中最容易混淆的地方,請一定牢記set_output_delay 中-max/-min 的定義,即時鐘采樣沿到達之前,數(shù)據(jù)的最大與最小的數(shù)據(jù)有效窗口,如下圖所示。
如果我們在紙上畫一下接收端的波形圖,就會很容易理解:用于setup 分析的-max 之后跟著正數(shù),表示數(shù)據(jù)在時鐘采樣沿之前就到達,而用于hold 分析的-min 之后跟著負數(shù),表示數(shù)據(jù)在時鐘采樣沿之后還保持了一段時間。只有這樣才能滿足接收端用于鎖存接口數(shù)據(jù)的觸發(fā)器的Tsu 和Th 要求。
方法二Skew Based Method(以FPGA寄存器為參照)
為了把同步數(shù)據(jù)相對于時鐘沿的Skew 限定在一定范圍內,我們可以基于Skew 的大小來設置源同步輸出接口的約束。此時可以不考慮下游采樣器件的Tsu 與Th 值。
我們可以通過波形圖來再次驗證set_output_delay 中-max/-min 的定義,即時鐘采樣沿到達之前最大與最小的數(shù)據(jù)有效窗口。
DDR接口的約束設置
DDR 接口的約束稍許復雜,需要將上升沿和下降沿分別考慮和約束,以下以源同步接口為例,分別就Setup/Hold Based 方法和Skew Based 方法舉例。
方法一Setup/Hold Based Method
已知條件如下:
時鐘信號src_sync_ddr_clk 的頻率: 100 MHz
隨路送出的時鐘src_sync_ddr_clk_out 的頻率: 100 MHz
數(shù)據(jù)總線:?src_sync_ddr_dout[3:0]
接收端的上升沿建立時間要求( tsu_r ) : 0.7 ns
接收端的上升沿保持時間要求(thd_r ) : 0.3 ns
接收端的下降沿建立時間要求(tsu_f) : 0.6 ns
接收端的下降沿保持時間要求(thd_f ) : 0.4 ns
板級走線延時:?0 ns
可以這樣計算輸出接口約束:已知條件包含接收端上升沿和下降沿的建立與保持時間要求,所以可以分別獨立計算。上升沿采樣數(shù)據(jù)的-max 是板級延時的最大值加上接收端的上升沿建立時間要求( tsu_r ),對應的-min 就應該是板級延時的最小值減去接收端的上升沿保持時間要求( thd_r );下降沿采樣數(shù)據(jù)的-max 是板級延時的最大值加上接收端的下降沿建立時間要求(?tsu_f ),對應的-min 就應該是板級延時的最小值減去接收端的下降沿保持時間要求(?thd_f )。所以最終寫入XDC 的Output 約束應該如下所示:
create_clock -period 10.0 -name clk [get_ports src_sync_ddr_clk];
create_generated_clock -name clk_out [get_ports ddr_src_sync_clk_out] \
-source [get_ports src_sync_ddr_clk] -divide_by 1;
set_output_delay -clock clk_out -max 0.7 [get_ports src_sync_ddr_dout[*]] ;
set_output_delay -clock clk_out -min -0.3 [get_ports src_sync_ddr_dout[*]] ;
set_output_delay -clock clk_out -max 0.6 [get_ports src_sync_ddr_dout[*]]-clock_fall -add_delay;
set_output_delay -clock clk_out -min -0.4 [get_ports src_sync_ddr_dout[*]] -clock_fall -add_delay;
方法二Skew Based Method
已知條件如下:
時鐘信號src_sync_ddr_clk 的頻率: 100 MHz
隨路送出的時鐘src_sync_ddr_clk_out 的頻率: 100 MHz
數(shù)據(jù)總線:?src_sync_ddr_dout[3:0]
上升沿之前的數(shù)據(jù)skew ( bre_skew ) : 0.4 ns
上升沿之后的數(shù)據(jù)skew ( are_skew ) : 0.6 ns
下降沿之前的數(shù)據(jù)skew ( bfe_skew ) : 0.7 ns
下降沿之后的數(shù)據(jù)skew ( afe_skew ) : 0.2 ns
可以這樣計算輸出接口約束:時鐘的周期是10ns ,因為是DDR 方式,所以數(shù)據(jù)實際的采樣周期是時鐘周期的一半;上升沿采樣的數(shù)據(jù)的-max 應該是采樣周期減去這個數(shù)據(jù)的發(fā)送沿(下降沿)之后的數(shù)據(jù)skew 即afe_skew ,而對應的-min 就應該是上升沿之前的數(shù)據(jù)skew 值bre_skew ;同理,下降沿采樣數(shù)據(jù)的-max應該是采樣周期減去這個數(shù)據(jù)的發(fā)送沿(上升沿)之后的數(shù)據(jù)skew 值are_skew ,而對應的-min 就應該是下降沿之前的數(shù)據(jù)skew 值bfe_skew 。
所以最終寫入?的Output 約束應該如下所示:
set period 10.0;
create_clock -period $period -name clk [get_ports src_sync_ddr_clk];
create_generated_clock -name clk_out [get_ports ddr_src_sync_clk_out] \
-source [get_ports src_sync_ddr_clk] -divide_by 1;
set_output_delay -clock clk_out -max [expr $period/2 – 0.2] [get_ports src_sync_ddr_dout[*]] ;
set_output_delay -clock clk_out -min 0.4 [get_ports src_sync_ddr_dout[*]] ;
set_output_delay -clock clk_out -max [expr $period/2 – 0.6] [get_ports src_sync_ddr_dout[*]] \
-clock_fall -add_delay ;
set_output_delay -clock clk_out -min 0.7 [get_ports src_sync_ddr_dout[*]] -clock_fall -add_delay;
對以上兩種方法稍作總結,就會發(fā)現(xiàn)在設置DDR 源同步輸出接口時,送出的數(shù)據(jù)是中心對齊的情況下,用Setup/Hold Based 方法來寫約束比較容易,而如果是邊沿對齊的情況,則推薦使用Skew Based 方法來寫約束。
例外約束
什么是時序例外?時序例外用于修改對特定路徑執(zhí)行時序分析的方式。默認情況下,時序引擎假定所有路徑都應通過單一建立時間分析周期要求來完成時序約束,以便覆蓋大部分消極的時鐘設置場景。對于某些路徑,并非如此。以下提供一些示例:
- 由于時鐘間缺乏固定的相位關系,導致無法安全完成異步 CDC 路徑的時序約束。此類狀況應予以忽略(時鐘組,偽路徑),或者只需設置數(shù)據(jù)路徑延遲約束(僅最大延遲數(shù)據(jù)路徑)即可
- 時序單元發(fā)送沿和捕獲沿并非在每個時鐘周期內都處于活動狀態(tài),因此可相應降低路徑要求(多周期路徑)
- 路徑延遲要求需收緊,以增加硬件中的設計裕度(最大延遲)
- 通過組合單元的路徑為靜態(tài)路徑,無需時序約束(偽路徑,案例分析)
- 應僅限對多路復用器驅動的特定時鐘執(zhí)行分析(案例分析)。
無論在任何情況下,都必須謹慎使用時序例外,并且不得為了隱藏實際時序問題而添加例外。常用的時序例外命令如下:
命令 | 功能簡介 |
set_clock_group | 建立時鐘組,組間時序路徑不進行分析 |
set_false_path | 指示某條路徑不進行時序分析 |
set_multicycle_path | 設置路徑上從起點到終點的傳遞數(shù)據(jù)需要的時鐘周期數(shù) |
set_max/min_delay | 設置最大和最小的延遲值,會重寫默認的建立/保持約束 |
Clock Group
在硬件設計中,沒有設置clock groups前,綜合工具是把所有的時鐘作為同步時鐘來處理,工具會分析所有時鐘下的所有路徑。具體的表現(xiàn)是工具會分析任意兩兩時鐘間的timing。可以理解為:增加group 是在原來同步的基礎上增加異步描述,不在描述中的還保持同步關系。默認情況下時鐘組約束set_clock_groups將關斷指定時鐘組之間的時序分析,但并不關斷時鐘組內各個時鐘之間的時鐘約束。set_false_path約束是單向的,set_clock_groups時序分析忽略是雙向的。使用-group選項定義組,工具會排除每個獨立組的時鐘之間的時序路徑。下表顯示了set_clock_groups的影響。
- set_clock_groups -group A
Dest\Source | A | B | C | D |
A | Analyzed | Cut | Cut | Cut |
B | Cut | Analyzed | Analyzed | Analyzed |
C | Cut | Analyzed | Analyzed | Analyzed |
D | Cut | Analyzed | Analyzed | Analyzed |
- set_clock_groups -group {A B}
Dest\Source | A | B | C | D |
A | Analyzed | Analyzed | Cut | Cut |
B | Analyzed | Analyzed | Cut | Cut |
C | Cut | Cut | Analyzed | Analyzed |
D | Cut | Cut | Analyzed | Analyzed |
- set_clock_groups -group A -group B
Dest\Source | A | B | C | D |
A | Analyzed | Cut | Cut | Cut |
B | Cut | Analyzed | Cut | Cut |
C | Cut | Cut | Analyzed | Analyzed |
D | Cut | Cut | Analyzed | Analyzed |
- set_clock_groups -group {A C} -group {B D}
Dest\Source | A | B | C | D |
A | Analyzed | Cut | Analyzed | Cut |
B | Cut | Analyzed | Cut | Analyzed |
C | Analyzed | Cut | Analyzed | Cut |
D | Cut | Analyzed | Cut | Analyzed |
- set_clock_groups -group {A C D}
Dest\Source | A | B | C | D |
A | Analyzed | Cut | Analyzed | Analyzed |
B | Cut | Analyzed | Cut | Cut |
C | Analyzed | Cut | Analyzed | Analyzed |
D | Analyzed | Cut | Analyzed | Analyzed |
n set_clock_groups可以接三個參數(shù)asynchronous/logically_
exclusive/physically_exclusive,這三個參數(shù)區(qū)別:
- asynchronous:多個時鐘之間相位關系不確定,就可以將這兩個(或多個)時鐘設置為asynchronous。一般而言當時鐘來自于不同的PLL或者晶振時,時鐘之間的相位是不固定的,此時就用asynchronous來設置異步時鐘分組。
- logically_exclusive:?兩個時鐘在傳播路徑上沒有相互的path,可以設置設logically_exclusive。例如下圖,mux的兩個輸入端(pin2、pin3)通過pin0 generated 新的時鐘,并設為logically_exclusive,那么路徑上寄存器就不會檢查這兩個新的衍生時鐘之間的timing。注意,不能將pin0和pin1上的時鐘設為logically_exclusive。pin0和pin1的時鐘是有path的,而且不是異步電路 是需要收timing的。
- physically_exclusive:如果兩個時鐘定義在同一個端口上,那么這兩個時鐘在物理層面就是不可能同時存在的(對同一時鐘節(jié)點定義不同的時鐘頻率,兩個時鐘在物理上不會共存),此時就需要聲明成 physically_exclusive。如下圖,pin4會流過兩個時鐘,一個是clk,一個是clk經(jīng)過PLL的二分頻時鐘。這兩個頻率是準靜態(tài)或靜態(tài)切換的,那么可以在pin4(mux的輸出端,物理上只有一個節(jié)點)上分別generated來源于pin2和pin3的時鐘,把這兩個衍生時鐘設為physically_exclusive。
如果有?2 個或更多個時鐘驅動到某 1 個多路復用器(或者更普遍的情況下,驅動到組合單元內)中,這些時鐘全部都能順利完成傳輸,并在單元扇出上重疊。實際上,每次只能傳輸?1 個時鐘,但時序分析允許同時報告多種時序模式。因此,必須審查?CDC 路徑,并添加新約束,以忽略部分時鐘關系。正確的約束取決于設計中時鐘交互的方式和位置。下圖演示了?2 個時鐘驅動到同一個多路復用器中的示例,并演示了在此多路復用器前后這 2 個時鐘之間可能發(fā)生的交互。
- 路徑?A、B 和 C 都不存在的情況
clk0 和 clk1 僅在多路復用器(FDM0 和 FDM1)的扇出中交互。毋庸置疑,時鐘組約束可直接應用到 clk0 和clk1 中。
set_clock_groups -logically_exclusive -group clk0 -group clk1
- 僅存在路徑?A、B 或 C 之一的情況
clk0 和/或 clk1 與多路復用時鐘直接交互。為了保留時序路徑 A、B 和 C,無法直接向 clk0 和 clk1 直接應用約束。而是改為必須將其應用于多路復用器的扇出中需要額外的時鐘定義的時鐘部分。
create_generated_clock -name clk0mux -divide_by 1 \
-source [get_pins mux/I0] [get_pins mux/O]
create_generated_clock -name clk1mux -divide_by 1 \
-add -master_clock clk1 -source [get_pins mux/I1] [get_pins mux/O]
set_clock_groups -physically_exclusive -group clk0mux -group clk1mux
Clock Group舉例1:
一個primary clock clk0到達MMCM0產(chǎn)生usrclk和itfclk,另一個primary clk1到達MMCM0產(chǎn)生了gtclkrx和gtclktx.
第一種約束方法:
set_clock_groups -name async_clk0_clk1 -asynchronous -group {clk0 usrclk itfclk} -group {clk1 gtclkrx gtclktx}
如果對于generated clock的名字無法預期,那么使用第二種方法:
set_clock_groups -name async_clk0_clk1 -asynchronous \
-group [get_clocks -include_generated_clocks clk0] \
-group [get_clocks -include_generated_clocks clk1]
Clock Group舉例2:相同時鐘源上定義的重疊時鐘
在相同網(wǎng)表對象上使用?create_clock -add 命令定義兩個時鐘,并表示單一應用的多種模式時,會出現(xiàn)此情況。在此情況下,可在兩個時鐘之間安全應用時鐘組約束。例如:
create_clock -name clk_mode0 -period 10 [get_ports clkin]
create_clock -name clk_mode1 -period 13.334 -add [get_ports clkin]
set_clock_groups -physically_exclusive -group clk_mode0 -group clk_mode1
如果?clk_mode0 和 clk_mode1 時鐘生成其他時鐘,那么還需對其生成時鐘應用相同的約束,操作方式如下所述:
set_clock_groups -physically_exclusive \
-group [get_clocks -include_generated_clock clk_mode0] \
-group [get_clocks -include_generated_clock clk_mode1]
Clock Group舉例3:
一個輸入時鐘管腳上會有兩種頻率的時鐘輸入(如果clk_100 和clk_66 除了通過clock?control block 后一模一樣的扇出外,沒有驅動其它時序元件,我們要做的僅僅是補齊時鐘關系的約束),采用如下約束:
create_clock –period 10.0 [get_ports clk_100]
create_clock –period 15.0 [get_ports clk_66]
set_clock_groups –logically_exclusive –group {clk_100} –group {clk_66}
如果一個mux的輸入是可變時鐘:
create_clock –name clk_100 –period 10.0 [get_ports clk]
create_clock –name clk_66 –period 15.0 [get_ports clk] –add
create_clock –name clk_200–period 5.0 [get_ports clk_200]
set_clock_groups –physically_exclusive –group {clk_100} \
–group {clk_66}
set_clock_groups –logically_exclusive –group {clk_100} \
?–group {clk_200}
set_clock_groups –logically_exclusive –group {clk_66} –group {clk_200}
說明:“-add”是用來對已添加約束的節(jié)點再添加新的約束,使得多個約束同時生效。如果不使用“-add”,那么最后一句約束將覆蓋前面的約束。
Clock Group舉例4:
在很多情況下,除了共同的扇出,其中一個時鐘或兩個都還驅動其它的時序元件,此時建議的做法是再創(chuàng)建兩個重疊的衍生鐘,并將其時鐘關系約束為-physically_exclusive 表示不可能同時通過,這樣做可以最大化約束覆蓋率。
create_clock –period 10.0 [get_ports clk_100]
create_clock –period 15.0 [get_ports clk_66]
create_generated_clock –name clkmux_100 –source clk_100 \
[get_pins clkmux|clkout]
create_generated_clock –name clkmux_66 –source clk_66 \
[get_pins clkmux|clkout] –add
set_clock_groups –physically_exclusive –group {clkmux_100} –group {clkmux_66}
注意,不能直接將clk_100和clk_66設成logically_exclusive,因為這兩個時鐘是有path的,并不是互斥的。只有mux之后的path,兩個時鐘才是互斥的。
Clock Group舉例5:
在某芯片中,輸入時鐘clk_640m為定頻640M,在phy_top層根據(jù)phy_mode進行CG得到clk_4x_phy_mode時鐘,支持頻率80/160/320/640MHz;在txdfe_top根據(jù)tx_en對clk_4x_phy_mode進行CG得到clk_tx,支持頻率80/160/320/640MHz;根據(jù)dpd_en對clk_4x_phy_mode進行CG得到clk_dpd,由于dpd模塊不支持640M應用場景,即clk_dpd只支持頻率80/160/320MHz,如何進行時鐘約束?
create_clock –period 1.5625 [get_ports clk_640m]
create_generated_clock –name clk_phy_640m –source clk_640m?\
[get_pins phy_cg|Q]
create_generated_clock –name clk_phy_320m -edges {1 2 5}–source clk_640m?[get_pins phy_cg|Q] -add
create_generated_clock –name clk_dpd –source clk_phy_320m \
[get_pins dpd_cg|Q]
set_clock_groups –physically_exclusive –group { clk_phy_320m } –group { clk_phy_640m }
我們再總結一下logically_exclusive和physically_exclusive的區(qū)別:
- Logically_exclusive用于在不同源根上定義的兩個時鐘;時鐘之間沒有任何功能路徑,但它們之間可能有耦合交互。logically_exclusive時鐘的一個例子是MUX輸入端口的多個時鐘,但仍然可以通過MUX單元的上游耦合進行交互。當兩個時鐘之間存在物理上存在但邏輯上例外的路徑時,使用“set_clock_groups -logical_exclusive”。
- physically_exclusive用于在同一個源根節(jié)點上通過create_clock/create_generated_clock -add定義的兩個時鐘,兩個時鐘物理上不存在時序路徑;使用set_clock_groups -physically_exclusive進行時序例外。
簡而言之,logical_exclusive用于選擇器的電路,兩個時鐘的source不一樣;而physical_exclusive兩個時鐘的source是一樣,比如在同一個時鐘輸入口,但可能會輸入兩個不同的時鐘。
False?Paths
False Paths(偽路徑)的定義:不希望工具進行分析的那些路徑,在設計中形式存在,但沒有功能性或不需要被時序分析的路徑。例如:跨時鐘域處理的電路、靜態(tài)配置寄存器、復位或測試邏輯、異步雙端口RAM。
偽路徑的優(yōu)勢:減少工具進行優(yōu)化的時間,增強實現(xiàn)結果,避免在不需要進行時序約束的地方花較多的時間,而忽略了真正需要進行優(yōu)化的地方。
False Paths舉例1
顯然MUX1和MUX2不可能同時選通。因此Q到D路徑不存在,可以約束為:
set_false_path -through [get_pins MUX1/a0] -through [get_pins MUX2/a1]
注意:“-through”選項至關重要,表示通過此節(jié)點的路徑。如果沒有“from”和“to”,則表示所有通過此節(jié)點的路徑。
set clock group和set_false_path的關系:
set_clock_group -asyncronous -group CLKA -group CLKB
等效于:
set_false_path -from [get_clocks CLKA] -to [get_clocks CLKB]
set_false_path -from [get_clocks CLKB] -to [get_clocks CLKA]
set_clock_groups -asyncronous -name MY_ASYNC -group {CLKA CLKA_DIV2} -group{CLK_OSC}
等效于:
set_false_path -from [get_clocks CLKA] -to [get_clocks CLK_OSC]
set_false_path -from [get_clocks CLKA_DIV2] -to [get_clocks CLK_OSC]
set_false_path -from [get_clocks CLK_OSC] -to [get_clocks CLKA]
set_false_path -from [get_clocks CLK_OSC] -to [get_clocks CLKA_DIV2]
False Paths舉例2
忽略設計中的靜態(tài)路徑。有些寄存器在應用的初始化階段接收?1 個值后,就不再切換。當這些寄存器出現(xiàn)在設計的關鍵路徑上時,可以忽略其時序,以放寬對實現(xiàn)工具的約束,從而有助于實現(xiàn)時序收斂。僅定義偽路徑約束始于靜態(tài)寄存器即可,無需明確指定路徑端點。例如,通過添加如下偽路徑約束,便可忽略從?32 位配置寄存器config_reg[31:0] 到其余部分的路徑:
set_false_path -from [get_cells config_reg[*]]
False Paths舉例3
set_false_path –from [get_pins reg1|clk] –to [get_pins reg2|datain]
False Paths舉例4
set_false_path –fall_from clk1 –to [get_pins test_logic|*|datain]
set_false_path –from [get_pins test_logic|*|clk] -to [get_pins?\ test_logic|*|datain]
set_false_path –from [get_pins test_logic|*|clk] \
-to [get_ports test_out]
Multi-cycles?Paths
對于我們的設計,如果有些信號采樣是同步的,但是扇出多,走線長,組合邏輯網(wǎng)絡的最大延時超過一個時鐘周期,我們就需要修改我們的設計,減小組合邏輯的延時;或者如果信號是多周期的電平信號,確實對時序沒有嚴格要求,我們也可以通過Multi-Cycles約束來放松。
Multi-Cycles path 意思是多周期的數(shù)據(jù)路徑,即一個時鐘周期不能完成數(shù)據(jù)傳輸?shù)穆窂?。一般是由于大的邏輯電路的存?#xff0c;導致數(shù)據(jù)的最大延遲可能超過一個時鐘周期,這時就需要指明該路徑為Multi-Cycles path。因為一般的時序檢查工具,默認按單周期的約束對數(shù)據(jù)路徑進行檢查,從有效的launch?edge 到有效的 capture edge。
標準電路的建立保持時間關系是:setup檢查是從source clk的一個上升沿(Current Launch Edge)到下一個destination clk的上升沿(Current Capture Edge),即Multicycle?Setup = 1(default);hold檢查是從source clk的一個上升沿(Current Launch Edge)到下一個destination clk的前一個上升沿(Previous?Capture Edge)或者source clk的下一個上升沿(Next?Launch Edge)到下一個destination clk的上升沿(Current?Capture Edge),即Multicycle?Hold= 0(default)。
圖xx 默認情況下建立保持關系
說白了,設置setup多周期,就是修改Current Launch Edge和Current?Capture Edge的位置;設置hold多周期,就是修改Previous?Capture Edge和Next?Launch Edge的位置(hold分析綁定到了setup分析,先由setup確定Current Launch Edge和Current?Capture Edge;再根據(jù)hold確定Previous?Capture Edge和Next?Launch Edge,是相對于Current Launch Edge和Current?Capture Edge的。也就是說設置setup多周期約束,會影響hold多周期分析)。默認情況下,setup多周期檢查是改變destination clk的Capture Edge,如果要改變source clk的Launch Edge,需要增加-start選項。同理,hold多周期檢查是改變source clk的Launch Edge,如果要改變destination clk的Capture Edge,需要增加-end選項。
同頻時鐘的多周期約束
如下圖所示,enable_reg每個clk翻轉一次,連接到data0_reg、data1_reg寄存器的使能端。因此,在data1_reg的第一個上升沿不采樣,只在第二個上升沿采樣新數(shù)據(jù),即源觸發(fā)器每隔兩拍打出一個數(shù)據(jù),下游觸發(fā)器也是每隔兩拍接收源觸發(fā)器打出的數(shù)據(jù)。這時定義data0_reg到data1_reg路徑多周期約束,電路是安全的。那如何進行多周期約束呢?
由前面章節(jié)分析可知默認約束下的建立/保持時間裕量如下(未考慮時鐘skew):
Setup Slack = T-Tsu?– (Tco+Tdata)
Hold Slack = (Tco+Tdata) - Th
圖xx 默認建立/保持關系(setup = 1,hold = 0)
如果對建立時間進行多周期約束:
set_multicycle_path 2 -setup -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
這時的建立/保持時間裕量如下(未考慮時鐘skew):
Setup Slack = 2T-Tsu?– (Tco+Tdata)
Hold Slack = (Tco+Tdata) – Th – T
可以看出,在增加建立時間多周期約束后,建立時間檢查的current capture edge往后移了一個時鐘,但保持時間檢查的previous capture edge還是current capture edge的前一個時鐘沿,保持時間檢查的next launch edge還是current launch edge的后一個時鐘沿。這時的建立時間裕量增加了一個時鐘周期,保持時間裕量卻縮減了一個時鐘周期,這時就需要再對保持時間做多周期約束,來改變previous capture edge和next launch edge的位置。
圖xx 建立/保持關系(setup = 2,hold = 0)
約束命令如下:
set_multicycle_path 1 -hold -end -from [get_pins data0_reg/C] \
-to [get_pins data1_reg/D]
這時的建立/保持時間裕量如下(未考慮時鐘skew):
Setup Slack = 2T-Tsu?– (Tco+Tdata)
Hold Slack = (Tco+Tdata) – Th
圖xx 建立/保持關系(setup = 2,hold = 1)
慢時鐘域到快時鐘域多周期約束
如圖所示,Launch Edge是慢時鐘域,Capture Edge是快時鐘域。
假設clk2的頻率是clk1的三倍,那么不添加約束的話,工具默認進行分析采樣關系如下:
圖xx 默認建立/保持關系(setup = 1,hold = 0)
如果只添加建立檢查多周期約束,即
set_multicycle_path 3 -setup -from [get_clocks CLK1] -to [get_clocks CLK2]
由于setup檢查添加了多周期約束,setup檢查相應的Capture Edge右移了2個時鐘周期。但hold檢查沒有添加多周期約束,會使用相對應setup的Launch Edge。
圖xx 建立/保持關系(setup = 3,hold = 0)
由上一小節(jié)可知,此時建立時間裕量放松了,但保持時間裕量縮減了。所以還要對hold進行多周期約束:
set_multicycle_path 2 -hold -end -from [get_clocks CLK1] -to [get_clocks CLK2]
值得注意的是:hold多周期檢查默認是改變Source Clk的Launch Edge,如果這條命令沒有-end選項,是達不到放松保持時間裕量的目的的。
圖xx 建立/保持關系(setup = 3,hold = 2)
此時建立時間裕量和保持時間裕量都放松了。
快時鐘域到慢時鐘域多周期約束
如圖所示,Launch Edge是快時鐘域,Capture Edge是慢時鐘域。
假設clk1的頻率是clk2的三倍,那么不添加約束的話,工具默認進行分析采樣關系如下:
圖xx 默認建立/保持關系(setup = 1,hold = 0)
此時需要添加多周期約束:
set_multicycle_path 3 -setup -start -from [get_clocks CLK1] -to [get_clocks CLK2]
set_multicycle_path 2 -hold -from [get_clocks CLK1] -to [get_clocks CLK2]
思考:下圖電路中,從觸發(fā)器FF3的輸出能否設置多周期約束?
圖xx 電路結構圖
答案是不能的,并不是觸發(fā)器每隔兩拍(或者以上)變化輸出數(shù)據(jù),或者接收觸發(fā)器每隔兩拍(或者以上)接收數(shù)據(jù),或者兩者的組合,就可以設置為多周期約束的。而是應該從Launch?Edge到有效的Capture Edge這一段時間內(設置多周期約束后),Launch的數(shù)據(jù)不發(fā)生變化,才能設置為多周期約束,例如上述電路變形后:
圖xx 電路結構圖
觸發(fā)器FF1每兩拍打出數(shù)據(jù),FF2每兩拍接收數(shù)據(jù),但是從FF1到FF2不能設置為多周期約束。我們畫出設計多周期約束后,時序檢查和實際數(shù)據(jù)變化關系如下:
圖xx 電路時序檢查示意圖
在上面電路中,源觸發(fā)器FF1在0,4,8,…等位置打出數(shù)據(jù),那么FF2觸發(fā)器就在2,4,6,…等位置接收數(shù)據(jù),這樣的電路是不能設置多周期約束的(必須在4,8,…等位置接收數(shù)據(jù))。
在上面說的Capture Edge時,我們說有效的Capture?Edge。有效的含義是只關心該拍輸出的數(shù)據(jù),而其它沿打出的數(shù)據(jù)是不關心的。例如上面電路再變化一下:
圖xx 電路結構圖
如果觸發(fā)器FF2的輸出只有到FF4,盡管每拍FF2都采樣,但是對于FF4來講,只關心FF1輸出變化數(shù)據(jù)那拍FF2對應的輸出數(shù)據(jù)。因此,對于這樣的電路,也是滿足多周期約束的,我們可以設置從FF1到FF2兩拍的多周期約束。
總結一下:
- Multi-cycles是放松Data require time達到放松時序的目的,Data arrival time是不變的。
- Multi-cycles?Paths設置方法有兩種:“-start”和”-end”?!?start”指定source clock的移動時鐘數(shù)量;“-end”指定destination clock的移動時鐘數(shù)量,Multi-cycles?Paths設置總是相對于參考較快頻率的時鐘。在setup分析時,默認為“-end”;在hold分析時,默認為“-start”。常用命令總結:
同步時鐘域場景 | 約束 |
同頻 | set_multicycle_path N -setup -from CLK1 -to CLK2 set_multicycle_path N-1 -hold -from CLK1 -to CLK2 說明:因為同頻,“-start”和“-end”是一樣的。 |
慢速到快速 | set_multicycle_path N -setup -from CLK1 -to CLK2 set_multicycle_path N-1 -hold -end -from CLK1 -to CLK2 |
快速到慢速 | set_multicycle_path N -setup -start -from CLK1 -to CLK2 set_multicycle_path N-1 -hold -from CLK1 -to CLK2 |
- 對于多周期電路,電路設計人員應該特別注意,它是RTL代碼設計出來的,并不是最大延遲超過一個周期就可以設置為多周期約束。另外,從DFT角度來看,不建議做多周期約束,否則會帶來測試困難,降低覆蓋率。對于我們自己設計比較復雜的單元,盡量中間插入觸發(fā)器,進行Pipeline設計。
Min/Max?Delay
Min/Max?Delay的用途:用來修改某路徑默認的setup和hold時序要求。
set_max_delay <delay> [-datapath_only] [-from <node_list>]
[-to <node_list>] [-through <node_list>]
set_min_delay <delay> [-from <node_list>]
[-to <node_list>] [-through <node_list>]
Min/Max?Delay和Input/Output Delay的區(qū)別:
set_max/min_delay命令典型應用不是約束input/outpu邏輯的。輸入端口到第一級寄存器間的邏輯路徑是用set_input_delay命令,最后一級寄存器到輸出端口間的邏輯路徑是用set_output_delay命令。set_max/min_delay典型應用是約束輸入端口到輸出端口間的純組合邏輯路徑。可以用來作為Min/Max Delay的Satrtpoint是時序元件的時鐘端或FPGA的輸入端口,用來作為Min/Max Delay的Endpoint是時序元件(reg/ram)的輸入數(shù)據(jù)端或FPGA的輸出端口。如果不是用上述端口作為Satrtpoint或Endpoint,則會出現(xiàn)路徑分割,這對時序分析很不利的。
舉例1:
正常情況下,set_max_delay 5 -from [get_pins FD1/C]進行約束,但如果set_max_delay 5 -from [get_pins FD1/Q],則FD1/Q到FD2/D成為Path Segmentation。導致在計算FD2的setup時,不會計算FD1/Q的時鐘延遲,但FD2/D的時鐘延遲仍然會被計算,因此造成很大的skew。
舉例2:
建議的做法不是設置set_clock_groups約束,轉而采用set_max_delay來約束這些跨時鐘域路徑。以寫入側為例,一個基本原則就是約束cell1到cell2的路徑之間時延等于或小于cell2的驅動時鐘一個周期,讀出側同理約束。
編寫 CDC 約束時,需要驗證是否遵循相應的優(yōu)先順序。如果在 2 個時鐘之間至少 1 條路徑上使用 set_max_delay –datapath_only,那么無法在相同時鐘之間使用 set_clock_groups 約束,并且只能在 2 個時鐘之間的其他路徑
上使用 set_false_path 約束。在下圖中(將上圖的cell2展開),時鐘 clk0 的周期為 5 ns,并且與 clk1 之間處于異步關系。從 clk0 域到 clk1 域存在兩條路徑。第 1 條路徑為 1 位數(shù)據(jù)同步。第 2 條路徑為多位格雷編碼總線傳輸。判定格雷編碼總線傳輸需要“Max Delay Datapath Only”(僅最大延遲數(shù)據(jù)路徑)來限制比特間延遲變動,因此無法在時鐘之間直接使用“Clock Group”(時鐘組)或“False Path”(偽路徑)約束。而改為必須定義以下 2 個約束:
Set_max_delay -from [get_cells GCB0[*]] -to [get_cells [GCB1a[*]] \
-datapath_only 5
Set_false_path -from [get_cells REG0] -to [get_cells REG1a]
無需設置從 clk1 到 clk0 的偽路徑,因為在此示例中不含任何路徑。
|
時序例外準則
盡量限制使用的時序例外的數(shù)量,并使時序例外盡可能保持簡單。否則,將面臨下面挑戰(zhàn):
- 如果過多使用例外,實現(xiàn)編譯時間將顯著增加,當這些例外與大量網(wǎng)表對象相關聯(lián)時尤其如此。
- 當多個例外覆蓋相同路徑時,約束調試會變得極為復雜。
- 對信號施加約束會阻礙該信號的最優(yōu)化。因此無論是包含非必要的例外還是在例外命令中包含非必要的點,都會妨礙信號最優(yōu)化。以下是可能會對運行時間產(chǎn)生不利影響的時序例外示例:
set_false_path -from [get_ports din] -to [all_registers]
如果 din 端口沒有輸入延遲,那么它將不受約束,因此無需添加偽路徑。如果 din 端口僅供給時序元件,那么無需對時序單元顯式指定偽路徑。按如下方法編寫此約束更有效:
set_false_path -from [get_ports din]
如果需要偽路徑,但從 din 端口到設計中的任意時序單元之間僅存在幾條路徑,那么約束可以更明確(all_registers 可能會返回數(shù)千個單元,這取決于設計中使用的寄存器數(shù)量):
set_false_path -from [get_ports din] -to [get_cells \ blockA/config_reg[*]]
時序例外優(yōu)先級規(guī)則
時序例外需遵循嚴格的優(yōu)先級規(guī)則。最重要的規(guī)則包括:
- 約束越具體,優(yōu)先級越高。例如:
Set_max_delay -from [get_clocks clkA] -to [get_pins inst0/D] 12
Set_max_delay -from [get_clocks clkA] -to [get_clocks clkB] 10
第一條set_max_delay 約束優(yōu)先級更高,因為 -to 選項使用管腳,這比時鐘更為具體。
- 例外優(yōu)先級如下所示:
- set_false_path
- set_max_delay 或 set_min_delay
- set_multicycle_path
set_clock_groups 命令不視為時序例外,即使它等同于 2 個時鐘之間的 2 條 set_false_path 命令也是如此。它的優(yōu)先級高于時序例外set_case_analysis 命令和 set_disable_timing 命令用于禁用特定設計部分上的時序分析。其優(yōu)先級高于時序例外。
建議的約束順序
約束語言?(無論是XDC還是SDC) 基于 Tcl 語法和解讀規(guī)則。與 Tcl 一樣,屬于順序語言:
- 必須先定義變量,然后才能加以使用。同樣,必須先定義時序時鐘,然后才能將其用于其他約束中。
- 對于覆蓋相同路徑并具有相同優(yōu)先級的等效約束,使用最后一項約束。
- 當多個時序例外覆蓋同一條路徑時,使用具有更高優(yōu)先級的約束。
- 當考慮以上優(yōu)先規(guī)則時,時序約束總體上應遵循以下順序:
## Timing Assertions Section
# Primary clocks
# Virtual clocks
# Generated clocks
# Delay for external MMCM/PLL feedback loop
# Clock Uncertainty and Jitter
# Input and output delay constraints
# Clock Groups and Clock False Paths
## Timing Exceptions Section
# False Paths
# Max Delay / Min Delay
# Multicycle Paths
# Case Analysis
# Disable Timing
當使用多個約束文件時,必須特別留意時鐘定義,并確認從屬關系排序是否正確。物理約束可能位于任意約束文件中的任意位置。
FPGA
|
分析并解決時序違例
- 了解當前設計資源情況,當前應用器件資源比例,識別資源瓶頸。
- 了解當前時鐘的分布情況與量級,組合邏輯情況,扇出情況,是否應用全局時鐘資源。
- 設計時要根據(jù)當前工作頻率,減少組合邏輯級數(shù)設計和高扇出設計。說明:組合邏輯級數(shù)可以根據(jù)30/70原則計算,30/70原則是指組合邏輯延時<(Tclk?-Tco)*30%,其它用于走線延遲,基于此,組合邏輯最大LUT級數(shù)<(Tclk?-Tco)*30%/一級LUT的平均延遲,Tco和一級LUT的平均延遲可以查手冊得到,由于這里不精確計算,所以未考慮時鐘抖動和延遲。假設基于4輸入LUT的FPGA器件進行開發(fā),工作時鐘為370MHz,查器件資料獲得Tco?= 0.3ns,一級LUT平均延遲為0.33ns,則該設計下最大組合邏輯LUT級聯(lián)數(shù)位2?(計算公式為:(1000/370-0.3)*30%/0.33 = 2.18)。根據(jù)這個計算結果,再編碼時,應控制邏輯LUT級聯(lián)數(shù)盡量不要超過2級,少量因設計困難(如時序匹配)而達到3級LUT級聯(lián)是允許的,最終以時序收斂情況判斷是否要進行優(yōu)化。也就是說違背該規(guī)則的編碼越多,合版本時,投入時序收斂優(yōu)化的代價越大。 ?
- DSP/RAM的輸入先寄存,輸出信號寄存后再使用,避免RAM-RAM的路徑。
- 模塊之間的輸入/輸出信號寄存(至少輸出需要寄存)。
- 時序與資源平衡,小塊的RAM請用分布式RAM,大深度大位寬高頻RAM提前考慮地址MUX選擇,考慮地址多打1-2拍。
- 查看時序分析報告時,不要只關注當前不滿足要求的時序,需要從這個時鐘出發(fā),工具會先滿足一些組合邏輯級數(shù)高、扇出大的路徑。需要線檢查設計中是否存在高組合邏輯高扇出的設計,先將這些組合邏輯級數(shù)降低,高扇出信號做適當?shù)膹椭啤?/li>
- 適當?shù)膶⒁韵驴梢苑潘傻穆窂椒潘杉s束,比如max_delay和false約束。
FPGA時序優(yōu)化
時序優(yōu)化的動機
邏輯設計的主體一般是時序邏輯,若時序不滿足會導致功能不正常。一般遇到以下情況,會進行時序優(yōu)化:
- 資源將滿,布局布線裕量小,開始出現(xiàn)時序問題;
- 改用低速器件,本來沒有時序問題的代碼開始出現(xiàn)時序問題;
- 有新設計需求,功能提速后,開始出現(xiàn)時序問題;
- 因裕量小導致跑版本速度慢,希望通過時序優(yōu)化來提速;
- 接口時序不當,導致時序不過;
- 存在多周期情形,希望提供更精細的時序描述讓工具布線更快更輕松。
時序優(yōu)化的途徑
代碼修改
在設計上保證FPGA器件跑出好時序,代碼途徑有兩種操作思路:
- 被動式
時序驅動法,出了時序問題就去優(yōu)化出問題的地方;
- 主動式
裕量驅動法,分析裕量最小的節(jié)點;扇出驅動法,分析扇出大的節(jié)點。
各方法的優(yōu)缺點為
- 問題驅動法
優(yōu)點:見效快,改好后馬上就能出無時序問題的版本。除了有問題的地方,還能識別出當前時序裕量最小的地方加以優(yōu)化;
缺點:可能不徹底,比如按下這個問題,另一個時序問題又冒出來了,增加一點資源又出問題了。
- 裕量驅動法
優(yōu)點:時序問題挖掘較全面,能找到未來可能優(yōu)先冒出來的時序問題;
缺點:版本變動后,可能最小時序點不同。
- 扇出驅動法
優(yōu)點:可一次性挖掘出較多的問題;
缺點:可能工作量比較大,需要權衡成本;一次改動得多可能對資源影響大;不一定挖掘出全部時序問題,比如資源緊張時,硬core的放置位置對時序的影響;可能報出來的時序最差地方并不是扇出大的地方。
約束優(yōu)化
通過合理約束,固化工具的已有成果,讓工具有正確的時序目標。
增加工具的努力程度
增加努力程度,讓工具更努力、更優(yōu)化的去布線;通過位置約束固化最優(yōu)的布局。
時序優(yōu)化的策略
代碼修改 | 約束優(yōu)化 | 增加工具努力程度 | |
工作量 | 大 | 大 | 小 |
布線時間 | 短 | 短 | 長 |
演進效果 | 好 | 好 | 查 |
如果時間精力有限,可以采取以下策略:
首先,將工具的努力程度降到最低,解決報出的時序問題;
其次,解決時序裕量較小且好改的地方,有余力就優(yōu)化;
若由于代碼變更導致新的時序問題且需要緊急出版本的,用工具方法實現(xiàn)時序問題的快速消除。
FPGA高速設計
簡介
什么是高速設計?
FPGA高速設計可以從廣義和狹義兩個角度進行定義。狹義上,FPGA的主時鐘頻率要求很高,如FPGA主時鐘工作頻率要求大于350MHz。廣義上,滿足一定苛刻條件下(器件等級,資源占用率)的FPGA設計,不一定都是350MHz。
無論從廣義還是狹義角度定義的FPGA高速設計,其基本原理均是通過從前端布局優(yōu)化、方案設計、到后端的一些列策略方法,來保證高速時鐘域下,兩個相鄰觸發(fā)器之間的組合邏輯延遲Tcomp與走線延遲Tnet之和小于該時鐘周期(或Tcomp+Tnet≈T-Tco).
基礎知識范圍
- 器件知識(后面章節(jié)會介紹):器件廠商、等級;器件資源(REG、LUT、BRAM、DRAM、DSP、BUFG…);器件結構等。
- 布局規(guī)劃:PINMAP布局;模塊預布局;時鐘規(guī)劃等
- 設計實現(xiàn):方案設計;代碼實現(xiàn);設計資源評估;組合邏輯級數(shù)評估;
- 后端(前面章節(jié)已講):時鐘約束;異步路徑約束;Multicycle/false path約束;位置約束;后端時序分析。
邏輯高速設計
高速設計流程
布局規(guī)劃
2W1H
What:布局規(guī)劃包括PINMAP分配、LE/DSP/BRAM/硬core按一級模塊劃分區(qū)域,理順數(shù)據(jù)流走向、布線資源的規(guī)劃(全局布線資源(全局時鐘、復位)、長線資源(bank間、一級模塊間信號傳遞,全局控制信號等)、分布式的布線資源(專有時鐘、復位、控制信號線))。
Why:從宏觀上看,布局規(guī)劃目的是平衡FPGA芯片內各類資源使用及分布,減少擁塞(congestion);從微觀上看,布局規(guī)劃目的是要縮短reg-to-reg間路徑delay。提前做好布局規(guī)劃,有利于優(yōu)化FPGA的整體布局,減少數(shù)據(jù)交叉及長線資源,讓時序問題止于前端。例如右圖的布局規(guī)劃明顯優(yōu)于左邊的。
How:要做好布局規(guī)劃,需要掌握備選器件整體架構、資源分布結構、邏輯資源固有特性;熟悉邏輯設計總體方案、功能模塊數(shù)據(jù)流關系,各模塊資源情況。
模塊規(guī)劃
基本原則:
- 高內聚,低耦合。各個模塊功能內聚,最好功能單一(盡量一個模塊一個功能),模塊間接口簡潔;
- 資源均衡。各一級模塊的資源均衡,最大不能超過總資源的35%。功能分配合理,一級模塊內REG/LUT/RAM/DSP保持均衡,如REG:LUT控制在1.2~1.6間。
- 功能模塊接口定義合理,模塊間的連線最少,避免強時序要求握手接口;
- 模塊時鐘域最少;
- 主體數(shù)據(jù)流向單調,盡量不要出現(xiàn)反饋結構、環(huán)狀結構;
- 一級模塊間不允許存在功能性代碼(接口間打拍可以),模塊輸入、輸出信號寄存;
- 復位及CPU接口采用分布式處理(避免復位信號扇出太大),如下圖;
時鐘規(guī)劃
時鐘、復位網(wǎng)絡的global、regional資源使用和規(guī)劃原則:
- 專用的時鐘管腳必須通過專用走線驅動其專用的時鐘資源(GCLK/BUFG/MMCM等)
- 盡量保證時鐘通過專用時鐘管腳驅動內部邏輯;
- 根據(jù)時鐘驅動范圍及扇出能力,決定時鐘管腳驅動的時鐘資源(BUFG、BUFR、BUFH);
- 單個BANK(CLOCK REGION)的時鐘數(shù)量必須遵循器件的要求,不能超過器件的上限;
- 避免時鐘驅動器級聯(lián)。
PINMAP規(guī)劃
PINMAP布局要充分考慮片上系統(tǒng)數(shù)據(jù)流走向,減少交織、耦合。外圍接口(尤其高速接口)在bank選擇時,成組的管腳(如CPU/RGMII等)必須分布在同一個bank上或者相鄰bank上;控制信號管腳及其相關聯(lián)的數(shù)據(jù)管腳一起分布;多die器件時鐘和IO盡量放在使用模塊所在的die上。對于硬core的管腳以及相關邏輯region劃分,要遵守就近原則。
Routing resource
交通規(guī)劃時,不要出現(xiàn)局部走線資源超負荷導致?lián)砣?#xff08;congrestion),布局要提前考慮一級模塊區(qū)域劃分,均衡不同routing resource的占用情況;高內聚,盡可能提高local interconnects/direct links使用率。
模塊方案實現(xiàn)
模塊設計流程
資源要關注總資源是否符合預期;REG/LUT比是否均衡,通常1.2~1.6間,超過1.8就要關注了;另外是否有某項資源使用特別突出(BRAM/DSP…)。時序要關注組合邏輯級數(shù)和高扇出信號。
組合邏輯級數(shù)處理
如何控制邏輯級數(shù)(logic-level)?第一,要了解SLICE內部結構,Xilinx從6系列器件開始,SLICE中REG和LUT的比例提升至2:1,對于高速設計需要適當增加打拍流水,使得所有邏輯盡量滿足邏輯級數(shù)限制(對于350MHz設計,邏輯級數(shù)一般不能超過4級);第二,邏輯級數(shù)估計及檢查,通過計算組合邏輯函數(shù)輸入變量個數(shù),可以大致估算出邏輯級數(shù);通過實際綜合布線之后相關命令可以報出最大邏輯級數(shù)。
方法1:pipeline
pipeline時序優(yōu)化方法,其本質是在一個較長的組合邏輯路徑中,增加寄存器,用寄存器合理分割該組合邏輯的路徑,從而降低路徑Clock-To-Output和setup等時間參數(shù)的要求,達到提高設計頻率的目的。Pipeline提升性能的方法是對具有多個邏輯層次的長數(shù)據(jù)路徑進行重構,并將其分布在多個時鐘周期中。此方法可加速時鐘周期并增加數(shù)據(jù)吞吐量,但代價是時延和流水線開銷邏輯管理工作增加。由于器件包含許多寄存器,因此通常額外的寄存器和開銷邏輯不足為慮。但是,數(shù)據(jù)路徑將跨多個周期,需特別留意設計其余部分,并考量路徑時延增加的問題。
如下圖,CIC濾波器會有很多級加法器級聯(lián),而且位寬很大,尤其在積分器側,速率也高,容易成為關鍵路徑??梢园鸭臃ㄆ骱图拇嫫魑恢媒粨Q實現(xiàn)pipeline,但濾波器延遲會增大;可以折中只在積分器側加pipeline(無論抽取,還是插值,都是積分器工作在高速側)。
一定要提前考量流水打拍。提前而非滯后考量流水線有助于改進時序收斂。在后期對某些路徑添加流水線通常會導致在電路中產(chǎn)生傳輸時延差異。這可能導致看似微小的更改需要對部分代碼進行大幅重新設計。在設計中提前識別是否有機會添加流水線可以顯著改進時序收斂、實現(xiàn)運行時間(因為時序問題變得更易于解決)和器件功耗(因為相關邏輯切換次數(shù)減少)。某個項目上接收鏈路前端使用了4級CIC抽取濾波器,前期未加pipeline,到后期綜合時加法器處于關鍵路徑上,此時再加pipeline的話,DV環(huán)境上所有接收鏈路的時延都要調整,所有case都要重新回歸,代價非常大。
另外要通過添加pipeline來平衡時延,可以添加到控制路徑中,而不是數(shù)據(jù)路徑中。數(shù)據(jù)路徑包含更寬的總線,這可增加所使用的觸發(fā)器和寄存器資源的數(shù)量。
例如,如果有一條?128 位數(shù)據(jù)路徑、2 個寄存器階段并且需要 5 個時延周期,插入 3 個寄存器階段會導致額外產(chǎn)生 3x128 = 384 個觸發(fā)器。或者,可以使用寄存器來控制啟用數(shù)據(jù)路徑的邏輯。使用 5 個階段的單比特寄存器可分別控制數(shù)據(jù)路徑觸發(fā)器的使能信號和多周期路徑時序例外。
注意:此示例僅適用于某些設計。例如,如果在中間數(shù)據(jù)路徑觸發(fā)器中存在扇出,那么僅采用?2 個階段是無效的。
方法2:retiming
由于觸發(fā)器與函數(shù)發(fā)生器包含在相同?slice 內,時鐘速度受到下列要素的限制:源觸發(fā)器的時鐘輸出時間、貫穿?1 個邏輯層次的邏輯延遲、布線延遲,以及目標寄存器的建立時間。在此示例中,完成流水打拍和重定時之后,系統(tǒng)時鐘運行速度比原始設計中更快,但總的延遲未變化。
方法3:面積換時序--one-hot
將關鍵路徑的優(yōu)先級路徑(多級mux級聯(lián))轉換成one-hot邏輯,以面積換時序。
方法4:分支判斷優(yōu)化
分支判斷優(yōu)化,用casex/casez替換優(yōu)先級判斷
方法5:計數(shù)器優(yōu)化
計數(shù)器優(yōu)化,提前產(chǎn)生判斷條件,減少大位寬比較器的組合邏輯延遲。
方法6:partial case
Xilinx 7系列FPGA中,一個6輸入LUT最大只支持4MUX1,超過4個輸入將用多級LUT級聯(lián)。
方法7:priority
其中critial信號到寄存器D端是時序的關鍵路徑,通過變化代碼風格,時序路徑中的組合邏輯從2級減小到1級。
方法8:反饋環(huán)優(yōu)化
反饋環(huán)優(yōu)化,非反饋部分電路提前計算,插入流水(適用CRC/PRBS/擾碼等帶有反饋的電路)
高fanout信號處理
如何控制扇出(fanout)?需要考慮寄存器和網(wǎng)線兩種類型的扇出。Reg信號加max_fanout約束,對模塊總體加max_fanout約束,總體max_fanout約束值不宜設置太小,否則容易使資源增加,對時序產(chǎn)生負面影響;復制信號時,需要加keep約束,對reg和wire扇出過大都有效,需要人工分配復制的信號。
高fanout信號是高速設計的關鍵點之一。第一,在設計中減少不必要的負載。對于高扇出控制信號,請評估是否設計的所有編碼部分都需要該信號線。減少負載數(shù)量可以大幅度減少時序問題。第二,高fanout信號盡可能放在芯片die中間,或者其扇出邏輯區(qū)域的中心(對于時鐘信號網(wǎng)絡,不關心走線的絕對時延,只關心相對的skew,而一般的高fanout信號還要關注到各扇出點的絕對時延大小)。第三,全局復位信號走全局時鐘網(wǎng)絡,區(qū)域復位信號走區(qū)域時鐘網(wǎng)絡。第四,要根據(jù)不同時鐘域,扇出資源,約束合理的fanout值;一般寄存器扇出控制到200以內,BRAM控制到4~8,LUT控制到20以內;
第五,增加適當?shù)膒ipeline,或復制,避免long heavy local routing。
對于扇出大,時序耦合緊或用 CBB不便修改的,可以加綜合扇出域值約束,以通過寄存器復制來分流。寄存器保留用于代碼明確分流時不讓工具優(yōu)化;寄存器復制用于代碼中不明寫,而用工具產(chǎn)生復制的寄存器,從而提升關鍵路徑的速度。這便于實現(xiàn)工具更加靈活地對各類不同負載和相關邏輯進行布局布線。綜合工具廣泛采用了這種方法。大多數(shù)綜合工具使用扇出閾值限值來自動判定是否需要復制寄存器。降低此全局閾值即可自動復制高扇出信號線。但這樣就無法控制需復制的寄存器范圍以及這些寄存器的負載分組方式。此外,全局復制機制無法準確評估時序裕量,導致不必要的復制單元、邏輯占用率增加以及潛在功耗增加。對于高頻率設計,要減少扇出,最好對高扇出信號使用平衡樹??煽紤]根據(jù)設計層級手動復制寄存器,因為層級中包含的單元通常布局在一起。例如,在下圖所示的平衡復位樹中,在?RTL 中復制高扇出復位?FF RST2 以平衡不同模塊之間的扇出。如果需要,物理綜合可以基于布局信息執(zhí)行進一步的復制以改進?WNS。
注意:要在綜合中保留重復寄存器,請使用 KEEP 屬性,而不是 DONT_TOUCH。在實現(xiàn)流程后期進行物理優(yōu)化期間,DONT_TOUCH 屬性會阻止進行進一步最優(yōu)化。注釋:如果復制的是 LUT而不是寄存器,表明應用的屬性或約束錯誤。
|
切勿復制用于同步跨時鐘域的信號的寄存器。如果這些寄存器上存在?ASYNC_REG 屬性,將導致工具無法復制這些寄存器。如果同步鏈扇出極高且復制必須滿足時序要求,那么要在不含?ASYNC_REG 約束的同步鏈之后添加額外的寄存器(后面跨時鐘域章節(jié)再細講)。下表提供了適用于中等性能的 7 系列器件的扇出指南:
|
第六,避免高fanout信號級聯(lián)耦合。
專用資源處理
- 全局布線資源
時鐘,復位等高扇出信號等使用全局布線資源。全局網(wǎng)絡的驅動能力強,時延小,利于連接到多扇出。采用全局時鐘網(wǎng)絡,可以減小時鐘網(wǎng)絡的時延和相差,有利于同步,提高系統(tǒng)性能。盡量減少不必要的復位信號,對于數(shù)據(jù)的流水,建議不做復位處理或采用同步復位。若時鐘資源不足導致某時鐘無法上全局,可分析是否通過共享時鐘資源解決。
- SRL用于延遲處理
能采用SRL進行延遲處理的地方盡量使用SRL,一方面降低資源占用,更重要的是可以減少走線資源的占用,提高版本時序。SRL為純組合邏輯單元,使用時要遵守“三明治”原則:REG-SRL-REG,SRL的輸入輸出都要寄存器打拍。
- BRAM
BRAM資源充足的情況下,優(yōu)先使用BRAM。RAM深度很小時,也可以考慮用分布式RAM,但輸入輸出均要用寄存器打拍。大RAM建議用拼接深度的方式,有利于功耗優(yōu)化,地址譯碼部分一般需要加max_fanout約束,必要時,采用手工復制分配不同地址copy到各個BRAM單元。BRAM輸出要寄存,對應原語的DOA_REG/DOB_REG參數(shù)要配置1’b1.
RAM硬core的放置導致時序問題,若時序耦合緊,不易打拍,如果RAM是打2拍的,可將RAM改為1拍,在外部輸出再打1拍。FIFO硬core的放置導致的時序問題,若時序耦合緊,不易打拍,如果FIFO是打2拍的,可將FIFO改為1拍,在外部將輸出再打拍;如果FIFO是1拍的,就改為預讀的0拍FIFO,用讀使能去鎖存FIFO輸出。
- DSP
DSP SLICE為器件內部重要的高速單元,要充分利用其特性。大位寬(超過30bit)加減法建議使用DSP SLICE實現(xiàn)。在資源允許的情況下,盡量可能多的使用DSP SLICE用于設計,并且盡可能多的使用DSP內部資源完成特定功能(如預加、累加、寄存器等)。DSP SLICE盡可能采用級聯(lián)方式,級聯(lián)時,使用DSP專用高速走線資源,采用級聯(lián)方式可以大大降低邏輯走線資源占用(如復乘器,根據(jù)需要可以采用三DSP級聯(lián)或四DSP級聯(lián)的方式,三DSP級聯(lián)使用的DSP資源更少,四DSP復乘級聯(lián)可以實現(xiàn)更高的速度)。DSP SLICE內部寄存器開關要參考器件用戶手冊fmax的說明,一般來講MREG、PREG需要使能,A/B/D端至少需要一拍寄存。
代碼設計不易跑出好時序(硬CORE的輸出直接被大組合邏輯使用,硬CORE中未配置多余的寄存器流水),同時時序耦合緊不易修改。此時,在資源充裕的條件下,可考慮添加冗余硬CORE來進行分流,實現(xiàn)面積換時序。
- IOB
XILINX三態(tài)信號是否成功鎖IOB(若不成功需要對使能信號進行復制,并對使能寄存器設置綜合時不優(yōu)化)。要鎖IOB的信號是否已鎖成功(輸入信號必須打一拍后再使用,輸出的PIN管腳寄存器不能再使用,否則會導致鎖不了IOB)。使用管腳寄存器(I/O Registers),了解器件的IO特性與結構,I/0的應用盡量例化器件的IOB模塊,采用IO pad上的寄存器。
可重用設計重點語法
【向量及索引部分選擇】
Verilog語法中沒有向量的語法描述,簡單的說就是將位寬等分成多個部分形成一個向量。對于參數(shù)、模塊端口等不支持多維數(shù)組的情況可以考慮使用向量來增加設計的可重用性,如input wire [DW_IN*CHANNEL-1:0] din,din[DW_IN-1:0]為channel 0的輸入,din[2*DW_IN-1:DW_IN]為channel 1的輸入...。索引部分選擇是Verilog2001的語法,在向量索引中使用索引部分選擇更加簡潔方便有利于代碼的可重用設計。
【參數(shù)】
通過使用參數(shù)向量可以方便實現(xiàn)可變數(shù)目模塊的參數(shù)化,比如用參數(shù)向量來實現(xiàn)任意階濾波器系數(shù)的參數(shù)化。通過使用參數(shù)向量可以實現(xiàn)不同位寬信號的參數(shù)化處理。通過對參數(shù)進行復雜運算以及調用常數(shù)函數(shù)計算參數(shù)來增加設計的可重用性。
【常數(shù)函數(shù)】
常數(shù)函數(shù)是Verilog函數(shù)的一個可綜合子集,對于參數(shù)化設計非常重要,如parameter DW_B = $clog2(DW_A)。常數(shù)函數(shù)跟參數(shù)配合使用,用于復雜參數(shù)化設計。
【Generate語句】
通過generate-if和參數(shù)的配合替代可重用性較差的ifdef語句。靈活使用generate-if/generate-for以及各種嵌套方式有利于提高代碼可重用性。
子模塊綜合布線
解決時序問題的階段越早越好,子模塊代碼風格、質量對后端綜合布線結果影響很大,做好模塊的綜合布線檢查對于大版本時序收斂非常重要。
【子模塊綜合布線工具設置】
對于子模塊端口數(shù)超過FPGA器件管腳的情況需要對ISE或者VIVADO進行設置。ISE 中Xilinx Specific Options中去掉Add I/O Buffer,?Map Properties(Advanced)中去掉Trim Unconnected Signals;VIVADO中需要在綜合設置的More Options中加入-mode out_of_context。加入時序約束,最好同時加入位置約束限制布局布線的范圍。
【子模塊綜合布線檢查項】
時序裕量是否足夠;是否存在較大級數(shù)(logic-level)路徑,超過350M設計邏輯級數(shù)一般不宜超過4級是否存在較大扇出信號,一般扇出超過50都需要進行Review。子模塊綜合布線修改后需要重新綜合布線確認直至閉環(huán)。
【將邏輯從控制管腳推送到數(shù)據(jù)管腳】
分析關鍵路徑期間,可能會發(fā)現(xiàn)有多條路徑止于控制管腳。必須對這些路徑進行分析,以判定是否能夠將邏輯推送到數(shù)據(jù)路徑中,同時避免發(fā)生懲罰(例如,額外的邏輯層次)。相同邏輯層次的前提下,相比于指向?CE/R/S 管腳的路徑,指向?D 管腳的路徑的延遲較小,因為從最后一個 LUT 的輸出到 FF 的 D 輸入之間存在直接連接。以下編碼示例顯示了如何將邏輯從控制管腳推送到寄存器的數(shù)據(jù)管腳。在以下示例中,dout_reg[0] 的使能管腳的邏輯層次數(shù)為 2,而數(shù)據(jù)管腳的邏輯層次數(shù)則為 0。在此情況下,可通過將使能邏輯移至?D 管腳來改進時序,方法是在 RTL 文件中的 dout 寄存器定義上將 EXTRACT_ENABLE 屬性設置為“no”。
止于寄存器控制管腳(使能)的關鍵路徑
以下示例顯示了如何拆分組合邏輯和順序邏輯以及如何將完整邏輯映射到數(shù)據(jù)路徑中。這將把邏輯推送到仍含?2 個邏輯層次的?D 管腳中??赏ㄟ^將?EXTRACT_ENABLE 屬性設置為“no”來實現(xiàn)相同的結構。
止于寄存器的數(shù)據(jù)管腳(禁用使能提取)的關鍵路徑
后端設計
工具的綜合選項?
XST為例:
- 設置“Optimization Goal”為“Speed”,XST會盡量減少邏輯級數(shù)來改進時序;
- 設置“Max Fanout”為“200~1000”。默認的值是“100000”。這是一個全局的扇出約束,會影響所有信號。如果個別關鍵信號需要更低的扇出,請在RTL代碼里單獨設置扇出約束;
- 使能“Read Cores”可以使XST讀入EDIF或者NGC格式的Core,于是XST可以看到邏輯是如何互連的,因此可以優(yōu)化Core接口的邏輯來獲得更好的Timing;
- 在大多數(shù)情況下,使能“Register Duplication”可以提高Timing;
- 在大多數(shù)情況下,使能”Register Balance可以提高Timing;
- 設置“LUT Combining”為“No”。在大多數(shù)情況下,將“LUT Combining”設置為"Area”會降低Timing;
- Pack I/O Registers/Latches into IOBs對于I/O時序敏感的設計,推薦設置為“Yes”。這是一個全局的設置,會影響所有I/O。如果不同的IO需要不同的設置,推薦在UCF里單獨設置。
后端約束
【False-path使用原則】
不相關時鐘域信號或者靜態(tài)配置信號,可以對其進行false-path約束,確保布局布線不會分析這些路徑。而對于靜態(tài)配置信號,盡管這些路徑不一定會成為關鍵路徑,但還是要約束,因為工具布線時會把其他路徑布完之后最后再布false-path,這就避免了這些路徑和其他時序更緊張的路徑搶奪寶貴的布線資源。寫代碼時可以有意將靜態(tài)配置奇存器用特定規(guī)則命名,比如加上_cfg的后綴,這樣在約束時一個通配符就搞定了,而不需要一條條列舉出來。
【multi-cycle使用原則】
識別并約束multi-cycle路徑,減小時序壓力。通過加上multi-cycle約束來讓總線的時序在滿足要求的基礎上,盡可能的讓位于其他工作邏輯的時序收斂。比如CPU總線通常可增加multi-cycle約束。加該約束主要注意不要有遺漏,包括CPU總線譯碼模塊內部路徑、各總線子譯碼模塊內部總線到配置寄存器的路徑、配置寄存器到讀總線的路徑。CPU總線譯碼模塊可以配合加上位置約束,將其位置約束在FPGA的中心,使其到各模塊的走線均不會太長。
【位置約束使用原則】
復位信號的BUFG及前級寄存器、與serdes相連的寄存器、RAM及DSP的位置反標等。復位信號的路徑可以分成兩段,從復位信號寄存器到BUFG是前半段,以及從BUFG到目標寄存器是后半段。后半段路徑主要是通過不同的種子跑時序,將復位信號時序較好的種子對應的BUFG的位置固定反標;前半段路徑主要是手動將復位信號寄存器的位置固定在相應的BUFG旁邊,以盡量減少走線延時。與SERDES相連的FF最好做位置約束,約束到SERDES附近。通過約束RAM和DSP位置,疏導后端布局,提升工具布局效率