1. 概念
状态机(State Machine):
有限状态机(Finite State Machine,简称FSM)
在有限个状态之间按一定规律转换的时序电路。
2 状态机模型
组成元素:输入、状态、状态转移条件、输出;
描述方式:
① 状态转移图:设计分析时使用,工具自动翻译的代码效率不高,适合规模小的设计;对于大规模设计,HDL更好;
② 状态转移表;
③ HDL描述;
设计步骤:
① 逻辑抽象,得到状态转移图:确定输入、输出、状态变量、画状态转移图;
② 状态简化,得到最简的状态转移图:合并等价状态;
③ 状态编码:binary、gray、one-hot编码方式;
④ 用HDL描述;
下面介绍状态机的两个模型
mealy状态机:输出与状态和当前输入均有关系
moore状态机:输出仅与当前状态值有关,而与此时的输入无关
状态寄存器由一组触发器组成,用来记忆状态机当前所处的状态,状态的改变只发生在时钟的跳变沿。
组合逻辑F不仅与输入有关,还与 当前状态 有关(F是当前状态和输入信号的函数)。
状态机的输出是由 输出组合逻辑G 提供的,G也是当前状态和输入信号的函数。
组合逻辑如果只是当前状态的函数,那就应该是Moore状态机
3 状态机设计代码
状态机一般有三种写法,他们在速度、面积、代码可维护性等各个方面互有优劣。
一段式:只有一个always block,把所有的逻辑(输入、输出、状态)都在一个always block中实现;这种写法看起来很简洁,但是不利于维护。如果状态复杂一些就很容易出错。不推荐这种方法,但是在简单的状态机可以使用。
二段式:有两个always block,把时序逻辑和组合逻辑分隔开来。时序逻辑里进行当前状态和下一状态的切换,组合逻辑实现各个输入、输出以及状态判断。这种写法不仅便于阅读、理解、维护,而且利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计。在两段式描述中,当前状态的输出用组合逻辑实现,可能存在竞争和冒险,产生毛刺。则要求对状态机的输出用寄存器打一拍,但很多情况不允许插入寄存器节拍,此时使用三段式描述。其优势在于能够根据状态转移规律,在上一状态根据输入条件判断出当前状态的输出,从而不需要额外插入时钟节拍。
三段式:有三个always block,一个时序逻辑采用同步时序的方式描述状态转移,一个采用组合逻辑的方式判断状态转移条件、描述状态转移规律,第三个模块使用同步时序的方式描述每个状态的输出。代码容易维护,时序逻辑的输出解决了两段式组合逻辑的毛刺问题,但是从资源消耗的角度上看,三段式的资源消耗多一些,且输出比另外两种会延时一个时钟周期。
三段式设计一般比较常用,可以理解为三个always程序块,且格式也比较固定。如下:
(1)第一个always程序块 时序逻辑描述状态转移。 (current_state<= nex_state)
(2)第二个always程序块 组合逻辑描述状态切换。( nex_state<= ......)
(3)第三个always程序块 时序逻辑将结果寄存后输出。
注意:
三段式并不是一定要写为3个always块,如果状态机更复杂,就不止3段了。
三段always模块中,第一个和第三个always模块是同步时序always模块,用非阻塞赋值(“ <= ”);第二个always模块是组合逻辑always模块,用阻塞赋值(“ = ”)。
第二部分为组合逻辑always模块,为了抑制warning信息,对于always的敏感列表建议采用always@(*)的方式。
第二部分,组合逻辑always模块,里面判断条件一定要包含所有情况!可以用else保证包含完全。
第二部分,组合逻辑电平要维持超过一个clock,仿真时注意。
需要注意:第二部分case中的条件应该为当前态(current_state)。
第三部分case中的条件应该为次态(next_state)。
编码原则,binary和gray-code适用于触发器资源较少,组合电路资源丰富的情况(CPLD),对于FPGA,适用one-hot code。这样不但充分利用FPGA丰富的触发器资源,还因为只需比较一个bit,速度快,组合电路简单。
还没整理完 还需要整理一下