欢迎光临散文网 会员登陆 & 注册

数字IC手撕代码-序列检测(状态机写法)

2022-02-26 17:50 作者:不吃葱的酸菜鱼  | 我要投稿

大家好我是酸菜鱼,这个系列着重讲解数字ic或FPGA实习面试及秋招面试的高频手撕代码题

数字IC手撕代码-分频器(任意偶数分频,任意奇数分频,任意小数分频)----分频大师 - 哔哩哔哩 (bilibili.com)

具体内容涉及:

        一说到序列检测,你脑子里要立马跳出两种解法,一种是状态机写法, 一种是移位寄存器写法,看过一个面经,面试官让手撕一个 五位01序列的序列检测,作者用状态机写的,写完被批评代码太复杂,再写一个简单的方法(也即移位寄存器方法)最后没写出来。虽然第二种方法更简单更好用,但是我们两种方法都得会。

序列检测有什么用?

        如果让你实现一个电子锁,输入密码,密码正确就开,密码错误就不开,你会如何写代码?用if-else嵌套嘛,如果第一个数对了,再去判断第二个数,完了再判断第三个数,判断第四个。

检测密码

        这种方法在输入密码位数比较少的时候可行,但是如果密码位数很多。而一个 if-else 语句最后被综合出来就是一个MUX,如果循环嵌套很多,那就是级联MUX,这会带来一连串长的组合逻辑,有很大的delay,所以这种方法是不可取的。

状态机写法

        我们引出有限状态机(FSM)来解决这个问题。

        要去写一个状态机,第一步要做的就是画出状态转移图,我们要知道总共有几个状态,以及状态和状态之间的跳转条件是什么。

        比如说我们做 序列检测 1011,检测到“1011”则输出1,没检测到输出0 

        先画出序列检测的状态转移图。

        画状态转移图要注意,在一个状态中,如果检测错误,不是一定会跳到IDLE初始状态,也可能跳到相邻状态。比如在S4状态,如果在下一个时钟周期,input = 0,状态不会跳转到IDLE,因为上一个输入是1,连起来是10,所以反而会调到S2状态。

状态转移部分我们用三段式的写法。

第一段:状态转移,每当时钟上升沿到来的时候,当前状态跳转到下一个状态。

第二段:根据状态转移图写case,组合逻辑,要用阻塞性赋值。只要状态转移图画的对,这里就不会出错

第三段:结果输出,时钟上升沿到来的时候,检测当前状态是否是S4,如果是,则det信号输出1,否则输出0。在这里我们要知道,这第三段的写法是时序逻辑,所以det信号拉高会比当前状态跳转到S4迟一个周期。

        RTL代码:

Testbench:

我们编写testbench,让data输入流为:011011011001

细心的小伙伴就发现我们这一串数据流里面,隐藏着两个1011.所以最终结果应该要输出2个1011才对,并且两个1011之间仅仅相隔了两个周期。

波形:

检测到data信号输入1011后,det信号在时钟的下一个上升沿拉高,并且和我们testbench编写的数据流反馈一致:011011011001输出两个det高电平,且相距两个时钟周期,符合我们的设计。

状态机写序列检测1011到此结束。

数字IC手撕代码-序列检测(状态机写法)的评论 (共 条)

分享到微博请遵守国家法律