日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

FPGA经验分享——时序收敛之路

發(fā)布時間:2024/9/21 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FPGA经验分享——时序收敛之路 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

首先感謝 coyoo 博主一直以來在 EDN 上分享他的經(jīng)驗(yàn),也感謝他這次慷慨拿出新作與我們分享。

非常希望能夠拜讀?coyoo 博主的大作,尤其希望對虛擬 JTAG 技術(shù)有一個深入的了解。 這里分享一下之前自己優(yōu)化設(shè)計時序時的經(jīng)驗(yàn)總結(jié)。相同的內(nèi)容之前已經(jīng)發(fā)在自己的 EDN 博客中了,不算違規(guī)吧? 內(nèi)容分為五個部分(其實(shí)只有三個啦)。
  • PART1 引子
  • PART2 ISE 綜合選項(xiàng)設(shè)置
  • PART3 代碼風(fēng)格
  • PART4 高速電路的設(shè)計方法
  • PART5 結(jié)語
PART1 引子 第一次做比較大型的設(shè)計,結(jié)果真的很悲劇。

布局布線以后,靜態(tài)時序分析的結(jié)果和自己的預(yù)期相差很遠(yuǎn),和綜合后XST的估值也相差很遠(yuǎn)。時延里面,route時延占了絕大部分(logic占20%,route占80%)。

惡補(bǔ)了一些資料,給自己的設(shè)計總結(jié)了三個可能的問題:有些控制信號的扇出太大,沒有做位置約束,不好的代碼風(fēng)格。

決定在這里記錄自己通向時序收斂的過程。這不是一條平坦的路吧。

PART2 綜合選項(xiàng)設(shè)置

?

這里想說一下我對綜合選項(xiàng)的設(shè)置。設(shè)置的依據(jù)是ISE的幫助,網(wǎng)上的資料,以及自己的理解。請大家能為我指正設(shè)置得不合理的地方。沒有提及的選項(xiàng)采用缺省設(shè)置。采用的EDA軟件是ISE 13.2,綜合器為XST。

【Synthesis Options】

Use Synthesis Constraints File & Synthesis Constraints File:

一般來說,會在implement之前,采用UCF文件對設(shè)計進(jìn)行時序約束。實(shí)際上,在synthesis之前,可以先采用XCF文件對設(shè)計進(jìn)行時序約束,以使XST針對時序約束進(jìn)行synthesis,在synthesis時產(chǎn)生更好的網(wǎng)表。按照網(wǎng)上的說法,XCF中的時序約束應(yīng)當(dāng)要比實(shí)際需求更緊一些。

XCF文件的實(shí)際效果嘛。我談一下自己使用XST的情況吧。XST完成綜合(synthesis)后,會產(chǎn)生一個估計的最大工作頻率。某一次綜合后,我使用XCF文件將最大工作頻率約束的比XST的估值大一些,再重新進(jìn)行綜合后,XST給出的估值確實(shí)增大了少許。大部分時候,在重新綜合后是看不到效果的。至于對最終結(jié)果的影響,就不得而知了。

XCF文件的語法與UCF文件完全一致。與UCF不同,ISE沒有為XCF提供編輯的工具,只能自己用文本編輯器編輯。

Keep Hierarchy:

這個選項(xiàng)是設(shè)置是否在synthesis與implement中打破設(shè)計的層次結(jié)構(gòu)。選項(xiàng)【yes】和【no】很容易理解。選項(xiàng)【soft】的意思則是在綜合時不打破層次結(jié)構(gòu),而在之后打破層次結(jié)構(gòu)。

個人理解。打破層次結(jié)構(gòu)后,有些信號就變了,不利于分析與約束。而打破層次結(jié)構(gòu),更有利于電路的優(yōu)化。

【HDL Options】

FSM Encoding Algorithm:

有限狀態(tài)機(jī)的編碼方式。我采用了【One-Hot】(獨(dú)熱碼)。其優(yōu)缺點(diǎn)相信大家都非常清楚,不再贅述了。

Case Implementation Style:

case語句的實(shí)現(xiàn)方式。使用verilog時,缺省狀態(tài)下XST不會把case語句綜合成你想象的結(jié)構(gòu)。這點(diǎn),大家可以自己寫一段簡單的代碼試試。

