verilog状态机

Verilog是硬件描述语言,硬件电路是并行执行的,当需要按照流程或者步骤来完成某个功能时,代码中通常会使用很多个if嵌套语句来实现,这样就增加了代码的复杂度,以及降低了代码的可读性,这个时候就可以使用状态机来编写代码。 状态机相当于一个控制器,它将一项功能的完成分解为若干步,每一步对应于二进制的一个状态,通过预先设计的顺序在各状态之间进行转换,状态转换的过程就是实现逻辑功能的过程。

状态机,全称是有限状态机( Finite State Machine,缩写为FSM),是一种在有限个状态之间按一定规律转换的时序电路,可以认为是组合逻辑和时序逻辑的一种组合。 状态机通过控制各个状态的跳转来控制流程,使得整个代码看上去更加清晰易懂,在控制复杂流程的时候,状态机优势明显,因此基本上都会用到状态机,如SDRAM控制器等。

根据状态机的输出是否与输入条件相关,可将状态机分为两大类,即摩尔(Moore)型状态机和米勒(Mealy)型状态机。
➢ Mealy状态机:组合逻辑的输出不仅取决于当前状态,还取决于输入状态。
➢ Moore状态机:组合逻辑的输出只取决于当前状态。

1 Mealy状态机

米勒状态机的模型如下图所示,模型中第一个方框是指产生下一状态的组合逻辑F, F是当前状态和输入信号的函数,状态是否改变、如何改变,取决于组合逻辑F的输出;第二框图是指状态寄存器,其由一组触发器组成,用来记忆状态机当前所处的状态,状态的改变只发生在时钟的跳边沿;第三个框图是指产生输出的组合逻辑G,状态机的输出是由输出组合逻辑G提供的, G也是当前状态和输入信号的函数。

在这里插入图片描述

2 Moore状态机

摩尔状态机的模型如下图所示,对比米勒状态机的模型可以发现,其区别在于米勒状态机的输出由当前状态和输入条件决定的,而摩尔状态机的输出只取决于当前状态。

在这里插入图片描述

3 三段式状态机

根据状态机的实际写法,状态机还可以分为一段式、二段式和三段式状态机。

一段式:**整个状态机写到一个always模块里面,在该模块中既描述状态转移,又描述状态的输入和输出。**不推荐采用这种状态机,因为从代码风格方面来讲,一般都会要求把组合逻辑和时序逻辑分开;从代码维护和升级来说,组合逻辑和时序逻辑混合在一起不利于代码维护和修改,也不利于约束。

二段式用两个always模块来描述状态机,其中一个always模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律以及输出。 不同于一段式状态机的是, 它需要定义两个状态, 现态和次态,然后通过现态和次态的转换来实现时序逻辑。

三段式:在两个always模块描述方法基础上,使用三个always模块,一个always模块采用同步时序描述状态转移,一个always采用组合逻辑判断状态转移条件,描述状态转移规律,另一个always模块描述状态输出(可以用组合电路输出,也可以时序电路输出)。

实际应用中三段式状态机使用最多, 因为三段式状态机将组合逻辑和时序分开,有利于综合器分析优化以及程序的维护;并且三段式状态机将状态转移与状态输出分开,使代码看上去更加清晰易懂,提高了代码的可读性, 推荐大家使用三段式状态机, 本文也着重讲解三段式。
三段式状态机的基本格式是:

第一个always语句实现同步状态跳转;
第二个always语句采用组合逻辑判断状态转移条件;
第三个always语句描述状态输出(可以用组合电路输出,也可以时序电路输出)。

在开始编写状态机代码之前,一般先画出状态跳转图,这样在编写代码时思路会比较清晰,下面以一个7分频为例(对于分频等较简单的功能,可以不使用状态机,这里只是演示状态机编写的方法),状态跳转图如下图所示:
在这里插入图片描述
状态跳转图画完之后,接下来通过parameter来定义各个不同状态的参数,如下代码所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在编写状态机代码时首先要定义状态变量(代码中的参数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)有关,而与输入状态无关,所以属于摩尔型状态机。状态机的第一段对应摩尔状态机模型的状态寄存器,用来记忆状态机当前所处的状态;状态机的第二段对应摩尔状态机模型产生下一状态的组合逻辑F;状态机的第三段对应摩尔状态机产生输出的组合逻辑G,因为采用时序电路输出有很大的优势,所以这里第三段状态机是由时序电路输出的。
状态机采用时序逻辑输出的状态机模型如下图所示:
在这里插入图片描述
采用这种描述方法虽然代码结构复杂了一些,但是这样做的好处是可以有效地滤去组合逻辑输出的毛刺,同时也可以更好的进行时序计算与约束,另外对于总线形式的输出信号来说,容易使总线数据对齐,减小总线数据间的偏移,从而降低接收端数据采样出错的频率。

  • 53
    点赞
  • 298
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值