設計一個序列檢測器電路,功能是:檢測出串行輸入數據Sin中的4位二進制序列0101(自左至右輸入),當檢測到該序列時,輸出Out=1;沒有檢測到該序列時,輸出Out=0(注意考慮序列重疊的可能性,如010101,相當于出現兩個0101序列)。
經過分析,首先可以確定采用米利型狀態機設計該電路。因為該電路在連續收到信號0101時,輸出為1,其他情況下輸出為0,所以采用米利型狀態機。
其次,確定狀態機的狀態圖,該電路必須能記憶所收到的輸入數據0、連續收到前兩個數據01.。。可見至少要是個狀態,分別用S1,S2,S3,S4,再加上電路初始態S0。根據要求可以畫出狀態圖:
觀察該圖可以看出,當狀態機處以S2、S4的時候,如果輸入Sin = 1,則電路會轉移到相同的次態S0,如果輸入Sin = 0,則電路會轉移到相同的次態S3,且兩種情況下輸出Out都為0。所以,S2、S4為等價狀態,可用S2代替S4,于是得到簡化的狀態圖:
如果用CPLD/FPGA器件實現狀態機,則邏輯綜合器會自動化簡狀態機。
利用Verilog HDL描述狀態圖主要包括:
(1) 利用參數定義語句parameter描述狀態機中各個狀態的名稱,并指定狀態編碼。
(2) 用時序的always塊描述狀態觸發器實現的狀態存儲。
(3) 使用敏感表和case語句(也可以采用if-else語句)描述狀態轉換邏輯。
(4) 描述狀態機的輸出邏輯。
這個電路我試著用3種方式來描述,看看他們的差別在哪里。
(1) 單個always塊描述狀態機方法(應該避免的寫法)
生成的RTL視圖:
State模塊里面其實就是一個狀態機:
仿真結果有時會出錯:
在每個clk上升沿讀取數據,可以看到是0101,在285ps時輸出oOut應該是高電平,但不是,這是為什么了?再看下面一張圖
這張是對的,為什么有時對又是錯了,如果是這樣那就失去了它的意義了。
對序列檢測器電路用單個always塊的描述的邏輯存在一個隱含的錯誤,即輸出信號oOut的描述存在錯誤。其原因是:oOut信號是由狀態機的當前狀態和輸入信號共同決定的,它是一個純組合邏輯電路,如果當前狀態不變,而輸入信號變了,oOut信號應立即發生變化,而不是等到時鐘上升沿來了才變化。因此,單個always塊描述狀態機的寫法僅僅適用于穆爾型狀態機。這雖然是個問題,但是跟我出現的問題貌似沒有什么直接關系,郁悶。。。繼續思考。
在實際應用中,為了消除組合邏輯輸出信號中的毛刺,在時序允許的情況下,通常允許米利型狀態機中輸出信號通過寄存器輸出。但是單個的always塊的描述方法將狀態轉換判斷的組合邏輯和狀態觸發器轉移的時序邏輯混合編寫在同一個always塊中,不符合將時序和組合邏輯分開描述的代碼風格(Coding Style),而且在描述當前狀態時還要考慮下一個狀態的邏輯,整個代碼的結構不清晰,不利于修改和維護,不利于時序約束條件的加入,不利于綜合器對設計的優化。所以不推薦使用單個always塊的描述方式。
必須為自己的粗心大意買單,還說輸出有時會出錯原來狀態圖都是錯了,不經意的一眼,看來不能隨便啊。case語句后的 S1:當條件滿足時(iSin == 1‘b1)時會跳到S2否則還會停留在S1。改過來看看正確的狀態機就不會出錯了。太粗心了!
正確的狀態機:
(2) 兩個always塊描述狀態機的方法(推薦寫法)
值得注意的是Next_state = 2’bxx;對狀態的默認賦值有3種方式:(1) 全部設置成不定狀態(x); (2) 設置成預先規定的初始狀態; (3) 設置成FSM中的某一有效狀態。設置成不定狀態(x)的好處是:(1) 在仿真時可以很好地考察所設計的FSM的完備性,若設計的FSM不完備,則進入任意狀態,仿真時容易發現;(2) 綜合器對代碼進行綜合時,會忽略沒有定義的狀態觸發器向量。
生成的RTL視圖:
和上面的比較了一下,少了個D觸發器,這是為什么呢?并且仿真的結果也不一樣了。仿真圖:
當然新的問題也就隨之而來:
我們可以明顯的看到這種寫法和上面寫法的區別,最重要的是:輸出oOut不在是在clk上升沿來的時候才能發生變化,它是一個純組合邏輯電路只要輸入條件滿足輸出就立馬發生改變。隨著毛刺的出現,毛刺是一個很重要的問題,很值得我們認真思考。為什么會出現毛刺了,我們可以清楚的看到這時次態是完全由組合邏輯電路決定的,時序電路做的事情僅僅是在clk上升沿來的時候把,把次態賦給現態。在445ps時在S1狀態,輸出為0、在455ps時在S2狀態,輸出為0、在465ps時在S3狀態,此時就算clk的posedge不來,只要iSin == 1,輸出同樣會為1,正如上圖,但在這里,clk 的上升沿和iSin 的高電平是同時來的,所以,在 iSin 的高電平來的那一瞬間,輸出oOut = 1,就在同時狀態裝換到S2,輸出oOut = 0;
這就導致了上面毛刺的產生。怎么解決這個問題呢?我們來看看第三種方法。
(3) 3個always塊描述狀態機(推薦寫法)
分析一下代碼,我們很容易看出:第一個always塊采用同步時序邏輯方式描述狀態轉移(在電路框圖的中間框),第二個always塊采用組合邏輯方式描述狀態轉移規律(一般是第一個方框),第三個always塊描述電路的輸出信號,在時序允許的情況下,通常讓輸出信號經過一個寄存器再輸出,保證輸出信號中沒有毛刺。
綜合后的RTL視圖,就跟第一版程序是一樣的了,又有了D觸發器,仿真結果和第一版也是一樣的,但是兩版代碼的風格(Coding Style)是不一樣的。
-
邏輯電路
+關注
關注
13文章
494瀏覽量
42581 -
檢測器
+關注
關注
1文章
860瀏覽量
47654 -
D觸發器
+關注
關注
3文章
164瀏覽量
47867 -
狀態機
+關注
關注
2文章
492瀏覽量
27486
發布評論請先 登錄
相關推薦
評論