以一個獨(dú)熱碼狀態(tài)機(jī)為例:

?

以下是代碼片段:
reg [2:0] sta;

case(1'b1)

sta[2]: ...;

sta[1]: ...;

sta[0]: ...;

endcase
?

?

首先,綜合出來的電路不止判斷一個比特。XST不知道sta只會出現(xiàn)3'b100、3'b010、3'b001三種可能,它會把諸如3'b101這樣的狀態(tài)也考慮在內(nèi),大概把電路綜合成如下的樣子:

?

以下是代碼片段:
reg [2:0] sta;

case (sta)

3'b001: ...;

3'b010: ...;

3'b100: ...;

default: ...;

endcase
?

這樣,采用獨(dú)熱碼似乎沒有什么意義。而且因?yàn)椴捎锚?dú)熱碼時,sta的比特數(shù)比采用格雷碼時更多,復(fù)雜度反而還增加了。

另外,XST也可能沒有把case語句轉(zhuǎn)換為并行結(jié)構(gòu),而是有優(yōu)先級的結(jié)構(gòu)。

【Case Implementation Style】中有三個選項(xiàng):【Full】、【Parallel】與【Full-Parallel】。其中,【Full】針對上述的第一點(diǎn),向XST說明有些狀態(tài)是不可能出現(xiàn)的,讓XST不要考慮太多;【Parallel】讓XST將case語句綜合為并行的電路結(jié)構(gòu);【Full-Parallel】則是兩者的結(jié)合。

對于狀態(tài)機(jī),這項(xiàng)設(shè)置的影響很大。器件為xc6vlx240t-1ff1156時,同樣代碼的8狀態(tài)獨(dú)熱碼狀態(tài)機(jī),缺省設(shè)置時占用11個寄存器、6個查找表,只能工作在575 MHz時鐘頻率下;改為【Full-Parallel】設(shè)置后,占用11個寄存器、3個查找表,可以工作在900 MHz時鐘頻率下。

【Xilinx Sepcific Options】

Max Fanout &?Register Duplication: 寄存器的最大扇出。扇出是一個門需要驅(qū)動的門數(shù)目。如果一個門的扇出很大,那么它的輸出布線將非常擁塞,布線的時延可能就會很長。在時序報告中,如果看到邏輯一條路徑的邏輯時延很短,但布線時延很長,很可能的原因就是信號的扇出太大。這樣,即使設(shè)計時保證了此處的組合邏輯很簡單,也無法減少時延。 一個有效的方法是寄存器復(fù)制。也就是說,像下圖一樣,為大扇出的門加入一些副本,讓這些完全相同的門來分擔(dān)扇出。寄存器復(fù)制可以通過代碼來實(shí)現(xiàn),不過顯然,這樣做是非常麻煩的。而【Max Fanout】這個選項(xiàng),能夠使XST自動實(shí)現(xiàn)寄存器復(fù)制。在綜合時,通過這個選項(xiàng)為所有寄存器都加上扇出的限制,一旦寄存器的扇出大于設(shè)置的值,XST會自動進(jìn)行寄存器復(fù)制。在我的設(shè)計中,將最大輸出設(shè)為20。 不過這么做沒法解決所有的問題。一方面,XST只能做寄存器復(fù)制,對于扇出大的組合邏輯,就沒有辦法了;另一方面,XST也無法跨越模塊進(jìn)行優(yōu)化。對于第一個問題,可以對大扇出的組合邏輯一級寄存器緩沖一下,這樣就可以復(fù)制了。對于第二個問題,采用扁平化的設(shè)計是一種方法,不過這樣會為設(shè)計帶來很大的困難。另一種方法,是在模塊的邊界處加入寄存器,即對模塊的輸入輸出都進(jìn)行緩存。這是比較推薦的做法。 順便提一句,在【Map Properties】中,同樣有【Register Duplication】的選項(xiàng)。該選項(xiàng)是根據(jù)時序約束(而非對扇出的限制)來進(jìn)行寄存器復(fù)制。 Equivalent Register Removal: 把設(shè)計中等效的寄存器去掉,合并為一個。顯然,這個選項(xiàng)讓人感覺與【Register Duplication】是互斥的。但是,在設(shè)置時,這兩個選項(xiàng)是能夠同時勾選的。因?yàn)椴恢劳瑫r勾選的效果會是怎樣的,我把這個選項(xiàng)前面的復(fù)選框去掉了。 要點(diǎn)總結(jié)
  • case 語句未必被綜合為并行電路。需要并行電路的話,需要設(shè)置【HDL Options】中的【Case Implementation Style】。
  • 配合【Max Fanout】與【Register Duplication】來進(jìn)行全局的寄存器復(fù)制,以減小扇出。
