目录
概念:
状态机的模型:
状态机的设计:
根据状态机的实际写法,状态机可以分为一段式、二段式和三段式状态机。
三段式状态机的基本格式:
概念:
状态机,全称是有限状态机(Finite State Machine,缩写为 FSM),是一种在有限个状态之间按一定规律转换的时序电路,可以认为是组合逻辑和时序逻辑的一种组合。状态机通过控制各个状态的跳转来控制流程,使得整个代码看上去更加清晰易懂,在控制复杂流程的时候,状态机优势明显,因此基本上都会用 到状态机,如 SDRAM 控制器等。
Verilog 是硬件描述语言,硬件电路是并行执行的,当需要按照流程或者步骤来完成某个功能时,代码中通常会使用很多个 if 嵌套语句来实现,这样就增加了代码的复杂度,以及降低了代码的可读性,这个时候就可以使用状态机来编写代码。状态机相当于一个控制器,它将一项功能的完成分解为若干步,每一步对应于二进制的一个状态,通过预先设计的顺序在各状态之间进行转换,状态转换的过程就是实现逻辑功能的过程。
状态机的模型:
状态机分为两大类,即摩尔(Moore)型状态机和米勒(Mealy) 型状态机。
Mealy 状态机:组合逻辑的输出不仅取决于当前状态,还取决于输入状态。
Moore 状态机:组合逻辑的输出只取决于当前状态。
状态机的设计:
根据状态机的实际写法,状态机可以分为一段式、二段式和三段式状态机。
一段式:整个状态机写到一个 always 模块里面,在该模块中既描述状态转移,又描述状态的输入和输出。不推荐采用这种状态机,因为从代码风格方面来讲,一般都会要求把组合逻辑和时序逻辑分开;从代码维护和升级来说,组合逻辑和时序逻辑混合在一起不利于代码维护和修改,也不利于约束。
二段式:用两个 always 模块来描述状态机,其中一个 always 模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律以及输出。不同于一段式状态机的是,它需要定义两个状态,现态和次态,然后通过现态和次态的转换来实现时序逻辑。
三段式:在两个 always 模块描述方法基础上,使用三个 always 模块,一个 always 模块采用同步时序描述状态转移,一个 always 采用组合逻辑判断状态转移条件,描述状态转移规律,另一个 always 模块描述状态输出(可以用组合电路输出,也可以时序电路输出)。
三段式状态机的基本格式:
第一个 always 语句实现同步状态跳转;
第二个 always 语句采用组合逻辑判断状态转移条件;
第三个 always 语句描述状态输出(可以用组合电路输出,也可以时序电路输出)。
下面以一个 7 分频为例:
状态跳转图画完之后,接下来通过 parameter 来定义各个不同状态的参数,如下代码所示:
这里是使用独热码的方式来定义状态机,每个状态只有一位为 1,当然也可以直接定义成十进制的 0,1,2……7。
因为我们定义成独热码的方式,每一个状态的位宽为 7 位,接下来还需要定义两个 7 位的寄存器,一个用来表示当前状态,另一个用来表示下一个状态,如下所示:
接下来就可以使用三个 always 语句来开始编写状态机的代码,第一个always 采用同步时序描述状态转 移,第二个always采用组合逻辑判断状态转移条件,第三个 always 是描述状态输出,一个完整的三段式状态机的例子如下代码所示:
在编写状态机代码时首先要定义状态变量(代码中的参数 S0~S6)与状态寄存器(curr_st、next_st),如代码中第 10 行至第 21 行所示;接下来使用三个 always 语句来实现三段状态机,第一个 always 语句实现同步状态跳转(如代码的第 27 至第 33 行所示),在复位的时候,当前状态处在 S0 状态,否则将下一个状态赋值给当前状态;第二个 always 采用组合逻辑判断状态转移条件(如代码的第 35 行至第 47 行代码所示),这里每一个状态只保持一个时钟周期,也就是直接跳转到下一个状态,在实际应用中,一般根据输入的条件来判断是否跳转到其它状态或者停留在当前转态,最后在 case 语句后面增加一个 default 语句,来防止状态机处在异常的状态;第三个 always 输出分频后的时钟(如代码的第 49 至第 59 行代码所示),状态机的第三段可以使用组合逻辑电路输出,也可以使用时序逻辑电路输出,一般推荐使用时序电路输出,因为状态机的设计和其它设计一样,最好使用同步时序方式设计,以提高设计的稳定性,消除毛刺。从代码中可以看出,输出的分频时钟 clk_divide_7 只与当前状态(curr_st)有关,而与输入状态无关,从代码中可以看出,输出的分频时钟 clk_divide_7 只与当前状态(curr_st)有关,而与输入状态无关,状态;状态机的第二段对应摩尔状态机模型产生下一状态的组合逻辑 F;状态机的第三段对应摩尔状态机产生输出的组合逻辑 G,因为采用时序电路输出有很大的优势,所以这里第三段状态机是由时序电路输出的。
状态机采用时序逻辑输出的状态机模型如下图所示:
采用这种描述方法虽然代码结构复杂了一些,但是这样做的好处是可以有效地滤去组合逻辑输出的毛刺,同时也可以更好的进行时序计算与约束,另外对于总线形式的输出信号来说,容易使总线数据对齐,减小总线数据间的偏移,从而降低接收端数据采样出错的频率。