系統(tǒng)的比較,與大家共享:
盡管FPGA和CPLD都是可編程ASIC器件,有很多共同特點,但由于CPLD和FPGA結構上的差異,具有各自的特點:
①CPLD更適合完成各種算法和組合邏輯,FP GA更適合于完成時序邏輯。換句話說,FPGA更適合于觸發(fā)器豐富的結構,而CPLD更適合于觸發(fā)器有限而乘積項豐富的結構。
②CPLD的連續(xù)式布線結構決定了它的時序延遲是均勻的和可預測的,而FPGA的分段式布線結構決定了其延遲的不可預測性。
③在編程上FPGA比CPLD具有更大的靈活性。CPLD通過修改具有固定內(nèi)連電路的邏輯功能來編程,FPGA主要通過改變內(nèi)部連線的布線來編程;FP GA可在邏輯門下編程,而CPLD是在邏輯塊下編程。
④FPGA的集成度比CPLD高,具有更復雜的布線結構和邏輯實現(xiàn)。
⑤CPLD比FPGA使用起來更方便。CPLD的編程采用E2PROM或FASTFLASH技術,無需外部存儲器芯片,使用簡單。而FPGA的編程信息需存放在外部存儲器上,使用方法復雜。
⑥CPLD的速度比FPGA快,并且具有較大的時間可預測性。這是由于FPGA是門級編程,并且CLB之間采用分布式互聯(lián),而CPLD是邏輯塊級編程,并且其邏輯塊之間的互聯(lián)是集總式的。
⑦在編程方式上,CPLD主要是基于E2PROM或FLASH存儲器編程,編程次數(shù)可達1萬次,優(yōu)點是系統(tǒng)斷電時編程信息也不丟失。CPLD又可分為在編程器上編程和在系統(tǒng)編程兩類。FPGA大部分是基于SRAM編程,編程信息在系統(tǒng)斷電時丟失,每次上電時,需從器件外部將編程數(shù)據(jù)重新寫入SRAM中。其優(yōu)點是可以編程任意次,可在工作中快速編程,從而實現(xiàn)板級和系統(tǒng)級的動態(tài)配置。
⑧CPLD保密性好,FPGA保密性差。
⑨一般情況下,CPLD的功耗要比FPGA大,且集成度越高越明顯。
隨著復雜可編程邏輯器件(CPLD)密度的提高,數(shù)字器件設計人員在進行大型設計時,既靈活又容易,而且產(chǎn)品可以很快進入市場。許多設計人員已經(jīng)感受到CPLD容易使用、時序可預測和速度高等優(yōu)點,然而,在過去由于受到CPLD密度的限制,他們只好轉向FPGA和ASIC?,F(xiàn)在,設計人員可以體會到密度高達數(shù)十萬門的CPLD所帶來的好處。
CPLD結構在一個邏輯路徑上采用1至16個乘積項,因而大型復雜設計的運行速度可以預測。因此,原有設計的運行可以預測,也很可靠,而且修改設計也很容易。CPLD在本質(zhì)上很靈活、時序簡單、路由性能極好,用戶可以改變他們的設計同時保持引腳輸出不變。與FPGA相比,CPLD的I/O更多,尺寸更小。
如今,通信系統(tǒng)使用很多標準,必須根據(jù)客戶的需要配置設備以支持不同的標準。CPLD可讓設備做出相應的調(diào)整以支持多種協(xié)議,并隨著標準和協(xié)議的演變而改變功能。這為系統(tǒng)設計人員帶來很大的方便,因為在標準尚未完全成熟之前他們就可以著手進行硬件設計,然后再修改代碼以滿足最終標準的要求。CPLD的速度和延遲特性比純軟件方案更好,它的NRE費用低於ASIC,更靈活,產(chǎn)品也可以更快入市。CPLD可編程方案的優(yōu)點如下:
●邏輯和存儲器資源豐富(Cypress Delta39K200的RAM超過480 Kb)
●帶冗余路由資源的靈活時序模型
●改變引腳輸出很靈活
●可以裝在系統(tǒng)上后重新編程
●I/O數(shù)目多
●具有可保證性能的集成存儲器控制邏輯
●提供單片CPLD和可編程PHY方案
由于有這些優(yōu)點,設計建模成本低,可在設計過程的任一階段添加設計或改變引腳輸出,可以很快上市
CPLD的結構
CPLD是屬於粗粒結構的可編程邏輯器件。它具有豐富的邏輯資源(即邏輯門與寄存器的比例高)和高度靈活的路由資源。CPLD的路由是連接在一起的,而FPGA的路由是分割開的。FPGA可能更靈活,但包括很多跳線,因此速度較CPLD慢。
CPLD以群陣列(array of clusters)的形式排列,由水平和垂直路由通道連接起來。這些路由通道把信號送到器件的引腳上或者傳進來,并且把CPLD內(nèi)部的邏輯群連接起來。
CPLD之所以稱作粗粒,是因為,與路由數(shù)量相比,邏輯群要大得到。CPLD的邏輯群比FPGA的基本單元大得多,因此FPGA是細粒的。
CPLD的功能塊
CPLD最基本的單元是宏單元。一個宏單元包含一個寄存器(使用多達16個乘積項作為其輸入)及其它有用特性。
因為每個宏單元用了16個乘積項,因此設計人員可部署大量的組合邏輯而不用增加額外的路徑。這就是為何CPLD被認為是“邏輯豐富”型的。
宏單元以邏輯模塊的形式排列(LB),每個邏輯模塊由16個宏單元組成。宏單元執(zhí)行一個AND操作,然后一個OR操作以實現(xiàn)組合邏輯。
每個邏輯群有8個邏輯模塊,所有邏輯群都連接到同一個可編程互聯(lián)矩陣。
每個群還包含兩個單端口邏輯群存儲器模塊和一個多端口通道存儲器模塊。前者每模塊有8,192b存儲器,后者包含4,096b專用通信存儲器且可配置為單端口、多端口或帶專用控制邏輯的FIFO。
CPLD有什麼好處?
I/O數(shù)量多
CPLD的好處之一是在給定的器件密度上可提供更多的I/O數(shù),有時甚至高達70%。
時序模型簡單
CPLD優(yōu)于其它可編程結構之處在于它具有簡單且可預測的時序模型。這種簡單的時序模型主要應歸功于CPLD的粗粒度特性。
CPLD可在給定的時間內(nèi)提供較寬的相等狀態(tài),而與路由無關。這一能力是設計成功的關鍵,不但可加速初始設計工作,而且可加快設計調(diào)試過程。
粗粒CPLD結構的優(yōu)點
CPLD是粗粒結構,這意味著進出器件的路徑經(jīng)過較少的開關,相應地延遲也小。因此,與等效的FPGA相比,CPLD可工作在更高的頻率,具有更好的性能。
CPLD的另一個好處是其軟件編譯快,因為其易于路由的結構使得布放設計任務更加容易執(zhí)行。
細粒FPGA結構的優(yōu)點
FPGA是細粒結構,這意味著每個單元間存在細粒延遲。如果將少量的邏輯緊密排列在一起,FPGA的速度相當快。然而,隨著設計密度的增加,信號不得不通過許多開關,路由延遲也快速增加,從而削弱了整體性能。CPLD的粗粒結構卻能很好地適應這一設計布局的改變。
靈活的輸出引腳
CPLD的粗粒結構和時序特性可預測,因此設計人員在設計流程的后期仍可以改變輸出引腳,而時序仍保持不變。
新的CPLD封裝
CPLD有多種密度和封裝類型,包括單芯片自引導方案。自引導方案在單個封裝內(nèi)集成了FLASH存儲器和CPLD,無須外部引導單元,從而可降低設計復雜性并節(jié)省板空間。在給定的封裝尺寸內(nèi),有更高的器件密度共享引腳輸出。這就為設計人員提供了“放大”設計的便利,而無須更改板上的引腳輸出。
/<br>
經(jīng)常會看到在狀態(tài)機設計中別人使用各種不同的編碼方式,那么一般情況下,這種編碼方式的選擇依據(jù)是什么?
我們知道,在數(shù)字邏輯設計中最常用的有三種編碼方式:二進制,格雷碼 Gray,獨熱編碼One-hot One hot 編碼使用一組碼元,每一個碼元僅有1bit有效,例如
IDLE = 0001,
WRITE = 0010,
READ = 0100,
WAIT = 1000
這種編碼的譯碼部分可以最簡,因此可以總結出One-hot編碼的特點:
組合邏輯最少,觸發(fā)器最多,工作時鐘頻率可以做到最高。
FPGA 的一個最小結構單元(CLB/LE)中含有查找表(實現(xiàn)組合邏輯)和DFF(實現(xiàn)時序邏輯),布局布線最好的結果是同一個結構單元中的查找表和DFF都使用,但是大部分情況是僅使用其中一種資源,這樣另外的資源就是閑置而浪費。而CPLD中DFF資源本來就很少,由此可見One-hot編碼更適合于 FPGA設計,而不適合CPLD設計,在CPLD中應該選擇二進制編碼。
IC設計中,應該綜合考慮。因為One-hot編碼使用DFF會大大增加設計面積(die size),因此在時序可以滿足的條件下盡可能使用二進制編碼。就面積與速度的折中考慮來說Gray碼是最好的選擇,當然Gray碼還有其他很多好的特性,暫時不屬于這次討論的范疇。一般的綜合工具對狀態(tài)機進行綜合時都可以讓用戶對這三種編碼進行選擇。基本依據(jù)就以上所說。
二進制與格雷碼之間的轉換
自然二進制碼轉換成二進制格雷碼,其法則是保留自然二進制碼的最高位作為格雷碼的最高位,而次高位格雷碼為二進制碼的高位與次高位相異或,而格雷碼其余各位與次高位的求法相類似
二進制格雷碼轉換成自然二進制碼,其法則是保留格雷碼的最高位作為自然二進制碼的最高位,而次高位自然二進制碼為高位自然二進制碼與次高位格雷碼相異或,而自然二進制碼的其余各位與次高位自然二進制碼的求法相類似
通過減少寄存器間的邏輯延時來提高工作頻率,或通過流水線設計來優(yōu)化數(shù)據(jù)處理時的數(shù)據(jù)通路來滿足高速環(huán)境下FPGA或CPLD中的狀態(tài)機設計要求。本文給出了采用這些技術的高速環(huán)境狀態(tài)機設計的規(guī)范及分析方法和優(yōu)化方法,并給出了相應的示例。
為了使FPGA或CPLD中的狀態(tài)機設計滿足高速環(huán)境要求,設計工程師需要認識到以下幾點:寄存器資源和邏輯資源已經(jīng)不是問題的所在,狀態(tài)機本身所占用的FPGA或CPLD邏輯資源或寄存器資源非常小;狀態(tài)機對整體數(shù)據(jù)流的是串行操作,如果希望數(shù)據(jù)處理的延時非常小,就必須提高操作的并行程度,壓縮狀態(tài)機中狀態(tài)轉移的路徑長度;高速環(huán)境下應合理分配狀態(tài)機的狀態(tài)及轉移條件。本文將結合實際應用案例來說明。
狀態(tài)機設計規(guī)范
1. 使用一位有效的方式進行狀態(tài)編碼
狀態(tài)機中狀態(tài)編碼主要有三種:連續(xù)編碼(sequential encoding)、一位有效(one-hot encoding)方式編碼以及不屬于這兩種的編碼。例如,對于一個5個狀態(tài)(State0~State4)的狀態(tài)機,連續(xù)編碼方式狀態(tài)編碼為:State0-000、State1-001、State2-010、State3-011、State4-100。一位有效方式為下為:State0-00001、State1-00010、State2-00100、State3-01000、State4-10000。對于自行定義的編碼則差別很大,例如試圖將狀態(tài)機的狀態(tài)位直接作為輸出所需信號,這可能會增加設計難度。
使用一位有效編碼方式使邏輯實現(xiàn)更簡潔,因為一個狀態(tài)只需要用一位來指示,而為此增加的狀態(tài)寄存器數(shù)目相對于整個設計來說可以忽略。一位有效至少有兩個含義:對每個狀態(tài)位,該位為1對應唯一的狀態(tài),判斷當前狀態(tài)是否為該狀態(tài),只需判斷該狀態(tài)位是否為1;如果狀態(tài)寄存器輸入端該位為1,則下一狀態(tài)將轉移為該狀態(tài),判斷下一狀態(tài)是否為該狀態(tài),只需判斷表示下一狀態(tài)的信號中該位是否為1。
2. 合理分配狀態(tài)轉移條件
在狀態(tài)轉移圖中,每個狀態(tài)都有對應的出線和入線,從不同狀態(tài)經(jīng)不同的轉移條件到該狀態(tài)的入線數(shù)目不能太多。以采用與或邏輯的CPLD設計來分析,如果這樣的入線太多則將會需要較多的乘積項及或邏輯,這就需要更多級的邏輯級聯(lián)來完成,從而增加了寄存器間的延遲;對于FPGA則需要多級查找表來實現(xiàn)相應的邏輯,同樣會增加延遲。狀態(tài)機的應用模型如圖1所示。
狀態(tài)機設計的分析方法
狀態(tài)機設計的分析方法可以分為兩種:一種是流程處理分析,即分析數(shù)據(jù)如何分步處理,將相應處理的步驟依次定為不同狀態(tài),該方法能夠分析非常復雜的狀態(tài)機,類似于編寫一個軟件程序的分析,典型設計如讀寫操作和數(shù)據(jù)包字節(jié)分析;另一種方法是關鍵條件分析,即根據(jù)參考信號的邏輯條件來確定相應的狀態(tài),這樣的參考信號如空或滿指示、起始或結束、握手應答信號等。這兩種分析方法并沒有嚴格的界限,在實際的狀態(tài)機設計分析時往往是這兩種方法結合使用。下面分別說明這兩種分析方法。
1. 流程處理分析
例如,在一個讀取ZBT SRAM中數(shù)據(jù)包的設計中,要根據(jù)讀出的數(shù)據(jù)中EOP(End of Packet)信號是否為1來決定一個包的讀操作是否結束,由于讀取數(shù)據(jù)的延后,這樣就會從ZBT SRAM中多讀取數(shù)據(jù),為此可以設計一個信號VAL_out來過濾掉多讀的數(shù)據(jù)。
根據(jù)數(shù)據(jù)到達的先后及占用的時鐘周期數(shù),可以設計如圖2所示的狀態(tài)機(本文設定:文字說明及插圖中當前狀態(tài)表示為s_State[n:0],為狀態(tài)寄存器的輸出;下一狀態(tài)next_State[n:0],為狀態(tài)寄存器的輸入;信號之間的邏輯關系采用Verilog語言(或C語言)中的符號表示;#R表示需要經(jīng)過一級寄存器,輸出信號對應寄存器的輸出端)。該狀態(tài)機首先判斷是否已經(jīng)到達包尾,如果是,則依次進入6個等待狀態(tài),等待狀態(tài)下的數(shù)據(jù)無效,6個等待狀態(tài)結束后將正常處理數(shù)據(jù)。
2. 關鍵條件分析
圖3為一個路由器線卡高速數(shù)據(jù)包分發(fā)處理的框圖,較高速率的數(shù)據(jù)包經(jīng)過分發(fā)模塊以包為單位送往兩個較低速率數(shù)據(jù)通路(即寫入FIFO1或FIFO2)。
對于分發(fā)模塊設計,關鍵參考信號是EOP及快滿信號AF1、AF2,參考EOP可以實現(xiàn)每次處理一個包,參考AF1、AF2信號可以決定相應的包該往哪個FIFO中寫入。分發(fā)算法為:FIFO1未滿(AF1=0),數(shù)據(jù)包將寫入FIFO1;如果FIFO1將滿且FIFO2未滿(AF1=1,且AF2=0),則下一數(shù)據(jù)包將寫入FIFO2;如果FIFO1、FIFO2都將滿(AF1=1且AF2=1),則進入丟包狀態(tài)。狀態(tài)機描述如圖4所示:UseFifo1狀態(tài)下數(shù)據(jù)包將寫入FIFO1,UseFifo2狀態(tài)下數(shù)據(jù)包將寫入FIFO2,丟包狀態(tài)下數(shù)據(jù)包被丟棄,提供丟包計數(shù)使能DropCountEnable。
狀態(tài)機的進一步優(yōu)化
1. 利用一位有效編碼方式HSPACE=12 ALT="圖2:對從ZBT RAM已讀出的包數(shù)據(jù)的過濾處理的狀態(tài)機。">
如前所述,狀態(tài)機的工作頻率跟狀態(tài)機中各個狀態(tài)對應的不同轉移條件的入線數(shù)目有關。如果到一個狀態(tài)的轉移條件相同但入線數(shù)非常多,其邏輯實現(xiàn)很可能并不復雜。在一位有效編碼方式下,對于某個狀態(tài),如果其他所有狀態(tài)經(jīng)相同的轉移條件到該狀態(tài),那么其邏輯實現(xiàn)可以很好地化簡。
例4:一位有效編碼方式下狀態(tài)位s_State[n:0]中,
s_State[1] | s_State[2] | ... | s_State[n]=1與 s_State[0]=1等價,那么
next_State[0]=(s_State[0]&S) | (s_State[1]&T) | (s_State[2]&T) | ... | (s_State[n]) 可以化簡為:
next_State[0]=(s_State[0]&S) | ((~s_State[0])&T),右端輸入信號數(shù)目大大減少。
2. 利用寄存器的使能信號
多數(shù)FPGA或CPLD寄存器提供使能端,如果所有的狀態(tài)機轉移必須至少滿足某個條件,那么這個條件可以通過使能信號連接實現(xiàn),從而可以降低寄存器輸入端的邏輯復雜度。如上例中不同狀態(tài)間轉移必須以EOP為1作為前提,因而可以將該信號作為使能信號來設計。
3. 結合所選FPGA或CPLD內(nèi)部邏輯單元結構編寫代碼
以Xilinx FPGA為例,一個單元內(nèi)2個4輸入查找表及相關配置邏輯可以實現(xiàn)5個信號輸入的最復雜的邏輯,或8~9個信號的簡單邏輯(例如全與或者全或),延時為一級查找表及配置邏輯延時;如果將相鄰單元的4個4輸入查找表輸出連接到一個4輸入查找表,那么可以實現(xiàn)最復雜的6輸入邏輯,此時需要兩級查找表延時及相關配置邏輯延時。更復雜的邏輯需要更多的級連來實現(xiàn)。針對高速狀態(tài)機的情況,可以盡量將狀態(tài)寄存器輸入端的邏輯來源控制在7個信號以內(nèi),從而自主控制查找表的級連級數(shù),提高設計的工作頻率。
4. 通過修改狀態(tài)機
如果一個狀態(tài)機達不到工作頻率要求,則必須根據(jù)延時最大路徑修改設計,通常的辦法有:改變狀態(tài)設置,添加新狀態(tài)或刪除某些狀態(tài),簡化轉移條件及單個狀態(tài)連接的轉移數(shù)目;修改轉移條件設置,包括改變轉移條件的組合,以及將復雜的邏輯改為分級經(jīng)寄存器輸出由寄存器信號再形成的邏輯,后者將會改變信號時序,因而可能需要改變狀態(tài)設置。
5. 使用并行邏輯
很多情況下要參考的關鍵信號可能非常多,如果參考這些關鍵信號直接設計狀態(tài)機所得到的結果可能很復雜,個別狀態(tài)的出線或入線將會非常多,因而將降低工作頻率??梢钥紤]通過設計并行邏輯來提供狀態(tài)機的關鍵信號以及所需的中間結果,狀態(tài)機負責維護并行邏輯以及產(chǎn)生數(shù)據(jù)處理的流程。并行邏輯應分級設計,級間為寄存器,從而減少寄存器到寄存器的延時。
圖5為一個使用并行邏輯的狀態(tài)機,該設計用于使用單一數(shù)據(jù)總線將FIFO1~4中的數(shù)據(jù)發(fā)送到4個數(shù)據(jù)通路上去,該設計中并行邏輯產(chǎn)生每次操作時的通路及FIFO選擇結果,狀態(tài)機負責控制每次操作的流程:在“Idle”狀態(tài)下,如果FIFO1~4中有數(shù)據(jù)包供讀取,則進入“Schedule”狀態(tài);獲得調(diào)度結果后“Schedule”經(jīng)過一個“Wait”狀態(tài),然后進入“ReadData”狀態(tài)讀取數(shù)據(jù),同時開始計數(shù),計數(shù)到達所指定數(shù)值或者讀到數(shù)據(jù)包尾時進入空閑狀態(tài)“Idle”,依次循環(huán)下去。
流水線設計
流水線(Pipelining)設計是將一個時鐘周期內(nèi)執(zhí)行的邏輯操作分成幾步較小的操作,并在較高速時鐘下完成。圖6a中邏輯被分為圖6b中三小部分,如果它的Tpd為T,則該電路最高時鐘頻率為1/T,而在圖6b中假設每部分的Tpd為T/3,則其時鐘頻率可提高到原來的3倍,因而單位時間內(nèi)的數(shù)據(jù)流量可以達到原來的三倍。代價是輸出信號相對于輸入滯后3個周期,時序有所改變(圖6b中輸出信號的總延時與圖6a中一樣,但數(shù)據(jù)吞吐量提高了),同時增加了寄存器資源,而FPGA具有豐富的寄存器資源。
本文所強調(diào)的通過減少寄存器間的邏輯延時來提高狀態(tài)機的工作頻率,與流水線設計的出發(fā)點一樣,不同的是流水線所強調(diào)的是數(shù)據(jù)處理時的數(shù)據(jù)通路優(yōu)化,而本文所強調(diào)的是狀態(tài)機中控制邏輯的優(yōu)化
mealy&moore狀態(tài)機典型程序
Verilog
// Example of a 5-state Mealy FSM
module mealy (data_in, data_out, reset, clock);
output data_out;
input [1:0] data_in;
input reset, clock;
reg data_out;
reg [2:0] pres_state, next_state;
parameter st0=3'd0, st1=3'd1, st2=3'd2, st3=3'd3, st4=3'd4;
// FSM register
always @ (posedge clock or negedge reset)
begin: statereg
if(!reset)// asynchronous reset
pres_state = st0;
else
pres_state = next_state;
end // statereg
// FSM combinational block
always @(pres_state or data_in)
begin: fsm
case (pres_state)
st0: case(data_in)
2'b00: next_state=st0;
2'b01: next_state=st4;
2'b10: next_state=st1;
2'b11: next_state=st2;
endcase
st1: case(data_in)
2'b00: next_state=st0;
2'b10: next_state=st2;
default: next_state=st1;
endcase
st2: case(data_in)
2'b0x: next_state=st1;
2'b1x: next_state=st3;
endcase
st3: case(data_in)
2'bx1: next_state=st4;
default: next_state=st3;
endcase
st4: case(data_in)
2'b11: next_state=st4;
default: next_state=st0;
endcase
default: next_state=st0;
endcase
end // fsm
// Mealy output definition using pres_state w/ data_in
always @(data_in or pres_state)
begin: outputs
case(pres_state)
st0: case(data_in)
2'b00: data_out=1'b0;
default: data_out=1'b1;
endcase
st1: data_out=1'b0;
st2: case(data_in)
2'b0x: data_out=1'b0;
default: data_out=1'b1;
endcase
st3: data_out=1'b1;
st4: case(data_in)
2'b1x: data_out=1'b1;
default: data_out=1'b0;
endcase
default: data_out=1'b0;
endcase
end // outputs
endmodule
Verilog
// Example of a 5-state Moore FSM
module moore (data_in, data_out, reset, clock);
output data_out;
input [1:0] data_in;
input reset, clock;
reg data_out;
reg [2:0] pres_state, next_state;
parameter st0=3'd0, st1=3'd1, st2=3'd2, st3=3'd3, st4=3'd4;
//FSM register
always @(posedge clock or negedge reset)
begin: statereg
if(!reset)
pres_state = st0;
else
pres_state = next_state;
end // statereg
// FSM combinational block
always @(pres_state or data_in)
begin: fsm
case (pres_state)
st0: case(data_in)
2'b00: next_state=st0;
2'b01: next_state=st4;
2'b10: next_state=st1;
2'b11: next_state=st2;
endcase
st1: case(data_in)
2'b00: next_state=st0;
2'b10: next_state=st2;
default: next_state=st1;
endcase
st2: case(data_in)
2'b0x: next_state=st1;
2'b1x: next_state=st3;
endcase
st3: case(data_in)
2'bx1: next_state=st4;
default: next_state=st3;
endcase
st4: case(data_in)
2'b11: next_state=st4;
default: next_state=st0;
endcase
default: next_state=st0;
endcase
end // fsm
// Moore output definition using pres_state only
always @(pres_state)
begin: outputs
case(pres_state)
st0: data_out=1'b1;
st1: data_out=1'b0;
st2: data_out=1'b1;
st3: data_out=1'b0;
st4: data_out=1'b1;
default: data_out=1'b0;
endcase
end // outputs
endmodule // Moore
使用狀態(tài)機做時鐘產(chǎn)生電路-獨特卻又最為精準(CPU設計中常用方法)
介紹一款時鐘發(fā)生器--獨特卻又最為精準(CPU設計中常用方法)
時鐘發(fā)生器 clkgen 利用外來時鐘信號clk 來生成一系列時鐘信號clk1、fetch、alu_clk 送往CPU的其他部件。其中fetch是外來時鐘 clk 的八分頻信號。利用fetch的上升沿來觸發(fā)CPU控制器開始執(zhí)行一條指令,同時fetch信號還將控制地址多路器輸出指令地址和數(shù)據(jù)地址。clk1信號用作指令寄存器、累加器、狀態(tài)控制器的時鐘信號。alu_clk 則用于觸發(fā)算術邏輯運算單元。
module clk_gen (clk,reset,clk1,clk2,clk4,fetch,alu_clk);
input clk,reset;
output clk1,clk2,clk4,fetch,alu_clk;
wire clk,reset;
reg clk2,clk4,fetch,alu_clk;
reg[7:0] state;
parameter S1 = 8'b00000001,
S2 = 8'b00000010,
S3 = 8'b00000100,
S4 = 8'b00001000,
S5 = 8'b00010000,
S6 = 8'b00100000,
S7 = 8'b01000000,
S8 = 8'b10000000,
idle = 8'b00000000;
assign clk1 = ~clk;
always @(negedge clk)
if(reset)
begin
clk2 <= 0;
clk4 <= 1;
fetch <= 0;
alu_clk <= 0;
state <= idle;
end
else
begin
case(state)
S1:
begin
clk2 <= ~clk2;
alu_clk <= ~alu_clk;
state <= S2;
end
S2:
begin
clk2 <= ~clk2;
clk4 <= ~clk4;
alu_clk <= ~alu_clk;
state <= S3;
end
S3:
begin
clk2 <= ~clk2;
state <= S4;
end
S4:
begin
clk2 <= ~clk2;
clk4 <= ~clk4;
fetch <= ~fetch;
state <= S5;
end
S5:
begin
clk2 <= ~clk2;
state <= S6;
end
S6:
begin
clk2 <= ~clk2;
clk4 <= ~clk4;
state <= S7;
end
S7:
begin
clk2 <= ~clk2;
state <= S8;
end
S8:
begin
clk2 <= ~clk2;
clk4 <= ~clk4;
fetch <= ~fetch;
state <= S1;
end
idle: state <= S1;
default: state <= idle;
endcase
end
endmodule
//--------------------------------------------------------------------------------
由于在時鐘發(fā)生器的設計中采用了同步狀態(tài)機的設計方法,不但使clk_gen模塊的源程序可以被各種綜合器綜合,也使得由其生成的clk1、clk2、clk4、fetch、alu_clk 在跳變時間同步性能上有明顯的提高,為整個系統(tǒng)的性能提高打下了良好的基礎。
諸位.這樣的時鐘發(fā)生器無論在時序上還是功能上都是完美的,難怪一直在CPU設計中采用.
評論
查看更多