PART3 代碼風(fēng)格 引子中提到的那個設(shè)計,已經(jīng)基本完成了。優(yōu)化后,電路工作的時鐘頻率提升了一倍左右,還是有明顯效果的。 在通向時序收斂的路途中,Xilinx的一些白皮書、《高級FPGA設(shè)計-結(jié)構(gòu)、實(shí)現(xiàn)和優(yōu)化》、特權(quán)與rickysu等前輩的博文,都對我有很大的幫助。不過,在這一過程中,我還是強(qiáng)烈地感覺到相關(guān)的資料太少、太簡略。 現(xiàn)在回頭想想,能夠理解這種現(xiàn)象的原因了。畢竟是進(jìn)行FPGA設(shè)計,完成設(shè)計后,大量的工作還是要交給EDA工具。這之中,能夠人為干涉的內(nèi)容有限,干涉的效果也未必好。改進(jìn)時序的過程中,主要的工作還是在靜態(tài)時序分析的基礎(chǔ)上優(yōu)化代碼。 因此,我們要做的其實(shí)還是:在設(shè)計時寫出那些能夠被EDA工具高效綜合、便于EDA工具優(yōu)化的具有良好代碼風(fēng)格的HDL程序。在FPGA開發(fā)的過程中,我深深地體會到HDL是非常容易被誤用的。尤其是在初學(xué)的時候,因?yàn)閷﹄娐返睦斫獠粔蛏?#xff0c;常常寫出一些綜合效率很低的代碼?;蛟S,針對HDL的也需要一本《Effective C++》吧! 在這個部分中,主要介紹一些有利于優(yōu)化電路時序的代碼風(fēng)格。這些內(nèi)容主要來源于我自己對于專著與Xilinx的白皮書的理解,如果有理解錯誤的地方,還請指正。 1. 復(fù)位 能不用復(fù)位就不用復(fù)位;不能的話,采用同步復(fù)位。 從學(xué)習(xí)FPGA開始,大量的示例代碼中,模塊都帶有一個異步復(fù)位端口。這本身沒有什么問題:有些電路,比如計數(shù)器、狀態(tài)機(jī),寄存器沒有初值的結(jié)果是災(zāi)難性的;而FPGA中的寄存器單元又具有異步復(fù)位的引腳,何樂而不為? 然而,在大型設(shè)計中,這卻真的會帶來一些問題。 首先,如果所有模塊都帶有復(fù)位端口,復(fù)位信號就會具有很大的扇出,導(dǎo)致布線擁塞,影響電路的速度。而且大扇出信號到達(dá)不同模塊的時間,會有很大的差距。 XST本身會對這種扇出極大的信號(時鐘、復(fù)位等)進(jìn)行處理:將大扇出的信號接到BUFG上,以緩解大扇出信號的各種問題。不過,ISE映射(MAP)時對連接BUFG的管腳的類型有要求(必須為時鐘管腳),否則將報錯。如果確實(shí)無法采用時鐘管腳作為復(fù)位管腳,可在UCF文件中添加語句放寬這一限制(具體的語句忘了,如果真出現(xiàn)了這一錯誤,在ISE的錯誤報告中會告知解決方案)。 復(fù)位的另一個問題,是阻止了綜合器可能進(jìn)行的一些優(yōu)化,從而同時影響電路的速度與面積。這其中一個典型的例子,就是當(dāng)移位寄存器具有復(fù)位信號時,便無法采用SRL單元實(shí)現(xiàn)。其它的這一類問題主要是因?yàn)楫惒綇?fù)位造成的,將在之后介紹異步復(fù)位的內(nèi)容中介紹。 其實(shí),在FPGA設(shè)計中,有許多模塊確實(shí)不需要復(fù)位。在設(shè)計時,認(rèn)真考慮一下這一點(diǎn),去掉那些無用的復(fù)位信號。 下面來談?wù)劗惒綇?fù)位的問題。 異步復(fù)位的一個常見問題,是亞穩(wěn)態(tài)問題。這一問題在很多資料中均有闡述。簡單來說,就是異步復(fù)位信號的釋放可能正好發(fā)生在寄存器的保持/建立時間內(nèi)。這樣,復(fù)位是否被釋放是一種隨機(jī)的狀態(tài):有些寄存器處于復(fù)位狀態(tài),而有些寄存器的異步復(fù)位信號則已經(jīng)釋放,導(dǎo)致不可重復(fù)的隨機(jī)錯誤。這種錯誤如下圖所示。 另外,異步復(fù)位將阻止綜合器對電路進(jìn)行優(yōu)化。前文提到過,當(dāng)有些電路具有復(fù)位信號后,綜合器就無法對其進(jìn)行一些優(yōu)化。而另一種更常見的情況是,綜合器能夠針對同步復(fù)位的電路進(jìn)行一些優(yōu)化,而對異步復(fù)位的電路,則無法進(jìn)行這些優(yōu)化。在Xilinx的白皮書WP231《HDL Coding Practices to Accelerate Design Performance》中,舉了一些這類的例子。比如:
  • 同步復(fù)位電路能夠被綜合為性能更好的基于硬核(塊RAM、DSP等)的電路,異步復(fù)位電路則不能。
  • 綜合器能夠?qū)⑼綇?fù)位信號與其它信號放在一起優(yōu)化,而異步復(fù)位信號只是復(fù)位信號。
