1.状态机
1.1理论
FPGA不同于CPU的一点特点就是CPU是顺序执行的,而FPGA是同步执行(并行)的。那么FPGA如何处理明显具有时间上先后顺序的事件呢?这个时候我们就需要使用到状态机了。状态机的引入就是为了通过不同的状态迁移来完成一些特定的顺序逻辑。
状态机简写为 FSM(Finite State Machine),也称为同步有限状态机,我们一般简称为状态机,之所以说“同步”是因为状态机中所有的状态跳转都是在时钟的作用下进行的,而“有限”则是说状态的个数是有限的。状态机的每一个状态代表一个事件,从执行当前事件到执行另一事件我们称之为状态的跳转或状态的转移,我们需要做的就是执行该事件然后跳转到一下时间,这样我们的系统就“活”了,可以正常的运转起来了。状态机通过控制各个状态的跳转来控制 流程,使得整个代码看上去更加清晰易懂,在控制复杂流程的时候,状态机优势明显。
1.2分类
状态机的结构:
从这张图中可以非常明显的看到状态机的四个要素分别是:当前输入、当前状态、下一状态、当前输出值。而状态机状态的转化明显是由两个外部输入(时钟clock、当前输入input)进行驱动的,根据外部输入的不同就可以做出以下两种分类:
- Mealy型状态机:输出不仅取决于当前状态,还受到输入的直接控制,并且可能与状态无关,从另一个角度来讲,这是一个“异步”输出的状态机(asynchronous machine)。相比于Moore型状态机,Mealy型状态机需要的状态数更少,而且由于其异步特性,输出不用等待一个时钟周期,但是也是因为异步的特性其输出有可能产生毛刺,所以Mealy型的输出通常还会接一个寄存器来达到同步的效果。
- Moore型状态机:输出只与当前状态有关,从另一个角度来讲,这是一个“同步”输出的状态机(synchronous machine)。
下面是一个上升沿检测的例子(两种状态机实现了相同的功能):
左边这个是Moore型的,右边这个是Mealy型的。对于Moore型的状态机来说,当系统处在状态“edge”的时候输出tick是1,输出仅与状态有关;而对于Mealy型的状态机来说,当系统处在状态“zero”并且输入信号level=1时输出tick才是1,输出与输入以及状态均相关。
从仿真结果上可以很明显的看出,两种类型的状态机都实现了相似的效果。但是Mealy型的状态机输出结果与level的变化是同步的,而Moore型的状态机输出结果比level的变化晚一个时钟周期。
这里有一篇写的很好的关于状态机如何写作的文章:FPGA状态机(一段式、二段式、三段式)、摩尔型(Moore)和米勒型(Mealy)_一段式状态机-CSDN博客
1.3另外补充
一、组合逻辑与时序逻辑区别
1 组合逻辑:
组合逻辑的特点是任意时刻的输出仅仅取决于该时刻的输入,与电路原本的状态无关,逻辑中不牵涉跳变沿信号的处理,组合逻辑的verilog描述方式有两种:
(1):always @(电平敏感信号列表)
always模块的敏感列表为所有判断条件信号和输入信号。always 模块中的信号必须定义为reg 型,不过最终的实现结果中并没有寄存器。这是由于在组合逻辑电路描述中,将信号定义为reg型,只是为了满足语法要求。
(2):assign描述的赋值语句。
信号只能被定义为wire型。
2 时序逻辑:
时序逻辑特点为任意时刻的输出不仅取决于该时刻的输入,而且还和电路原来的状态有关。不管输入如何变化,仅当时钟的沿(上升沿或下降沿)到达时,才有可能使输出发生变化。
与组合逻辑不同的是:
(1)在描述时序电路的always块中的reg型信号都会被综合成寄存器,这是和组合逻辑电路所不同的。
(2)时序逻辑中推荐使用非阻塞赋值“<=”。
(3)时序逻辑的敏感信号列表只需要加入所用的时钟触发沿即可,其余所有的输入和条件判断信号都不用加入,这是因为时序逻辑是通过时钟信号的跳变沿来控制的。
二、独热码、格雷码与二进制编码
1.格雷编码,则相邻状态转换时只有一个状态位发生翻转,这样不仅能消除状态转换时由多条状态信号线的传输延迟所造成的毛刺,又可以降低功耗。格雷码的相邻码元值间只有一位是不同的,如S0=3'b000,S1=3'b001,S2=3'b011,S3=3'b010....
2.二进制编码也可称连续编码,也就是码元值的大小是连续变化的。如S0=3'd0,S1=3'd1,S2=3'd2,S3=3'd3....
3.独热编码即 One-Hot 编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效。虽然使用较多的触发器,但由于状态译码简单,可减少组合逻辑且速度较快。
独热码 格雷码 二进制码 4'b0001 4'b0000 4'b0000 4‘b0010 4'b0001 4'b0001 4'b0100 4'b0011 4'b0010 4'b1000 4'b0010 4'b0011
1.4三段状态机写法
1个always模块采用同步时序状态转移
1个always模块组合逻辑判断状态转移条件,描述状态转移规律及输出
1个always时序逻辑描述输出
第三段使用next_state和cur_state的区别在于,当状态跳转时,基于next_state的输出是立刻变化的,而基于cur_state输出会延迟一个周期,其他情况都一样,应该根据自己的时序要求选择。
下面通过HDLBits中的联系来实践
引用:
FPGA状态机(一段式、二段式、三段式)、摩尔型(Moore)和米勒型(Mealy)_一段式状态机-CSDN博客组合逻辑和时序逻辑有什么区别_组合逻辑和时序逻辑的区别-CSDN博客Verilog-状态机编码方式对比:独热码 vs 格雷码_最紧凑的编码方式是( )a一位热码编码(独热码)-CSDN博客