状态机的VHDL设计

状态机的基本三要素:状态,输入条件,输出

状态机的分类:
根据状态数:无限状态机(Infinite State Machine,ISM);有限状态机(Finite State Machine,FSM)逻辑状态的设计一般是有限状态机。
根据信号输出方式:Moore型:同步输出状态机,输出仅和当前状态有关,输入的变化需要等待时钟信号的到来;Mealy型属于异步输出状态机,其输出是当前状态和所有输入信号的函数,他的输出是在输入之后立即发生的。
状态机的VHDL设计:
一般有三个模块:
这里写图片描述
所以根据三个基本模块,状态机设计方法分为一段式(单进程),二段式(两进程),三段式(三进程)。
单进程:将三个模块合并起来,写在一个进程中。
两进程:当前状态寄存器用一个进程,输出逻辑和次态逻辑合并起来用另外一个进程。(下面链接的PPT这样讲~不过我按到的很多代码是把输出和描述当前状态的寄存器一起)
三进程:即三个模块用三个进程来描述。
至于三个进程方法的比较可见下面的链接:
http://www.doc88.com/p-105556511191.html

不过感觉以上的分类方法很牵强,个人觉得下面介绍的方法更好(以一个信号发生器为例子说明):
1).说明部分
说明部分中使用
TYPE
语句定义新的数据类型,此数据类型为枚举型,
其元素通常都用
状态机的状态名来定义。
状态变量定义为信号,
便于信息传递,
并将状态变量的数据类型定
义为含有既定状态元素的新定义的数据类型。说明部分一般放在结构体的
ARCHITECTURE

BEGIN
之间。

     architecture one of generator is
        type states is(zero,one,two,three,four,five,six,seven);
        signal present_state,next_state:states;
        signal temp:std_logic;
        signal clk_count:std_logic_vector(23 downto 0);
     begin 

2).主控时序进程
是指负责状态机运转和在时钟驱动正负现状态机转换的进程。状态机随外部时钟信号以同步方式工作,当时钟的有效跳变到来时,时序进程将代表次态的信号next_state中的内容送入现态信号
current_state中,而next_state中的内容完全由其他进程根据实际情况而定,此进程中往往也包括一些清零或置位的控制信号。

-----Lower section of FSM-----
    process(clkdiv)
    begin
      if(rising_edge(clkdiv))then
      present_state<=next_state;
      wave<=temp;
      end if;
      end process;

3).主控组合进程:
根据外部输入的控制信号
(包括来自外部的和状态机内容的非主控进程的信号)或(和)当前状态值确定下一状态next_state的取值内容,以及对外或对内部其他进程输出控制信号的内容。

   ---Upper section of FSM----
  process(present_state)
  begin
  case present_state is
  when zero=>
       temp<='0';
       next_state<=one;
       when one=>
           temp<='1';
           next_state<=two;
       when two=>
           temp<='0';
           next_state<=three;
       when three=>
           temp<='1';
           next_state<=four;
       when four=>
           temp<='0';
           next_state<=five;
       when five=>
           temp<='1';
           next_state<=six;
       when six=>
           temp<='0';
           next_state<=seven;
       when seven=>
           temp<='0';
           next_state<=zero;
       end case;
      end process;
   end;

4) 辅助进程

用于配合状态机工作的组合、时序进程或配合状态机工作的其他时序进程。
在一般状态机的设计过程中,为了能获得可综合的,高效的VHDL状态机描述,建议使用枚举类数据类型来定义状态机的状态,并使用多进程方式来描述状态机的内部逻辑。例如,可使用两个进程来描述,—个进程描述时序逻辑,包括状态寄存器的工作和寄存器状态的输
出,另一个进程描述组合逻辑,包括进程间状态值的传递逻辑以及状态转换值的输出。必要时还可以引入第三个进程完成其它的逻辑功能。
综上所描述的信号发生器完整的代码(含分频):

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity generator is
port
     (
     clk,rst:in std_logic;
     clkdiv:inout std_logic;
     wave_d:inout std_logic_vector(7 downto 0);
     wave:out std_logic
     );
     end;
     architecture one of generator is
        type states is(zero,one,two,three,four,five,six,seven);
        signal present_state,next_state:states;
        signal temp:std_logic;
        signal clk_count:std_logic_vector(23 downto 0);
     begin 
       ----ckl=12MHZ,clkdiv=1HZ--------
       process(clk,rst)
       begin
       if rst='0' then clk_count<=(others=>'0');clkdiv<=not clkdiv;
         elsif(rising_edge(clk))then
            if(clk_count=6000000)then clk_count<=(others=>'0');clkdiv<=not clkdiv;
            else clk_count<=clk_count+1;
            end if;
           end if;
         end process;

   process(clkdiv)
   begin
   if(rising_edge(clkdiv))then
   if(present_state=zero)then wave_d<=(others=>'0');
   else wave_d<=wave_d(7 downto 0)&temp;
   end if;
   end if;
   end process;
    -----Lower section of FSM------
    process(clkdiv)
    begin
      if(rising_edge(clkdiv))then
      present_state<=next_state;
      wave<=temp;
      end if;
      end process;
   -----Upper section of FSM------
  process(present_state)
  begin
  case present_state is
  when zero=>
       temp<='0';
       next_state<=one;
       when one=>
           temp<='1';
           next_state<=two;
       when two=>
           temp<='0';
           next_state<=three;
       when three=>
           temp<='1';
           next_state<=four;
       when four=>
           temp<='0';
           next_state<=five;
       when five=>
           temp<='1';
           next_state<=six;
       when six=>
           temp<='0';
           next_state<=seven;
       when seven=>
           temp<='0';
           next_state<=zero;
       end case;
      end process;
   end;




三段式状态机是一种常见的有限状态机设计模式,在VHDL中经常被用于数字电路的设计。它将状态机分为三个部分:**当前状态寄存器、次态逻辑和输出逻辑**。这种结构清晰地分离了各个功能模块,使得代码更易于维护和理解。 ### 1. 当前状态寄存器 这部分负责存储当前的状态,并在时钟信号的驱动下更新到下一个状态。通常会使用一个`process`块来描述: ```vhdl -- 定义状态类型 type state_type is (S0, S1, S2); signal current_state, next_state : state_type; process(clk, reset) begin if reset = '1' then current_state <= S0; -- 初始化状态 elsif rising_edge(clk) then current_state <= next_state; -- 更新状态 end if; end process; ``` --- ### 2. 次态逻辑 这一部分根据输入条件计算出下一状态值。它是组合逻辑的一部分,决定了当前状态下应该转移到哪一个新状态。 ```vhdl process(current_state, input_signal) begin case current_state is when S0 => if input_signal = '1' then next_state <= S1; else next_state <= S0; end if; when S1 => if input_signal = '0' then next_state <= S2; else next_state <= S1; end if; when S2 => next_state <= S0; -- 回到初始状态 end case; end process; ``` --- ### 3. 输出逻辑 此部分生成状态机的输出结果,也是基于当前状态及可能的其他输入变量通过组合逻辑得出的结果。 ```vhdl process(current_state) begin output_signal <= '0'; -- 默认输出为低电平 case current_state is when S0 => output_signal <= '0'; when S1 => output_signal <= '1'; when S2 => output_signal <= '0'; end case; end process; ``` --- ### 总结 以上就是典型的三段式状态机设计框架: 1. **第一段**处理同步过程中的状态转换; 2. **第二段**提供确定性的次态选择规则; 3. **第三段**定义输出映射关系。 这种方式可以有效避免竞态冒险等问题,并且由于其良好的结构性适合复杂的硬件描述任务。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值