狀態機設計.doc_第1頁
狀態機設計.doc_第2頁
狀態機設計.doc_第3頁
狀態機設計.doc_第4頁
狀態機設計.doc_第5頁
已閱讀5頁,還剩2頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

狀態機設計 FSM簡介: FSM 分兩大類:米里型和摩爾型,組成要素有輸入(包括復位),狀態(包括當前狀態的操作),狀態轉移條件,狀態的輸出條件,圖1為狀態機結構圖。設計FSM 的方法和技巧多種多樣,但是總結起來有兩大類:第一種,將狀態轉移和狀態的操作和判斷等寫到一個模塊(process、block)中。另一種是將狀態轉移單獨寫成一個模塊,將狀態的操作和判斷等寫到另一個模塊中(在Verilog代碼中,相當于使用兩個“always” block)。其中較好的方式是后者。其原因如下: 首先FSM 和其他設計一樣,最好使用同步時序方式設計,好處不再贅述。而狀態機實現后,狀態轉移是用寄存器實現的,是同步時序部分。狀態的轉移條件的判斷是通過組合邏輯判斷實現的,之所以第二種比第一種編碼方式合理,就在于第二種編碼將同步時序和組合邏輯分別放到不同的程序塊(process,block)中實現。這樣做的好處不僅僅是便于閱讀、理解、維護,更重要的是利于綜合器優化代碼,利于用戶添加合適的時序約束條件,利于布局布線器實現設計。圖1為狀態機結構圖 顯式的FSM 描述方法可以描述任意的FSM(參考Verilog 第四版P181 有限狀態機的說明)。兩個always 模塊。其中一個是時序模塊,一個為組合邏輯。時序模塊設計與書上完全一致,表示狀態轉移,可分為同步與異步復位。 同步: always (posedge clk) if (!reset) 異步: always (posedge clk or negedge reset) if (!reset) 組合邏輯用case 語句,sensitive list 包括當然狀態(current state)和輸入(a,b,c)。 編者注:以下是編者從“State Machine Coding Styles for Synthesis”一文中摘取的程序代碼,是一個簡單狀態機的示例,采用兩個always塊的方法: module bm1_s (err, n_o1, o2, o3, o4,i1, i2, i3, i4, clk, rst); output err, n_o1, o2, o3, o4; input i1, i2, i3, i4, clk, rst; reg err, n_o1, o2, o3, o4; parameter 2:0 /可以在此處添加綜合約束屬性來限定狀態機的編碼:binary,one-hot,gray,etc IDLE = 3d0, S1 = 3d1, S2 = 3d2, S3 = 3d3, ERROR = 3d4; reg 2:0 state, next; always (posedge clk or posedge rst)/異步復位,時序邏輯 if (rst) state = IDLE; else state = next; always (state or i1 or i2 or i3 or i4) begin /組合邏輯,敏感列表包含當前狀態以及所有的狀態機輸入 next = 3bx;/設置默認值,以便防止因為if或者case語句不完整綜合生成鎖存器 err = 0; n_o1 = 1; o2 = 0; o3 = 0; o4 = 0; case (state) IDLE: begin next = ERROR;/如果下面所有的if條件都不符合,則對next賦該默認值 if (!i1) next = IDLE; if (i1 & i2) next = S1; if (i1 & !i2 & i3) next = S2; end S1: begin next = ERROR; if (!i2) next = S1; if (i2 & i3) next = S2; if (i2 & !i3 & i4) next = S3; n_o1 = 0; o2 = 1; end S2: begin next = ERROR; if (i3) next = S2; if (!i3 & i4) next = S3; o2 = 1; o3 = 1; end S3: begin next = S3; if (!i1) next = IDLE; if (i1 & i2) next = ERROR; o4 = 1; end endmodule 對于狀態機的輸出可以通過寄存器寄存一下,消除毛刺,這將另外需要一個always塊,也就是狀態機三個always塊的寫法。 編碼風格: 1. 避免生成鎖存器 一個完備的狀態機(健壯性強)應該具備初始化(reset)狀態和默認(default)狀態。當芯片加電或者復位后,狀態機應該能夠自動將所有判斷條件復位,并進入初始化狀態。需要注 明的一點是,大多數FPGA 有GSR(Global Set/Reset)信號,當FPGA 加電后,GSR 信號拉高,對所有的寄存器,RAM 等單元復位/置位,這時配置于FPGA 的邏輯并未生效,所以不能保證正確的進入初始化狀態。所以使用GSR 進入FPGA 的初始化狀態,常常會產生種種不必一定的麻煩。一般簡單方便的方法是采用異步復位信號,當然也可以使用同步復位,但是要注意同步復位的邏輯設計。狀態機也應該有一個默認(default)狀態,當轉移條件不滿足,或者狀態發生了突變時,要能保證邏輯不會陷入“死循環”。這是對狀態機健壯性的一個重要要求,也就是常說的要具備“自恢復”功能。對應于編碼就是對case,ifelse 語句要特別注意,要寫完備的條件判斷語句。VHDL 中,當使用CASE 語句的時候,要使用“When Others”建立默認狀態。使用“IF.THEN.ELSE”語句的時候,要在“ELSE”指定默認狀態。Verilog 中,使用“case”語句的時候要用“default”建立默認狀態,使用“if.else”語句的注意事項相似。 另外有一個技巧:大多數綜合器都支持Verilog 編碼狀態機的完備狀態屬性“full case”。這個屬性用于指定將狀態機綜合成完備的狀態,如Synplicity 的綜合工具(Synplify/Synplify Pro)支持的命令格式如下: case (current_state) / synthesis full_case 2b00 : next_state = 2b01; 2b01 : next_state = 2b11; 2b11 : next_state = 2b00; /這兩段代碼等效 case (current_state) 2b00 : next_state = 2b01; 2b01 : next_state = 2b11; 2b11 : next_state = 2b00; default : next_state = 2bx; Synplicity 還有一個關于狀態機的綜合屬性,叫“/ synthesis parallel_case”其功能是檢查所有的狀態是“并行的”(parallel),也就是說在同一時間只有一個狀態能夠成立。 編者注:使用上述兩個綜合約束屬性會造成綜合前后仿真結果的不一致,請慎重使用。 2. 參數定義用parameter 狀態的定義用parameter 定義,不推薦使用define 宏定義的方式,因為define 宏定義在編譯時自動替換整個設計中所定義的宏,而parameter 僅僅定義模塊內部的參數,定義的參數不會與模塊外的其他狀態機混淆。 3. 時序電路中一定要使用”=”非阻塞賦值方式 Verilog的非阻塞行賦值模擬的是實際硬件中串行寄存器的行為,排除了很多潛在的競爭冒險。在使用非阻塞賦值的時候,很多設計者采用intra-assignment timing delay(在非阻塞賦值前人為加入一個很小單位的延時)。如下例: always (posedge clk or posedge rst) if (rst) state = #1 IDLE; else state = #1 nextstate; 關于這種寫法的闡釋有下面幾點: I. 首先,這種描述是行為級描述方式,僅僅在仿真時起作用,在綜合時會自動被綜合器忽略。也就是通常所說的延時描述是不可綜合的。 II. 這種描述的好處之一是:它簡單模擬了賦值過程寄存器內部的clock-to-output 的延時,在做行為級功能仿真的時候,也可以發現一些由于寄存器固有延遲造成的時序和功能問題。 III. 避免了由RTL 級代碼向門級描述轉變過程中的一些潛在錯誤,如保持時間帶來的問題。 4 不論是二進制編碼的FSM,還是獨熱碼FSM,復位時狀態寄存器應該賦值為IDLE狀態,如下: always( posedge clk or posedge rst ) if( rst ) state = #1 IDLE; else state = #1 next; 如果實現簡化的獨熱碼FSM,復位時狀態寄存器首先賦值為全零,然后再立即置位狀態寄存器的IDLE位。注意:兩個非阻塞性賦值作用在同一位上。這完全符合Verilog標準 規定,在此情況下,最后的非阻塞性賦值會代替前面所有的非阻塞性賦值,即更新狀態機的IDLE位,如下所示: always( posedge clk or posedge rst ) if( rst ) begin state = 5b0; stateIDLE = 1b1; end else state = next; 5 狀態機中組合邏輯塊的賦值 在組合always塊中只能使用阻塞性賦值。來自同步always塊的狀態寄存器和狀態機的所有輸入觸發組合always塊,該塊更新下一狀態。應該在組合always塊的最前面為下一狀態賦一個默認值,塊內的case語句會更新該默認值。通常下一狀態有三種默認值:全x;預定的恢復狀態,如IDLE;狀態寄存器的當前值。如果默認值為全x,那么前仿真模型會使狀態機在沒有任何明確的狀態轉移時,輸出未知。這不僅有利于狀態機的調試,還有利于綜合,因為綜合工具將x作為無關。一些設計(如衛星應用,媒體應用,需要使用FSM觸發器作為檢測掃描鏈的設計和使用正規驗證工具做等價檢測的設計)要求下一狀態是已知的,而不是全x。通常這些設計下一狀態的默認值應該是IDLE或全零,才能滿足設計的要求。將下一狀態初始化為默認值,可能比在每個case語句中指定明確的狀態轉移更簡單。 6 Synplify中狀態機設計: 可以在Synplify中添加在state定義時添加如下約束屬性來限定狀態機的編碼: reg 2:0 state /* synthesis syn_encoding = onehot */; Synplify中包含一個強大的FSM編輯器,可以產生在時間和面積上均得到優化的狀態機設計,但這將忽略一些狀態機中未定義的狀態(invalid state),如果必須在狀態機進入了未定義的狀態后能自動回到有效狀態,可以在狀態機生成時添加一個安全屬性(safe),使得到達無效狀態時能回到初始狀態,這對電路的時間和面積產生很小的影響:reg 2:0 state /* synthesis syn_encoding = safe,onehot */; 這種方法可能與源代碼中實際描述的不一致,對于大多數設計來說這不會產生問題,但如果必須與源代碼中描述的狀態機流程圖相吻合,可以通過約束屬性關掉FSM編輯器:reg 4:0 state /* synthesis syn_preserve=1 */;但這將嚴重影響電路的時間和面積特性,下表是將三種方法應用在Altera Flex10k 和 Xilinx Virtex上的比較:編者注:對第5條和第6條在Synplicity公司的Application Note ”Designing Safe Verilog State Machines with Synplify”中有更詳細的說明。 7 幾種狀態機編碼比較: 狀態機編碼有gray、binary、onehot 等,其中Binary、gray-code 編碼使用最少的觸發器,較多的組合邏輯。而one-hot 編碼反之。由于CPLD 更多的提供組合邏輯資源,而FPGA 更多的提供觸發器資源,所以CPLD 多使用gray-code,而FPGA 多使用one-hot 編碼。另一方面,對于小型設計使用gray-code 和binary 編碼更有效,而大型狀態機使用one-hot更高效。看synplicity 的文檔,推薦在24 個狀態以上會用格雷碼,在524 個狀態會用獨熱碼,在4 個狀態以內用二進制碼,肯定獨熱碼比二進制碼在實現FSM 部分會占更多資源,但是譯碼輸出控制簡單,所以如果狀態不是太多,獨熱碼較好。狀態太少譯碼不會太復雜,二進制就可以了。狀態太多,前面獨熱碼所占資源太多,綜合考慮就用格雷碼了。在代碼中添加綜合器的綜合約束屬性或者在圖形界面下設置綜合約束屬性可以比較方便的改變狀態的編碼。在synplify 綜合時,把FSM compile 勾上,就算用binary 表示,綜合器會自動綜合成one-hot 模式。 也可在coding 時直接添加描述:VHDL attribute TYPE_ENCODING_style of : type is ONEHOT; Verilog Reg2:0 state; / synthesis syn_encoding = value(onehot) 其中onehot編碼又分為幾種:verbose one-hot 、simplified one-hot、one-hot with zero-idle,關于其具體區別請參考“State Machine Coding Styles for Synthesis“一文。 8 同步狀態機輸入變量的處理 所有的輸入變量都必須與狀態機時鐘同步,否則,狀態機的實際運行可能出現奇怪的現 象,會莫名其妙地出現非法狀態。所有的狀態機都不可避免地可能死鎖,在運行中間歇地中止。為什么呢?這是因為,實際上所有的物理狀態機是用物理門實現的,而物理門的傳播延時不為0。輸入信號經過不同的物理門組合到不同的狀態觸發器輸入端D的傳播延時有細微的差別。如果輸入信號正好在錯誤的時間改變,那么較快的通路會探測到變化,而較慢的通路則不會。時鐘是不變的,所以必定有一個觸發器會出現錯誤的電平。這樣就導致狀態轉移錯 誤,整個狀態機電路就會誤動作。這種設計錯誤通常不被人注意,因為誤動作的幾率很小。所以,一定要注意異步輸入。解決異步輸入的辦法是同步器,通常二級同步器能夠預防錯誤的狀態入口。雖然可能性很小,還是必須注意一個統計問題,即異步輸入還是有可能傳播通過同步器。因為兩個同步階段的出現,這種可能性被大大地減小了。一些空間或軍事設計需要使用三級同步器,但是對于商業和工業級設計,二級同步器已經足夠了。為了最大的減小延遲,第一級使用下降沿觸發,第二級使用上升沿觸發。 9 FSM輸出產生 FSM的輸出邏輯可以編碼為一個獨立的連續賦值塊,也可以編碼為一個組合邏輯always塊。如果輸出賦值編碼到組合always塊中,那么輸出賦值就可以放到Verilog的task中,每 個case語句調用task。將輸出賦值與組合always塊分開,不僅有利于在需要更改時改變輸出邏輯,還可以避免綜合工具產生意外的鎖存

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論