前幾天參加了一場面試,選擇題凈是關於實際開發的關鍵知識,對於沒有項目經驗的我而言,完全不知所雲。在看不到成功的希望的同時,最后的序列檢測本應該是手到擒拿,結果以翻車結束。這里吃一塹長一智,避免下次出現類似的悲劇。
題目是檢測序列 11001,使用三段時狀態機:
這里約定以下信號,
- 時鍾 clk
- 復位(低電平有效) rst_n
- 數據輸入 dat_in
- 檢測結果輸出(檢測到了就置位) check
- 啟動信號 go
這里約定使用摩爾狀態機,米里機的在下一章:
檢測方式,遇到這樣包含重復序列的信號的話就直接忽略后面的序列(xxxx110011001xxx)
首先是檢測表(姑且就這么叫吧),數學上叫二叉樹、二叉表,但是我呢,比較任性。
Start |
|||||||||||||||||||||||||||||||
0 |
1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
00 |
01 |
10 |
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
000 |
001 |
010 |
011 |
100 |
101 |
110 |
111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
00000 |
00001 |
00010 |
00011 |
00100 |
00101 |
00110 |
00111 |
01000 |
01001 |
01010 |
01011 |
01100 |
01101 |
01110 |
01111 |
10000 |
10001 |
10010 |
10011 |
10100 |
10101 |
10110 |
10111 |
11000 |
11001 |
11010 |
11011 |
11100 |
11101 |
11110 |
11111 |
這個表很重要,它展示了信息分類的結果,每一步都只有兩個選擇,在表中紅色的表示正確的序列,黃色的表示還可以繼續檢測的序列,而黑色的表示必須回到開始的序列。
在這個表中,存在很多判斷結構,比如第四行第八列的值為 111,它包含兩個正確的 11,狀態機應該回到上一步。
這里約定狀態
Start: 初始狀態,go 信號置位,進入狀態 S0
S0: 有零個正確值 ,
S1: 有一個正確值 11
S2: 有兩個正確值 11
S3: 有三個正確值 110
S4: 有四個正確值 1100
S5: 有五個正確值 11001
狀態轉移圖如下:
狀態機的輸出就比較簡單了,摩爾機的輸出只與現態有關:
僅僅狀態 S5 的時候輸出 1,其他情況輸出 0。
Word 寫文件多好,面試非要用筆,本來期望答案寫的像小學語文作業,結果弄的像醫生的處方一樣。
開始經典的三段式狀態機:
代碼如下:
仿真結果如下:
時序報告:
可以看到,這個三段式狀態機大概能跑 730MHz,似乎速度還不錯。
較高的速度也拜良好的編碼習慣所賜。
下一章描述米里狀態機。畢竟知識也需要經常溫習,避免忘記。