數(shù)字IC手撕代碼-序列檢測(cè)(狀態(tài)機(jī)寫(xiě)法)
大家好我是酸菜魚(yú),這個(gè)系列著重講解數(shù)字ic或FPGA實(shí)習(xí)面試及秋招面試的高頻手撕代碼題
數(shù)字IC手撕代碼-分頻器(任意偶數(shù)分頻,任意奇數(shù)分頻,任意小數(shù)分頻)----分頻大師 - 嗶哩嗶哩 (bilibili.com)
具體內(nèi)容涉及:
????????一說(shuō)到序列檢測(cè),你腦子里要立馬跳出兩種解法,一種是狀態(tài)機(jī)寫(xiě)法, 一種是移位寄存器寫(xiě)法,看過(guò)一個(gè)面經(jīng),面試官讓手撕一個(gè) 五位01序列的序列檢測(cè),作者用狀態(tài)機(jī)寫(xiě)的,寫(xiě)完被批評(píng)代碼太復(fù)雜,再寫(xiě)一個(gè)簡(jiǎn)單的方法(也即移位寄存器方法)最后沒(méi)寫(xiě)出來(lái)。雖然第二種方法更簡(jiǎn)單更好用,但是我們兩種方法都得會(huì)。
序列檢測(cè)有什么用?
????????如果讓你實(shí)現(xiàn)一個(gè)電子鎖,輸入密碼,密碼正確就開(kāi),密碼錯(cuò)誤就不開(kāi),你會(huì)如何寫(xiě)代碼?用if-else嵌套嘛,如果第一個(gè)數(shù)對(duì)了,再去判斷第二個(gè)數(shù),完了再判斷第三個(gè)數(shù),判斷第四個(gè)。

????????這種方法在輸入密碼位數(shù)比較少的時(shí)候可行,但是如果密碼位數(shù)很多。而一個(gè) if-else 語(yǔ)句最后被綜合出來(lái)就是一個(gè)MUX,如果循環(huán)嵌套很多,那就是級(jí)聯(lián)MUX,這會(huì)帶來(lái)一連串長(zhǎng)的組合邏輯,有很大的delay,所以這種方法是不可取的。
狀態(tài)機(jī)寫(xiě)法
????????我們引出有限狀態(tài)機(jī)(FSM)來(lái)解決這個(gè)問(wèn)題。
????????要去寫(xiě)一個(gè)狀態(tài)機(jī),第一步要做的就是畫(huà)出狀態(tài)轉(zhuǎn)移圖,我們要知道總共有幾個(gè)狀態(tài),以及狀態(tài)和狀態(tài)之間的跳轉(zhuǎn)條件是什么。
????????比如說(shuō)我們做?序列檢測(cè)?1011,檢測(cè)到“1011”則輸出1,沒(méi)檢測(cè)到輸出0?
????????先畫(huà)出序列檢測(cè)的狀態(tài)轉(zhuǎn)移圖。

????????畫(huà)狀態(tài)轉(zhuǎn)移圖要注意,在一個(gè)狀態(tài)中,如果檢測(cè)錯(cuò)誤,不是一定會(huì)跳到IDLE初始狀態(tài),也可能跳到相鄰狀態(tài)。比如在S4狀態(tài),如果在下一個(gè)時(shí)鐘周期,input = 0,狀態(tài)不會(huì)跳轉(zhuǎn)到IDLE,因?yàn)樯弦粋€(gè)輸入是1,連起來(lái)是10,所以反而會(huì)調(diào)到S2狀態(tài)。
狀態(tài)轉(zhuǎn)移部分我們用三段式的寫(xiě)法。
第一段:狀態(tài)轉(zhuǎn)移,每當(dāng)時(shí)鐘上升沿到來(lái)的時(shí)候,當(dāng)前狀態(tài)跳轉(zhuǎn)到下一個(gè)狀態(tài)。
第二段:根據(jù)狀態(tài)轉(zhuǎn)移圖寫(xiě)case,組合邏輯,要用阻塞性賦值。只要狀態(tài)轉(zhuǎn)移圖畫(huà)的對(duì),這里就不會(huì)出錯(cuò)
第三段:結(jié)果輸出,時(shí)鐘上升沿到來(lái)的時(shí)候,檢測(cè)當(dāng)前狀態(tài)是否是S4,如果是,則det信號(hào)輸出1,否則輸出0。在這里我們要知道,這第三段的寫(xiě)法是時(shí)序邏輯,所以det信號(hào)拉高會(huì)比當(dāng)前狀態(tài)跳轉(zhuǎn)到S4遲一個(gè)周期。
? ? ? ? RTL代碼:

Testbench:
我們編寫(xiě)testbench,讓data輸入流為:011011011001
細(xì)心的小伙伴就發(fā)現(xiàn)我們這一串?dāng)?shù)據(jù)流里面,隱藏著兩個(gè)1011.所以最終結(jié)果應(yīng)該要輸出2個(gè)1011才對(duì),并且兩個(gè)1011之間僅僅相隔了兩個(gè)周期。

波形:

檢測(cè)到data信號(hào)輸入1011后,det信號(hào)在時(shí)鐘的下一個(gè)上升沿拉高,并且和我們testbench編寫(xiě)的數(shù)據(jù)流反饋一致:011011011001輸出兩個(gè)det高電平,且相距兩個(gè)時(shí)鐘周期,符合我們的設(shè)計(jì)。
狀態(tài)機(jī)寫(xiě)序列檢測(cè)1011到此結(jié)束。