VHDL状态机设计

状态机概述

状态机的定义

  • 任何时序模型都可以归结为一个状态机,比如说时序电路一节中提到的D触发器其实就是一个包含两种状态的状态机
  • 状态机的工作方式是:根据控制信号,按预先设定的各个状态,进行顺序执行

状态机的特点

  • 在一些简单的控制方面,状态机具备巨大的优越性:
  • 控制过程高效:状态机控制与运行方式简单,可以进行高速、高效的过程控制
  • 性能稳定高速:因为状态机变化周期只有一个时钟周期,在每个状态中可以并行同步完成许多操作,比起CPU逐条执行指令更快更稳定

状态机的分类

  • 状态机可以分成类似时序电路的两类:

  • Moore型

    当前输出只和前一状态有关

  • Mealy型

    当前输出不仅与前一状态有关,还和当前的输入有关

  • 当然,状态机有很多分类方式:比如按结构分单进程和多进程状态机,状态表达上分符号化状态机和确定状态编码的状态机等等

状态机设计

原理分析

  • 以一个简单的状态机为例介绍Moore状态机的构成与设计

  • 需求是:有CLK输入和EN/LOAD/CLR三个输出,当CLK出现第一个上升沿时,EN为高,其他两个输出为低,第二个上升沿使得LOAD为高,EN和CLR为低,第三个上升沿让CLR为高,其他两个为低,如此循环

  • 可见,这种状态机只受CLK的控制来进行三个状态间的切换,下一状态是什么取决于上一状态,是典型的Moore状态机,实现它的要点有三:

    • 描述所有的状态
    • 让CLK决定切换状态
    • 由上一状态决定切换什么状态

说明部分

  • 描述状态

    使用TYPE语句定义新的数据类型:此数据类型是枚举型,每个元素代表状态机的其中一个状态

    另外还要定义状态变量:用于表示现态和次态,定义为信号(因为信号有全局性,可以将数据从时序模块带到组合逻辑部分),其数据类型是刚刚定义的包含各个状态的数据类型

    这一部分放在结构体的BEGIN前

  • 代码示例

    根据要求,要写的状态机可以分为三个状态:每个状态都有一个输出信号为高,而其他输出为低,用为高的输出来命名状态方便区分

        TYPE state_type IS (STATE_EN, STATE_LOAD, STATE_CLR);
        SIGNAL current_state, next_state : state_type;
    
  • current_state和next_state相当于两个只能装state_type数据类型的容器

    在任一时刻,其只能是state_type中包含的STATE_EN, STATE_LOAD, STATE_CLR这三种状态之一

主控时序REG进程

  • 切换状态

    状态机受时钟驱动进行状态的切换,在上一步描述好状态之后,就应该通过主控时序进程来让CLK信号控制状态的转换

    时序进程在CLK的驱动下不断地将next_state的内容赋给现态current_state,并由此信号将状态变量传输给COM组合进程结构

  • 代码示例

    根据要求,每次时钟上升沿到来进行状态转换

    REG:process(CLK)
        begin
            if CLK'EVENT AND CLK ='1' then
                current_state <= next_state;
    			--当CLK上升沿到来,就将next_state的状态赋予current_state
            end if;
        end process;
    

主控组合COM进程

  • 控制各个状态功能与下一状态

    描述了状态和状态的切换,就要详细说明状态按什么顺序切换,以及每个状态具体如何表现

  • 代码示例

    根据要求在每个状态中对信号赋值,并且决定哪一个状态会被送入新状态供下一次切换

    COM:process(current_state)
        begin
            case current_state is
                when STATE_EN =>--当current_state是STATE_EN时
                    EN <= '1';
                    LOAD <= '0';
                    CLR <= '0';
                    next_state <= STATE_LOAD;--下一个切换到的状态next_state就是STATE_LOAD
                when STATE_LOAD =>
                    EN <= '0';
                    LOAD <= '1';
                    CLR <= '0';
                    next_state <= STATE_CLR;
                when STATE_CLR =>
                    EN <= '0';
                    LOAD <= '0';
                    CLR <= '1';
                    next_state <= STATE_EN;
                when others =>
                    EN <= '0';
                    LOAD <= '0';
                    CLR <= '0';
                    next_state <= STATE_EN;
            end case;
        end process;
    

辅助进程

  • 配合状态机工作

    以上三个部分已经能实现状态机的概念,但实际的状态机还有更多功能,需要辅助进程来配合状态机工作的组合或时序逻辑,或者来实现其他功能

Mealy型状态机设计

  • 根据定义,mealy型状态机的输出不仅仅依赖于当前状态,还受输入信号的影响,也就是说输入变化后不需要像moore型那样等待时钟同步,而是状态即刻发生变化,因此mealy型状态机也是异步输出状态机(但工作时序都是同步的)

  • 如果给上文的状态机添加一个异步有效的reset信号,那也就成为了mealy型状态机

    REG:PROCESS(reset,clk)
    	begin
            IF reset='0' THEN current_state <= STATE_EN;
    		--复位低电平有效,立即回到EN状态
    		ELSIF CLK'EVENT AND CLK ='1' then 
                current_state <= next_state;
    			--当CLK上升沿到来,就将next_state的状态赋予current_state
            END IF;
        end process;
    
  • 但需要注意的是,这样的状态机待输出的数据还是必须等待时钟边沿到达后才能输出

posted on 2024-12-17 23:20  无术师  阅读(70)  评论(0编辑  收藏  举报