今天跟大家分享的內(nèi)容很重要,也是調(diào)試FPGA經(jīng)驗(yàn)的總結(jié)。隨著FPGA對時(shí)序和性能的要求越來越高,高頻率、大位寬的設(shè)計(jì)越來越多。在調(diào)試這些FPGA樣機(jī)時(shí),需要從寫代碼時(shí)就要小心謹(jǐn)慎,否則寫出來的代碼可能無法滿足時(shí)序要求。
問題一:沒有對設(shè)計(jì)進(jìn)行全面的約束導(dǎo)致綜合結(jié)果異常,比如沒有設(shè)置異步時(shí)鐘分組,綜合器對異步時(shí)鐘路徑進(jìn)行靜態(tài)時(shí)序分析導(dǎo)致誤報(bào)時(shí)序違例。
約束文件包括三類,建議用戶應(yīng)該將這三類約束文件分開寫在三個xdc/sdc文件中。
第一類是物理約束,它主要對設(shè)計(jì)頂層的輸入輸出引腳的分配約束、電平標(biāo)準(zhǔn)的約束,
如下圖所示:在quartus環(huán)境下,對pcie_rstn和pcie_refclk的電平標(biāo)準(zhǔn)和管腳進(jìn)行了約束。
如下圖所示:在vivado環(huán)境下,對rst_n和sys_clk_PCIe_p的電平標(biāo)準(zhǔn)和管教進(jìn)行了約束。
第二類是調(diào)試約束,用戶在使用ila調(diào)試時(shí),Vivado會自動生成相關(guān)ila的調(diào)試約束。 如下圖所示,這是Vivado自動生成的相關(guān)ila的調(diào)試約束。
第三類是時(shí)序約束,這類約束的種類最多,它包括時(shí)鐘周期約束、輸入輸出延遲約束、跨時(shí)鐘域路徑約束、多周期路徑約束、偽路徑約束等。 時(shí)鐘周期約束:用戶需要將設(shè)計(jì)中的所有時(shí)鐘進(jìn)行約束后,綜合器才能進(jìn)行合理的靜態(tài)時(shí)序分析。一個設(shè)計(jì)中的時(shí)鐘主要分為兩類:主時(shí)鐘和生成時(shí)鐘。主時(shí)鐘包括由全局時(shí)鐘引腳接入的時(shí)鐘、高速收發(fā)器的輸出時(shí)鐘。生成時(shí)鐘包括由MMCM/PLL產(chǎn)生的時(shí)鐘、用戶邏輯分頻產(chǎn)生的時(shí)鐘,建議用戶不要使用后者,因?yàn)樗ǔJ怯山M合邏輯或觸發(fā)器生成的時(shí)鐘,這種時(shí)鐘的歪斜、抖動、驅(qū)動能力都很差。對時(shí)鐘進(jìn)行約束時(shí),主要針對時(shí)鐘的頻率、占空比、抖動、不確定性等參數(shù)進(jìn)行約束。 全局時(shí)鐘引腳接入的時(shí)鐘約束舉例: 如下圖所示,在quatus環(huán)境下,對全局時(shí)鐘引腳接入的時(shí)鐘pcie_refclk進(jìn)行了約束,因?yàn)檎伎毡仁?0%,抖動和不確定性也采用默認(rèn)值,所以圖中只對頻率進(jìn)行了約束。
如下圖所示,在vivado環(huán)境下,對全局時(shí)鐘引腳接入的時(shí)鐘sys_clk_PCIe_p進(jìn)行了約束,因?yàn)檎伎毡仁?0%,抖動和不確定性也采用默認(rèn)值,所以圖中只對頻率進(jìn)行了約束。
高速收發(fā)器的輸出時(shí)鐘約束舉例:由于高速收發(fā)器通常是例化IP核來使用的,所以這種約束通常是IP核自帶的。 如下圖所示,在vivado環(huán)境下,PCIE IP核中對高速收發(fā)器的輸出時(shí)鐘進(jìn)行約束。
MMCM/PLL生成時(shí)鐘約束舉例: 如下圖所示,在quatus環(huán)境下,在sdc中加入以下命令,quatus會對所有PLL產(chǎn)生的時(shí)鐘進(jìn)行了約束。因?yàn)橛脩糁灰獙LL的輸入時(shí)鐘(通常情況下是主時(shí)鐘)進(jìn)行了約束,在sdc中加入以下命令后,quatus能夠根據(jù)輸入時(shí)鐘和輸出時(shí)鐘的關(guān)系自動推斷出PLL的輸出時(shí)鐘的時(shí)鐘周期、占空比、相位關(guān)系等。
如下圖所示,在vivado環(huán)境下,用戶對PCIE IP核中的MMCM的輸出時(shí)鐘進(jìn)行重命名,用戶只要確保對MMCM的輸入時(shí)鐘(通常情況下是主時(shí)鐘)進(jìn)行了約束,Vivado會自動能夠根據(jù)輸入時(shí)鐘和輸出時(shí)鐘的關(guān)系自動推斷出PLL的輸出時(shí)鐘的時(shí)鐘周期、占空比、相位關(guān)系等。
跨時(shí)鐘域約束:在介紹跨時(shí)鐘域之前,先介紹兩個概念:同步時(shí)鐘和異步時(shí)鐘。同步時(shí)鐘:當(dāng)兩個時(shí)鐘間的相位是固定的,則可以稱這兩個時(shí)鐘為同步時(shí)鐘。一般同源,如由同一個MMCM/PLL產(chǎn)生的兩個時(shí)鐘可以稱為同步時(shí)鐘。異步時(shí)鐘:無法判定兩個時(shí)鐘間相位時(shí),則可以稱這兩個時(shí)鐘為異步時(shí)鐘。兩個來自不同晶振的時(shí)鐘,一定是異步時(shí)鐘。通常情況下設(shè)計(jì)中不同的主時(shí)鐘肯定是異步時(shí)鐘。由不同的MMCM/PLL產(chǎn)生的兩個輸出時(shí)鐘即使頻率相同,但是由于相位關(guān)系不確定,所以也屬于異步時(shí)鐘。 用戶想要進(jìn)行跨時(shí)鐘域的約束,首先需要對設(shè)計(jì)中的所有時(shí)鐘進(jìn)行異步時(shí)鐘分組。若用戶沒有設(shè)置異步時(shí)鐘分組,綜合器在綜合時(shí)會認(rèn)為所有的時(shí)鐘都是相關(guān)的,從而對某些源時(shí)鐘與目的時(shí)鐘屬于異步時(shí)鐘關(guān)系的路徑進(jìn)行了靜態(tài)時(shí)序分析,由于源時(shí)鐘與目的時(shí)鐘的相位關(guān)系不確定,所以該路徑的建立時(shí)間或保持時(shí)間必定是存在違例的。若用戶設(shè)置了異步時(shí)鐘分組,Vivado在時(shí)序分析時(shí),當(dāng)源時(shí)鐘和目的時(shí)鐘屬于同一個時(shí)鐘組時(shí),才會分析此時(shí)序路徑;而源時(shí)鐘和目的時(shí)鐘屬于不同時(shí)鐘組時(shí),則會略過此時(shí)序路徑的分析。 那么如何進(jìn)行時(shí)鐘的異步分組呢?首先要按照上面提到同步時(shí)鐘和異步時(shí)鐘的概念對設(shè)計(jì)中的所有時(shí)鐘進(jìn)行分類,屬于異步時(shí)鐘關(guān)系的時(shí)鐘必定要劃分在不同的分組中,屬于同步時(shí)鐘關(guān)系的時(shí)鐘可以分在同一個分組也可以分在不同的分組中,如何劃分要看具體情況而定。 如下圖所示,在quatus環(huán)境下,對時(shí)鐘進(jìn)行異步時(shí)鐘分組的劃分,圖中主要有3類時(shí)鐘, 由全局時(shí)鐘引腳輸入的pcie_refclk,PCIE IP核中的MMCM輸出的時(shí)鐘(圖中用通配符*表示) Flash_pll輸出的兩個不同頻率的時(shí)鐘outclk0和outclk1。首先要確定全局時(shí)鐘引腳輸入的時(shí)鐘和PCIE IP核中的MMCM輸出的時(shí)鐘以及Flash_pll輸出的兩個不同頻率的時(shí)鐘屬于異步時(shí)鐘關(guān)系,它們必須要劃分在不同的分組中。但是,F(xiàn)lash_pll輸出的兩個不同頻率的時(shí)鐘outclk0和outclk1如何進(jìn)行劃分呢?首先,考慮一下設(shè)計(jì)中,outclk0和outclk1之間有沒有進(jìn)行數(shù)據(jù)交互,如果沒有數(shù)據(jù)交互,那么就將這兩個時(shí)鐘劃分在同一個時(shí)鐘分組即可,圖中就屬于這種情況。如果有數(shù)據(jù)交互,可以分為以下三種方案進(jìn)行操作: 1.將這兩個時(shí)鐘劃分在不同的時(shí)鐘分組,用戶在邏輯中進(jìn)行了跨時(shí)鐘域處理。(推薦使用) 2.將這個時(shí)鐘劃分在相同的時(shí)鐘分組,用戶在邏輯中進(jìn)行了跨時(shí)鐘域處理,在xdc/sdc中添加set_flase_path(偽路徑約束)禁止綜合器對跨時(shí)鐘域路徑(通常是雙觸發(fā)器同步的跨時(shí)鐘路徑)進(jìn)行靜態(tài)時(shí)序分析。 3. 將這個時(shí)鐘劃分在相同的時(shí)鐘分組,用戶邏輯中不需要進(jìn)行跨時(shí)鐘域處理,由后端保證時(shí)序。
偽路徑約束:偽路徑約束主要用于以下情況:1.上文提到的對通過雙觸發(fā)器同步的跨時(shí)鐘域路徑設(shè)置偽路徑。2.異步復(fù)位路徑
在vivado環(huán)境下,通過以下指令將異步復(fù)位路徑sys_rst_n 設(shè)置為偽路徑
set_false_path-from [get_ports sys_rst_n]
在quatus環(huán)境下,通過以下指令將異步復(fù)位路徑pcie_rstn 設(shè)置為偽路徑
set_false_path-from [get_ports pcie_rstn] -to *
判斷條件過長問題
問題二:一個always塊的判斷條件中的部分變量或賦值語句中的部分被賦值變量是直接由組合邏輯產(chǎn)生的。當(dāng)組合邏輯不是特別長時(shí)或FPGA的資源利用率比較低時(shí),這種時(shí)序問題很可能會被綜合器優(yōu)化處理掉。但是當(dāng)組合邏輯鏈路過長時(shí),尤其是大位寬的寄存器進(jìn)行邏輯運(yùn)算生成了較長的組合邏輯鏈路時(shí),這種代碼風(fēng)格導(dǎo)致的時(shí)序問題就會比較明顯,最終導(dǎo)致always塊的輸入信號的延時(shí)變大,建立時(shí)間違例。
有時(shí)序問題的代碼如下圖所示,req_start_addr_reg信號和PC_LAST_ADDR信號屬于位寬較大的寄存器,圖中有三個典型問題需要注意。
第一個需要注意的問題:PC_LAST_ADDR信號是一個組合邏輯鏈路的輸出信號,該組合邏輯鏈路是由邏輯運(yùn)算導(dǎo)致的。錯誤的地方在于PC_LAST_ADDR信號直接被當(dāng)做always塊的輸入信號使用,導(dǎo)致always塊的輸入信號的延時(shí)變大,建立時(shí)間違例。正確的處理方式應(yīng)該是將PC_LAST_ADDR信號打一拍后,再將打一拍后的輸出信號作為always塊的輸入信號使用。
第二個需要注意的問題:在always塊的第三個和第四個的判斷條件中都是先進(jìn)行了邏輯運(yùn)算后再進(jìn)行邏輯判斷的。這個問題的本質(zhì)和第一個問題相同,都是將組合邏輯的輸出信號直接作為always塊的輸入信號使用,導(dǎo)致always塊的輸入信號的延時(shí)變大,建立時(shí)間違例。正確的處理方式應(yīng)該是將組合邏輯單獨(dú)拎出來,然后將組合邏輯的輸出結(jié)果打一拍后,再將打一拍后的輸出信號作為always塊的輸入信號使用。而且在always塊的第三個和第四個的判斷條件中使用了三段式狀態(tài)機(jī)的n_state作為了判斷條件,原因同上。正確的處理方式應(yīng)該盡量使用c_state作為判斷條件。
第三個需要注意的問題:在always塊的第四個賦值語句中,將兩個信號進(jìn)行邏輯運(yùn)算后進(jìn)行賦值操作。這個問題的本質(zhì)和第一個問題相同,都是將組合邏輯的輸出信號直接作為always塊的輸入信號使用,導(dǎo)致always塊的輸入信號的延時(shí)變大,建立時(shí)間違例。正確的處理方式應(yīng)該是將組合邏輯單獨(dú)拎出來,然后將組合邏輯的輸出結(jié)果打一拍后,再將打一拍后的輸出信號作為always塊的輸入信號使用。 修改之后的代碼如下圖所示:
總結(jié):在編寫代碼時(shí),應(yīng)該注意以下三點(diǎn): 1.應(yīng)該盡量保證每一個always塊的判斷條件簡潔(判斷條件中盡量只進(jìn)行邏輯判斷,盡量避免邏輯運(yùn)算) 2.應(yīng)該盡量保證每一個always塊的判斷條件中的每一個變量都是直接來源于某個always塊輸出信號,盡量避免將組合邏輯的輸出直接作為某個always塊的判斷條件的一部分,這樣就可以保證每一個always塊的輸入信號的延時(shí)比較固定,有利于時(shí)序收斂。 3.應(yīng)該盡量保證每一個always塊的賦值語句中的被賦值變量都是直接來源于某個always塊輸出信號,盡量避免將組合邏輯的輸出直接作為某個always塊的賦值語句中的一部分,這樣就可以保證每一個always塊的輸入信號的延時(shí)比較固定,有利于時(shí)序收斂。
if else嵌套層數(shù)過多
問題三:always塊中的if…else…嵌套層數(shù)過多導(dǎo)致綜合問題 有時(shí)序問題的代碼如下圖所示,always塊中嵌套了三層if…else…,正確的處理方式應(yīng)該盡量減少always塊中if…else…的嵌套層數(shù)。
修改之后的代碼如下圖所示,
總結(jié): 在編寫代碼時(shí),應(yīng)該盡量減少always塊中的if…else…嵌套層數(shù).
邏輯信號扇出過大
問題四:部分用戶邏輯信號扇出過大,導(dǎo)致驅(qū)動能力不足。
有時(shí)序問題的代碼如下圖所示,圖中三個always塊產(chǎn)生了一組RAM的寫信號,這組信號作為55個always塊的輸入信號,也就是說該信號驅(qū)動了55個always塊,普通的信號的扇出能力一般在15-20左右。這組信號作為普通的用戶邏輯,如果采用加BUFG的方式來增加驅(qū)動能力,這樣不僅浪費(fèi)BUFG的資源,而且BUFG會給信號加入極大的延時(shí),這種延時(shí)對于有些高速設(shè)計(jì)來說也許是不可接受的,一般只有全局復(fù)位信號才會使用BUFG增加驅(qū)動能力。所以對于這種用戶邏輯信號,推薦采用復(fù)制寄存器的方式解決驅(qū)動能力不夠的問題。
修改之后的代碼如下圖所示:將原來的一組信號,復(fù)制了兩份,總共三組信號,且三組信號的邏輯相同,每組信號驅(qū)動的always塊的個數(shù)變成了原來的1/3。但是同時(shí)需要注意的問題是,這種復(fù)制的寄存器有極大的可能會被綜合器當(dāng)作等效寄存器優(yōu)化掉,為了防止綜合器多管閑事,在quatus下需要在聲明被復(fù)制的寄存器前面加上(* noprune *)告知綜合器此寄存器不需要優(yōu)化,在vivado下需要在聲明被復(fù)制的寄存器前面加上(* keep =“true”*)告知綜合器此寄存器不需要優(yōu)化。
總結(jié):在編寫代碼時(shí),需要注意信號驅(qū)動能力與扇出的問題,對扇出大的用戶邏輯信號進(jìn)行寄存器復(fù)制解決驅(qū)動能力不足的問題。對于全局復(fù)位信號,使用加BUFG解決驅(qū)動能力不足的問題。
數(shù)據(jù)選擇器過大
問題五:用戶需要使用大型的數(shù)據(jù)選擇器(8選1以上的選擇器)時(shí),如果直接使用組合邏輯的case語句實(shí)現(xiàn)大型數(shù)據(jù)選擇器,可能會導(dǎo)致以下問題:綜合器綜合速度變慢,邏輯資源占用率變大,數(shù)據(jù)選擇器的相關(guān)信號時(shí)序違例會很大,數(shù)據(jù)選擇器的輸出結(jié)果也會極不穩(wěn)定。
有時(shí)序問題的部分代碼如下圖所示:用戶需要一個128選1的數(shù)據(jù)選擇器,圖中直接使用了一個組合邏輯的case語句實(shí)現(xiàn)了128選1。正確的處理方式應(yīng)該是將一個128選1的選擇器,分為3級,第一級使用了16個8選1,第二級使用了2個8選1,第三級使用了1個2選1,總共消耗3個時(shí)鐘,選出最終的輸出結(jié)果,注意每一級的輸出結(jié)果都需要打一拍后再輸入到下一級進(jìn)行選擇。
修改之后的部分代碼如下圖所示,
總結(jié):大型數(shù)據(jù)選擇器不能直接使用組合邏輯的case語句實(shí)現(xiàn),在對選擇器的延時(shí)要求不是很高的情況下,最好將大型數(shù)據(jù)選擇器進(jìn)行分級選擇的處理。
大位寬RAM數(shù)據(jù)總線約束
問題六:高速設(shè)計(jì)中,RAM的輸出或寄存器的位寬太寬時(shí)(64bit以上),可能會出現(xiàn)在某個時(shí)鐘的上升沿時(shí),寄存器的某些bit由于布線導(dǎo)致路徑時(shí)延不一致,不能與其他bit的數(shù)據(jù)在同一個時(shí)鐘上升沿到達(dá),導(dǎo)致用戶采樣到數(shù)據(jù)出現(xiàn)錯誤或者采樣到亞穩(wěn)態(tài)。所以,用戶要使用某個數(shù)據(jù)位寬很寬的寄存器時(shí),無論這個寄存器數(shù)據(jù)來源于FIFO還是來源于用戶邏輯,建議先將該寄存器打拍,然后使用打拍后的數(shù)據(jù),這樣更有利于時(shí)序收斂。 但如果從RAM里面輸出的大位寬的數(shù)據(jù)總線經(jīng)過打拍后仍然不穩(wěn)定又該怎么辦呢?筆者在實(shí)際調(diào)試過程中發(fā)現(xiàn),采用對使用大位寬總線RAM的時(shí)鐘信號進(jìn)行約束的方法非常有效。具體實(shí)現(xiàn)跟FPGA外圍管腳時(shí)鐘信號約束的方法一樣,比如下圖中在vivado工具中可以對設(shè)計(jì)中內(nèi)部某個用到大位寬的RAM的時(shí)鐘進(jìn)行創(chuàng)建即可。
總結(jié):大位寬的數(shù)據(jù)總線需要保持?jǐn)?shù)據(jù)傳輸過程中時(shí)延的一致性,盡可能的多采用時(shí)序邏輯,同時(shí)對于大位寬RAM的時(shí)鐘要進(jìn)行約束。
責(zé)任編輯:彭菁
-
FPGA
+關(guān)注
關(guān)注
1641文章
21910瀏覽量
611622 -
時(shí)鐘
+關(guān)注
關(guān)注
11文章
1855瀏覽量
132632 -
時(shí)序
+關(guān)注
關(guān)注
5文章
395瀏覽量
37709 -
代碼
+關(guān)注
關(guān)注
30文章
4876瀏覽量
69956 -
Vivado
+關(guān)注
關(guān)注
19文章
823瀏覽量
67869
原文標(biāo)題:FPGA設(shè)計(jì)中大位寬、高時(shí)鐘頻率時(shí)序問題調(diào)試經(jīng)驗(yàn)總結(jié)
文章出處:【微信號:FPGA研究院,微信公眾號:FPGA研究院】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
FPGA入門學(xué)習(xí)經(jīng)驗(yàn)總結(jié)(轉(zhuǎn))
15條經(jīng)驗(yàn)總結(jié),讓FPGA設(shè)計(jì)更簡單!
調(diào)試FRAM經(jīng)驗(yàn)總結(jié)
FPGA的約束設(shè)計(jì)和時(shí)序分析
SOPC Builder/Nios 學(xué)習(xí)經(jīng)驗(yàn)總結(jié)

開關(guān)電源測量的經(jīng)驗(yàn)總結(jié)
模擬電路設(shè)計(jì)經(jīng)驗(yàn)總結(jié)
基于verilog的FPGA編程經(jīng)驗(yàn)總結(jié)

Xilinx FPGA時(shí)序約束設(shè)計(jì)和分析
FPGA時(shí)鐘頻率時(shí)序問題調(diào)試經(jīng)驗(yàn)總結(jié)

評論