一文搞懂有限状态机FSM

1.什么是有限状态机? 有限状态机(Finite State Machine,FSM),有时候也简称状态机,它是一种数学模型,通常用来设计电脑程序或者时序电路。它被构思为一个抽象的机器,并且在某个时刻只能处于一个有限的数字代表之下。
组成元素:输入、输出、状态、状态转移条件;
描述方式:状态转移图、状态转移表、HDL描述
分类:
按照输出的产生方式,可以将状态机分为两类:
Moore:时序逻辑的输出只取决于当前状态。Moore状态机最大的特点就是将输入和输出信号隔离开来,而且输出与时钟信号是同步的。
Mealy:时序逻辑的输出不但取决于状态还取决于输入。Mealy状态机对时钟的响应发生在当前时钟周期,比Moore状态机对时钟的响应早一个周期,因此,输入信号的噪声可能影响在输出的信号。


2.如何设计一个有限状态机: (1)逻辑抽像,得出状态转换图;
(2)状态化简;
(3)状态分配;在触发器资源丰富的FPGA或这ASIC设计中,采用独热编码(one-hot-coding)既可以使电路得到充分的保证又可以充分利用其触发器数量多的优势,也可以采取输出编码的状态指定来简化电路结构,并提高状态机的运行速度。
(4)选定触发器的类型并求出状态方程、驱动方程、和输出方程;
(5)按照方程得出逻辑图
3.状态机的三种写法: 状态机一般有三种写法,他们在代码可维护性上、速度、面积等方面各有优劣。
一段式:只有一个always block,把所有的逻辑(输入、输出、状态)都在一个always block中实现
优点:看起来很简洁;
缺点:不利于维护,如果状态复杂就容易出错误;
不推荐这种方法,但是在简单的状态机可以使用。
二段式:有两个always block块,把组合逻辑和时序逻辑分隔开来。时序逻辑里进行当前状态和下一逻辑的切换,组合逻辑实现各个输出和输入及状态的判断。
优点:便于阅读、理解、维护,而且利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计;
缺点:输出是组合逻辑,输出可能含有毛刺;
解决输出毛刺的问题,最简单的方法就是用寄存器打一拍,但是很多情况下不让插入寄存器节拍,此时,使用三段式进行描述,其优势在于能够根据状态转移规律,在上一状态根据输入条件判断当前的输出,从而不需要额外插入时钟节拍。
三段式:有三个always block,一个时序逻辑采用同步时序的方式描述状态转移,一个采用组合逻辑的方式判断状态转移,描述状态转移规律,第三个模块使用同步时序的方式描述每个状态的输出,这三个always block刚好对应三个子模块,更加容易理解。
优点:代码容易维护,时序逻辑的输出解决了组合逻辑的毛刺问题;
缺点:代码量大,资源消耗多一些。
一般来说,三段式的效果最好,唯一的缺点就是资源的占用多一些,这对于FPGA这类触发器资源丰富的器件来说,无所谓,除非特别简单的状态机,使用一段式实现,其他基本都使用三段式。
4.其他问题 【一文搞懂有限状态机FSM】(1)localparam:
尽量使用localparam而不是define或者parameter,这个原则不仅适用于FSM,对其他模块也适用。
理由:不适用define,在设计中可能有多个FSM,而且他们很可能包含相同的状态名,使用define定义的状态名是全局可见的,那么这些FSM之间会相互影响。(c++解决这个问题的办法是namespa)
不使用parameter,虽然它定义的参数是局部的,但是它可以被其他的模块通过参数修改,FSM中的状态定义应该是内部可见的,外部模块应该是不能修改的。(类似于c++中的private)
(2)state encode
状态机的编码通常有三种,分别是Binary、One-hot(独热)、Gray等几种;
Bianry码:
采用最简单的递增的方式对状态进行编码,对于n个状态的状态机,共需要log2(n)个触发器来表示所有的状态。
优点:在状态很多的情况下,可以大大减少触发器的数量,对设计的面积有积极作用。
缺点:但是在状态跳转过程中,很可能出现多位同时变化的情况,容易在next_state的生成逻辑上产生毛刺。同时,输出也是所有状态码的译码,译码逻辑多数很复杂,往往成为整个设计的关键。
Gray码:
采用了格雷码的编码方式,每两个相邻的状态只有一位信号变化;
优点:避免了next state上产生的毛刺,同时两个相邻状态的译码输出变得简单了,避免了复杂组合逻辑的产生。
缺点;格雷码的这些优点都是建立在状态跳转是顺序执行的情况下,如果状态机有很多随机跳转和分支,格雷码的实际效果
和二进制编码差不多。
One_Hot码:
当前状态机中应用最多的是独热码,One-Hot编码在一组0中只有一个1,对一个n个状态的FSM设计,需要n个触发器。
优点:在任意两个状态之间跳转都只有两个状态位的变化,不会产生复杂的组合逻辑,各个状态之间的译码也相对简单。
缺点:对状态编码需要的寄存器比其他方式多。
结论:Binary、Gray编码使用较少的触发器,较多的组合逻辑。而One_Hot编码反之。由于CPLD更多的提供组合逻辑资源,而FPGA更加提供的是触发器资源,所以CPLD多使用Gray码,而FPGA多使用One_Hot编码,另一方面,对于小型设计,使用Binary和Gray码更加有效,而大型状态机使用One_Hot更加高效。
(3)OUTPUT
避免Latch:
1)在第三个always块中,在case前面,所有的输出都有默认的值。这样做的好处是可以消除Latch的出现,而且可以减少在后面每种状态下重复相同的复制,而且强调显示了case内那个输出会发生变化。
2)书写完备的if_else和case语句;

    推荐阅读