原创 浅谈有限状态机FSM——以序列检测为例

2014-9-1 23:37 8919 20 21 分类: FPGA/CPLD

什么是状态机?简单来说,就是通过不同的状态迁移来完成一些特定的顺序逻辑。硬件的并行性决定了用Verilog描述的硬件实现(譬如不同的always语句)都是并行执行的,那么如果希望分多个时间完成一个任务,怎么办?也许可以用多个使能信号来衔接多个不同的模块,但这样做显得有些繁琐。状态机的提出大大简化这一工作。

硬件设计很讲究并行设计思想,虽然用Verilog描述的电路大都是并行实现,但是对于实际工程应用,往往需要让硬件来实现一些具有一定顺序的工作,这就是要用到状态机的思想。(以上摘自特权同学的《深入浅出玩转FPGA》一书)

 有限状态机FSMFinite State Machine)是数字电路设计中的常用模块。

组成元素:输入、状态、状态转移条件、输出

分类:Mealy状态机:时序逻辑的输出不仅取决于当前状态,还与输入有关;

Moore状态机:时序逻辑的输出只与当前状态有关;

描述方式:1. 状态转移图:设计分析时使用,工具自动翻译的代码效率不高,适合规模小的设计;对于大规模设计,HDL更好;

                    2. 状态转移表;

                    3. HDL描述;

设计步骤:1. 逻辑抽象,得到状态转移图:确定输入、输出、状态变量、画状态转移图;

                    2.状态简化,得到最简的状态转移图:合并等价状态;

                    3.状态编码:binarygrayone-hot编码方式;

                    4.HDL描述;

写法:一般有三种写法,他们在速度、面积、代码可维护性等各个方面互有优劣。

      一段式:   只有一个always block,把所有的逻辑(输入、输出、状态)都在一个always block中实现;这种写法看起来很简洁,但是不利于维护。如果状态复杂一些就很容易出错。不推荐这种方法,但是在简单的状态机可以使用。

       二段式:  有两个always block,把时序逻辑和组合逻辑分隔开来。时序逻辑里进行当前状态和下一状态的切换,组合逻辑实现各个输入、输出以及状态判断。这种写法不仅便于阅读、理解、维护,而且利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计。在两段式描述中,当前状态的输出用组合逻辑实现,可能存在竞争和冒险,产生毛刺。则要求对状态机的输出用寄存器打一拍,但很多情况不允许插入寄存器节拍,此时使用三段式描述。其优势在于能够根据状态转移规律,在上一状态根据输入条件判断出当前状态的输出,从而不需要额外插入时钟节拍。

        三段式: 有三个always block,一个时序逻辑采用同步时序的方式描述状态转移,一个采用组合逻辑的方式判断状态转移条件、描述状态转移规律,第三个模块使用同步时序的方式描述每个状态的输出。代码容易维护,时序逻辑的输出解决了两段式组合逻辑的毛刺问题,但是从资源消耗的角度上看,三段式的资源消耗多一些,且输出比另外两种会延时一个时钟周期。

应用:接口控制,协议转换和处理,以及处理器设计等等。

我们以1101序列检测器为例:

1101序列检测器Mealy状态机状态转移图

20140901233553337.jpg

1101序列检测器Moore状态机状态转移图

20140901233533367.jpg

我们以Mealy状态机为例

一段式状态机(部分核心代码)

20140901233507426.jpg

两段式状态机(部分核心代码)

20140901232819346.jpg

三段式状态机(部分核心代码):

20140901233022397.jpg

三种方式的状态机的写法,使用Quartus IIState Machine Viewer观察状态转移图都是:

20140901233114577.jpg

Testbench

module ex3_tb;

reg    clk;

reg    rst_n;

reg    in;

wire   out;

ex3 i_ex3(

            .clk        (clk  ) ,

            .rst_n      (rst_n) ,

            .in         (in   ) ,

            .out        (out  )

          );                 

initial

begin

     clk = 1;

     forever  #10 clk = ~clk;

end

initial

begin

     rst_n = 0;

     in = 0;

     #1000;

     rst_n = 1;

     in = 1;

     #20;

     in = 1;

     #20;

     in = 1;

     #20;

     in = 0;

     #20;

     in = 1;

     #20;

     in = 1;

     #20;

     in = 0;

     #20;

     in = 1;

     #20;

     in = 0;

     #20;

     in = 1;

     #1000;

     $stop;

end

endmodule

Modelsim仿真结果:

20140901233349863.jpg

有什么不对的地方欢迎大家批评指正!!!

文章评论1条评论)

登录后参与讨论

422661936_845140222 2015-8-4 17:42

不错
相关推荐阅读
wiliamzhou_446210705 2015-04-10 14:57
【博客大赛】Odyssey Max 10双配置闪存
 MAX10的非易失性是因为它把FPGA配置的Flsah做到了芯片里面,增加了安全性,减小了电路板面积,降低成本与功耗,而且逻辑单元在4000以上的Max10内部都含有两个配置闪存,今天我们就对这...
wiliamzhou_446210705 2015-04-08 20:47
【博客大赛】Odyssey Max 10 overview
    Odyssey Max 10 IOT Evaluation Kit是来自世界著名分销商品牌Macnica的一款开发套件,我从同事手上拿到了这个开发套件,终于见识到传说中的MAX 10,这是Al...
wiliamzhou_446210705 2014-11-21 20:46
如何计算射频串联器件的噪声指数
如何计算射频串联器件的噪声指数噪声指数是用来衡量某一电子器件的噪声性能,它定义为信号在进入这一器件前和从该器件输出后的载噪比变化的倍数。射频电子元器件在信号处理过程中会将其本身所具有的热噪声附加到信号...
wiliamzhou_446210705 2014-09-22 22:58
串口通信之发送模块
上篇博文介绍了一下UART接收模块,这篇我们谈一谈发送模块。 发送模块将需要传输的8位数据以字符帧格式发送出去。那我们就开门见山,发送模块由哪些模块组成? 由上图可知,波特率定时模块...
wiliamzhou_446210705 2014-09-20 00:19
串口通信之接收模块
    好久没有写博客了,这次我们谈一谈串口通信,记得以前看过特权同学的uart收发模块的代码,当时没能很好的弄明白,主要原因可能特权同学的代码即包含接收模块,又包含发射模块,代码量很大一时难以理...
我要评论
1
20
1
2
3
4
5
6
7
8
9
0
关闭 热点推荐上一条 /2 下一条