綜上所述,同步復(fù)位要優(yōu)于異步復(fù)位。采用同步復(fù)位時出現(xiàn)亞穩(wěn)態(tài)的可能性很小,而且電路可得到更好的優(yōu)化。 一些資料中提到,與異步復(fù)位相比,同步復(fù)位需要更多的寄存器(如下圖所示)。不過,實(shí)際上不用擔(dān)心這點(diǎn):較新的Xilinx器件中的寄存器都具有專門的同步復(fù)位端口,不需要額外的寄存器實(shí)現(xiàn)同步復(fù)位。 2. 條件判斷語句 在HDL代碼中,盡量不要使用多層嵌套的條件判斷語句。 這么做的原因是多層嵌套的代碼將被綜合為具有優(yōu)先級的電路。其中,最典型的例子是狀態(tài)機(jī)。 以一個4狀態(tài)的獨(dú)熱碼狀態(tài)機(jī)為例。
以下是代碼片段:
? ? ?reg [0:3] sta;

? ? ?always@(posedge clk)
? ? ?if (sta[0]) ...;
? ? ?end else if (sta[1]) ...;
? ? ?end else if (sta[2]) ...;
? ? ?end else if (sta[3]) ...;
如果使用上述代碼實(shí)現(xiàn)狀態(tài)機(jī),綜合出的電路是具有優(yōu)先級的電路。而如果采用下面的代碼實(shí)現(xiàn),并如 PART2 中所述,將【HDL Options】中的【Case Implementation Style】設(shè)為【Full-Parallel】,則綜合出的電路為并行結(jié)構(gòu),關(guān)鍵路徑明顯減小。
以下是代碼片段:
? ? ?reg [0:3] sta;

