状态机常见的3种类型 状态机案例设计

电子说

1.3w人已加入

描述

1、状态机设计

Mealy 机方框图

寄存器

状态寄存器输出当前的信号,用来控制下一个状态是什么,和当前状态下的输出是什么。

Moore机方框图

寄存器

2、状态机---3种类型

二元的:(CPLD与阵列扇入比较多,寄存器比较少)

S1 = 001, S2 = 010, S3 = 011, S3 = 100,etc。。。

枚举的:

S1 = 100, S2 = 110, S3 = 101, S4 = 111,etc。。。

One Hot:每1 个状态机只有1个寄存器(FPGA触发器比较多)

S1 = 00000001, S2 =00000010,S3 = 00000100,etc。。。

3、对生剩余状态的处理

1、在CASE 语句中增加语句,对每个非法状态明确地给出状态轮换的指示;

2、用OTHERS语句来对未提及的状态做统一处理。

Moore 型状态机设计

摩尔型的有限状态机的输出只与当前状态有关,而与输入信号的当前值无关,且仅丰时钟信号边沿到来时才发生变化。

要实现这种结构,必须使用暂存信号(如 temp)来存储电路的输出值,当今信号在时钟边沿出现时才能够更新输出。

例:

library ieee;

use ieee.std_logic_1164.all;

entity s_machine2 is

port(

clk, reset : in std_logic;

x : in std_logic;

z : out std_logic

);

architecture behav of s_machine2 is

type m_state is(s0, s1, s2);

signal present_state, next_state : m_state;

signal temp : std_logic;

begin

-----------------------时序进程---------------------------

reg : process(reset, clk)

begin

if reset = ‘1’ then present_state 《= s0;

elsif clk = ‘1’ and clk‘event then

z 《=temp; --只有在时钟的上升沿时,输出才会发生变化。是同步输出。

prsent_state 《=nxet_state;

end if;

end process;

-------------------------组合进程-----------------------------

com : process(present_state, x)

begin

case prsent_state is

when s0 =》

if x = ’0‘ then next_state 《= s0;

else next_state 《= s1;

end if;

temp 《= ’0‘;

when s1 =》

if x = ’0‘ then next_state 《= s0;

else next_state 《= s2;

end if;

temp 《= ’0‘;

when s2 =》

if x = ’0‘; then next_state 《= s0; temp 《= ’1‘;

else next_state 《= s2; temp 《= ’0‘;

end if

end case;

end process;

end behv;

Mearly 型的有限状态机设计

米立状态机的输出信号是当前状态和输出信号的函数,它的输出在输入变化后立即发生变化,

不依赖时钟信号的同步。是异步输出。

例:

library ieee;

use ieee.std_logic_1164.all;

entity s_machine1 is

port(

clk, reset : in std_logic;

x : in std_logic;

z : out std_logic

);

end s_machine1;

architecture behav of s_machine2 is

type m_state is(s0, s1, s2);

signal present_state, next_state : m_state;

begin

-----------------------时序进程---------------------------

reg : process(reset, clk)

begin

if reset = ’1‘ then present_state 《= s0;

elsif clk = ’1‘ and clk’event then

prsent_state 《=nxet_state;

end if;

end process;

-------------------------组合进程-----------------------------

com : process(present_state, x)

begin

case prsent_state is

when s0 =》

if x = ‘0’ then next_state 《= s0;

else next_state 《= s1;

end if;

z 《= ‘0’;

when s1 =》

if x = ‘0’ then next_state 《= s0;

else next_state 《= s2;

end if;

z 《= ‘0’;

when s2 =》

if x = ‘0’; then next_state 《= s0; z 《= ‘1’;

else next_state 《= s2; z《= ‘0’;

end if

end case;

end process;

end behv;

可以看到在该程序中,只要输入有变化,输出z就会有变化,它并不依赖于时钟的上升沿。

怎样确保一个进程是组合进程:

1、不出现带沿的语句,即组合进程中决不能出现用时钟沿控制的敏感信号;

2、在组合电路的进程中,给出输出端口的缺省值,这样可以防止锁存器的生成;

3、在敏感清单中包含所有的输入量,防止锁存器的生成。

敏感清单不全的话综合时可能出现敬告。

例:下例敏感清单中输入端口不全,可能出现锁存器

p0 : process (a)

begin

q 《= a and b;

end process p0;

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

下面是一个实例,洗衣机的工作过程:

TYPE state_type IS(idle, fill, heat_w, wash, drain);

entity wm is

port(

clk, reset, door_closed, full : in std_logic;

heat_demand, done, empty : in std_logic;

water, spin, heat, pump : out std_logic

);

end wm;

architecture behave of wm is

------------------------说明部分--------------------------

--说明部分用枚举数据类型来字义状态机中的状态;并把状态变量(如现态和次态)定义为信号。

type state_type is (

idle, fill, heat_w, wash, drain);

signal state : state_type;

begin

process (clk, reset)

begin

if reset = ‘1’ then

state 《= idle;

elsif clk‘event and clk= ’1‘ then

case state is

when idle =》

if door_closed = ’1‘ then

state 《= fill;

else

state 《= idle;

end if

when fill =》

if full =’1‘; then

state 《= neat_w;

else

state 《= fill;

when others =》

state 《= idle;

end case

end if;

end process;

----------------------------------------------

利用两个进程(纯组合逻辑措施一)

--------------时序进程----------------------------

--时序进程是指在时钟驱动下负责状态转换的进程,只表示次态和现态的关系

process(clk, reset)

begin

if reset =’1‘ then

state 《= idle;

elsif clk’event and clk = ‘1’ then

state 《= next_state;

end if;

end process;

------------------组合进程---------------------

组合进程的任务是根据输入信号和现态对输出端口赋值以及确定状态机的下一个状态,由于没有任何信号

的赋值是通过其他某个信号的跳变来触发的,所以不会产生寄存器。一般用CASE 或IF语句来实现

process(state, door_closed, full,

heat_demand, done, empty)

begin

case state is

when idle =》

if door_closed =‘1’ then

next_state 《= fill;

else

next_state 《= idle;

end if;

when fill =》

if full = ‘1’ then

next_state 《= heat_w;

else

next_state 《= fill;

end case;

end if;

end process;

process(state)

begin

water_i 《= ‘0’;

spin_i 《= ‘0’;

heat_i 《= ‘0’;

pump_i 《= ‘0’;

case state is

when idle =》

when fill =》

water_i 《= ‘1’;

when heat_w =》

spin_i 《=‘1’;

heat_i 《= ‘1’;

when wash =》

spin_i 《= ‘1’;

when drain =》

spin_i 《= ‘1’;

pump_i 《= ‘i’;

end case;

end process;

--------------寄存输出---------------------

process (clk)

begin

if rising_edge(clk) then

water 《= water_i;

spin 《= spin_i;

heat 《= heat_i;

pump 《= pump_i;

end if;

end process

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分