? ? ?always@(posedge clk)
? ? ?case(1'b1)
? ? ?sta[0]: ...;
? ? ?sta[1]: ...;
? ? ?sta[2]: ...;
? ? ?sta[3]: ...;
? ? ?endcase
兩者的差別可以參考下面的示意圖(A為優(yōu)先級結(jié)構(gòu),B為并行結(jié)構(gòu))。注意,只是示意圖,實(shí)際的電路與之有較大差別。 可以看到,在第一段代碼中,由于sta[0]、sta[1]、sta[2]、sta[3]的優(yōu)先級依次遞減,綜合而成的優(yōu)先級電路中有很長的組合邏輯鏈路,嚴(yán)重影響電路的速度;而第二段代碼綜合出的是并行電路,其關(guān)鍵路徑要短不少。我對8狀態(tài)的狀態(tài)機(jī)進(jìn)行了測試,并行電路的關(guān)鍵路徑僅有優(yōu)先級電路的一半。 為什么綜合器沒有把功能相同的電路優(yōu)化為相同的結(jié)構(gòu)?答案是兩者的邏輯其實(shí)并不相同。考慮sta為4'b0101的情況,優(yōu)先級電路的輸出與sta為4'b0100時的輸出一致;而并行電路的輸出則未知(這里指電路是并行結(jié)構(gòu);如果代碼是并行的,但未開啟之前所述的【Full-Parallel】選項(xiàng),也將被綜合為優(yōu)先級電路)。 所以說,綜合器并沒有問題。如果可能出現(xiàn)4'b0101,確實(shí)需要優(yōu)先級電路,否則電路將出現(xiàn)異常。但是,在獨(dú)熱碼狀態(tài)機(jī)中,不會出現(xiàn)4'b0101的情況,使用優(yōu)先級電路,是一種浪費(fèi)。 在實(shí)際設(shè)計時,有時候無法避免多層嵌套的邏輯。并不是什么時候都有替代的并行電路,該嵌套的時候還是得嵌套,畢竟實(shí)現(xiàn)功能是首要的目的。如果關(guān)鍵路徑確實(shí)無法滿足需求,就需要考慮進(jìn)行一些電路結(jié)構(gòu)上的變換了。這部分內(nèi)容,將在 PART4 中闡述。 3. 模塊的輸入輸出寄存器 通常需要用寄存器對模塊的輸入與輸出進(jìn)行緩存。 對于連接至其它異步電路的輸入輸出,緩存是必須的。否則,可能導(dǎo)致錯誤。此時,用寄存器緩存輸入,能夠減小亞穩(wěn)態(tài)發(fā)生的概率;用寄存器緩存輸出,能夠消除組合邏輯競爭與冒險帶來的毛刺。 如果輸入輸出連接的是同步電路呢?這時候,不緩存輸入輸出不會引發(fā)錯誤,但緩存仍有一定的必要性。 一方面,是基于寄存器復(fù)制的需求來考慮的。如 PART2 中所述,綜合器無法進(jìn)行跨模塊的寄存器復(fù)制。未經(jīng)緩存的輸入輸出,即使扇出很大,也不會被復(fù)制。 另一方面,不緩存輸入輸出,容易在模塊連接處形成關(guān)鍵路徑。與緩存輸入輸出的模塊相比,不緩存的模塊的輸入輸出門延時要大不少。雖然也會去注意控制輸入輸出門延時的大小,但是畢竟外部的情況是未知的,不確定的因素太多。與其如此,倒不如為輸入輸出添加緩存,將輸入輸出門延時降到最低。 當(dāng)然,也不是所有模塊都必須緩存輸入輸出。比如,只完成子模塊連接的頂層模塊,就不該緩存輸入輸出(其實(shí)都在子模塊內(nèi)部完成緩存了)。 另外,電路內(nèi)部的一些同步子模塊,如果能夠確保扇出不大,并且模塊之間不形成關(guān)鍵路徑的話,也可以考慮不緩存輸入輸出。不管怎么說,緩存需要占用資源,還帶來一個時鐘周期的延遲,并非免費(fèi)的午餐。 總結(jié)
  • 能不用復(fù)位就不用復(fù)位;不能的話,采用同步復(fù)位。
  • 盡量不要使用多層嵌套的條件判斷語句。
  • 一般情況下,需要用寄存器對模塊的輸入與輸出進(jìn)行緩存。
  • PART4 高速電路的設(shè)計方法 在上一個部分中,說明了幾種自己總結(jié)的利于設(shè)計出高速電路的代碼風(fēng)格。這里其實(shí)暗含著下面這樣的場景:電路已經(jīng)設(shè)計好了,而且已經(jīng)很棒,只是需要用風(fēng)格良好的 HDL 代碼進(jìn)行輸入,以保證綜合出的電路和設(shè)計的一樣好。 而在這一部分中,想討論一下怎樣設(shè)計高速電路。可以說,是進(jìn)行 HDL 輸入前的工作。 最初的時候,是沒有這個部分的。原因是這部分并非是自己總結(jié)的內(nèi)容,更多還是從前輩們那兒吸取的經(jīng)驗(yàn)。不過,少了這個部分,感覺有點(diǎn)缺乏完整性。畢竟 PART3 和 PART4 的內(nèi)容,只是一些小技巧。而且我想了一下,將獲取的知識再整理整理,也沒有什么不好的。 因此,這部分內(nèi)容是我對 Steve Kilts 的《高級 FPGA 設(shè)計:結(jié)構(gòu)、實(shí)現(xiàn)和優(yōu)化》第 1 章 1.3 節(jié)(4 至 13 頁)的總結(jié)。讀過這本書的朋友可以跳過這個部分了。其中的例子大都是我自己歸納后想出的簡單例子,可能還有些不妥之處,還請各位朋友指出。 這里強(qiáng)烈推薦這本書。一般的 FPGA 書中,講流程、接口的多,講電路結(jié)構(gòu)的感覺比較少,而這本書涉及的還挺多的;而比起 Parhi 的《VLSI 數(shù)字信號處理系統(tǒng):設(shè)計與實(shí)現(xiàn)》這種比較純粹的 IC 設(shè)計的專著(當(dāng)然這本也很好),這本書又和 FPGA 有著非常緊密的聯(lián)系。 1 增加寄存器層次 通過在組合邏輯中插入一級寄存器來優(yōu)化關(guān)鍵路徑。 考慮下圖所示的三輸入加法器。此時電路的關(guān)鍵路徑為兩個加法器的門延時。
    以下是代碼片段:
    always @ (posedge clk) begin
    ? ? ?// 第一層
    ? ? ?a_d <= a;
    ? ? ?b_d <= b;
    ? ? ?c_d <= c;
    ? ? ?// 第二層
    ? ? ?s <= m+c_d;
    end

    assign m = a_d+b_d;
    通過在兩個加法器之間引入一級寄存器,能夠?qū)㈥P(guān)鍵路徑縮短為一個加法器的門延時。當(dāng)然,這會帶來一個周期的時延,同時也引入了多余的寄存器,增加了電路面積。
    以下是代碼片段:
    always @ (posedge clk) begin
    ? ? ? ? ? // 第一層
    ? ? ?a_d <= a;
    ? ? ?b_d <= b;
    ? ? ?c_d <= c;
    ? ? ?// 第二層
    ? ? ?c_2d <= c_d;
    ? ? ?m <= a_d+c_d;
    ? ? ?// 第三層
    ? ? ?s <= m+c_2d;
    end
    2 并行結(jié)構(gòu) 與通常所說的通過增加并行路數(shù)從而提高吞吐量的并行架構(gòu)不同,這里指的是通過重新組織組合邏輯的結(jié)構(gòu),來優(yōu)化關(guān)鍵路徑。 考慮一個鏈狀的四輸入加法器電路。其關(guān)鍵路徑為三個加法器的門延時。
    以下是代碼片段:
    assign m1 = a+b;
    assign m2 = c+m1;
    assign s ?= d+m2;
    如果采用樹狀結(jié)構(gòu),則關(guān)鍵路徑僅為兩個加法器的門延時。
    以下是代碼片段:
    assign m1 = a+b;
    assign m2 = c+d;
    assign s ?= m1+m2;
    3 去除電路中的優(yōu)先級編碼 這點(diǎn)就是 PART3 中所說的“盡量不要使用多層嵌套的條件判斷語句”。 考慮一個四狀態(tài)的獨(dú)熱碼狀態(tài)機(jī),采用優(yōu)先級編碼的電路有四層組合邏輯。
    以下是代碼片段:
    ? ? ?reg [0:3] sta;

    ? ? ?always@(posedge clk)
    ? ? ?if (sta[0]) ...;
    ? ? ?end else if (sta[1]) ...;
    ? ? ?end else if (sta[2]) ...;
    ? ? ?end else if (sta[3]) ...;
    而如果使用 case 語句,并在【綜合選項(xiàng)】中設(shè)置好對應(yīng)的項(xiàng)目(見 PART2),得到的非優(yōu)先級編碼電路則是并行結(jié)構(gòu),速度更快。
    以下是代碼片段:
    ? ? ?reg [0:3] sta;

    ? ? ?always@(posedge clk)
    ? ? ?case(1'b1)
    ? ? ?sta[0]: ...;
    ? ? ?sta[1]: ...;
    ? ? ?sta[2]: ...;
    ? ? ?sta[3]: ...;
    ? ? ?endcase
    這里需要強(qiáng)調(diào)的是,如果電路的邏輯確實(shí)需要優(yōu)先級,還應(yīng)該使用嵌套的條件判斷語句,而不該盲目采用無優(yōu)先級的電路。 4 寄存器平衡(重定時) 電路的速度,是由關(guān)鍵路徑?jīng)Q定的。因此在設(shè)計電路時,如果有一條路徑的門延時特別長,其它路徑的門延時再短,該電路的速度也仍然很慢。因此,設(shè)計電路時,可以通過改變寄存器的位置,使得各路徑的門延時變得平均,以達(dá)到提高電路速度的目的。 考慮下面的五輸入加法器。可以看到,第一級寄存器和第二級寄存器之間的路徑長度是一個加法器的門延時,而第二級寄存器和第三級寄存器之間的關(guān)鍵路徑長度是三個加法器的門延時。因此,整個電路的關(guān)鍵路徑長度是三個加法器的門延時。
    以下是代碼片段:
    always @ (posedge clk) begin
    ? ? ?// 第一層
    ? ? ?a_d <= a;
    ? ? ?b_d <= b;
    ? ? ?c_d <= c;
    ? ? ?d_d <= d;
    ? ? ?e_d <= e;
    ? ? ?// 第二層
    ? ? ?m1 <= a_d+b_d;
    ? ? ?c_2d <= c_d;
    ? ? ?d_2d <= d_d;
    ? ? ?e_2d <= e_d;
    ? ? ?// 第三層
    ? ? ?s <= m4;
    end

    assign m2 = m1+c_2d;
    assign m3 = m2+d_2d;
    assign m4 = m3+e_2d;
    經(jīng)過寄存器平衡后,輸入輸出之間的邏輯關(guān)系沒有改變,但兩條路徑的長度都變?yōu)閮蓚€加法器的時延,整個電路的關(guān)鍵路徑長度縮短為兩個加法器的時延。
    以下是代碼片段:
    always @ (posedge clk) begin
    ? ? ?// 第一層
    ? ? ?a_d <= a;
    ? ? ?b_d <= b;
    ? ? ?c_d <= c;
    ? ? ?d_d <= d;
    ? ? ?e_d <= e;
    ? ? ?// 第二層
    ? ? ?m2 <= m1+c_d;
    ? ? ?d_2d <= d_d;
    ? ? ?e_2d <= e_d;
    ? ? ?// 第三層
    ? ? ?s <= m4;
    end

    assign m1 = a_d+b_d;
    assign m3 = m2+d_2d;
    assign m4 = m3+e_2d;
    在《高級 FPGA 設(shè)計:結(jié)構(gòu)、實(shí)現(xiàn)和優(yōu)化》中,還有一種“重新安排路徑”的策略。對于這點(diǎn),可能我的理解還不夠深,感覺這一策略和上面第二種策略類似:都是通過重新組織組合邏輯的結(jié)構(gòu),以提升電路速度。此處就不對這種策略進(jìn)行詳細(xì)的說明了。 總結(jié)
    • 最基本的策略:在組合邏輯中插入寄存器,通過引入時延與增大電路面積來提升電路速度。
    • 組合電路設(shè)計策略:提升組合邏輯的并行度,縮短門延時。
    • 條件判斷電路設(shè)計策略:不需要優(yōu)先級編碼的話,采用無優(yōu)先級的電路。
    • 整體設(shè)計策略:移動寄存器位置,平衡各組合邏輯路徑的門延時。
    PART5 結(jié)語 關(guān)于前一段時間優(yōu)化電路速度工作的總結(jié)到這里就結(jié)束了。 其實(shí)之前還打算通過使用位置約束,將各個模塊約束在較小的范圍內(nèi),以使 EDA 軟件實(shí)現(xiàn)出更優(yōu)化的電路。不過因?yàn)榻?jīng)驗(yàn)不足,實(shí)際操作時位置約束后性能反而更差。關(guān)于這點(diǎn),還需要進(jìn)一步的研究,也請朋友們指導(dǎo)一二。 (全文完)

總結(jié)

以上是生活随笔為你收集整理的FPGA经验分享——时序收敛之路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。